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