Skip to content

Commit

Permalink
[ARM64] Pass through all unknown MMIO to the host. (#652) (#655)
Browse files Browse the repository at this point in the history
There are some hardware configurations on ARM64 that are not yet
completely described in the MMIO map. Since ARM64 is not expected to do
any x86-style legacy device detection probes, pass all MMIO accesses
through to the host. If the host does not recognize the address, it will
handle the bad access.

---------

Co-authored-by: Brian Perkins <[email protected]>
  • Loading branch information
Brian-Perkins and Brian Perkins authored Jan 11, 2025
1 parent ec7cfcb commit 6213a2e
Showing 1 changed file with 31 additions and 15 deletions.
46 changes: 31 additions & 15 deletions openhcl/underhill_core/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2572,15 +2572,19 @@ async fn new_underhill_vm(
// If VTOM is present (CVM scenario), accesses to physical device and PCI config space may
// occur below or above vTOM, but only within MMIO regions. Forward both to the host.
let vtom = vtom.unwrap_or(0);
let mut untrusted_mmio_ranges: Vec<_> = mem_layout.mmio().to_vec();
if vtom > 0 {
untrusted_mmio_ranges.extend(
mem_layout
.mmio()
.iter()
.map(|range| MemoryRange::new((range.start() + vtom)..(range.end() + vtom))),
);
}
let untrusted_mmio_ranges =
if cfg!(guest_arch = "aarch64") && vtom == 0 {
// By default on aarch64 send all MMIO accesses to the host.
None
} else {
let mut untrusted_mmio_ranges: Vec<_> = mem_layout.mmio().to_vec();
if vtom > 0 {
untrusted_mmio_ranges.extend(mem_layout.mmio().iter().map(|range| {
MemoryRange::new((range.start() + vtom)..(range.end() + vtom))
}));
}
Some(untrusted_mmio_ranges)
};

Arc::new(CloseableMutex::new(FallbackMmioDevice {
partition: Arc::downgrade(&partition),
Expand Down Expand Up @@ -3365,30 +3369,42 @@ impl chipset::pm::PmTimerAssist for UnderhillPmTimerAssist {
// MmioIntercept traits.
struct FallbackMmioDevice {
partition: std::sync::Weak<UhPartition>,
mmio_ranges: Vec<MemoryRange>,
mmio_ranges: Option<Vec<MemoryRange>>,
}

impl chipset_device::mmio::MmioIntercept for FallbackMmioDevice {
fn mmio_read(&mut self, addr: u64, data: &mut [u8]) -> chipset_device::io::IoResult {
data.fill(!0);
if let Some(partition) = self.partition.upgrade() {
if self.mmio_ranges.iter().any(|range| {
let Some(partition) = self.partition.upgrade() else {
return chipset_device::io::IoResult::Ok;
};

if let Some(mmio_ranges) = &self.mmio_ranges {
data.fill(!0);
if mmio_ranges.iter().any(|range| {
range.contains_addr(addr) && range.contains_addr(addr + data.len() as u64 - 1)
}) {
partition.host_mmio_read(addr, data);
}
} else {
partition.host_mmio_read(addr, data);
}

chipset_device::io::IoResult::Ok
}

fn mmio_write(&mut self, addr: u64, data: &[u8]) -> chipset_device::io::IoResult {
if let Some(partition) = self.partition.upgrade() {
if self.mmio_ranges.iter().any(|range| {
let Some(partition) = self.partition.upgrade() else {
return chipset_device::io::IoResult::Ok;
};

if let Some(mmio_ranges) = &self.mmio_ranges {
if mmio_ranges.iter().any(|range| {
range.contains_addr(addr) && range.contains_addr(addr + data.len() as u64 - 1)
}) {
partition.host_mmio_write(addr, data);
}
} else {
partition.host_mmio_write(addr, data);
}

chipset_device::io::IoResult::Ok
Expand Down

0 comments on commit 6213a2e

Please sign in to comment.