Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/vmm/src/arch/aarch64/fdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::arch::{
use crate::device_manager::DeviceManager;
use crate::device_manager::mmio::MMIODeviceInfo;
use crate::device_manager::pci_mngr::PciDevices;
use crate::devices::acpi::vmclock::{VMCLOCK_SIZE, VmClock};
use crate::devices::acpi::vmgenid::{VMGENID_MEM_SIZE, VmGenId};
use crate::initrd::InitrdConfig;
use crate::vstate::memory::{Address, GuestMemory, GuestMemoryMmap, GuestRegionType};
Expand Down Expand Up @@ -97,6 +98,7 @@ pub fn create_fdt(
create_psci_node(&mut fdt_writer)?;
create_devices_node(&mut fdt_writer, device_manager)?;
create_vmgenid_node(&mut fdt_writer, &device_manager.acpi_devices.vmgenid)?;
create_vmclock_node(&mut fdt_writer, &device_manager.acpi_devices.vmclock)?;
create_pci_nodes(&mut fdt_writer, &device_manager.pci_devices)?;

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

fn create_vmclock_node(fdt: &mut FdtWriter, vmclock: &VmClock) -> Result<(), FdtError> {
let vmclock_node = fdt.begin_node(&format!("ptp@{}", vmclock.guest_address.0))?;
fdt.property_string("compatible", "amazon,vmclock")?;
fdt.property_array_u64("reg", &[vmclock.guest_address.0, VMCLOCK_SIZE as u64])?;
fdt.property_array_u32(
"interrupts",
&[GIC_FDT_IRQ_TYPE_SPI, vmclock.gsi, IRQ_TYPE_EDGE_RISING],
)?;
fdt.end_node(vmclock_node)?;
Ok(())
}

fn create_gic_node(fdt: &mut FdtWriter, gic_device: &GICDevice) -> Result<(), FdtError> {
let interrupt = fdt.begin_node("intc")?;
fdt.property_string("compatible", gic_device.fdt_compatibility())?;
Expand Down
Binary file modified src/vmm/src/arch/aarch64/output_GICv3.dtb
Binary file not shown.
Binary file modified src/vmm/src/arch/aarch64/output_initrd_GICv3.dtb
Binary file not shown.
56 changes: 33 additions & 23 deletions src/vmm/src/device_manager/acpi.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

#[cfg(target_arch = "x86_64")]
use acpi_tables::{Aml, aml};
use vm_memory::GuestMemoryError;

use crate::Vm;
#[cfg(target_arch = "x86_64")]
use crate::devices::acpi::vmclock::VmClock;
use crate::devices::acpi::vmgenid::VmGenId;
use crate::vstate::resources::ResourceAllocator;
Expand All @@ -23,7 +23,6 @@ pub struct ACPIDeviceManager {
/// VMGenID device
pub vmgenid: VmGenId,
/// VMclock device
#[cfg(target_arch = "x86_64")]
pub vmclock: VmClock,
}

Expand All @@ -32,7 +31,6 @@ impl ACPIDeviceManager {
pub fn new(resource_allocator: &mut ResourceAllocator) -> Self {
ACPIDeviceManager {
vmgenid: VmGenId::new(resource_allocator),
#[cfg(target_arch = "x86_64")]
vmclock: VmClock::new(resource_allocator),
}
}
Expand All @@ -43,13 +41,14 @@ impl ACPIDeviceManager {
Ok(())
}

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

#[cfg(target_arch = "x86_64")]
impl Aml for ACPIDeviceManager {
fn append_aml_bytes(&self, v: &mut Vec<u8>) -> Result<(), aml::AmlError> {
// AML for [`VmGenId`] device.
Expand All @@ -65,30 +64,41 @@ impl Aml for ACPIDeviceManager {
&aml::Name::new("_HID".try_into()?, &"ACPI0013")?,
&aml::Name::new(
"_CRS".try_into()?,
&aml::ResourceTemplate::new(vec![&aml::Interrupt::new(
true,
true,
false,
false,
self.vmgenid.gsi,
)]),
&aml::ResourceTemplate::new(vec![
&aml::Interrupt::new(true, true, false, false, self.vmgenid.gsi),
&aml::Interrupt::new(true, true, false, false, self.vmclock.gsi),
]),
)?,
&aml::Method::new(
"_EVT".try_into()?,
1,
true,
vec![&aml::If::new(
// We know that the maximum IRQ number fits in a u8. We have up to
// 32 IRQs in x86 and up to 128 in
// ARM (look into
// `vmm::crate::arch::layout::GSI_LEGACY_END`)
#[allow(clippy::cast_possible_truncation)]
&aml::Equal::new(&aml::Arg(0), &(self.vmgenid.gsi as u8)),
vec![&aml::Notify::new(
&aml::Path::new("\\_SB_.VGEN")?,
&0x80usize,
)],
)],
vec![
&aml::If::new(
// We know that the maximum IRQ number fits in a u8. We have up to
// 32 IRQs in x86 and up to 128 in
// ARM (look into
// `vmm::crate::arch::layout::GSI_LEGACY_END`)
#[allow(clippy::cast_possible_truncation)]
&aml::Equal::new(&aml::Arg(0), &(self.vmgenid.gsi as u8)),
vec![&aml::Notify::new(
&aml::Path::new("\\_SB_.VGEN")?,
&0x80usize,
)],
),
&aml::If::new(
// We know that the maximum IRQ number fits in a u8. We have up to
// 32 IRQs in x86 and up to 128 in
// ARM (look into
// `vmm::crate::arch::layout::GSI_LEGACY_END`)
#[allow(clippy::cast_possible_truncation)]
&aml::Equal::new(&aml::Arg(0), &(self.vmclock.gsi as u8)),
vec![&aml::Notify::new(
&aml::Path::new("\\_SB_.VCLK")?,
&0x80usize,
)],
),
],
),
],
)
Expand Down
4 changes: 4 additions & 0 deletions src/vmm/src/device_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,10 @@ impl<'a> Persist<'a> for DeviceManager {
// Restore ACPI devices
let mut acpi_devices = ACPIDeviceManager::restore(constructor_args.vm, &state.acpi_state)?;
acpi_devices.vmgenid.notify_guest()?;
#[cfg(target_arch = "x86_64")]
acpi_devices
.vmclock
.post_load_update(constructor_args.vm.guest_memory());

// Restore PCI devices
let pci_ctor_args = PciDevicesConstructorArgs {
Expand Down
11 changes: 6 additions & 5 deletions src/vmm/src/device_manager/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use super::mmio::*;
#[cfg(target_arch = "aarch64")]
use crate::arch::DeviceType;
use crate::device_manager::acpi::ACPIDeviceError;
#[cfg(target_arch = "x86_64")]
use crate::devices::acpi::vmclock::{VmClock, VmClockState};
use crate::devices::acpi::vmgenid::{VMGenIDState, VmGenId};
#[cfg(target_arch = "aarch64")]
Expand Down Expand Up @@ -169,7 +168,6 @@ impl fmt::Debug for MMIODevManagerConstructorArgs<'_> {
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct ACPIDeviceManagerState {
vmgenid: VMGenIDState,
#[cfg(target_arch = "x86_64")]
vmclock: VmClockState,
}

Expand All @@ -181,7 +179,6 @@ impl<'a> Persist<'a> for ACPIDeviceManager {
fn save(&self) -> Self::State {
ACPIDeviceManagerState {
vmgenid: self.vmgenid.save(),
#[cfg(target_arch = "x86_64")]
vmclock: self.vmclock.save(),
}
}
Expand All @@ -191,10 +188,14 @@ impl<'a> Persist<'a> for ACPIDeviceManager {
// Safe to unwrap() here, this will never return an error.
vmgenid: VmGenId::restore((), &state.vmgenid).unwrap(),
// Safe to unwrap() here, this will never return an error.
#[cfg(target_arch = "x86_64")]
vmclock: VmClock::restore(vm.guest_memory(), &state.vmclock).unwrap(),
vmclock: VmClock::restore((), &state.vmclock).unwrap(),
};

vm.register_irq(
&acpi_devices.vmclock.interrupt_evt,
acpi_devices.vmclock.gsi,
)?;

acpi_devices.attach_vmgenid(vm)?;
Ok(acpi_devices)
}
Expand Down
7 changes: 6 additions & 1 deletion src/vmm/src/devices/acpi/generated/vmclock_abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub const VMCLOCK_FLAG_PERIOD_MAXERROR_VALID: u64 = 16;
pub const VMCLOCK_FLAG_TIME_ESTERROR_VALID: u64 = 32;
pub const VMCLOCK_FLAG_TIME_MAXERROR_VALID: u64 = 64;
pub const VMCLOCK_FLAG_TIME_MONOTONIC: u64 = 128;
pub const VMCLOCK_FLAG_VM_GEN_COUNTER_PRESENT: u64 = 256;
pub const VMCLOCK_FLAG_NOTIFICATION_PRESENT: u64 = 512;
pub const VMCLOCK_STATUS_UNKNOWN: u8 = 0;
pub const VMCLOCK_STATUS_INITIALIZING: u8 = 1;
pub const VMCLOCK_STATUS_SYNCHRONIZED: u8 = 2;
Expand Down Expand Up @@ -153,10 +155,11 @@ pub struct vmclock_abi {
pub time_frac_sec: __le64,
pub time_esterror_nanosec: __le64,
pub time_maxerror_nanosec: __le64,
pub vm_generation_counter: __le64,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of vmclock_abi"][::std::mem::size_of::<vmclock_abi>() - 104usize];
["Size of vmclock_abi"][::std::mem::size_of::<vmclock_abi>() - 112usize];
["Alignment of vmclock_abi"][::std::mem::align_of::<vmclock_abi>() - 8usize];
["Offset of field: vmclock_abi::magic"][::std::mem::offset_of!(vmclock_abi, magic) - 0usize];
["Offset of field: vmclock_abi::size"][::std::mem::offset_of!(vmclock_abi, size) - 4usize];
Expand Down Expand Up @@ -198,4 +201,6 @@ const _: () = {
[::std::mem::offset_of!(vmclock_abi, time_esterror_nanosec) - 88usize];
["Offset of field: vmclock_abi::time_maxerror_nanosec"]
[::std::mem::offset_of!(vmclock_abi, time_maxerror_nanosec) - 96usize];
["Offset of field: vmclock_abi::vm_generation_counter"]
[::std::mem::offset_of!(vmclock_abi, vm_generation_counter) - 104usize];
};
Loading