Nothing to see here, move along meow
0

Configure Feed

Select the types of activity you want to include in your feed.

at main 9.7 kB View raw
1use lancer_core::header::{NONE_SENTINEL, obj_link_to_phys, phys_to_obj_link}; 2use lancer_core::header::KernelObjectHeader; 3use lancer_core::object_layout::UntypedObject; 4use lancer_core::object_tag::ObjectTag; 5 6use super::pool::ObjectPool; 7use crate::error::KernelError; 8use crate::mem::addr; 9use crate::types::{Generation, ObjPhys}; 10use x86_64::PhysAddr; 11 12const MAX_REVOKE_DEPTH: u8 = 16; 13const MAX_CHILDREN_WALK: u32 = 65535; 14 15pub fn link_child( 16 pool: &mut ObjectPool, 17 parent_phys: ObjPhys, 18 parent_gen: Generation, 19 child_phys: ObjPhys, 20) -> Result<(), KernelError> { 21 let ut = pool.write_as::<UntypedObject>(parent_phys, parent_gen)?; 22 let old_first = ut.first_child; 23 ut.first_child = phys_to_obj_link(child_phys.raw()); 24 25 let child_hdr = unsafe { 26 &mut *(addr::phys_to_virt(PhysAddr::new(child_phys.raw())).as_mut_ptr::<KernelObjectHeader>()) 27 }; 28 child_hdr.set_parent_untyped(phys_to_obj_link(parent_phys.raw())); 29 child_hdr.set_next_child(old_first); 30 Ok(()) 31} 32 33pub fn unlink_child(pool: &mut ObjectPool, child_phys: ObjPhys) { 34 let child_hdr = unsafe { 35 &*(addr::phys_to_virt(PhysAddr::new(child_phys.raw())).as_ptr::<KernelObjectHeader>()) 36 }; 37 let parent_link = child_hdr.parent_untyped(); 38 if parent_link == NONE_SENTINEL { 39 return; 40 } 41 42 let parent_phys = ObjPhys::new(obj_link_to_phys(parent_link)); 43 44 let parent_gen = match pool.generation_of(parent_phys) { 45 Some(g) => g, 46 None => { 47 let child_hdr_mut = unsafe { 48 &mut *(addr::phys_to_virt(PhysAddr::new(child_phys.raw())) 49 .as_mut_ptr::<KernelObjectHeader>()) 50 }; 51 child_hdr_mut.set_parent_untyped(NONE_SENTINEL); 52 child_hdr_mut.set_next_child(NONE_SENTINEL); 53 return; 54 } 55 }; 56 57 let parent_generation = Generation::new(parent_gen); 58 let splice_result = splice_child_from_parent(pool, parent_phys, parent_generation, child_phys); 59 60 let child_hdr_mut = unsafe { 61 &mut *(addr::phys_to_virt(PhysAddr::new(child_phys.raw())).as_mut_ptr::<KernelObjectHeader>()) 62 }; 63 child_hdr_mut.set_parent_untyped(NONE_SENTINEL); 64 child_hdr_mut.set_next_child(NONE_SENTINEL); 65 66 if splice_result && let Ok(ut) = pool.write_as::<UntypedObject>(parent_phys, parent_generation) { 67 let mut state = ut.to_state(); 68 let all_gone = state.remove_child(); 69 if all_gone { 70 state.reset_watermark(); 71 } 72 ut.apply_state(&state); 73 if all_gone { 74 ut.first_child = NONE_SENTINEL; 75 } 76 } 77} 78 79fn splice_child_from_parent( 80 pool: &mut ObjectPool, 81 parent_phys: ObjPhys, 82 parent_gen: Generation, 83 child_phys: ObjPhys, 84) -> bool { 85 let first_link = match pool.read_as::<UntypedObject>(parent_phys, parent_gen) { 86 Ok(ut) => ut.first_child, 87 Err(_) => return false, 88 }; 89 90 match first_link { 91 NONE_SENTINEL => return false, 92 _ => {} 93 } 94 95 let child_link = phys_to_obj_link(child_phys.raw()); 96 97 if first_link == child_link { 98 let child_hdr = unsafe { 99 &*(addr::phys_to_virt(PhysAddr::new(child_phys.raw())).as_ptr::<KernelObjectHeader>()) 100 }; 101 let next = child_hdr.next_child(); 102 if let Ok(ut) = pool.write_as::<UntypedObject>(parent_phys, parent_gen) { 103 ut.first_child = next; 104 } 105 return true; 106 } 107 108 let mut prev_phys = obj_link_to_phys(first_link); 109 let mut steps = 0u32; 110 loop { 111 if steps >= MAX_CHILDREN_WALK { 112 return false; 113 } 114 steps += 1; 115 116 let prev_hdr = unsafe { 117 &*(addr::phys_to_virt(PhysAddr::new(prev_phys)).as_ptr::<KernelObjectHeader>()) 118 }; 119 let next_link = prev_hdr.next_child(); 120 match next_link { 121 NONE_SENTINEL => return false, 122 link if link == child_link => { 123 let child_hdr = unsafe { 124 &*(addr::phys_to_virt(PhysAddr::new(child_phys.raw())) 125 .as_ptr::<KernelObjectHeader>()) 126 }; 127 let child_next = child_hdr.next_child(); 128 let prev_hdr_mut = unsafe { 129 &mut *(addr::phys_to_virt(PhysAddr::new(prev_phys)) 130 .as_mut_ptr::<KernelObjectHeader>()) 131 }; 132 prev_hdr_mut.set_next_child(child_next); 133 return true; 134 } 135 link => prev_phys = obj_link_to_phys(link), 136 } 137 } 138} 139 140pub fn destroy_children( 141 pool: &mut ObjectPool, 142 ptable: &mut crate::proc::ProcessManager, 143 untyped_phys: ObjPhys, 144 untyped_gen: Generation, 145) -> Result<(), KernelError> { 146 destroy_children_inner(pool, ptable, untyped_phys, untyped_gen, 0) 147} 148 149fn destroy_children_inner( 150 pool: &mut ObjectPool, 151 ptable: &mut crate::proc::ProcessManager, 152 untyped_phys: ObjPhys, 153 untyped_gen: Generation, 154 depth: u8, 155) -> Result<(), KernelError> { 156 if depth >= MAX_REVOKE_DEPTH { 157 return Err(KernelError::DepthLimit); 158 } 159 160 let first_child_link = { 161 let ut = pool.read_as::<UntypedObject>(untyped_phys, untyped_gen)?; 162 ut.first_child 163 }; 164 165 let mut current_link = match first_child_link { 166 NONE_SENTINEL => return Ok(()), 167 link => link, 168 }; 169 170 let mut steps = 0u32; 171 loop { 172 if current_link == NONE_SENTINEL || steps >= MAX_CHILDREN_WALK { 173 break; 174 } 175 steps += 1; 176 177 let current_phys = ObjPhys::new(obj_link_to_phys(current_link)); 178 179 let child_hdr = unsafe { 180 &*(addr::phys_to_virt(PhysAddr::new(current_phys.raw())).as_ptr::<KernelObjectHeader>()) 181 }; 182 let next_sibling_link = child_hdr.next_child(); 183 184 let child_gen = match pool.generation_of(current_phys) { 185 Some(g) => g, 186 None => { 187 let child_hdr_mut = unsafe { 188 &mut *(addr::phys_to_virt(PhysAddr::new(current_phys.raw())) 189 .as_mut_ptr::<KernelObjectHeader>()) 190 }; 191 child_hdr_mut.set_parent_untyped(NONE_SENTINEL); 192 child_hdr_mut.set_next_child(NONE_SENTINEL); 193 current_link = next_sibling_link; 194 continue; 195 } 196 }; 197 198 let child_generation = Generation::new(child_gen); 199 200 let child_tag = match pool.get_tag(current_phys, child_generation) { 201 Ok(tag) => tag, 202 Err(_) => { 203 let child_hdr_mut = unsafe { 204 &mut *(addr::phys_to_virt(PhysAddr::new(current_phys.raw())) 205 .as_mut_ptr::<KernelObjectHeader>()) 206 }; 207 child_hdr_mut.set_parent_untyped(NONE_SENTINEL); 208 child_hdr_mut.set_next_child(NONE_SENTINEL); 209 current_link = next_sibling_link; 210 continue; 211 } 212 }; 213 214 let stale_gen = child_generation; 215 216 match child_tag { 217 ObjectTag::Untyped => { 218 destroy_children_inner(pool, ptable, current_phys, child_generation, depth + 1)?; 219 let _ = pool.revoke_phys(current_phys, child_generation); 220 } 221 222 ObjectTag::Process => { 223 let pid = pool 224 .read_as::<lancer_core::object_layout::ProcessObject>( 225 current_phys, 226 child_generation, 227 ) 228 .ok() 229 .and_then(|p| crate::types::Pid::try_new(p.pid)); 230 231 if let Some(pid) = pid { 232 ptable.force_destroy_with_pool(pid, pool); 233 } 234 235 let _ = pool.revoke_phys(current_phys, child_generation); 236 } 237 238 ObjectTag::CNode => { 239 let cnode_snapshot = pool 240 .read_as::<lancer_core::object_layout::CNodeObject>( 241 current_phys, 242 child_generation, 243 ) 244 .ok() 245 .map(|c| { 246 ( 247 x86_64::PhysAddr::new(c.slots_phys), 248 c.size_bits, 249 c.frame_count, 250 ) 251 }); 252 253 let _ = pool.revoke_phys(current_phys, child_generation); 254 255 if let Some((slots_phys, size_bits, frame_count)) = cnode_snapshot { 256 super::cnode::drain_cnode_phys( 257 slots_phys, 258 size_bits, 259 frame_count, 260 pool, 261 ptable, 262 ); 263 } 264 } 265 266 _ => { 267 let revoke_result = pool.revoke_phys(current_phys, child_generation); 268 if let Ok((_new_gen, Some((phys, tag)))) = revoke_result { 269 super::ops::cleanup_by_tag_with_ptable(tag, phys, ptable); 270 } 271 } 272 } 273 274 super::ops::invalidate_stale_caps_via_cnode(ptable, pool, current_phys, stale_gen); 275 276 let child_hdr_mut = unsafe { 277 &mut *(addr::phys_to_virt(PhysAddr::new(current_phys.raw())) 278 .as_mut_ptr::<KernelObjectHeader>()) 279 }; 280 child_hdr_mut.set_parent_untyped(NONE_SENTINEL); 281 child_hdr_mut.set_next_child(NONE_SENTINEL); 282 283 current_link = next_sibling_link; 284 } 285 286 let ut = pool.write_as::<UntypedObject>(untyped_phys, untyped_gen)?; 287 ut.first_child = NONE_SENTINEL; 288 let mut state = ut.to_state(); 289 state.reset_all_children(); 290 ut.apply_state(&state); 291 292 Ok(()) 293}