Nothing to see here, move along
at main 1247 lines 42 kB view raw
1use crate::cap::cnode; 2use crate::cap::object::{ 3 EndpointData, FramebufferData, IrqHandlerData, IrqSource, NotificationData, ObjectData, 4 ObjectTag, PciDeviceData, PortRange, ProcessObjectData, 5}; 6 7const COM1_PORTS: PortRange = match PortRange::new(0x3F8, 8) { 8 Some(pr) => pr, 9 None => unreachable!(), 10}; 11 12const PS2_KBD_PORTS: PortRange = match PortRange::new(0x60, 5) { 13 Some(pr) => pr, 14 None => unreachable!(), 15}; 16use crate::cap::pool::POOL; 17use crate::cap::table::{CapRef, Rights}; 18use crate::error::KernelError; 19use crate::types::Pid; 20 21const SLOT_SELF: u64 = 0; 22 23mod init_slots { 24 pub const SERIAL_EP: u64 = 1; 25 pub const FB_EP: u64 = 2; 26 pub const INIT_NOTIF: u64 = 9; 27 pub const NETSTACK_NOTIF: u64 = 10; 28 pub const VFS_PROC: u64 = 15; 29 pub const NETSTACK_RING_BASE: u64 = 288; 30 pub const NETSTACK_RING_FRAMES: u16 = 2; 31} 32 33mod irq_driver_slots { 34 pub const EP: u64 = 1; 35 pub const IRQ: u64 = 2; 36 pub const NOTIF: u64 = 3; 37} 38 39mod fbconsole_slots { 40 pub const EP: u64 = 1; 41 pub const FB: u64 = 2; 42 pub const CONSOLE_RING_BASE: u64 = 64; 43} 44 45pub fn bootstrap_root_cnode(pid: Pid, size_bits: u8) -> Result<(), KernelError> { 46 let allocator = &crate::mem::phys::BitmapFrameAllocator; 47 let cnode_data = cnode::create_cnode(size_bits, allocator)?; 48 let frame_count = cnode_data.frame_count; 49 let (cnode_id, cnode_gen) = POOL.lock().allocate(ObjectData::CNode(cnode_data))?; 50 let mut ptable = crate::proc::PROCESSES.lock(); 51 let proc = ptable 52 .get_mut(pid) 53 .ok_or(KernelError::InvalidObject)?; 54 proc.root_cnode = Some((cnode_id, cnode_gen)); 55 proc.cnode_depth = size_bits; 56 proc.charge_frames(frame_count as u16)?; 57 Ok(()) 58} 59 60fn install_cap(pid: Pid, slot: u64, data: ObjectData) -> Result<(), KernelError> { 61 let tag = data.tag(); 62 let (object_id, generation) = POOL.lock().allocate(data)?; 63 let cap = CapRef::new(tag, object_id, Rights::ALL, generation); 64 let ptable = crate::proc::PROCESSES.lock(); 65 let pool = POOL.lock_after(&ptable); 66 match cnode::resolve_caller_insert(pid, slot, cap, &ptable, &pool) { 67 Ok(()) => Ok(()), 68 Err(e) => { 69 drop(pool); 70 let r = POOL.lock_after(&ptable).free(object_id, generation); 71 debug_assert!(r.is_ok()); 72 Err(e) 73 } 74 } 75} 76 77fn insert_cap_into( 78 pid: Pid, 79 slot: u64, 80 cap: CapRef, 81 ptable: &crate::sync::IrqMutexGuard<'_, crate::proc::ProcessManager, 0>, 82) -> Result<(), KernelError> { 83 let pool = POOL.lock_after(ptable); 84 cnode::resolve_caller_insert(pid, slot, cap, ptable, &pool) 85} 86 87fn read_cap_from( 88 pid: Pid, 89 slot: u64, 90 expected_tag: ObjectTag, 91 required_rights: Rights, 92 ptable: &crate::sync::IrqMutexGuard<'_, crate::proc::ProcessManager, 0>, 93) -> Result<CapRef, KernelError> { 94 let pool = POOL.lock_after(ptable); 95 cnode::resolve_caller_validate(pid, slot, expected_tag, required_rights, ptable, &pool) 96} 97 98use crate::cap::object::FrameObjectData; 99 100fn create_shared_ring_frames( 101 pid_a: Pid, 102 base_slot_a: u64, 103 pid_b: Pid, 104 base_slot_b: u64, 105 frame_count: u16, 106) -> Result<(), KernelError> { 107 let allocator = crate::mem::phys::BitmapFrameAllocator; 108 (0..frame_count).try_fold((), |(), i| { 109 let owned = allocator.allocate().ok_or(KernelError::PoolExhausted)?; 110 let phys = owned.phys_addr(); 111 core::mem::forget(owned); 112 crate::mem::addr::zero_frame(phys); 113 crate::mem::refcount::increment(phys).map_err(|_| { 114 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys); 115 KernelError::ResourceExhausted 116 })?; 117 118 let data = ObjectData::Frame(FrameObjectData::new(phys)); 119 let tag = data.tag(); 120 let (obj_id, obj_gen) = POOL.lock().allocate(data).inspect_err(|_| { 121 let _ = crate::mem::refcount::decrement(phys); 122 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys); 123 })?; 124 let cap = CapRef::new(tag, obj_id, Rights::ALL, obj_gen); 125 126 let ptable = crate::proc::PROCESSES.lock(); 127 insert_cap_into(pid_a, base_slot_a + i as u64, cap, &ptable).inspect_err(|_| { 128 let r = POOL.lock_after(&ptable).free(obj_id, obj_gen); 129 debug_assert!(r.is_ok()); 130 let _ = crate::mem::refcount::decrement(phys); 131 crate::mem::phys::BitmapFrameAllocator::free_frame_by_addr(phys); 132 })?; 133 POOL.lock_after(&ptable).inc_ref(obj_id, obj_gen)?; 134 insert_cap_into(pid_b, base_slot_b + i as u64, cap, &ptable).inspect_err(|_| { 135 POOL.lock_after(&ptable).dec_ref(obj_id, obj_gen); 136 })?; 137 Ok(()) 138 }) 139} 140 141fn create_ring_frames_from_phys( 142 pid: Pid, 143 base_slot: u64, 144 phys_addrs: &[x86_64::PhysAddr], 145) -> Result<(), KernelError> { 146 phys_addrs.iter().enumerate().try_fold((), |(), (i, &phys)| { 147 crate::mem::refcount::increment(phys).map_err(|_| KernelError::ResourceExhausted)?; 148 let data = ObjectData::Frame(FrameObjectData::new(phys)); 149 install_cap(pid, base_slot + i as u64, data).inspect_err(|_| { 150 let _ = crate::mem::refcount::decrement(phys); 151 }) 152 }) 153} 154 155pub fn bootstrap_self_cap(pid: Pid, cnode_size_bits: u8) -> Result<(), KernelError> { 156 bootstrap_root_cnode(pid, cnode_size_bits)?; 157 install_cap(pid, SLOT_SELF, ObjectData::Process(ProcessObjectData { pid })) 158} 159 160pub fn bootstrap_serial_driver( 161 init_pid: Pid, 162 driver_pid: Pid, 163 com1_gsi: crate::arch::ioapic::Gsi, 164) -> Result<(), KernelError> { 165 let ep_data = ObjectData::Endpoint(EndpointData::new()); 166 let ep_tag = ep_data.tag(); 167 let (ep_id, ep_gen) = POOL.lock().allocate(ep_data)?; 168 let ep_cap = CapRef::new(ep_tag, ep_id, Rights::ALL, ep_gen); 169 170 { 171 let ptable = crate::proc::PROCESSES.lock(); 172 match insert_cap_into(init_pid, init_slots::SERIAL_EP, ep_cap, &ptable) { 173 Ok(()) => {} 174 Err(e) => { 175 let r = POOL.lock_after(&ptable).free(ep_id, ep_gen); 176 debug_assert!(r.is_ok()); 177 return Err(e); 178 } 179 } 180 POOL.lock_after(&ptable).inc_ref(ep_id, ep_gen)?; 181 match insert_cap_into(driver_pid, irq_driver_slots::EP, ep_cap, &ptable) { 182 Ok(()) => {} 183 Err(e) => { 184 POOL.lock_after(&ptable).dec_ref(ep_id, ep_gen); 185 return Err(e); 186 } 187 } 188 } 189 190 crate::show!(boot, 191 "endpoint obj {} shared pid {} slot {} <-> pid {} slot {}", 192 ep_id.raw(), 193 init_pid.raw(), 194 init_slots::SERIAL_EP, 195 driver_pid.raw(), 196 irq_driver_slots::EP 197 ); 198 199 let com1_vector = crate::arch::idt::COM1_VECTOR; 200 install_cap( 201 driver_pid, 202 irq_driver_slots::IRQ, 203 ObjectData::IrqHandler(IrqHandlerData { 204 vector: com1_vector, 205 source: IrqSource::Ioapic { gsi: com1_gsi }, 206 port_range: COM1_PORTS, 207 }), 208 )?; 209 210 let notif_data = ObjectData::Notification(NotificationData::new()); 211 let notif_tag = notif_data.tag(); 212 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?; 213 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen); 214 { 215 let ptable = crate::proc::PROCESSES.lock(); 216 insert_cap_into(driver_pid, irq_driver_slots::NOTIF, notif_cap, &ptable) 217 .inspect_err(|_| { 218 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen); 219 debug_assert!(r.is_ok()); 220 })?; 221 } 222 223 crate::irq::bind( 224 com1_vector, 225 IrqSource::Ioapic { gsi: com1_gsi }, 226 notif_id, 227 notif_gen, 228 crate::types::NotificationBit::ZERO, 229 )?; 230 231 crate::show!(boot, 232 "serial irq slot {} notif slot {} com1 gsi {} -> vec {}", 233 irq_driver_slots::IRQ, 234 irq_driver_slots::NOTIF, 235 com1_gsi, 236 com1_vector 237 ); 238 239 Ok(()) 240} 241 242pub fn bootstrap_ps2kbd( 243 init_pid: Pid, 244 ps2kbd_pid: Pid, 245 kbd_gsi: crate::arch::ioapic::Gsi, 246) -> Result<(), KernelError> { 247 let ep_cap = { 248 let ptable = crate::proc::PROCESSES.lock(); 249 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)? 250 }; 251 252 POOL.lock() 253 .inc_ref(ep_cap.object_id(), ep_cap.generation())?; 254 { 255 let ptable = crate::proc::PROCESSES.lock(); 256 insert_cap_into(ps2kbd_pid, irq_driver_slots::EP, ep_cap, &ptable) 257 .inspect_err(|_| { 258 POOL.lock_after(&ptable) 259 .dec_ref(ep_cap.object_id(), ep_cap.generation()); 260 })?; 261 } 262 263 let kbd_vector = crate::arch::idt::KBD_VECTOR; 264 install_cap( 265 ps2kbd_pid, 266 irq_driver_slots::IRQ, 267 ObjectData::IrqHandler(IrqHandlerData { 268 vector: kbd_vector, 269 source: IrqSource::Ioapic { gsi: kbd_gsi }, 270 port_range: PS2_KBD_PORTS, 271 }), 272 )?; 273 274 let notif_data = ObjectData::Notification(NotificationData::new()); 275 let notif_tag = notif_data.tag(); 276 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?; 277 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen); 278 { 279 let ptable = crate::proc::PROCESSES.lock(); 280 insert_cap_into(ps2kbd_pid, irq_driver_slots::NOTIF, notif_cap, &ptable) 281 .inspect_err(|_| { 282 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen); 283 debug_assert!(r.is_ok()); 284 })?; 285 } 286 287 crate::irq::bind( 288 kbd_vector, 289 IrqSource::Ioapic { gsi: kbd_gsi }, 290 notif_id, 291 notif_gen, 292 crate::types::NotificationBit::ZERO, 293 )?; 294 295 crate::show!(boot, 296 "ps2 kbd caps installed irq slot {} notification slot {} kbd gsi {} -> vector {}", 297 irq_driver_slots::IRQ, 298 irq_driver_slots::NOTIF, 299 kbd_gsi, 300 kbd_vector, 301 ); 302 303 Ok(()) 304} 305 306mod nvme_slots { 307 pub const EP: u64 = 1; 308 pub const PCI: u64 = 2; 309 pub const IRQ: u64 = 3; 310 pub const NOTIF: u64 = 4; 311 pub const CLIENT_NOTIF: u64 = 6; 312 pub const BLOCK_RING_BASE: u64 = 64; 313 pub const BLOCK_RING_FRAMES: u16 = 16; 314} 315 316mod fs_service_slots { 317 pub const NOTIF: u64 = 3; 318 pub const DRIVER_NOTIF: u64 = 4; 319 pub const BLOCK_RING_BASE: u64 = 64; 320} 321 322mod fs_service_client_slots { 323 pub const CLIENT_NOTIF: u64 = 6; 324 pub const CLIENT_RING_BASE: u64 = 96; 325} 326 327mod vfs_slots { 328 pub const NOTIF: u64 = 3; 329 pub const LANCERFS_NOTIF: u64 = 4; 330 pub const LANCERFS_RING_BASE: u64 = 64; 331 pub const LANCERFS_RING_FRAMES: u16 = 16; 332 pub const CLIENT0_RING_BASE: u64 = 160; 333 pub const CLIENT0_RING_FRAMES: u16 = 16; 334 pub const CLIENT0_NOTIF: u64 = 176; 335} 336 337mod ramfs_slots { 338 pub const NOTIF: u64 = 3; 339 pub const VFS_NOTIF: u64 = 4; 340 pub const CLIENT_RING_BASE: u64 = 64; 341} 342 343mod vfs_ramfs_slots { 344 pub const RAMFS_NOTIF: u64 = 6; 345 pub const RAMFS_RING_BASE: u64 = 96; 346 pub const RAMFS_RING_FRAMES: u16 = 16; 347} 348 349mod vfs_client_slots { 350 pub const NOTIF: u64 = 12; 351 pub const VFS_NOTIF: u64 = 13; 352 pub const CLIENT_RING_BASE: u64 = 320; 353} 354 355mod virtio_net_slots { 356 pub const EP: u64 = 1; 357 pub const PCI: u64 = 2; 358 pub const IRQ: u64 = 3; 359 pub const NOTIF: u64 = 4; 360 pub const NETSTACK_NOTIF: u64 = 7; 361 pub const PACKET_RING_BASE: u64 = 64; 362 pub const PACKET_RING_FRAMES: u16 = 16; 363} 364 365mod net_service_slots { 366 pub const EP: u64 = 1; 367 pub const NOTIF: u64 = 3; 368 pub const DRIVER_NOTIF: u64 = 4; 369 pub const SHELL_NOTIF: u64 = 6; 370 pub const INIT_NOTIF: u64 = 8; 371 pub const PACKET_RING_BASE: u64 = 64; 372 pub const SHELL_RING_BASE: u64 = 96; 373 pub const SHELL_RING_FRAMES: u16 = 4; 374 pub const INIT_RING_BASE: u64 = 128; 375} 376 377mod remote_shell_slots { 378 pub const EP: u64 = 1; 379 pub const NOTIF: u64 = 3; 380 pub const NETSTACK_NOTIF: u64 = 4; 381 pub const SHELL_RING_BASE: u64 = 64; 382 pub const VFS_RING_BASE: u64 = 128; 383 pub const VFS_RING_FRAMES: u16 = 16; 384} 385 386pub fn bootstrap_fbconsole(init_pid: Pid, fbconsole_pid: Pid) -> Result<(), KernelError> { 387 let fb = crate::arch::boot::framebuffer().ok_or(KernelError::NotFound)?; 388 389 let ep_data = ObjectData::Endpoint(EndpointData::new()); 390 let ep_tag = ep_data.tag(); 391 let (ep_id, ep_gen) = POOL.lock().allocate(ep_data)?; 392 let ep_cap = CapRef::new(ep_tag, ep_id, Rights::ALL, ep_gen); 393 394 { 395 let ptable = crate::proc::PROCESSES.lock(); 396 insert_cap_into(init_pid, init_slots::FB_EP, ep_cap, &ptable) 397 .inspect_err(|_| { 398 let r = POOL.lock_after(&ptable).free(ep_id, ep_gen); 399 debug_assert!(r.is_ok()); 400 })?; 401 POOL.lock_after(&ptable).inc_ref(ep_id, ep_gen)?; 402 insert_cap_into(fbconsole_pid, fbconsole_slots::EP, ep_cap, &ptable) 403 .inspect_err(|_| { 404 POOL.lock_after(&ptable).dec_ref(ep_id, ep_gen); 405 })?; 406 } 407 408 crate::show!(boot, 409 "fb endpoint obj {} shared pid {} slot {} <-> pid {} slot {}", 410 ep_id.raw(), 411 init_pid.raw(), 412 init_slots::FB_EP, 413 fbconsole_pid.raw(), 414 fbconsole_slots::EP, 415 ); 416 417 let fb_phys = fb.addr() as u64 - crate::mem::addr::hhdm_offset(); 418 let fb_byte_size = fb 419 .pitch() 420 .checked_mul(fb.height()) 421 .ok_or(KernelError::InvalidParameter)?; 422 let page_count = fb_byte_size.div_ceil(4096); 423 crate::show!(boot, 424 "fb phys {:#x} {} bytes {} pages pitch {} {}x{} {}bpp", 425 fb_phys, 426 fb_byte_size, 427 page_count, 428 fb.pitch(), 429 fb.width(), 430 fb.height(), 431 fb.bpp(), 432 ); 433 let fb_data = FramebufferData::new( 434 fb_phys, 435 fb.width() as u32, 436 fb.height() as u32, 437 fb.pitch() as u32, 438 fb.bpp(), 439 fb_byte_size, 440 ) 441 .ok_or(KernelError::InvalidParameter)?; 442 443 install_cap( 444 fbconsole_pid, 445 fbconsole_slots::FB, 446 ObjectData::Framebuffer(fb_data), 447 )?; 448 449 let ring_frame_count = crate::console::phys_frame_count(); 450 if ring_frame_count > 0 { 451 let mut ring_phys: [x86_64::PhysAddr; 16] = [x86_64::PhysAddr::zero(); 16]; 452 (0..ring_frame_count).fold((), |(), i| { 453 ring_phys[i as usize] = crate::console::phys_addr(i).unwrap(); 454 }); 455 456 create_ring_frames_from_phys( 457 fbconsole_pid, 458 fbconsole_slots::CONSOLE_RING_BASE, 459 &ring_phys[..ring_frame_count as usize], 460 )?; 461 462 crate::show!(boot, 463 "console ring granted to fbconsole {} frames at base slot {}", 464 ring_frame_count, 465 fbconsole_slots::CONSOLE_RING_BASE, 466 ); 467 } 468 469 crate::show!(boot, 470 "fbconsole caps installed endpoint slot {} framebuffer slot {}", 471 fbconsole_slots::EP, 472 fbconsole_slots::FB, 473 ); 474 475 Ok(()) 476} 477 478pub fn bootstrap_nvme( 479 init_pid: Pid, 480 driver_pid: Pid, 481 device_table_idx: u8, 482 mapper: &mut x86_64::structures::paging::OffsetPageTable, 483 allocator: &mut crate::mem::phys::BitmapFrameAllocator, 484 hhdm_offset: u64, 485) -> Result<(), KernelError> { 486 let ep_cap = { 487 let ptable = crate::proc::PROCESSES.lock(); 488 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)? 489 }; 490 491 POOL.lock() 492 .inc_ref(ep_cap.object_id(), ep_cap.generation())?; 493 { 494 let ptable = crate::proc::PROCESSES.lock(); 495 insert_cap_into(driver_pid, nvme_slots::EP, ep_cap, &ptable) 496 .inspect_err(|_| { 497 POOL.lock_after(&ptable) 498 .dec_ref(ep_cap.object_id(), ep_cap.generation()); 499 })?; 500 } 501 502 install_cap( 503 driver_pid, 504 nvme_slots::PCI, 505 ObjectData::PciDevice(PciDeviceData { device_table_idx }), 506 )?; 507 508 crate::pci::enable_bus_master(device_table_idx)?; 509 510 if crate::iommu::is_available() { 511 crate::iommu::setup_device_context(device_table_idx, driver_pid, allocator, hhdm_offset)?; 512 } 513 514 let nvme_vector = crate::arch::idt::NVME_VECTOR; 515 let dummy_ports = match PortRange::new(0, 1) { 516 Some(pr) => pr, 517 None => return Err(KernelError::InvalidParameter), 518 }; 519 520 crate::pci::msix::ensure_table_mapped(device_table_idx, mapper, allocator, hhdm_offset)?; 521 crate::pci::msix::configure_entry(device_table_idx, 0, nvme_vector, 0)?; 522 crate::pci::msix::enable_msix(device_table_idx)?; 523 crate::pci::msix::unmask_entry(device_table_idx, 0)?; 524 crate::show!(boot, "nvme msi-x configured entry 0 -> vector {}", nvme_vector); 525 526 let irq_source = IrqSource::Msix { 527 device_table_idx, 528 entry_idx: 0, 529 }; 530 531 install_cap( 532 driver_pid, 533 nvme_slots::IRQ, 534 ObjectData::IrqHandler(IrqHandlerData { 535 vector: nvme_vector, 536 source: irq_source, 537 port_range: dummy_ports, 538 }), 539 )?; 540 541 let notif_data = ObjectData::Notification(NotificationData::new()); 542 let notif_tag = notif_data.tag(); 543 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?; 544 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen); 545 { 546 let ptable = crate::proc::PROCESSES.lock(); 547 insert_cap_into(driver_pid, nvme_slots::NOTIF, notif_cap, &ptable) 548 .inspect_err(|_| { 549 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen); 550 debug_assert!(r.is_ok()); 551 })?; 552 } 553 554 crate::irq::bind( 555 nvme_vector, 556 irq_source, 557 notif_id, 558 notif_gen, 559 crate::types::NotificationBit::ZERO, 560 )?; 561 562 crate::show!(boot, 563 "nvme caps installed pci slot {} irq slot {} notification slot {} vector {}", 564 nvme_slots::PCI, 565 nvme_slots::IRQ, 566 nvme_slots::NOTIF, 567 nvme_vector, 568 ); 569 570 Ok(()) 571} 572 573pub fn bootstrap_nvme_service(driver_pid: Pid, client_pid: Pid) -> Result<(), KernelError> { 574 create_shared_ring_frames( 575 driver_pid, 576 nvme_slots::BLOCK_RING_BASE, 577 client_pid, 578 fs_service_slots::BLOCK_RING_BASE, 579 nvme_slots::BLOCK_RING_FRAMES, 580 )?; 581 582 let client_notif_data = ObjectData::Notification(NotificationData::new()); 583 let client_notif_tag = client_notif_data.tag(); 584 let (client_notif_id, client_notif_gen) = POOL.lock().allocate(client_notif_data)?; 585 let client_notif_cap = CapRef::new( 586 client_notif_tag, 587 client_notif_id, 588 Rights::ALL, 589 client_notif_gen, 590 ); 591 { 592 let ptable = crate::proc::PROCESSES.lock(); 593 insert_cap_into(client_pid, fs_service_slots::NOTIF, client_notif_cap, &ptable) 594 .inspect_err(|_| { 595 let r = POOL 596 .lock_after(&ptable) 597 .free(client_notif_id, client_notif_gen); 598 debug_assert!(r.is_ok()); 599 })?; 600 POOL.lock_after(&ptable) 601 .inc_ref(client_notif_id, client_notif_gen)?; 602 insert_cap_into(driver_pid, nvme_slots::CLIENT_NOTIF, client_notif_cap, &ptable) 603 .inspect_err(|_| { 604 POOL.lock_after(&ptable) 605 .dec_ref(client_notif_id, client_notif_gen); 606 })?; 607 } 608 609 let driver_notif_cap = { 610 let ptable = crate::proc::PROCESSES.lock(); 611 read_cap_from(driver_pid, nvme_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 612 }; 613 POOL.lock() 614 .inc_ref(driver_notif_cap.object_id(), driver_notif_cap.generation())?; 615 { 616 let ptable = crate::proc::PROCESSES.lock(); 617 insert_cap_into(client_pid, fs_service_slots::DRIVER_NOTIF, driver_notif_cap, &ptable) 618 .inspect_err(|_| { 619 POOL.lock_after(&ptable) 620 .dec_ref(driver_notif_cap.object_id(), driver_notif_cap.generation()); 621 })?; 622 } 623 624 crate::show!(boot, 625 "nvme service caps ring base {}/{} notif slots {}/{} driver-notif slot {}", 626 nvme_slots::BLOCK_RING_BASE, 627 fs_service_slots::BLOCK_RING_BASE, 628 nvme_slots::CLIENT_NOTIF, 629 fs_service_slots::NOTIF, 630 fs_service_slots::DRIVER_NOTIF, 631 ); 632 633 Ok(()) 634} 635 636pub fn bootstrap_vfs_lancerfs(vfs_pid: Pid, lancerfs_pid: Pid) -> Result<(), KernelError> { 637 create_shared_ring_frames( 638 vfs_pid, 639 vfs_slots::LANCERFS_RING_BASE, 640 lancerfs_pid, 641 fs_service_client_slots::CLIENT_RING_BASE, 642 vfs_slots::LANCERFS_RING_FRAMES, 643 )?; 644 645 let vfs_notif_data = ObjectData::Notification(NotificationData::new()); 646 let vfs_notif_tag = vfs_notif_data.tag(); 647 let (vfs_notif_id, vfs_notif_gen) = POOL.lock().allocate(vfs_notif_data)?; 648 let vfs_notif_cap = CapRef::new(vfs_notif_tag, vfs_notif_id, Rights::ALL, vfs_notif_gen); 649 { 650 let ptable = crate::proc::PROCESSES.lock(); 651 insert_cap_into(vfs_pid, vfs_slots::NOTIF, vfs_notif_cap, &ptable) 652 .inspect_err(|_| { 653 let r = POOL.lock_after(&ptable).free(vfs_notif_id, vfs_notif_gen); 654 debug_assert!(r.is_ok()); 655 })?; 656 POOL.lock_after(&ptable) 657 .inc_ref(vfs_notif_id, vfs_notif_gen)?; 658 insert_cap_into(lancerfs_pid, fs_service_client_slots::CLIENT_NOTIF, vfs_notif_cap, &ptable) 659 .inspect_err(|_| { 660 POOL.lock_after(&ptable) 661 .dec_ref(vfs_notif_id, vfs_notif_gen); 662 })?; 663 } 664 665 let lancerfs_notif_cap = { 666 let ptable = crate::proc::PROCESSES.lock(); 667 read_cap_from(lancerfs_pid, fs_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 668 }; 669 POOL.lock().inc_ref( 670 lancerfs_notif_cap.object_id(), 671 lancerfs_notif_cap.generation(), 672 )?; 673 { 674 let ptable = crate::proc::PROCESSES.lock(); 675 insert_cap_into(vfs_pid, vfs_slots::LANCERFS_NOTIF, lancerfs_notif_cap, &ptable) 676 .inspect_err(|_| { 677 POOL.lock_after(&ptable).dec_ref( 678 lancerfs_notif_cap.object_id(), 679 lancerfs_notif_cap.generation(), 680 ); 681 })?; 682 } 683 684 crate::show!(boot, 685 "vfs-lancerfs caps ring base {}/{} vfs-notif slots {}/{} lancerfs-notif slot {}", 686 vfs_slots::LANCERFS_RING_BASE, 687 fs_service_client_slots::CLIENT_RING_BASE, 688 vfs_slots::NOTIF, 689 fs_service_client_slots::CLIENT_NOTIF, 690 vfs_slots::LANCERFS_NOTIF, 691 ); 692 693 Ok(()) 694} 695 696pub fn bootstrap_vfs_ramfs(vfs_pid: Pid, ramfs_pid: Pid) -> Result<(), KernelError> { 697 create_shared_ring_frames( 698 vfs_pid, 699 vfs_ramfs_slots::RAMFS_RING_BASE, 700 ramfs_pid, 701 ramfs_slots::CLIENT_RING_BASE, 702 vfs_ramfs_slots::RAMFS_RING_FRAMES, 703 )?; 704 705 let vfs_notif_cap = { 706 let ptable = crate::proc::PROCESSES.lock(); 707 match read_cap_from(vfs_pid, vfs_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable) { 708 Ok(cap) => { 709 drop(ptable); 710 POOL.lock().inc_ref(cap.object_id(), cap.generation())?; 711 cap 712 } 713 Err(_) => { 714 drop(ptable); 715 let notif_data = ObjectData::Notification(NotificationData::new()); 716 let notif_tag = notif_data.tag(); 717 let (nid, ngen) = POOL.lock().allocate(notif_data)?; 718 let cap = CapRef::new(notif_tag, nid, Rights::ALL, ngen); 719 let ptable = crate::proc::PROCESSES.lock(); 720 insert_cap_into(vfs_pid, vfs_slots::NOTIF, cap, &ptable) 721 .inspect_err(|_| { 722 let r = POOL.lock_after(&ptable).free(nid, ngen); 723 debug_assert!(r.is_ok()); 724 })?; 725 cap 726 } 727 } 728 }; 729 { 730 POOL.lock() 731 .inc_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation())?; 732 let ptable = crate::proc::PROCESSES.lock(); 733 insert_cap_into(ramfs_pid, ramfs_slots::VFS_NOTIF, vfs_notif_cap, &ptable) 734 .inspect_err(|_| { 735 POOL.lock_after(&ptable) 736 .dec_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation()); 737 })?; 738 } 739 740 let ramfs_notif_data = ObjectData::Notification(NotificationData::new()); 741 let ramfs_notif_tag = ramfs_notif_data.tag(); 742 let (ramfs_notif_id, ramfs_notif_gen) = POOL.lock().allocate(ramfs_notif_data)?; 743 let ramfs_notif_cap = CapRef::new( 744 ramfs_notif_tag, 745 ramfs_notif_id, 746 Rights::ALL, 747 ramfs_notif_gen, 748 ); 749 { 750 let ptable = crate::proc::PROCESSES.lock(); 751 insert_cap_into(ramfs_pid, ramfs_slots::NOTIF, ramfs_notif_cap, &ptable) 752 .inspect_err(|_| { 753 let r = POOL 754 .lock_after(&ptable) 755 .free(ramfs_notif_id, ramfs_notif_gen); 756 debug_assert!(r.is_ok()); 757 })?; 758 POOL.lock_after(&ptable) 759 .inc_ref(ramfs_notif_id, ramfs_notif_gen)?; 760 insert_cap_into(vfs_pid, vfs_ramfs_slots::RAMFS_NOTIF, ramfs_notif_cap, &ptable) 761 .inspect_err(|_| { 762 POOL.lock_after(&ptable) 763 .dec_ref(ramfs_notif_id, ramfs_notif_gen); 764 })?; 765 } 766 767 crate::show!(boot, 768 "vfs-ramfs caps ring base {}/{} vfs-notif slot {} ramfs-notif slots {}/{}", 769 vfs_ramfs_slots::RAMFS_RING_BASE, 770 ramfs_slots::CLIENT_RING_BASE, 771 ramfs_slots::VFS_NOTIF, 772 ramfs_slots::NOTIF, 773 vfs_ramfs_slots::RAMFS_NOTIF, 774 ); 775 776 Ok(()) 777} 778 779pub fn bootstrap_vfs_client(client_pid: Pid, vfs_pid: Pid) -> Result<(), KernelError> { 780 create_shared_ring_frames( 781 client_pid, 782 vfs_client_slots::CLIENT_RING_BASE, 783 vfs_pid, 784 vfs_slots::CLIENT0_RING_BASE, 785 vfs_slots::CLIENT0_RING_FRAMES, 786 )?; 787 788 let client_notif_data = ObjectData::Notification(NotificationData::new()); 789 let client_notif_tag = client_notif_data.tag(); 790 let (client_notif_id, client_notif_gen) = POOL.lock().allocate(client_notif_data)?; 791 let client_notif_cap = CapRef::new( 792 client_notif_tag, 793 client_notif_id, 794 Rights::ALL, 795 client_notif_gen, 796 ); 797 { 798 let ptable = crate::proc::PROCESSES.lock(); 799 insert_cap_into(client_pid, vfs_client_slots::NOTIF, client_notif_cap, &ptable) 800 .inspect_err(|_| { 801 let r = POOL 802 .lock_after(&ptable) 803 .free(client_notif_id, client_notif_gen); 804 debug_assert!(r.is_ok()); 805 })?; 806 POOL.lock_after(&ptable) 807 .inc_ref(client_notif_id, client_notif_gen)?; 808 insert_cap_into(vfs_pid, vfs_slots::CLIENT0_NOTIF, client_notif_cap, &ptable) 809 .inspect_err(|_| { 810 POOL.lock_after(&ptable) 811 .dec_ref(client_notif_id, client_notif_gen); 812 })?; 813 } 814 815 let vfs_notif_cap = { 816 let ptable = crate::proc::PROCESSES.lock(); 817 read_cap_from(vfs_pid, vfs_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 818 }; 819 POOL.lock() 820 .inc_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation())?; 821 { 822 let ptable = crate::proc::PROCESSES.lock(); 823 insert_cap_into(client_pid, vfs_client_slots::VFS_NOTIF, vfs_notif_cap, &ptable) 824 .inspect_err(|_| { 825 POOL.lock_after(&ptable) 826 .dec_ref(vfs_notif_cap.object_id(), vfs_notif_cap.generation()); 827 })?; 828 } 829 830 crate::show!(boot, 831 "vfs client caps ring base {}/{} client-notif slots {}/{} vfs-notif slot {}", 832 vfs_client_slots::CLIENT_RING_BASE, 833 vfs_slots::CLIENT0_RING_BASE, 834 vfs_client_slots::NOTIF, 835 vfs_slots::CLIENT0_NOTIF, 836 vfs_client_slots::VFS_NOTIF, 837 ); 838 839 Ok(()) 840} 841 842pub fn bootstrap_init_vfs_control(init_pid: Pid, vfs_pid: Pid) -> Result<(), KernelError> { 843 install_cap( 844 init_pid, 845 init_slots::VFS_PROC, 846 ObjectData::Process(ProcessObjectData { pid: vfs_pid }), 847 )?; 848 849 crate::show!(boot, 850 "init vfs control process cap for vfs at init slot {}", 851 init_slots::VFS_PROC, 852 ); 853 854 Ok(()) 855} 856 857pub fn bootstrap_virtio_net( 858 init_pid: Pid, 859 driver_pid: Pid, 860 virtio_net_gsi: crate::arch::ioapic::Gsi, 861 device_table_idx: u8, 862 mapper: &mut x86_64::structures::paging::OffsetPageTable, 863 allocator: &mut crate::mem::phys::BitmapFrameAllocator, 864 hhdm_offset: u64, 865) -> Result<(), KernelError> { 866 let ep_cap = { 867 let ptable = crate::proc::PROCESSES.lock(); 868 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)? 869 }; 870 871 POOL.lock() 872 .inc_ref(ep_cap.object_id(), ep_cap.generation())?; 873 { 874 let ptable = crate::proc::PROCESSES.lock(); 875 insert_cap_into(driver_pid, virtio_net_slots::EP, ep_cap, &ptable) 876 .inspect_err(|_| { 877 POOL.lock_after(&ptable) 878 .dec_ref(ep_cap.object_id(), ep_cap.generation()); 879 })?; 880 } 881 882 install_cap( 883 driver_pid, 884 virtio_net_slots::PCI, 885 ObjectData::PciDevice(PciDeviceData { device_table_idx }), 886 )?; 887 888 crate::pci::enable_bus_master(device_table_idx)?; 889 890 if crate::iommu::is_available() { 891 crate::iommu::setup_device_context(device_table_idx, driver_pid, allocator, hhdm_offset)?; 892 } 893 894 let virtio_net_vector = crate::arch::idt::VIRTIO_NET_VECTOR; 895 let dummy_ports = match PortRange::new(0, 1) { 896 Some(pr) => pr, 897 None => return Err(KernelError::InvalidParameter), 898 }; 899 900 let has_msix = { 901 let dev_table = crate::pci::DEVICE_TABLE.lock(); 902 dev_table 903 .get(device_table_idx as usize) 904 .and_then(|d| d.msix_cap) 905 .is_some() 906 }; 907 908 let irq_source = match has_msix { 909 true => { 910 crate::pci::msix::ensure_table_mapped( 911 device_table_idx, 912 mapper, 913 allocator, 914 hhdm_offset, 915 )?; 916 crate::pci::msix::configure_entry(device_table_idx, 0, virtio_net_vector, 0)?; 917 crate::pci::msix::enable_msix(device_table_idx)?; 918 crate::pci::msix::unmask_entry(device_table_idx, 0)?; 919 crate::show!(boot, 920 "virtio-net msi-x configured entry 0 -> vector {}", 921 virtio_net_vector, 922 ); 923 IrqSource::Msix { 924 device_table_idx, 925 entry_idx: 0, 926 } 927 } 928 false => IrqSource::Ioapic { 929 gsi: virtio_net_gsi, 930 }, 931 }; 932 933 install_cap( 934 driver_pid, 935 virtio_net_slots::IRQ, 936 ObjectData::IrqHandler(IrqHandlerData { 937 vector: virtio_net_vector, 938 source: irq_source, 939 port_range: dummy_ports, 940 }), 941 )?; 942 943 let notif_data = ObjectData::Notification(NotificationData::new()); 944 let notif_tag = notif_data.tag(); 945 let (notif_id, notif_gen) = POOL.lock().allocate(notif_data)?; 946 let notif_cap = CapRef::new(notif_tag, notif_id, Rights::ALL, notif_gen); 947 { 948 let ptable = crate::proc::PROCESSES.lock(); 949 insert_cap_into(driver_pid, virtio_net_slots::NOTIF, notif_cap, &ptable) 950 .inspect_err(|_| { 951 let r = POOL.lock_after(&ptable).free(notif_id, notif_gen); 952 debug_assert!(r.is_ok()); 953 })?; 954 } 955 956 crate::irq::bind( 957 virtio_net_vector, 958 irq_source, 959 notif_id, 960 notif_gen, 961 crate::types::NotificationBit::ZERO, 962 )?; 963 964 crate::show!(boot, 965 "virtio-net caps installed pci slot {} irq slot {} notification slot {} vector {}", 966 virtio_net_slots::PCI, 967 virtio_net_slots::IRQ, 968 virtio_net_slots::NOTIF, 969 virtio_net_vector, 970 ); 971 972 Ok(()) 973} 974 975pub fn bootstrap_net_service( 976 init_pid: Pid, 977 driver_pid: Pid, 978 netstack_pid: Pid, 979) -> Result<(), KernelError> { 980 let ep_cap = { 981 let ptable = crate::proc::PROCESSES.lock(); 982 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)? 983 }; 984 985 POOL.lock() 986 .inc_ref(ep_cap.object_id(), ep_cap.generation())?; 987 { 988 let ptable = crate::proc::PROCESSES.lock(); 989 insert_cap_into(netstack_pid, net_service_slots::EP, ep_cap, &ptable) 990 .inspect_err(|_| { 991 POOL.lock_after(&ptable) 992 .dec_ref(ep_cap.object_id(), ep_cap.generation()); 993 })?; 994 } 995 996 create_shared_ring_frames( 997 driver_pid, 998 virtio_net_slots::PACKET_RING_BASE, 999 netstack_pid, 1000 net_service_slots::PACKET_RING_BASE, 1001 virtio_net_slots::PACKET_RING_FRAMES, 1002 )?; 1003 1004 let netstack_notif_data = ObjectData::Notification(NotificationData::new()); 1005 let netstack_notif_tag = netstack_notif_data.tag(); 1006 let (netstack_notif_id, netstack_notif_gen) = POOL.lock().allocate(netstack_notif_data)?; 1007 let netstack_notif_cap = CapRef::new( 1008 netstack_notif_tag, 1009 netstack_notif_id, 1010 Rights::ALL, 1011 netstack_notif_gen, 1012 ); 1013 { 1014 let ptable = crate::proc::PROCESSES.lock(); 1015 insert_cap_into(netstack_pid, net_service_slots::NOTIF, netstack_notif_cap, &ptable) 1016 .inspect_err(|_| { 1017 let r = POOL 1018 .lock_after(&ptable) 1019 .free(netstack_notif_id, netstack_notif_gen); 1020 debug_assert!(r.is_ok()); 1021 })?; 1022 POOL.lock_after(&ptable) 1023 .inc_ref(netstack_notif_id, netstack_notif_gen)?; 1024 insert_cap_into(driver_pid, virtio_net_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable) 1025 .inspect_err(|_| { 1026 POOL.lock_after(&ptable) 1027 .dec_ref(netstack_notif_id, netstack_notif_gen); 1028 })?; 1029 } 1030 1031 let driver_notif_cap = { 1032 let ptable = crate::proc::PROCESSES.lock(); 1033 read_cap_from(driver_pid, virtio_net_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 1034 }; 1035 POOL.lock() 1036 .inc_ref(driver_notif_cap.object_id(), driver_notif_cap.generation())?; 1037 { 1038 let ptable = crate::proc::PROCESSES.lock(); 1039 insert_cap_into(netstack_pid, net_service_slots::DRIVER_NOTIF, driver_notif_cap, &ptable) 1040 .inspect_err(|_| { 1041 POOL.lock_after(&ptable) 1042 .dec_ref(driver_notif_cap.object_id(), driver_notif_cap.generation()); 1043 })?; 1044 } 1045 1046 crate::show!(boot, 1047 "net service caps ring base {}/{} notif slots {}/{} driver-notif slot {}", 1048 virtio_net_slots::PACKET_RING_BASE, 1049 net_service_slots::PACKET_RING_BASE, 1050 virtio_net_slots::NETSTACK_NOTIF, 1051 net_service_slots::NOTIF, 1052 net_service_slots::DRIVER_NOTIF, 1053 ); 1054 1055 Ok(()) 1056} 1057 1058pub fn bootstrap_remote_shell( 1059 init_pid: Pid, 1060 netstack_pid: Pid, 1061 shell_pid: Pid, 1062) -> Result<(), KernelError> { 1063 let ep_cap = { 1064 let ptable = crate::proc::PROCESSES.lock(); 1065 read_cap_from(init_pid, init_slots::SERIAL_EP, ObjectTag::Endpoint, Rights::ALL, &ptable)? 1066 }; 1067 1068 POOL.lock() 1069 .inc_ref(ep_cap.object_id(), ep_cap.generation())?; 1070 { 1071 let ptable = crate::proc::PROCESSES.lock(); 1072 insert_cap_into(shell_pid, remote_shell_slots::EP, ep_cap, &ptable) 1073 .inspect_err(|_| { 1074 POOL.lock_after(&ptable) 1075 .dec_ref(ep_cap.object_id(), ep_cap.generation()); 1076 })?; 1077 } 1078 1079 create_shared_ring_frames( 1080 netstack_pid, 1081 net_service_slots::SHELL_RING_BASE, 1082 shell_pid, 1083 remote_shell_slots::SHELL_RING_BASE, 1084 net_service_slots::SHELL_RING_FRAMES, 1085 )?; 1086 1087 let shell_notif_data = ObjectData::Notification(NotificationData::new()); 1088 let shell_notif_tag = shell_notif_data.tag(); 1089 let (shell_notif_id, shell_notif_gen) = POOL.lock().allocate(shell_notif_data)?; 1090 let shell_notif_cap = CapRef::new( 1091 shell_notif_tag, 1092 shell_notif_id, 1093 Rights::ALL, 1094 shell_notif_gen, 1095 ); 1096 { 1097 let ptable = crate::proc::PROCESSES.lock(); 1098 insert_cap_into(shell_pid, remote_shell_slots::NOTIF, shell_notif_cap, &ptable) 1099 .inspect_err(|_| { 1100 let r = POOL 1101 .lock_after(&ptable) 1102 .free(shell_notif_id, shell_notif_gen); 1103 debug_assert!(r.is_ok()); 1104 })?; 1105 POOL.lock_after(&ptable) 1106 .inc_ref(shell_notif_id, shell_notif_gen)?; 1107 insert_cap_into(netstack_pid, net_service_slots::SHELL_NOTIF, shell_notif_cap, &ptable) 1108 .inspect_err(|_| { 1109 POOL.lock_after(&ptable) 1110 .dec_ref(shell_notif_id, shell_notif_gen); 1111 })?; 1112 } 1113 1114 let netstack_notif_cap = { 1115 let ptable = crate::proc::PROCESSES.lock(); 1116 read_cap_from(netstack_pid, net_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 1117 }; 1118 POOL.lock().inc_ref( 1119 netstack_notif_cap.object_id(), 1120 netstack_notif_cap.generation(), 1121 )?; 1122 { 1123 let ptable = crate::proc::PROCESSES.lock(); 1124 insert_cap_into(shell_pid, remote_shell_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable) 1125 .inspect_err(|_| { 1126 POOL.lock_after(&ptable).dec_ref( 1127 netstack_notif_cap.object_id(), 1128 netstack_notif_cap.generation(), 1129 ); 1130 })?; 1131 } 1132 1133 { 1134 let ptable = crate::proc::PROCESSES.lock(); 1135 match read_cap_from(init_pid, vfs_client_slots::CLIENT_RING_BASE, ObjectTag::Frame, Rights::ALL, &ptable) { 1136 Ok(_) => { 1137 drop(ptable); 1138 (0..remote_shell_slots::VFS_RING_FRAMES).try_fold((), |(), i| { 1139 let src_slot = vfs_client_slots::CLIENT_RING_BASE + i as u64; 1140 let dst_slot = remote_shell_slots::VFS_RING_BASE + i as u64; 1141 let cap = { 1142 let ptable = crate::proc::PROCESSES.lock(); 1143 read_cap_from(init_pid, src_slot, ObjectTag::Frame, Rights::ALL, &ptable)? 1144 }; 1145 POOL.lock().inc_ref(cap.object_id(), cap.generation())?; 1146 let ptable = crate::proc::PROCESSES.lock(); 1147 insert_cap_into(shell_pid, dst_slot, cap, &ptable) 1148 .inspect_err(|_| { 1149 POOL.lock_after(&ptable) 1150 .dec_ref(cap.object_id(), cap.generation()); 1151 }) 1152 })?; 1153 [(vfs_client_slots::NOTIF, ObjectTag::Notification), 1154 (vfs_client_slots::VFS_NOTIF, ObjectTag::Notification), 1155 (init_slots::VFS_PROC, ObjectTag::Process)] 1156 .iter() 1157 .try_for_each(|&(slot, tag)| { 1158 let cap = { 1159 let ptable = crate::proc::PROCESSES.lock(); 1160 read_cap_from(init_pid, slot, tag, Rights::ALL, &ptable)? 1161 }; 1162 POOL.lock().inc_ref(cap.object_id(), cap.generation())?; 1163 let ptable = crate::proc::PROCESSES.lock(); 1164 insert_cap_into(shell_pid, slot, cap, &ptable) 1165 .inspect_err(|_| { 1166 POOL.lock_after(&ptable) 1167 .dec_ref(cap.object_id(), cap.generation()); 1168 }) 1169 })?; 1170 } 1171 Err(_) => { 1172 drop(ptable); 1173 } 1174 } 1175 } 1176 1177 crate::show!(boot, 1178 "remote shell caps ring base {}/{} shell-notif slots {}/{} netstack-notif slot {}", 1179 net_service_slots::SHELL_RING_BASE, 1180 remote_shell_slots::SHELL_RING_BASE, 1181 net_service_slots::SHELL_NOTIF, 1182 remote_shell_slots::NOTIF, 1183 remote_shell_slots::NETSTACK_NOTIF, 1184 ); 1185 1186 Ok(()) 1187} 1188 1189pub fn bootstrap_init_netring(init_pid: Pid, netstack_pid: Pid) -> Result<(), KernelError> { 1190 create_shared_ring_frames( 1191 init_pid, 1192 init_slots::NETSTACK_RING_BASE, 1193 netstack_pid, 1194 net_service_slots::INIT_RING_BASE, 1195 init_slots::NETSTACK_RING_FRAMES, 1196 )?; 1197 1198 let init_notif_data = ObjectData::Notification(NotificationData::new()); 1199 let init_notif_tag = init_notif_data.tag(); 1200 let (init_notif_id, init_notif_gen) = POOL.lock().allocate(init_notif_data)?; 1201 let init_notif_cap = CapRef::new(init_notif_tag, init_notif_id, Rights::ALL, init_notif_gen); 1202 { 1203 let ptable = crate::proc::PROCESSES.lock(); 1204 insert_cap_into(init_pid, init_slots::INIT_NOTIF, init_notif_cap, &ptable) 1205 .inspect_err(|_| { 1206 let r = POOL.lock_after(&ptable).free(init_notif_id, init_notif_gen); 1207 debug_assert!(r.is_ok()); 1208 })?; 1209 POOL.lock_after(&ptable) 1210 .inc_ref(init_notif_id, init_notif_gen)?; 1211 insert_cap_into(netstack_pid, net_service_slots::INIT_NOTIF, init_notif_cap, &ptable) 1212 .inspect_err(|_| { 1213 POOL.lock_after(&ptable) 1214 .dec_ref(init_notif_id, init_notif_gen); 1215 })?; 1216 } 1217 1218 let netstack_notif_cap = { 1219 let ptable = crate::proc::PROCESSES.lock(); 1220 read_cap_from(netstack_pid, net_service_slots::NOTIF, ObjectTag::Notification, Rights::ALL, &ptable)? 1221 }; 1222 POOL.lock().inc_ref( 1223 netstack_notif_cap.object_id(), 1224 netstack_notif_cap.generation(), 1225 )?; 1226 { 1227 let ptable = crate::proc::PROCESSES.lock(); 1228 insert_cap_into(init_pid, init_slots::NETSTACK_NOTIF, netstack_notif_cap, &ptable) 1229 .inspect_err(|_| { 1230 POOL.lock_after(&ptable).dec_ref( 1231 netstack_notif_cap.object_id(), 1232 netstack_notif_cap.generation(), 1233 ); 1234 })?; 1235 } 1236 1237 crate::show!(boot, 1238 "init-netstack ring base {}/{} init-notif slots {}/{} netstack-notif slot {}", 1239 init_slots::NETSTACK_RING_BASE, 1240 net_service_slots::INIT_RING_BASE, 1241 init_slots::INIT_NOTIF, 1242 net_service_slots::INIT_NOTIF, 1243 init_slots::NETSTACK_NOTIF, 1244 ); 1245 1246 Ok(()) 1247}