Revise IoMem::resize into IoMem::slice

This commit is contained in:
Ruihan Li
2024-08-24 12:56:08 +08:00
committed by Tate, Hongliang Tian
parent c8ba695c85
commit cefeea7b50
3 changed files with 19 additions and 38 deletions

View File

@ -198,10 +198,7 @@ impl VirtioTransport for VirtioMmioTransport {
fn device_config_memory(&self) -> IoMem { fn device_config_memory(&self) -> IoMem {
// offset: 0x100~0x200 // offset: 0x100~0x200
let mut io_mem = self.common_device.io_mem().clone(); self.common_device.io_mem().slice(0x100..0x200)
let paddr = io_mem.paddr();
io_mem.resize((paddr + 0x100)..(paddr + 0x200)).unwrap();
io_mem
} }
fn device_features(&self) -> u64 { fn device_features(&self) -> u64 {

View File

@ -125,18 +125,11 @@ impl VirtioTransport for VirtioPciTransport {
} }
fn device_config_memory(&self) -> IoMem { fn device_config_memory(&self) -> IoMem {
let mut memory = self let memory = self.device_cfg.memory_bar().as_ref().unwrap().io_mem();
.device_cfg
.memory_bar() let offset = self.device_cfg.offset() as usize;
.as_ref() let length = self.device_cfg.length() as usize;
.unwrap() memory.slice(offset..offset + length)
.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
} }
fn device_features(&self) -> u64 { fn device_features(&self) -> u64 {

View File

@ -34,8 +34,8 @@ impl IoMem {
/// - The given physical address range must be in the I/O memory region. /// - 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 /// - 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). /// must not cause soundness problems (e.g., they must not corrupt the kernel memory).
pub(crate) unsafe fn new(range: Range<Paddr>) -> IoMem { pub(crate) unsafe fn new(range: Range<Paddr>) -> Self {
IoMem { Self {
virtual_address: paddr_to_vaddr(range.start), virtual_address: paddr_to_vaddr(range.start),
limit: range.len(), limit: range.len(),
} }
@ -51,29 +51,20 @@ impl IoMem {
self.limit 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. /// This method will panic if the range is empty or out of bounds.
pub fn resize(&mut self, range: Range<Paddr>) -> Result<()> { pub fn slice(&self, range: Range<usize>) -> Self {
let start_vaddr = paddr_to_vaddr(range.start); // This ensures `range.start < range.end` and `range.end <= limit`.
let virtual_end = self assert!(!range.is_empty() && range.end <= self.limit);
.virtual_address
.checked_add(self.limit) // We've checked the range is in bounds, so we can construct the new `IoMem` safely.
.ok_or(Error::Overflow)?; Self {
if start_vaddr < self.virtual_address || start_vaddr >= virtual_end { virtual_address: self.virtual_address + range.start,
return Err(Error::InvalidArgs); 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(())
} }
} }