Nothing to see here, move along meow
0

Configure Feed

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

at main 16 kB View raw
1use crate::cap::cnode; 2use crate::cap::pool::POOL; 3use crate::cap::retype::kernel_retype; 4use crate::proc::PROCESSES; 5use crate::tests::helpers; 6use lancer_core::header::KernelObjectHeader; 7use lancer_core::object_layout::{KernelObject, UntypedObject}; 8use lancer_core::object_tag::ObjectTag; 9 10crate::kernel_test!( 11 fn revoke_untyped_destroys_children() { 12 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 13 let mut ptable = PROCESSES.lock(); 14 let created = ptable.allocate(&mut allocator).expect("alloc"); 15 ptable.start(created).expect("start"); 16 let pid = created.pid(); 17 helpers::bootstrap_test_cnode(pid, &mut ptable); 18 19 let (ut_id, ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 20 let (cnode_id, cnode_gen, depth, gv, gb) = 21 cnode::cnode_coords(pid, &ptable).expect("coords"); 22 let dest_base = 50u64; 23 let count = 5u32; 24 25 { 26 let mut pool = POOL.lock_after(&ptable); 27 kernel_retype( 28 &mut pool, 29 None, 30 ut_id, 31 ut_gen, 32 ObjectTag::Endpoint, 33 0, 34 cnode_id, 35 cnode_gen, 36 dest_base, 37 depth, 38 gv, 39 gb, 40 count, 41 ) 42 .expect("retype 5 endpoints"); 43 } 44 45 (0..count as u64).for_each(|i| { 46 let pool = POOL.lock_after(&ptable); 47 let cap = 48 cnode::resolve_and_read(&pool, cnode_id, cnode_gen, dest_base + i, depth, gv, gb) 49 .expect("read slot before revoke"); 50 assert!(cap.tag() == ObjectTag::Endpoint); 51 }); 52 53 { 54 let mut pool = POOL.lock_after(&ptable); 55 crate::cap::derivation::destroy_children(&mut pool, &mut ptable, ut_id, ut_gen) 56 .expect("destroy_children"); 57 } 58 59 { 60 let pool = POOL.lock_after(&ptable); 61 let ut = pool 62 .read_as::<UntypedObject>(ut_id, ut_gen) 63 .expect("untyped still valid"); 64 assert!(ut.watermark == 0, "watermark must reset after revoke"); 65 assert!(ut.child_count == 0, "child_count must be 0 after revoke"); 66 assert!( 67 ut.first_child == lancer_core::header::NONE_SENTINEL, 68 "first_child must be sentinel after revoke" 69 ); 70 } 71 72 ptable.destroy(pid, &mut allocator); 73 } 74); 75 76crate::kernel_test!( 77 fn revoke_then_retype_succeeds() { 78 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 79 let mut ptable = PROCESSES.lock(); 80 let created = ptable.allocate(&mut allocator).expect("alloc"); 81 ptable.start(created).expect("start"); 82 let pid = created.pid(); 83 helpers::bootstrap_test_cnode(pid, &mut ptable); 84 85 let (ut_id, ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 86 let (cnode_id, cnode_gen, depth, gv, gb) = 87 cnode::cnode_coords(pid, &ptable).expect("coords"); 88 89 { 90 let mut pool = POOL.lock_after(&ptable); 91 kernel_retype( 92 &mut pool, 93 None, 94 ut_id, 95 ut_gen, 96 ObjectTag::Endpoint, 97 0, 98 cnode_id, 99 cnode_gen, 100 50, 101 depth, 102 gv, 103 gb, 104 3, 105 ) 106 .expect("first retype"); 107 } 108 109 { 110 let mut pool = POOL.lock_after(&ptable); 111 crate::cap::derivation::destroy_children(&mut pool, &mut ptable, ut_id, ut_gen) 112 .expect("destroy_children"); 113 } 114 115 { 116 let mut pool = POOL.lock_after(&ptable); 117 kernel_retype( 118 &mut pool, 119 None, 120 ut_id, 121 ut_gen, 122 ObjectTag::Endpoint, 123 0, 124 cnode_id, 125 cnode_gen, 126 60, 127 depth, 128 gv, 129 gb, 130 4, 131 ) 132 .expect("second retype after revoke must succeed"); 133 } 134 135 (0..4u64).for_each(|i| { 136 let pool = POOL.lock_after(&ptable); 137 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 60 + i, depth, gv, gb) 138 .expect("read re-retyped slot"); 139 assert!(cap.tag() == ObjectTag::Endpoint); 140 }); 141 142 ptable.destroy(pid, &mut allocator); 143 } 144); 145 146crate::kernel_test!( 147 fn delete_last_cap_unlinks_from_parent() { 148 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 149 let mut ptable = PROCESSES.lock(); 150 let created = ptable.allocate(&mut allocator).expect("alloc"); 151 ptable.start(created).expect("start"); 152 let pid = created.pid(); 153 helpers::bootstrap_test_cnode(pid, &mut ptable); 154 155 let (ut_id, ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 156 let (cnode_id, cnode_gen, depth, gv, gb) = 157 cnode::cnode_coords(pid, &ptable).expect("coords"); 158 let dest_base = 70u64; 159 let count = 3u32; 160 161 { 162 let mut pool = POOL.lock_after(&ptable); 163 kernel_retype( 164 &mut pool, 165 None, 166 ut_id, 167 ut_gen, 168 ObjectTag::Endpoint, 169 0, 170 cnode_id, 171 cnode_gen, 172 dest_base, 173 depth, 174 gv, 175 gb, 176 count, 177 ) 178 .expect("retype 3 endpoints"); 179 } 180 181 { 182 let pool = POOL.lock_after(&ptable); 183 let ut = pool 184 .read_as::<UntypedObject>(ut_id, ut_gen) 185 .expect("get ut"); 186 assert!(ut.child_count == 3, "3 children after retype"); 187 } 188 189 (0..count as u64).for_each(|i| { 190 let mut pool = POOL.lock_after(&ptable); 191 let cap = 192 cnode::resolve_and_clear(&pool, cnode_id, cnode_gen, dest_base + i, depth, gv, gb) 193 .expect("clear slot"); 194 let freed_id = cap.phys(); 195 if let Some((_phys, _tag)) = pool.dec_ref_phys(cap.phys(), cap.generation()) { 196 crate::cap::derivation::unlink_child(&mut pool, freed_id); 197 } 198 }); 199 200 { 201 let pool = POOL.lock_after(&ptable); 202 let ut = pool 203 .read_as::<UntypedObject>(ut_id, ut_gen) 204 .expect("get ut after deletes"); 205 assert!( 206 ut.child_count == 0, 207 "child_count must be 0 after all deletes" 208 ); 209 assert!( 210 ut.watermark == 0, 211 "watermark must reset when last child deleted" 212 ); 213 assert!( 214 ut.first_child == lancer_core::header::NONE_SENTINEL, 215 "first_child must be sentinel" 216 ); 217 } 218 219 ptable.destroy(pid, &mut allocator); 220 } 221); 222 223crate::kernel_test!( 224 fn revoke_nested_untypeds_cascades() { 225 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 226 let mut ptable = PROCESSES.lock(); 227 let created = ptable.allocate(&mut allocator).expect("alloc"); 228 ptable.start(created).expect("start"); 229 let pid = created.pid(); 230 helpers::bootstrap_test_cnode(pid, &mut ptable); 231 232 let (parent_ut_id, parent_ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 233 let (cnode_id, cnode_gen, depth, gv, gb) = 234 cnode::cnode_coords(pid, &ptable).expect("coords"); 235 236 let child_size_bits = 14u8; 237 let child_frames = 1usize << (child_size_bits - 12); 238 let child_phys = crate::mem::phys::BitmapFrameAllocator 239 .allocate_contiguous(child_frames) 240 .expect("alloc child untyped backing"); 241 let child_virt = crate::mem::addr::phys_to_virt(child_phys); 242 unsafe { 243 core::ptr::write_bytes(child_virt.as_mut_ptr::<u8>(), 0, child_frames * 4096); 244 } 245 246 let header = KernelObjectHeader::new(ObjectTag::Untyped, 0, 64); 247 let mut child_ut = UntypedObject::init_default(header); 248 child_ut.phys_base = child_phys.as_u64(); 249 child_ut.size_bits = child_size_bits; 250 child_ut.is_device = 0; 251 let child_slot_phys = 252 crate::cap::kernel_objects::alloc_slot().expect("alloc child ut slot"); 253 crate::cap::kernel_objects::write_at(child_slot_phys, child_ut); 254 255 let (child_ut_id, child_ut_gen) = { 256 let mut pool = POOL.lock_after(&ptable); 257 let (cid, cgen) = pool 258 .register_object(child_slot_phys, ObjectTag::Untyped) 259 .expect("register child ut"); 260 crate::cap::derivation::link_child(&mut pool, parent_ut_id, parent_ut_gen, cid) 261 .expect("link child untyped to parent"); 262 let cap = crate::cap::table::CapRef::new( 263 ObjectTag::Untyped, 264 cid, 265 crate::cap::table::Rights::ALL, 266 cgen, 267 ); 268 cnode::resolve_and_insert(&pool, cnode_id, cnode_gen, 80, depth, gv, gb, cap) 269 .expect("insert child untyped cap"); 270 (cid, cgen) 271 }; 272 273 { 274 let mut pool = POOL.lock_after(&ptable); 275 kernel_retype( 276 &mut pool, 277 None, 278 child_ut_id, 279 child_ut_gen, 280 ObjectTag::Endpoint, 281 0, 282 cnode_id, 283 cnode_gen, 284 81, 285 depth, 286 gv, 287 gb, 288 2, 289 ) 290 .expect("retype endpoints from child untyped"); 291 } 292 293 let ep_ids: [(crate::types::ObjPhys, crate::types::Generation); 2] = { 294 let pool = POOL.lock_after(&ptable); 295 let c0 = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 81, depth, gv, gb) 296 .expect("read ep 0"); 297 let c1 = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 82, depth, gv, gb) 298 .expect("read ep 1"); 299 [ 300 (c0.phys(), c0.generation()), 301 (c1.phys(), c1.generation()), 302 ] 303 }; 304 305 { 306 let mut pool = POOL.lock_after(&ptable); 307 crate::cap::derivation::destroy_children( 308 &mut pool, 309 &mut ptable, 310 parent_ut_id, 311 parent_ut_gen, 312 ) 313 .expect("destroy_children on parent"); 314 } 315 316 { 317 let pool = POOL.lock_after(&ptable); 318 let ut = pool 319 .read_as::<UntypedObject>(parent_ut_id, parent_ut_gen) 320 .expect("parent untyped still valid"); 321 assert!(ut.watermark == 0, "parent watermark must reset"); 322 assert!(ut.child_count == 0, "parent child_count must be 0"); 323 assert!( 324 ut.first_child == lancer_core::header::NONE_SENTINEL, 325 "parent first_child must be sentinel" 326 ); 327 328 assert!( 329 pool.get_tag(child_ut_id, child_ut_gen).is_err(), 330 "child untyped must be destroyed" 331 ); 332 333 ep_ids.iter().for_each(|&(eid, egen)| { 334 assert!( 335 pool.get_tag(eid, egen).is_err(), 336 "grandchild endpoint must be destroyed" 337 ); 338 }); 339 } 340 341 ptable.destroy(pid, &mut allocator); 342 } 343); 344 345crate::kernel_test!( 346 fn revoke_frame_caps_destroys_objects() { 347 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 348 let mut ptable = PROCESSES.lock(); 349 let created = ptable.allocate(&mut allocator).expect("alloc"); 350 ptable.start(created).expect("start"); 351 let pid = created.pid(); 352 helpers::bootstrap_test_cnode(pid, &mut ptable); 353 354 let (ut_id, ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 355 let (cnode_id, cnode_gen, depth, gv, gb) = 356 cnode::cnode_coords(pid, &ptable).expect("coords"); 357 358 { 359 let mut pool = POOL.lock_after(&ptable); 360 kernel_retype( 361 &mut pool, 362 None, 363 ut_id, 364 ut_gen, 365 ObjectTag::Frame, 366 12, 367 cnode_id, 368 cnode_gen, 369 90, 370 depth, 371 gv, 372 gb, 373 2, 374 ) 375 .expect("retype 2 frames"); 376 } 377 378 let frame_ids: [(crate::types::ObjPhys, crate::types::Generation); 2] = { 379 let pool = POOL.lock_after(&ptable); 380 let cap0 = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 90, depth, gv, gb) 381 .expect("read frame 0"); 382 let cap1 = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 91, depth, gv, gb) 383 .expect("read frame 1"); 384 [ 385 (cap0.phys(), cap0.generation()), 386 (cap1.phys(), cap1.generation()), 387 ] 388 }; 389 390 { 391 let mut pool = POOL.lock_after(&ptable); 392 crate::cap::derivation::destroy_children(&mut pool, &mut ptable, ut_id, ut_gen) 393 .expect("destroy_children"); 394 } 395 396 { 397 let pool = POOL.lock_after(&ptable); 398 frame_ids.iter().for_each(|&(fid, fgen)| { 399 assert!( 400 pool.get_tag(fid, fgen).is_err(), 401 "frame object must be destroyed" 402 ); 403 }); 404 405 let ut = pool 406 .read_as::<UntypedObject>(ut_id, ut_gen) 407 .expect("untyped still valid"); 408 assert!(ut.watermark == 0, "watermark must reset"); 409 assert!(ut.child_count == 0, "child_count must be 0"); 410 } 411 412 ptable.destroy(pid, &mut allocator); 413 } 414); 415 416crate::kernel_test!( 417 fn revoke_with_active_tcb() { 418 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 419 let mut ptable = PROCESSES.lock(); 420 let created = ptable.allocate(&mut allocator).expect("alloc"); 421 ptable.start(created).expect("start"); 422 let pid = created.pid(); 423 helpers::bootstrap_test_cnode(pid, &mut ptable); 424 425 let (ut_id, ut_gen, _phys) = helpers::allocate_untyped(&ptable, false); 426 let (cnode_id, cnode_gen, depth, gv, gb) = 427 cnode::cnode_coords(pid, &ptable).expect("coords"); 428 429 { 430 let mut pool = POOL.lock_after(&ptable); 431 kernel_retype( 432 &mut pool, 433 Some(&mut ptable), 434 ut_id, 435 ut_gen, 436 ObjectTag::Process, 437 0, 438 cnode_id, 439 cnode_gen, 440 95, 441 depth, 442 gv, 443 gb, 444 1, 445 ) 446 .expect("retype process from untyped"); 447 } 448 449 let (proc_obj_id, proc_obj_gen) = { 450 let pool = POOL.lock_after(&ptable); 451 let cap = cnode::resolve_and_read(&pool, cnode_id, cnode_gen, 95, depth, gv, gb) 452 .expect("read process cap"); 453 assert!(cap.tag() == ObjectTag::Process); 454 (cap.phys(), cap.generation()) 455 }; 456 457 { 458 let mut pool = POOL.lock_after(&ptable); 459 crate::cap::derivation::destroy_children(&mut pool, &mut ptable, ut_id, ut_gen) 460 .expect("destroy_children with tcb"); 461 } 462 463 { 464 let pool = POOL.lock_after(&ptable); 465 assert!( 466 pool.get_tag(proc_obj_id, proc_obj_gen).is_err(), 467 "process object must be destroyed" 468 ); 469 470 let ut = pool 471 .read_as::<UntypedObject>(ut_id, ut_gen) 472 .expect("untyped still valid"); 473 assert!(ut.watermark == 0, "watermark must reset"); 474 } 475 476 ptable.destroy(pid, &mut allocator); 477 } 478);