diff --git a/drivers/src/imsic/core.rs b/drivers/src/imsic/core.rs index 34a85389..ae414e48 100644 --- a/drivers/src/imsic/core.rs +++ b/drivers/src/imsic/core.rs @@ -357,16 +357,16 @@ impl Imsic { // Each MMIO region must map the start of a group. let location = geometry .addr_to_location(region_base_addr) - .ok_or_else(|| Error::InvalidMmioRegion(region_base_addr.bits()))?; - if location.hart().bits() != 0 || location.file().bits() != 0 { + .ok_or_else(|| Error::InvalidMmioRegionLocation(region_base_addr.bits()))?; + if location.file().bits() != 0 { return Err(Error::InvalidMmioRegion(region_base_addr.bits())); } // Unwrap ok, we've guaranteed there are an even number of `reg` cells. let region_size = regs.next().unwrap(); - if region_size % per_hart_size != 0 { - return Err(Error::MisalignedMmioRegion(region_base_addr.bits())); + if region_size < guests_per_hart as u64 * PageSize::Size4k as u64 { + return Err(Error::MmioRegionTooSmall(region_size)); } - let harts_in_region = region_size / per_hart_size; + let harts_in_region = core::cmp::max(region_size / per_hart_size, 1); for i in 0..harts_in_region { // Each 'interrupts-extended' property is of the from " ". diff --git a/drivers/src/imsic/error.rs b/drivers/src/imsic/error.rs index 225e0c96..d197f3fc 100644 --- a/drivers/src/imsic/error.rs +++ b/drivers/src/imsic/error.rs @@ -27,6 +27,8 @@ pub enum Error { MisalignedMmioRegion(u64), /// An MMIO region specified in the device tree did not match the expected pattern. InvalidMmioRegion(u64), + /// Regions doesn't map to a hart-stride aligned address. + InvalidMmioRegionLocation(u64), /// Invalid parent interrupt specification in the device tree. InvalidParentInterrupt(u32, u32), /// The given CPU does not have a valid IMSIC location specified in the device tree. @@ -37,6 +39,8 @@ pub enum Error { TooManyInterruptFiles, /// There were fewer interrupt files than CPUs found in the device tree. MissingInterruptFiles, + /// An imsic reg regions was specified that is too small to hold the guest files. + MmioRegionTooSmall(u64), /// Failed to add an MMIO region to the system memory map. AddingMmioRegion(page_tracking::MemMapError), /// The requested CPU does not exist. diff --git a/page-tracking/src/page_info.rs b/page-tracking/src/page_info.rs index bf58a231..6957ad6b 100644 --- a/page-tracking/src/page_info.rs +++ b/page-tracking/src/page_info.rs @@ -488,7 +488,7 @@ impl PageMap { let page_map_region = mem_map .regions() .find(|r| r.region_type() == HwMemRegionType::Available && r.size() >= page_map_size) - .ok_or(PageTrackingError::PageMapNoSpace)?; + .ok_or(PageTrackingError::PageMapNoSpace(page_map_size))?; let page_map_base = page_map_region.base(); diff --git a/page-tracking/src/page_tracker.rs b/page-tracking/src/page_tracker.rs index 1b385664..ca5e2dd7 100644 --- a/page-tracking/src/page_tracker.rs +++ b/page-tracking/src/page_tracker.rs @@ -66,7 +66,7 @@ pub enum Error { /// Failed to reserve region for page map PageMapReserveRegion(hw_mem_map::Error), /// No memory available for page map - PageMapNoSpace, + PageMapNoSpace(u64), } /// Holds the result of page tracking operations. diff --git a/src/main.rs b/src/main.rs index c571c21c..aff1b190 100644 --- a/src/main.rs +++ b/src/main.rs @@ -359,7 +359,6 @@ enum RequiredDeviceProbe { Imsic(drivers::imsic::ImsicError), Pci(drivers::pci::PciError), Reset(drivers::reset::Error), - Uart(drivers::uart::Error), } impl Display for RequiredDeviceProbe { @@ -369,7 +368,6 @@ impl Display for RequiredDeviceProbe { Imsic(e) => write!(f, "IMSIC: {:?}", e), Pci(e) => write!(f, "PCI: {:?}", e), Reset(e) => write!(f, "Reset: {:?}", e), - Uart(e) => write!(f, "UART: {:?}", e), } } } @@ -478,8 +476,9 @@ fn primary_init(hart_id: u64, fdt_addr: u64) -> Result { let hyp_dt = DeviceTree::from(&hyp_fdt).map_err(Error::FdtCreation)?; // Find the UART and switch to it as the system console. - UartDriver::probe_from(&hyp_dt, &mut mem_map) - .map_err(|e| Error::RequiredDeviceProbe(RequiredDeviceProbe::Uart(e)))?; + if let Err(e) = UartDriver::probe_from(&hyp_dt, &mut mem_map) { + println!("Failed to probe UART: {:?}", e); + } // Discover the CPU topology. CpuInfo::parse_from(&hyp_dt).map_err(Error::CpuTopologyGeneration)?;