(&self, offset: u64, data: &[u8])
| 616 | } |
| 617 | |
| 618 | fn handle_guest_write(&self, offset: u64, data: &[u8]) { |
| 619 | if offset as usize != std::mem::offset_of!(PvmemcontrolTransport, command) { |
| 620 | if data.len() != 4 && data.len() != 8 { |
| 621 | warn!("guest write is not 4 or 8 bytes long"); |
| 622 | return; |
| 623 | } |
| 624 | self.dev.write().unwrap().write_transport(offset, data); |
| 625 | return; |
| 626 | } |
| 627 | let data = if data.len() == 4 { |
| 628 | let mut d = [0u8; 4]; |
| 629 | d.iter_mut() |
| 630 | .zip(data.iter()) |
| 631 | .for_each(|(d, data)| *d = *data); |
| 632 | d |
| 633 | } else { |
| 634 | warn!("guest write with non u32 at command register"); |
| 635 | return; |
| 636 | }; |
| 637 | let data_cmd = u32::from_le_bytes(data); |
| 638 | let command = PvmemcontrolTransportCommand::try_from(data_cmd); |
| 639 | |
| 640 | match command { |
| 641 | Ok(command) => self.dev.write().unwrap().run_command(&self.mem, command), |
| 642 | Err(_) => { |
| 643 | GuestConnection::try_from(data_cmd) |
| 644 | .and_then(|conn| { |
| 645 | self.dev |
| 646 | .read() |
| 647 | .unwrap() |
| 648 | .find_connection(conn) |
| 649 | .ok_or(Error::InvalidConnection(conn.command)) |
| 650 | }) |
| 651 | .map_or_else( |
| 652 | |err| warn!("{err:?}"), |
| 653 | |gpa| self.handle_pvmemcontrol_request(gpa), |
| 654 | ); |
| 655 | } |
| 656 | } |
| 657 | } |
| 658 | |
| 659 | fn handle_guest_read(&self, offset: u64, data: &mut [u8]) { |
| 660 | self.dev.read().unwrap().read_transport(offset, data); |
no test coverage detected