Take data passed via syscall and convert to a kernel Message object. If the user passed rendezvous or memory handles then these are removed from the process using take_rendezvous() and take_memory_chunk() methods, and stored in the Message.
(
thread: &mut Thread,
syscall_id: u64,
data1: u64,
data2: u64,
data3: u64)
| 143 | /// take_memory_chunk() methods, and stored in the Message. |
| 144 | /// |
| 145 | pub fn from_values( |
| 146 | thread: &mut Thread, |
| 147 | syscall_id: u64, |
| 148 | data1: u64, |
| 149 | data2: u64, |
| 150 | data3: u64) -> Result<Message, usize> { |
| 151 | |
| 152 | if syscall_id & MESSAGE_LONG == 0 { |
| 153 | Ok(Message::Short(data1, |
| 154 | data2, |
| 155 | data3)) |
| 156 | } else { |
| 157 | // Long message |
| 158 | let message = Message::Long( |
| 159 | data1, |
| 160 | match syscall_id & MESSAGE_DATA2_TYPE { |
| 161 | MESSAGE_DATA2_RDV => { |
| 162 | // Moving or copying a handle |
| 163 | // First copy, then drop if message is valid |
| 164 | if let Some(rdv) = thread.rendezvous(data2) { |
| 165 | MessageData::Rendezvous(rdv) |
| 166 | } else { |
| 167 | // Invalid handle |
| 168 | return Err(syscalls::SYSCALL_ERROR_INVALID_HANDLE); |
| 169 | } |
| 170 | } |
| 171 | MESSAGE_DATA2_MEM => { |
| 172 | // Memory handle |
| 173 | let (physaddr, _level) = thread.memory_chunk( |
| 174 | VirtAddr::new(data2))?; |
| 175 | MessageData::Memory(physaddr) |
| 176 | } |
| 177 | _ => MessageData::Value(data2) |
| 178 | }, |
| 179 | match syscall_id & MESSAGE_DATA3_TYPE { |
| 180 | MESSAGE_DATA3_RDV => { |
| 181 | if let Some(rdv) = thread.rendezvous(data3) { |
| 182 | MessageData::Rendezvous(rdv) |
| 183 | } else { |
| 184 | // Invalid handle. |
| 185 | // If we moved data2 we would have to put it back here |
| 186 | return Err(syscalls::SYSCALL_ERROR_INVALID_HANDLE); |
| 187 | } |
| 188 | } |
| 189 | MESSAGE_DATA3_MEM => { |
| 190 | // Memory handle |
| 191 | let (physaddr, _level) = thread.memory_chunk( |
| 192 | VirtAddr::new(data3))?; |
| 193 | MessageData::Memory(physaddr) |
| 194 | } |
| 195 | _ => MessageData::Value(data3) |
| 196 | }); |
| 197 | // Message is valid => Remove handles being moved |
| 198 | match syscall_id & MESSAGE_DATA2_TYPE { |
| 199 | MESSAGE_DATA2_RDV => { |
| 200 | let _ = thread.take_rendezvous(data2); |
| 201 | } |
| 202 | MESSAGE_DATA2_MEM => { |
nothing calls this directly
no test coverage detected