From cefeea7b50427da70cf802c84fdf0cd92e283264 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sat, 24 Aug 2024 12:56:08 +0800 Subject: [PATCH] Revise `IoMem::resize` into `IoMem::slice` --- .../comps/virtio/src/transport/mmio/device.rs | 5 +-- .../comps/virtio/src/transport/pci/device.rs | 17 +++------ ostd/src/io_mem.rs | 35 +++++++------------ 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/kernel/comps/virtio/src/transport/mmio/device.rs b/kernel/comps/virtio/src/transport/mmio/device.rs index a9db5b07a..97584537b 100644 --- a/kernel/comps/virtio/src/transport/mmio/device.rs +++ b/kernel/comps/virtio/src/transport/mmio/device.rs @@ -198,10 +198,7 @@ impl VirtioTransport for VirtioMmioTransport { fn device_config_memory(&self) -> IoMem { // offset: 0x100~0x200 - let mut io_mem = self.common_device.io_mem().clone(); - let paddr = io_mem.paddr(); - io_mem.resize((paddr + 0x100)..(paddr + 0x200)).unwrap(); - io_mem + self.common_device.io_mem().slice(0x100..0x200) } fn device_features(&self) -> u64 { diff --git a/kernel/comps/virtio/src/transport/pci/device.rs b/kernel/comps/virtio/src/transport/pci/device.rs index 6d90e09ad..02f0c0066 100644 --- a/kernel/comps/virtio/src/transport/pci/device.rs +++ b/kernel/comps/virtio/src/transport/pci/device.rs @@ -125,18 +125,11 @@ impl VirtioTransport for VirtioPciTransport { } fn device_config_memory(&self) -> IoMem { - let mut memory = self - .device_cfg - .memory_bar() - .as_ref() - .unwrap() - .io_mem() - .clone(); - let new_paddr = memory.paddr() + self.device_cfg.offset() as usize; - memory - .resize(new_paddr..(self.device_cfg.length() as usize + new_paddr)) - .unwrap(); - memory + let memory = self.device_cfg.memory_bar().as_ref().unwrap().io_mem(); + + let offset = self.device_cfg.offset() as usize; + let length = self.device_cfg.length() as usize; + memory.slice(offset..offset + length) } fn device_features(&self) -> u64 { diff --git a/ostd/src/io_mem.rs b/ostd/src/io_mem.rs index 1e2f58c6e..a0a6597f3 100644 --- a/ostd/src/io_mem.rs +++ b/ostd/src/io_mem.rs @@ -34,8 +34,8 @@ impl IoMem { /// - The given physical address range must be in the I/O memory region. /// - Reading from or writing to I/O memory regions may have side effects. Those side effects /// must not cause soundness problems (e.g., they must not corrupt the kernel memory). - pub(crate) unsafe fn new(range: Range) -> IoMem { - IoMem { + pub(crate) unsafe fn new(range: Range) -> Self { + Self { virtual_address: paddr_to_vaddr(range.start), limit: range.len(), } @@ -51,29 +51,20 @@ impl IoMem { self.limit } - /// Resizes the I/O memory region to the new `range`. + /// Slices the `IoMem`, returning another `IoMem` representing the subslice. /// - /// # Errors + /// # Panics /// - /// Returns an error if the new `range` is not within the current range. - pub fn resize(&mut self, range: Range) -> Result<()> { - let start_vaddr = paddr_to_vaddr(range.start); - let virtual_end = self - .virtual_address - .checked_add(self.limit) - .ok_or(Error::Overflow)?; - if start_vaddr < self.virtual_address || start_vaddr >= virtual_end { - return Err(Error::InvalidArgs); + /// This method will panic if the range is empty or out of bounds. + pub fn slice(&self, range: Range) -> Self { + // This ensures `range.start < range.end` and `range.end <= limit`. + assert!(!range.is_empty() && range.end <= self.limit); + + // We've checked the range is in bounds, so we can construct the new `IoMem` safely. + Self { + virtual_address: self.virtual_address + range.start, + limit: range.end - range.start, } - let end_vaddr = start_vaddr - .checked_add(range.len()) - .ok_or(Error::Overflow)?; - if end_vaddr <= self.virtual_address || end_vaddr > virtual_end { - return Err(Error::InvalidArgs); - } - self.virtual_address = start_vaddr; - self.limit = range.len(); - Ok(()) } }