Nothing to see here, move along
at main 105 lines 3.0 kB view raw
1use crate::cap::cnode; 2use crate::cap::object::ObjectTag; 3use crate::cap::pool::POOL; 4use crate::cap::table::Rights; 5use crate::error::KernelError; 6use crate::proc::PROCESSES; 7use crate::proc::context::CpuContext; 8use crate::ring; 9use crate::syscall::{SyscallResult, try_syscall}; 10use lancer_core::object_layout::FrameObject; 11 12pub fn sys_ring_register(ctx: &mut CpuContext) { 13 let frame_cap_addr = ctx.rdi; 14 let pid = crate::arch::syscall::current_pid(); 15 16 let mut ptable = PROCESSES.lock(); 17 18 let cap = { 19 let pool = POOL.lock_after(&ptable); 20 match cnode::resolve_caller_validate( 21 pid, 22 frame_cap_addr, 23 ObjectTag::Frame, 24 Rights::READ, 25 &ptable, 26 &pool, 27 ) { 28 Ok(c) => c, 29 Err(e) => { 30 ctx.rax = SyscallResult::error(e).raw(); 31 return; 32 } 33 } 34 }; 35 36 { 37 let pool = POOL.lock_after(&ptable); 38 match pool.read_as::<FrameObject>(cap.phys(), cap.generation()) { 39 Ok(_) => { 40 if 4096 < ring::ring_total_size() { 41 ctx.rax = SyscallResult::error(KernelError::InvalidParameter).raw(); 42 return; 43 } 44 } 45 Err(e) => { 46 ctx.rax = SyscallResult::error(e).raw(); 47 return; 48 } 49 } 50 } 51 52 if let Some(e) = ptable.exec_mut(pid) { 53 e.ring_region_id = Some((cap.phys(), cap.generation())); 54 } 55 ctx.rax = SyscallResult::ok().raw(); 56} 57 58pub fn sys_ring_enter(ctx: &mut CpuContext) { 59 let min_complete = try_syscall!(ctx, super::u32_from_reg(ctx.rdi)); 60 let pid = crate::arch::syscall::current_pid(); 61 62 let ptable = PROCESSES.lock(); 63 let exec = match ptable.exec(pid) { 64 Some(e) => e, 65 None => { 66 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw(); 67 return; 68 } 69 }; 70 71 let (region_id, region_gen) = match exec.ring_region_id { 72 Some(pair) => pair, 73 None => { 74 ctx.rax = SyscallResult::error(KernelError::BadState).raw(); 75 return; 76 } 77 }; 78 79 let pool = POOL.lock_after(&ptable); 80 let phys_base = match pool.read_as::<FrameObject>(region_id, region_gen) { 81 Ok(f) => x86_64::PhysAddr::new(f.phys_addr), 82 Err(e) => { 83 ctx.rax = SyscallResult::error(e).raw(); 84 return; 85 } 86 }; 87 88 if crate::mem::refcount::increment(phys_base).is_err() { 89 ctx.rax = SyscallResult::error(KernelError::ResourceExhausted).raw(); 90 return; 91 } 92 93 drop(pool); 94 drop(ptable); 95 96 let result = ring::process::ring_enter(phys_base, pid, min_complete); 97 98 let r = crate::mem::refcount::decrement(phys_base); 99 debug_assert!(r.is_ok()); 100 101 ctx.rax = match result { 102 Ok(n) => SyscallResult::success(n as u64).raw(), 103 Err(e) => SyscallResult::error(e).raw(), 104 }; 105}