Skip to content

Commit 183de99

Browse files
committed
vmclock: add support for Aarch64
Expose VMClock device to guest via DT and enable compiling the vmclock for ARM architectures. Keep VMClock tests only on x86 until we get support from the guest kernel. Signed-off-by: Babis Chalios <[email protected]>
1 parent 2738d00 commit 183de99

File tree

5 files changed

+18
-13
lines changed

5 files changed

+18
-13
lines changed

src/vmm/src/arch/aarch64/fdt.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::arch::{
2020
use crate::device_manager::DeviceManager;
2121
use crate::device_manager::mmio::MMIODeviceInfo;
2222
use crate::device_manager::pci_mngr::PciDevices;
23+
use crate::devices::acpi::vmclock::{VMCLOCK_SIZE, VmClock};
2324
use crate::devices::acpi::vmgenid::{VMGENID_MEM_SIZE, VmGenId};
2425
use crate::initrd::InitrdConfig;
2526
use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap, GuestRegionType};
@@ -97,6 +98,7 @@ pub fn create_fdt(
9798
create_psci_node(&mut fdt_writer)?;
9899
create_devices_node(&mut fdt_writer, device_manager)?;
99100
create_vmgenid_node(&mut fdt_writer, &device_manager.acpi_devices.vmgenid)?;
101+
create_vmclock_node(&mut fdt_writer, &device_manager.acpi_devices.vmclock)?;
100102
create_pci_nodes(&mut fdt_writer, &device_manager.pci_devices)?;
101103

102104
// End Header node.
@@ -287,6 +289,18 @@ fn create_vmgenid_node(fdt: &mut FdtWriter, vmgenid: &VmGenId) -> Result<(), Fdt
287289
Ok(())
288290
}
289291

292+
fn create_vmclock_node(fdt: &mut FdtWriter, vmclock: &VmClock) -> Result<(), FdtError> {
293+
let vmclock_node = fdt.begin_node(&format!("ptp@{}", vmclock.guest_address.0))?;
294+
fdt.property_string("compatible", "amazon,vmclock")?;
295+
fdt.property_array_u64("reg", &[vmclock.guest_address.0, VMCLOCK_SIZE as u64])?;
296+
fdt.property_array_u32(
297+
"interrupts",
298+
&[GIC_FDT_IRQ_TYPE_SPI, vmclock.gsi, IRQ_TYPE_EDGE_RISING],
299+
)?;
300+
fdt.end_node(vmclock_node)?;
301+
Ok(())
302+
}
303+
290304
fn create_gic_node(fdt: &mut FdtWriter, gic_device: &GICDevice) -> Result<(), FdtError> {
291305
let interrupt = fdt.begin_node("intc")?;
292306
fdt.property_string("compatible", gic_device.fdt_compatibility())?;

src/vmm/src/device_manager/acpi.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use acpi_tables::{Aml, aml};
66
use vm_memory::GuestMemoryError;
77

88
use crate::Vm;
9-
#[cfg(target_arch = "x86_64")]
109
use crate::devices::acpi::vmclock::VmClock;
1110
use crate::devices::acpi::vmgenid::VmGenId;
1211
use crate::vstate::resources::ResourceAllocator;
@@ -24,7 +23,6 @@ pub struct ACPIDeviceManager {
2423
/// VMGenID device
2524
pub vmgenid: VmGenId,
2625
/// VMclock device
27-
#[cfg(target_arch = "x86_64")]
2826
pub vmclock: VmClock,
2927
}
3028

@@ -33,7 +31,6 @@ impl ACPIDeviceManager {
3331
pub fn new(resource_allocator: &mut ResourceAllocator) -> Self {
3432
ACPIDeviceManager {
3533
vmgenid: VmGenId::new(resource_allocator),
36-
#[cfg(target_arch = "x86_64")]
3734
vmclock: VmClock::new(resource_allocator),
3835
}
3936
}
@@ -44,7 +41,6 @@ impl ACPIDeviceManager {
4441
Ok(())
4542
}
4643

47-
#[cfg(target_arch = "x86_64")]
4844
pub fn attach_vmclock(&self, vm: &Vm) -> Result<(), ACPIDeviceError> {
4945
vm.register_irq(&self.vmclock.interrupt_evt, self.vmclock.gsi)?;
5046
self.vmclock.activate(vm.guest_memory())?;

src/vmm/src/device_manager/persist.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use super::mmio::*;
1515
#[cfg(target_arch = "aarch64")]
1616
use crate::arch::DeviceType;
1717
use crate::device_manager::acpi::ACPIDeviceError;
18-
#[cfg(target_arch = "x86_64")]
1918
use crate::devices::acpi::vmclock::{VmClock, VmClockState};
2019
use crate::devices::acpi::vmgenid::{VMGenIDState, VmGenId};
2120
#[cfg(target_arch = "aarch64")]
@@ -169,7 +168,6 @@ impl fmt::Debug for MMIODevManagerConstructorArgs<'_> {
169168
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
170169
pub struct ACPIDeviceManagerState {
171170
vmgenid: VMGenIDState,
172-
#[cfg(target_arch = "x86_64")]
173171
vmclock: VmClockState,
174172
}
175173

@@ -181,7 +179,6 @@ impl<'a> Persist<'a> for ACPIDeviceManager {
181179
fn save(&self) -> Self::State {
182180
ACPIDeviceManagerState {
183181
vmgenid: self.vmgenid.save(),
184-
#[cfg(target_arch = "x86_64")]
185182
vmclock: self.vmclock.save(),
186183
}
187184
}
@@ -191,11 +188,9 @@ impl<'a> Persist<'a> for ACPIDeviceManager {
191188
// Safe to unwrap() here, this will never return an error.
192189
vmgenid: VmGenId::restore((), &state.vmgenid).unwrap(),
193190
// Safe to unwrap() here, this will never return an error.
194-
#[cfg(target_arch = "x86_64")]
195191
vmclock: VmClock::restore((), &state.vmclock).unwrap(),
196192
};
197193

198-
#[cfg(target_arch = "x86_64")]
199194
vm.register_irq(
200195
&acpi_devices.vmclock.interrupt_evt,
201196
acpi_devices.vmclock.gsi,

src/vmm/src/devices/acpi/vmclock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::vstate::resources::ResourceAllocator;
2727
unsafe impl ByteValued for vmclock_abi {}
2828

2929
// We are reserving a physical page to expose the [`VmClock`] data
30-
const VMCLOCK_SIZE: u32 = 0x1000;
30+
pub const VMCLOCK_SIZE: u32 = 0x1000;
3131

3232
// Write a value in `vmclock_abi` both in the Firecracker-managed state
3333
// and inside guest memory address that corresponds to it.

tests/integration_tests/functional/test_max_devices.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ def max_devices(uvm):
1818
match platform.machine():
1919
case "aarch64":
2020
# On aarch64, IRQs are available from 32 to 127. We always use one IRQ each for
21-
# the VMGenID, RTC and serial devices, so the maximum number of devices supported
22-
# at the same time is 93.
23-
return 93
21+
# the VMGenID, VMClock, RTC and serial devices, so the maximum number of devices
22+
# supported at the same time is 92.
23+
return 92
2424
case "x86_64":
2525
# IRQs are available from 5 to 23. We always use one IRQ for VMGenID and VMClock
2626
# devices, so the maximum number of devices supported at the same time is 17.

0 commit comments

Comments
 (0)