diff --git a/src/devices/pci/src/config.rs b/src/devices/pci/src/config.rs index 44c1e45d..18d8066b 100644 --- a/src/devices/pci/src/config.rs +++ b/src/devices/pci/src/config.rs @@ -6,7 +6,7 @@ use bitflags::bitflags; use core::convert::From; use crate::mmio::{alloc_mmio32, alloc_mmio64}; -use crate::{PciCommand, Result}; +use crate::{PciCommand, PciError, Result}; pub const PCI_CONFIGURATION_ADDRESS_PORT: u16 = 0xCF8; pub const PCI_CONFIGURATION_DATA_PORT: u16 = 0xCFC; @@ -453,7 +453,7 @@ impl PciDevice { self.bars[current_bar].address = addr & PCI_MEM64_BASE_ADDRESS_MASK; current_bar_offset += 4; } - _ => panic!("Unsupported BAR type"), + _ => return Err(PciError::InvalidBarType), } } diff --git a/src/devices/pci/src/lib.rs b/src/devices/pci/src/lib.rs index ed6be3b2..bc9d6e8f 100644 --- a/src/devices/pci/src/lib.rs +++ b/src/devices/pci/src/lib.rs @@ -25,4 +25,5 @@ pub type Result = core::result::Result; pub enum PciError { InvalidParameter, MmioOutofResource, + InvalidBarType, } diff --git a/src/devices/pci/src/mmio.rs b/src/devices/pci/src/mmio.rs index ee191df2..9f322bac 100644 --- a/src/devices/pci/src/mmio.rs +++ b/src/devices/pci/src/mmio.rs @@ -35,10 +35,10 @@ pub fn alloc_mmio32(size: u32) -> Result { #[cfg(not(feature = "fuzz"))] pub fn alloc_mmio32(size: u32) -> Result { - let addr = *MMIO32.lock(); - let addr = align_up(addr as usize, size as usize); + let cur = *MMIO32.lock(); + let addr = align_up(cur as u64, size as u64).ok_or(PciError::InvalidParameter)?; - if size > MMIO32_SIZE || addr > (MMIO32_START + MMIO32_SIZE - size) as usize { + if size > MMIO32_SIZE || addr > (MMIO32_START + MMIO32_SIZE - size) as u64 { return Err(PciError::MmioOutofResource); } @@ -54,14 +54,16 @@ pub fn alloc_mmio64(size: u64) -> Result { #[cfg(not(feature = "fuzz"))] pub fn alloc_mmio64(size: u64) -> Result { - let addr = *MMIO64.lock(); - addr.checked_add(size).ok_or(PciError::InvalidParameter)?; + let cur = *MMIO64.lock(); + let addr = align_up(cur, size).ok_or(PciError::InvalidParameter)? as u64; - let addr = align_up(addr as usize, size as usize) as u64; - *MMIO64.lock() = addr + size; + *MMIO64.lock() = addr.checked_add(size).ok_or(PciError::InvalidParameter)?; Ok(addr) } -fn align_up(addr: usize, align: usize) -> usize { - (addr + align - 1) & !(align - 1) +fn align_up(addr: u64, align: u64) -> Option { + if align == 0 { + return None; + } + Some((addr.checked_add(align)? - 1) & !(align - 1)) }