Nothing to see here, move along
at main 179 lines 7.4 kB view raw
1use crate::cap::object::ObjectTag; 2use crate::cap::pool::POOL; 3use crate::cap::table::{CapRef, Rights}; 4use crate::ipc::{AlwaysBlocked, IpcOutcome, endpoint, message}; 5use crate::proc::context::{IpcMessage, Reply}; 6use crate::proc::{BlockedReason, PROCESSES, ProcessState}; 7use lancer_core::object_layout::EndpointObject; 8 9crate::kernel_test!( 10 fn reply_recv_delivers_reply_and_receives() { 11 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 12 let mut ptable = PROCESSES.lock(); 13 14 let client_created = ptable.allocate(&mut allocator).expect("alloc client"); 15 let server_created = ptable.allocate(&mut allocator).expect("alloc server"); 16 let sender_created = ptable.allocate(&mut allocator).expect("alloc sender"); 17 ptable.start(client_created).expect("start client"); 18 ptable.start(server_created).expect("start server"); 19 ptable.start(sender_created).expect("start sender"); 20 let client_pid = client_created.pid(); 21 let server_pid = server_created.pid(); 22 let sender_pid = sender_created.pid(); 23 24 let (ep_id, ep_gen) = 25 crate::tests::helpers::alloc_endpoint(&mut POOL.lock()).expect("alloc endpoint"); 26 27 let cap = CapRef::new(ObjectTag::Endpoint, ep_id, Rights::ALL, ep_gen); 28 29 ptable.exec_mut(client_pid).unwrap().ipc_message = 30 IpcMessage::from_regs([0x1111, 0, 0, 0, 0, 0]); 31 ptable.simulate_dispatch(client_pid); 32 ptable.simulate_dispatch(server_pid); 33 let blocked_server = ptable[server_pid] 34 .block_on(BlockedReason::Receiving(ep_id, ep_gen)) 35 .expect("block server"); 36 37 { 38 let mut pool = POOL.lock(); 39 let ep = pool 40 .write_as::<EndpointObject>(ep_id, ep_gen) 41 .expect("get ep"); 42 let mut receivers = endpoint::load_receivers(ep); 43 endpoint::enqueue(&mut receivers, blocked_server, &mut ptable).expect("enqueue server"); 44 let ep = pool 45 .write_as::<EndpointObject>(ep_id, ep_gen) 46 .expect("get ep for store"); 47 endpoint::store_receivers(ep, &receivers); 48 } 49 50 let call_result = endpoint::do_call(&cap, client_pid, &mut ptable); 51 match call_result { 52 Ok(AlwaysBlocked) => {} 53 _ => panic!("expected Blocked from do_call"), 54 } 55 56 assert!( 57 ptable.exec(server_pid).unwrap().reply_target == Some(client_pid), 58 "server should have reply_target set to client" 59 ); 60 61 ptable.exec_mut(sender_pid).unwrap().ipc_message = 62 IpcMessage::from_regs([0x2222, 0, 0, 0, 0, 0]); 63 ptable.simulate_dispatch(sender_pid); 64 let sender_blocked = ptable[sender_pid] 65 .block_on(BlockedReason::Sending(ep_id, ep_gen)) 66 .expect("block sender"); 67 68 { 69 let mut pool = POOL.lock(); 70 let ep = pool 71 .write_as::<EndpointObject>(ep_id, ep_gen) 72 .expect("get ep"); 73 let mut senders = endpoint::load_senders(ep); 74 endpoint::enqueue(&mut senders, sender_blocked, &mut ptable).expect("enqueue sender"); 75 let ep = pool 76 .write_as::<EndpointObject>(ep_id, ep_gen) 77 .expect("get ep for store"); 78 endpoint::store_senders(ep, &senders); 79 } 80 81 let full_reply = IpcMessage::<Reply>::from_reply_regs([0xAAAA, 0, 0, 0, 0]).into_full(); 82 { 83 let client_exec = ptable.exec_mut(client_pid).unwrap(); 84 let proof = unsafe { crate::types::BlockedPid::trust(client_pid) }; 85 client_exec.ipc_message = full_reply; 86 message::inject_into_context(&mut client_exec.saved_context, &full_reply); 87 client_exec.saved_context.rax = server_pid.raw() as u64; 88 ptable.unblock_and_enqueue(client_pid, proof).expect("unblock client"); 89 } 90 ptable.exec_mut(server_pid).unwrap().reply_target = None; 91 92 let recv_result = endpoint::do_recv(&cap, server_pid, &mut ptable); 93 match recv_result { 94 Ok(IpcOutcome::Done(s)) => { 95 assert!(s == sender_pid, "server should receive from sender"); 96 } 97 _ => panic!("expected Done from do_recv after reply"), 98 } 99 100 let _ = POOL.lock().dec_ref_phys(ep_id, ep_gen); 101 ptable.destroy(client_pid, &mut allocator); 102 ptable.destroy(server_pid, &mut allocator); 103 ptable.destroy(sender_pid, &mut allocator); 104 } 105); 106 107crate::kernel_test!( 108 fn reply_recv_rejects_non_calling_target() { 109 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 110 let mut ptable = PROCESSES.lock(); 111 112 let server_created = ptable.allocate(&mut allocator).expect("alloc server"); 113 let receiver_created = ptable.allocate(&mut allocator).expect("alloc receiver"); 114 ptable.start(server_created).expect("start server"); 115 ptable.start(receiver_created).expect("start receiver"); 116 let server_pid = server_created.pid(); 117 let receiver_pid = receiver_created.pid(); 118 119 let (ep_id, ep_gen) = 120 crate::tests::helpers::alloc_endpoint(&mut POOL.lock()).expect("alloc endpoint"); 121 122 ptable.simulate_dispatch(receiver_pid); 123 let blocked_recv = ptable[receiver_pid] 124 .block_on(BlockedReason::Receiving(ep_id, ep_gen)) 125 .expect("block receiver"); 126 127 { 128 let mut pool = POOL.lock(); 129 let ep = pool 130 .write_as::<EndpointObject>(ep_id, ep_gen) 131 .expect("get ep"); 132 let mut receivers = endpoint::load_receivers(ep); 133 endpoint::enqueue(&mut receivers, blocked_recv, &mut ptable).expect("enqueue receiver"); 134 let ep = pool 135 .write_as::<EndpointObject>(ep_id, ep_gen) 136 .expect("get ep for store"); 137 endpoint::store_receivers(ep, &receivers); 138 } 139 140 ptable.exec_mut(server_pid).unwrap().reply_target = Some(receiver_pid); 141 142 let is_call_target = ptable[receiver_pid].state() == ProcessState::Blocked 143 && matches!( 144 ptable[receiver_pid].blocked_reason(), 145 Some(BlockedReason::Calling(id, _)) if id == ep_id 146 ); 147 148 assert!( 149 !is_call_target, 150 "a Receiving process should NOT be accepted as a Calling reply target" 151 ); 152 153 let _ = POOL.lock().dec_ref_phys(ep_id, ep_gen); 154 ptable.destroy(server_pid, &mut allocator); 155 ptable.destroy(receiver_pid, &mut allocator); 156 } 157); 158 159crate::kernel_test!( 160 fn reply_recv_invalid_reply_pid() { 161 let mut allocator = crate::mem::phys::BitmapFrameAllocator; 162 let mut ptable = PROCESSES.lock(); 163 164 let server_created = ptable.allocate(&mut allocator).expect("alloc server"); 165 ptable.start(server_created).expect("start server"); 166 let server_pid = server_created.pid(); 167 168 let (ep_id, ep_gen) = 169 crate::tests::helpers::alloc_endpoint(&mut POOL.lock()).expect("alloc endpoint"); 170 171 ptable.exec_mut(server_pid).unwrap().reply_target = None; 172 173 let reply_pid = crate::types::Pid::try_new(u32::MAX); 174 assert!(reply_pid.is_none(), "Pid::try_new(MAX) should return None"); 175 176 let _ = POOL.lock().dec_ref_phys(ep_id, ep_gen); 177 ptable.destroy(server_pid, &mut allocator); 178 } 179);