From bedb499edb5c4e28a0cb86fa3905dcc44dd2d562 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Wed, 1 Apr 2020 17:27:59 +0800 Subject: [PATCH] kernel: get immutable borrows working We can now pass memory immutably between processes Signed-off-by: Sean Cross --- kernel/src/server.rs | 247 +++++++++++++++++++++++++++++-------- kernel/src/services.rs | 72 ++++++++--- kernel/src/syscall.rs | 118 +++++++++++++----- xous-rs/src/definitions.rs | 11 +- xous-rs/src/syscall.rs | 12 +- 5 files changed, 347 insertions(+), 113 deletions(-) diff --git a/kernel/src/server.rs b/kernel/src/server.rs index c30d84162..8990f859b 100644 --- a/kernel/src/server.rs +++ b/kernel/src/server.rs @@ -1,16 +1,30 @@ pub use crate::arch::ProcessContext; use core::{mem, slice}; -use xous::{CtxID, MemoryRange, MemorySize, PID, SID}; +use xous::{CtxID, MemoryAddress, MemoryRange, MemorySize, PID, SID, Message}; + +pub struct SenderID { + pub sidx: usize, + pub tidx: usize, +} + +impl SenderID { + pub fn from_usize(src: usize) -> Result { + Ok(SenderID { + sidx: src >> 16, + tidx: src & 0xffff, + }) + } +} /// Internal representation of a queued message for a server. This should be /// exactly 8 words / 32 bytes, yielding 128 queued messages per server #[repr(usize)] -#[derive(PartialEq)] +#[derive(PartialEq, Debug)] enum QueuedMessage { Empty, ScalarMessage( - usize, /* sender */ - usize, /* context */ + usize, /* sender PID/CtxID */ + usize, /* sender base address */ usize, /* id */ usize, /* arg1 */ usize, /* arg2 */ @@ -18,8 +32,8 @@ enum QueuedMessage { usize, /* arg4 */ ), MemoryMessageSend( - usize, /* sender */ - usize, /* context */ + usize, /* sender PID/CtxID */ + usize, /* reserved */ usize, /* id */ usize, /* buf */ usize, /* buf_size */ @@ -27,8 +41,8 @@ enum QueuedMessage { usize, /* valid */ ), MemoryMessageROLend( - usize, /* sender */ - usize, /* context */ + usize, /* sender PID/CtxID */ + usize, /* sender base address */ usize, /* id */ usize, /* buf */ usize, /* buf_size */ @@ -36,14 +50,25 @@ enum QueuedMessage { usize, /* valid */ ), MemoryMessageRWLend( - usize, /* sender */ - usize, /* context */ + usize, /* sender PID/CtxID */ + usize, /* sender base address */ usize, /* id */ usize, /* buf */ usize, /* buf_size */ usize, /* offset */ usize, /* valid */ ), + + /// When a message is taken that needs to be returned -- such as an ROLend + /// or RWLend -- the slot is replaced with a WaitingResponse token and its + /// index is returned as the message sender. This is used to unblock the + /// sending process. + WaitingResponse( + usize, /* sender PID/CtxID */ + usize, /* Client base address */ + usize, /* Server base address */ + usize, /* Range size */ + ), } /// A pointer to resolve a server ID to a particular process @@ -98,14 +123,60 @@ impl Server { }); Ok(()) } + + pub fn print_queue(&self) { + println!(" Q Queue Head: {}", self.queue_head); + println!(" Q Queue Tail: {}", self.queue_tail); + for (_idx, _entry) in self.queue.iter().enumerate() { + if _entry != &QueuedMessage::Empty { + println!(" Q entry[{}]: {:?}", _idx, _entry); + } + } + } + + /// Convert a `QueuedMesage::WaitingResponse` into `QueuedMessage::Empty` + /// and return the pair. Advance the tail. Note that the `idx` could be + /// somewhere other than the tail, but as long as it points to a valid + /// message that's waiting a response, that's acceptable. + pub fn take_waiting_message( + &mut self, + idx: usize, + ) -> Result, xous::Error> { + if idx > self.queue.len() { + return Err(xous::Error::BadAddress); + } + let (pid_ctx, server_addr, client_addr, len) = match self.queue[idx] { + QueuedMessage::WaitingResponse(pid_ctx, server_addr, client_addr, len) => { + (pid_ctx, server_addr, client_addr, len) + } + _ => return Err(xous::Error::BadAddress), + }; + self.queue[idx] = QueuedMessage::Empty; + self.queue_tail += 1; + if self.queue_tail >= self.queue.len() { + self.queue_tail = 0; + } + + let pid = ((pid_ctx >> 16) & 0xff) as PID; + let ctx = (pid_ctx & 0xffff) as CtxID; + let server_addr = match MemoryAddress::new(server_addr) { + Some(o) => o, + None => return Ok(None) + }; + let client_addr = MemoryAddress::new(client_addr).expect("client memory address was 0, but server address was not"); + let len = MemorySize::new(len).expect("memory length was 0, but address was not None"); + Ok(Some((pid, ctx, server_addr, client_addr, len))) + } + /// Remove a message from the server's queue and replace it with - /// QueuedMessage::Empty. Advance the queue pointer while we're at it. - pub fn take_next_message(&mut self) -> Option<(xous::MessageEnvelope, CtxID)> { + /// QueuedMessage::WaitingResponse. + pub fn take_next_message(&mut self, server_idx: usize) -> Option { let result = match self.queue[self.queue_tail] { QueuedMessage::Empty => return None, + QueuedMessage::WaitingResponse(_, _, _, _) => return None, QueuedMessage::MemoryMessageROLend( - sender, - context, + pid_ctx, + client_addr, id, buf, buf_size, @@ -113,7 +184,7 @@ impl Server { valid, ) => ( xous::MessageEnvelope { - sender: sender, + sender: self.queue_tail | (server_idx << 16), message: xous::Message::ImmutableBorrow(xous::MemoryMessage { id, buf: MemoryRange::new(buf, buf_size), @@ -121,11 +192,14 @@ impl Server { valid: MemorySize::new(valid), }), }, - context, + pid_ctx, + buf, + client_addr, + buf_size, ), QueuedMessage::MemoryMessageRWLend( - sender, - context, + pid_ctx, + client_addr, id, buf, buf_size, @@ -133,7 +207,7 @@ impl Server { valid, ) => ( xous::MessageEnvelope { - sender: sender, + sender: self.queue_tail | (server_idx << 16), message: xous::Message::MutableBorrow(xous::MemoryMessage { id, buf: MemoryRange::new(buf, buf_size), @@ -141,25 +215,37 @@ impl Server { valid: MemorySize::new(valid), }), }, - context, + pid_ctx, + buf, + client_addr, + buf_size, ), - QueuedMessage::MemoryMessageSend(sender, context, id, buf, buf_size, offset, valid) => { - ( - xous::MessageEnvelope { - sender: sender, - message: xous::Message::Move(xous::MemoryMessage { - id, - buf: MemoryRange::new(buf, buf_size), - offset: MemorySize::new(offset), - valid: MemorySize::new(valid), - }), - }, - context, - ) - } - QueuedMessage::ScalarMessage(sender, context, id, arg1, arg2, arg3, arg4) => ( + QueuedMessage::MemoryMessageSend( + pid_ctx, + _reserved, + id, + buf, + buf_size, + offset, + valid, + ) => ( xous::MessageEnvelope { - sender: sender, + sender: self.queue_tail | (server_idx << 16), + message: xous::Message::Move(xous::MemoryMessage { + id, + buf: MemoryRange::new(buf, buf_size), + offset: MemorySize::new(offset), + valid: MemorySize::new(valid), + }), + }, + pid_ctx, + 0, + 0, + 0, + ), + QueuedMessage::ScalarMessage(pid_ctx, _reserved, id, arg1, arg2, arg3, arg4) => ( + xous::MessageEnvelope { + sender: self.queue_tail | (server_idx << 16), message: xous::Message::Scalar(xous::ScalarMessage { id, arg1, @@ -168,31 +254,37 @@ impl Server { arg4, }), }, - context, + pid_ctx, + 0, + 0, + 0, ), }; - self.queue[self.queue_tail] = QueuedMessage::Empty; - self.queue_tail += 1; - if self.queue_tail >= self.queue.len() { - self.queue_tail = 0; - } - Some(result) + self.queue[self.queue_tail] = + QueuedMessage::WaitingResponse(result.1, result.2, result.3, result.4); + Some(result.0) } /// Add the given message to this server's queue. + /// + /// # Errors + /// + /// * **ServerQueueFull**: The server queue cannot accept any more messages pub fn queue_message( &mut self, - context: usize, - envelope: xous::MessageEnvelope, - ) -> core::result::Result<(), xous::Error> { + pid: PID, + context: CtxID, + message: xous::Message, + original_address: Option, + ) -> core::result::Result { if self.queue[self.queue_head] != QueuedMessage::Empty { return Err(xous::Error::ServerQueueFull); } - self.queue[self.queue_head] = match envelope.message { + self.queue[self.queue_head] = match message { xous::Message::Scalar(msg) => QueuedMessage::ScalarMessage( - envelope.sender, - context, + pid as usize | (context << 16), + original_address.map(|x| x.get()).unwrap_or(0), msg.id, msg.arg1, msg.arg2, @@ -200,25 +292,72 @@ impl Server { msg.arg4, ), xous::Message::Move(msg) => QueuedMessage::MemoryMessageSend( - envelope.sender, - context, + pid as usize | (context << 16), + original_address.map(|x| x.get()).unwrap_or(0), + msg.id, + msg.buf.addr.get(), + msg.buf.size.get(), + msg.offset.map(|x| x.get()).unwrap_or(0) as usize, + msg.valid.map(|x| x.get()).unwrap_or(0) as usize, + ), + xous::Message::MutableBorrow(msg) => QueuedMessage::MemoryMessageRWLend( + pid as usize | (context << 16), + original_address.map(|x| x.get()).unwrap_or(0), + msg.id, + msg.buf.addr.get(), + msg.buf.size.get(), + msg.offset.map(|x| x.get()).unwrap_or(0) as usize, + msg.valid.map(|x| x.get()).unwrap_or(0) as usize, + ), + xous::Message::ImmutableBorrow(msg) => QueuedMessage::MemoryMessageROLend( + pid as usize | (context << 16), + original_address.map(|x| x.get()).unwrap_or(0), msg.id, msg.buf.addr.get(), msg.buf.size.get(), msg.offset.map(|x| x.get()).unwrap_or(0) as usize, msg.valid.map(|x| x.get()).unwrap_or(0) as usize, ), - xous::Message::MutableBorrow(_msg) => unimplemented!(), - xous::Message::ImmutableBorrow(_msg) => unimplemented!(), }; + let idx = self.queue_head; self.queue_head += 1; if self.queue_head >= self.queue.len() { self.queue_head = 0; } - Ok(()) + Ok(idx) } + pub fn queue_address( + &mut self, + pid: PID, + context: CtxID, + message: &Message, + client_address: Option, + ) -> core::result::Result { + if self.queue[self.queue_head] != QueuedMessage::Empty { + return Err(xous::Error::ServerQueueFull); + } + let (server_address, len) = match message { + xous::Message::Scalar(_) | xous::Message::Move(_) => (0, 0), + xous::Message::MutableBorrow(msg) | xous::Message::ImmutableBorrow(msg) => { + (msg.buf.addr.get(), msg.buf.size.get()) + } + }; + + self.queue[self.queue_head] = QueuedMessage::WaitingResponse( + pid as usize | (context << 16), + server_address, + client_address.map(|x| x.get()).unwrap_or(0), + len, + ); + let idx = self.queue_head; + self.queue_head += 1; + if self.queue_head >= self.queue.len() { + self.queue_head = 0; + } + Ok(idx) + } // assert!( // mem::size_of::() == 32, // "QueuedMessage was supposed to be 32 bytes, but instead was {} bytes", diff --git a/kernel/src/services.rs b/kernel/src/services.rs index 534c990f8..ef4602a44 100644 --- a/kernel/src/services.rs +++ b/kernel/src/services.rs @@ -6,8 +6,8 @@ use crate::args::KernelArguments; use crate::filled_array; use crate::mem::{MemoryManagerHandle, PAGE_SIZE}; use crate::server::Server; -use core::{mem, slice}; -use xous::{CtxID, MemoryFlags, MemoryType, MessageEnvelope, CID, PID, SID}; +use core::slice; +use xous::{CtxID, MemoryAddress, MemoryFlags, MemoryType, Message, CID, PID, SID}; const MAX_PROCESS_COUNT: usize = 32; const MAX_SERVER_COUNT: usize = 32; @@ -634,10 +634,10 @@ impl SystemServices { // Restore the previous context, if one exists. process.set_context_nr(new_context); self.processes[self.pid as usize - 1].current_context = new_context as u8; - let ctx = process.current_context(); + let _ctx = process.current_context(); println!( "Switched to PID {}, context {}, with sepc: {:08x}", - new_pid, new_context, ctx.sepc + new_pid, new_context, _ctx.sepc ); Ok(new_context) @@ -664,6 +664,7 @@ impl SystemServices { &mut self, src_virt: *mut usize, dest_pid: PID, + dest_virt: *mut usize, len: usize, writable: bool, _borrow: bool, @@ -704,7 +705,7 @@ impl SystemServices { } let result = mm.map_range( phys as *mut usize, - 0 as *mut usize, + dest_virt, len, dest_pid, flags, @@ -775,7 +776,7 @@ impl SystemServices { /// server table is full, return an error. pub fn create_server(&mut self, name: usize) -> Result { println!("Looking through server list for free server"); - println!("Server entries are {} bytes long", mem::size_of::()); + println!("Server entries are {} bytes long", core::mem::size_of::()); for entry in self.servers.iter_mut() { if entry == &None { @@ -863,12 +864,16 @@ impl SystemServices { } } + /// Switch to the server's memory space and add the message to its server + /// queue pub fn queue_server_message( &mut self, sidx: usize, - context: usize, - envelope: MessageEnvelope, - ) -> Result<(), xous::Error> { + pid: PID, + context: CtxID, + message: Message, + original_address: Option, + ) -> Result { let current_pid = self.current_pid(); let result = { let server_pid = self @@ -882,7 +887,9 @@ impl SystemServices { let server = self .server_from_sidx(sidx) .expect("couldn't re-discover server index"); - server.queue_message(context, envelope) + let result = server.queue_message(pid, context, message, original_address); + server.print_queue(); + result }; let current_process = self .get_process(current_pid) @@ -891,18 +898,51 @@ impl SystemServices { result } - /// Get a server based on a SID - pub fn server_mut(&mut self, sid: SID) -> Option<&mut Server> { - for server in self.servers.iter_mut() { + /// Switch to the server's address space and add a "remember this address" + /// entry to its server queue + pub fn remember_server_message( + &mut self, + sidx: usize, + pid: PID, + context: CtxID, + message: &Message, + client_address: Option, + ) -> Result { + let current_pid = self.current_pid(); + let result = { + let server_pid = self + .server_from_sidx(sidx) + .ok_or(xous::Error::ServerNotFound)? + .pid; + { + let server_process = self.get_process(server_pid)?; + server_process.mapping.activate(); + } + let server = self + .server_from_sidx(sidx) + .expect("couldn't re-discover server index"); + let result = server.queue_address(pid, context, message, client_address); + server.print_queue(); + result + }; + let current_process = self + .get_process(current_pid) + .expect("couldn't restore previous process"); + current_process.mapping.activate(); + result + } + + /// Get a server index based on a SID + pub fn server_sidx(&mut self, sid: SID) -> Option { + for (idx, server) in self.servers.iter_mut().enumerate() { if let Some(active_server) = server { if active_server.sid == sid { - return server.as_mut(); + return Some(idx); } } } None - } -} + }} /// How many people have checked out the handle object. This should be replaced /// by an AtomicUsize when we get multicore support. For now, we can get away diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index 1cd464b22..537ee36f8 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -2,6 +2,7 @@ use crate::arch; use crate::arch::process::ProcessHandle; use crate::irq::interrupt_claim; use crate::mem::{MemoryManagerHandle, PAGE_SIZE}; +use crate::server::SenderID; use crate::services::SystemServicesHandle; use core::mem; use xous::*; @@ -264,7 +265,11 @@ pub fn handle(call: SysCall) -> core::result::Result let mut ss = SystemServicesHandle::get(); let context_nr = ss.current_context_nr(); // See if there is a pending message. If so, return immediately. - let server = ss.server_mut(sid).ok_or(xous::Error::ServerNotFound)?; + let sidx = ss.server_sidx(sid).ok_or(xous::Error::ServerNotFound)?; + let server = ss + .server_from_sidx(sidx) + .ok_or(xous::Error::ServerNotFound)?; + server.print_queue(); // Ensure the server is for this PID if server.pid != pid { @@ -272,12 +277,16 @@ pub fn handle(call: SysCall) -> core::result::Result } // If there is a pending message, return it immediately. - if let Some(msg) = server.take_next_message() { - return Ok(xous::Result::Message(msg.0)); + if let Some(msg) = server.take_next_message(sidx) { + println!("PID {} had a message ready -- returning it", pid); + return Ok(xous::Result::Message(msg)); } - // There is no pending message, so return control to the parent process - // and mark ourselves as awaiting an event. + // There is no pending message, so return control to the parent + // process and mark ourselves as awaiting an event. When a message + // arrives, our return value will already be set to the + // MessageEnvelope of the incoming message. + println!("PID {} did not have any waiting messages -- parking context", pid); server.park_context(context_nr); let ppid = ss.get_process(pid).expect("Can't get current process").ppid; @@ -309,6 +318,51 @@ pub fn handle(call: SysCall) -> core::result::Result ss.connect_to_server(sid) .map(|x| xous::Result::ConnectionID(x)) } + SysCall::ReturnMemory(sender) => { + let mut ss = SystemServicesHandle::get(); + let sender = SenderID::from_usize(sender)?; + + let server = ss + .server_from_sidx(sender.sidx) + .ok_or(xous::Error::ServerNotFound)?; + if server.pid != pid { + return Err(xous::Error::ServerNotFound); + } + let result = server.take_waiting_message(sender.tidx)?; + let (client_pid, client_ctx, server_addr, client_addr, len) = match result { + Some(s) => s, + None => { + println!("Tried to return memory to client, but address was bad. Assuming this is not memory that needs to be returned."); + return Ok(xous::Result::Ok); + } + }; + println!( + "Returning {} bytes from {:08x} in PID {} to {:08x} in PID {} in context {}", + len, + server_addr.get(), + pid, + client_addr.get(), + client_pid, + client_ctx + ); + + // Return the memory to the other process + // XXX This should keep the same previous write permissions as it used to have! + ss.send_memory( + server_addr.get() as *mut usize, + client_pid, + client_addr.get() as *mut usize, + len.get(), + true, + false, + )?; + + // Unblock the client context to allow it to continue. + println!("Unblocking PID {} CTX {}", client_pid, client_ctx); + ss.ready_context(client_pid, client_ctx)?; + ss.set_context_result(client_pid, client_ctx, xous::Result::Ok)?; + Ok(xous::Result::Ok) + } SysCall::SendMessage(cid, message) => { let mut ss = SystemServicesHandle::get(); let context_nr = ss.current_context_nr(); @@ -319,19 +373,29 @@ pub fn handle(call: SysCall) -> core::result::Result .expect("server couldn't be located") .pid; + // Remember the address the message came from, in case we need to + // return it after the borrow is through. + let client_address = match &message { + Message::Scalar(_) => None, + Message::Move(msg) + | Message::MutableBorrow(msg) + | Message::ImmutableBorrow(msg) => Some(msg.buf.addr), + }; + // Translate memory messages from the client process to the server - // process. Additionally, determine whether the call is blocking. - // If so, switch to the server context right away. + // process. Additionally, determine whether the call is blocking. If + // so, switch to the server context right away. let (message, blocking) = match message { Message::Scalar(_) => (message, false), Message::Move(msg) => { let new_virt = ss.send_memory( - msg.buf.as_mut_ptr(), - server_pid, - msg.buf.len(), - true, - false, - )?; + msg.buf.as_mut_ptr(), + server_pid, + 0 as *mut usize, + msg.buf.len(), + true, + false, + )?; ( Message::Move(MemoryMessage { id: msg.id, @@ -345,12 +409,13 @@ pub fn handle(call: SysCall) -> core::result::Result Message::MutableBorrow(_) => unimplemented!(), Message::ImmutableBorrow(msg) => { let new_virt = ss.send_memory( - msg.buf.as_mut_ptr(), - server_pid, - msg.buf.len(), - false, - true, - )?; + msg.buf.as_mut_ptr(), + server_pid, + 0 as *mut usize, + msg.buf.len(), + false, + true, + )?; ( Message::ImmutableBorrow(MemoryMessage { id: msg.id, @@ -361,12 +426,6 @@ pub fn handle(call: SysCall) -> core::result::Result true, ) } -, - }; - - let envelope = MessageEnvelope { - sender: (((pid as usize) << 16) & 0xffff0000) | ((context_nr << 0) & 0xffff), - message, }; // If the server has an available context to receive the message, @@ -380,6 +439,10 @@ pub fn handle(call: SysCall) -> core::result::Result "There are contexts available to handle this message. Marking PID {} as Ready", server_pid ); + let sender = + ss.remember_server_message(sidx, pid, context_nr, &message, client_address)?; + let envelope = MessageEnvelope { sender, message }; + ss.ready_context(server_pid, ctx_number)?; if blocking { println!("Activating Server context and switching away from Client"); @@ -399,10 +462,7 @@ pub fn handle(call: SysCall) -> core::result::Result // Add this message to the queue. If the queue is full, this // returns an error. - // let server = ss - // .server_from_sidx(sidx) - // .ok_or(xous::Error::ServerNotFound)?; - ss.queue_server_message(sidx, context_nr, envelope)?; + ss.queue_server_message(sidx, pid, context_nr, message, client_address)?; // Park this context if it's blocking. This is roughly // equivalent to a "Yield". diff --git a/xous-rs/src/definitions.rs b/xous-rs/src/definitions.rs index a022ffc05..31dc829b0 100644 --- a/xous-rs/src/definitions.rs +++ b/xous-rs/src/definitions.rs @@ -109,15 +109,10 @@ pub struct MessageEnvelope { /// (in the case of a Borrow). Ignore Scalar messages. impl Drop for MessageEnvelope { fn drop(&mut self) { - match &self.message { - Message::MutableBorrow(msg) | Message::ImmutableBorrow(msg) => { - crate::syscall::return_memory(self.sender, msg.buf).expect("couldn't return memory"); - } - Message::Move(msg) => { - crate::syscall::unmap_memory(msg.buf.addr, msg.buf.size) + crate::syscall::return_memory(self.sender).expect("couldn't return memory"); + if let Message::Move(msg) = &self.message { + crate::syscall::unmap_memory(msg.buf.addr, msg.buf.size) .expect("couldn't free memory message"); - } - Message::Scalar(_) => (), } } } diff --git a/xous-rs/src/syscall.rs b/xous-rs/src/syscall.rs index c45325ed5..b496c51e1 100644 --- a/xous-rs/src/syscall.rs +++ b/xous-rs/src/syscall.rs @@ -283,7 +283,7 @@ pub enum SysCall { SendMessage(CID, Message), /// Return a Borrowed memory region to a sender - ReturnMemory(MessageSender, MemoryRange), + ReturnMemory(MessageSender), /// Spawn a new thread SpawnThread( @@ -499,8 +499,8 @@ impl SysCall { sc.arg4, ], }, - SysCall::ReturnMemory(a1, a2) => [SysCallNumber::ReturnMemory as usize, - *a1, a2.addr.get(), a2.addr.get(), 0, 0, 0, 0], + SysCall::ReturnMemory(a1) => [SysCallNumber::ReturnMemory as usize, + *a1, 0, 0, 0, 0, 0, 0], SysCall::SpawnThread(a1, a2, a3) => [ SysCallNumber::SpawnThread as usize, *a1 as usize, @@ -606,7 +606,7 @@ impl SysCall { ), _ => SysCall::Invalid(a1, a2, a3, a4, a5, a6, a7), }, - Some(SysCallNumber::ReturnMemory) => SysCall::ReturnMemory(a1, MemoryRange::new(a2, a3)), + Some(SysCallNumber::ReturnMemory) => SysCall::ReturnMemory(a1), Some(SysCallNumber::SpawnThread) => { SysCall::SpawnThread(a1 as *mut usize, a2 as *mut usize, a3 as *mut usize) } @@ -711,8 +711,8 @@ pub fn unmap_memory(virt: MemoryAddress, size: MemorySize) -> core::result::Resu /// Map the given physical address to the given virtual address. /// The `size` field must be page-aligned. -pub fn return_memory(sender: MessageSender, range: MemoryRange) -> core::result::Result<(), Error> { - let result = rsyscall(SysCall::ReturnMemory(sender, range))?; +pub fn return_memory(sender: MessageSender) -> core::result::Result<(), Error> { + let result = rsyscall(SysCall::ReturnMemory(sender))?; if let Result::Ok = result { Ok(()) } else if let Result::Error(e) = result {