Skip to content
Merged
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
1 change: 1 addition & 0 deletions resources/guest_configs/vmclock.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_PTP_1588_CLOCK_VMCLOCK=y
5 changes: 3 additions & 2 deletions resources/rebuild.sh
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ function build_al_kernels {
PCIE_CONFIG="$PWD/guest_configs/pcie.config"
PMEM_CONFIG="$PWD/guest_configs/virtio-pmem.config"
MEM_CONFIG="$PWD/guest_configs/virtio-mem.config"
VMCLOCK_CONFIG="$PWD/guest_configs/vmclock.config"

if [[ "$KERNEL_VERSION" == @(all|5.10) ]]; then
build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10.config "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG"
Expand All @@ -258,7 +259,7 @@ function build_al_kernels {
build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-5.10-no-acpi.config "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG"
fi
if [[ "$KERNEL_VERSION" == @(all|6.1) ]]; then
build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG"
build_al_kernel $PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG" "$VMCLOCK_CONFIG"
fi

# Build debug kernels
Expand All @@ -271,7 +272,7 @@ function build_al_kernels {
vmlinux_split_debuginfo $OUTPUT_DIR/vmlinux-5.10.*
fi
if [[ "$KERNEL_VERSION" == @(all|6.1) ]]; then
build_al_kernel "$PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config" "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG" "$FTRACE_CONFIG" "$DEBUG_CONFIG"
build_al_kernel "$PWD/guest_configs/microvm-kernel-ci-$ARCH-6.1.config" "$CI_CONFIG" "$PCIE_CONFIG" "$PMEM_CONFIG" "$MEM_CONFIG" "$FTRACE_CONFIG" "$DEBUG_CONFIG" "$VMCLOCK_CONFIG"
vmlinux_split_debuginfo $OUTPUT_DIR/vmlinux-6.1.*
fi
}
Expand Down
8 changes: 8 additions & 0 deletions src/firecracker/src/generated/prctl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ pub const PR_MTE_TCF_MASK: u32 = 6;
pub const PR_MTE_TAG_SHIFT: u32 = 3;
pub const PR_MTE_TAG_MASK: u32 = 524280;
pub const PR_MTE_TCF_SHIFT: u32 = 1;
pub const PR_PMLEN_SHIFT: u32 = 24;
pub const PR_PMLEN_MASK: u32 = 2130706432;
pub const PR_SET_IO_FLUSHER: u32 = 57;
pub const PR_GET_IO_FLUSHER: u32 = 58;
pub const PR_SET_SYSCALL_USER_DISPATCH: u32 = 59;
Expand Down Expand Up @@ -197,3 +199,9 @@ pub const PR_PPC_DEXCR_CTRL_CLEAR: u32 = 4;
pub const PR_PPC_DEXCR_CTRL_SET_ONEXEC: u32 = 8;
pub const PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC: u32 = 16;
pub const PR_PPC_DEXCR_CTRL_MASK: u32 = 31;
pub const PR_GET_SHADOW_STACK_STATUS: u32 = 74;
pub const PR_SET_SHADOW_STACK_STATUS: u32 = 75;
pub const PR_SHADOW_STACK_ENABLE: u32 = 1;
pub const PR_SHADOW_STACK_WRITE: u32 = 2;
pub const PR_SHADOW_STACK_PUSH: u32 = 4;
pub const PR_LOCK_SHADOW_STACK_STATUS: u32 = 76;
43 changes: 9 additions & 34 deletions src/vmm/src/arch/aarch64/fdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,15 @@ fn create_chosen_node(
Ok(())
}

fn create_vmgenid_node(fdt: &mut FdtWriter, vmgenid: &Option<VmGenId>) -> Result<(), FdtError> {
if let Some(vmgenid_info) = vmgenid {
let vmgenid = fdt.begin_node("vmgenid")?;
fdt.property_string("compatible", "microsoft,vmgenid")?;
fdt.property_array_u64("reg", &[vmgenid_info.guest_address.0, VMGENID_MEM_SIZE])?;
fdt.property_array_u32(
"interrupts",
&[GIC_FDT_IRQ_TYPE_SPI, vmgenid_info.gsi, IRQ_TYPE_EDGE_RISING],
)?;
fdt.end_node(vmgenid)?;
}
fn create_vmgenid_node(fdt: &mut FdtWriter, vmgenid: &VmGenId) -> Result<(), FdtError> {
let vmgenid_node = fdt.begin_node("vmgenid")?;
fdt.property_string("compatible", "microsoft,vmgenid")?;
fdt.property_array_u64("reg", &[vmgenid.guest_address.0, VMGENID_MEM_SIZE])?;
fdt.property_array_u32(
"interrupts",
&[GIC_FDT_IRQ_TYPE_SPI, vmgenid.gsi, IRQ_TYPE_EDGE_RISING],
)?;
fdt.end_node(vmgenid_node)?;
Ok(())
}

Expand Down Expand Up @@ -586,29 +584,6 @@ mod tests {
.unwrap();
}

#[test]
fn test_create_fdt_with_vmgenid() {
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
let mut device_manager = default_device_manager();
let kvm = Kvm::new(vec![]).unwrap();
let vm = Vm::new(&kvm).unwrap();
let gic = create_gic(vm.fd(), 1, None).unwrap();
let mut cmdline = kernel_cmdline::Cmdline::new(4096).unwrap();
cmdline.insert("console", "/dev/tty0").unwrap();

device_manager.attach_vmgenid_device(&mem, &vm).unwrap();

create_fdt(
&mem,
vec![0],
CString::new("console=tty0").unwrap(),
&device_manager,
&gic,
&None,
)
.unwrap();
}

#[test]
fn test_create_fdt() {
let mem = arch_mem(layout::FDT_MAX_SIZE + 0x1000);
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.
1 change: 0 additions & 1 deletion src/vmm/src/arch/x86_64/generated/msr_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ pub const MSR_AMD64_OSVW_ID_LENGTH: u32 = 0xc0010140;
pub const MSR_AMD64_OSVW_STATUS: u32 = 0xc0010141;
pub const MSR_AMD_PPIN_CTL: u32 = 0xc00102f0;
pub const MSR_AMD_PPIN: u32 = 0xc00102f1;
pub const MSR_AMD64_CPUID_FN_7: u32 = 0xc0011002;
pub const MSR_AMD64_CPUID_FN_1: u32 = 0xc0011004;
pub const MSR_AMD64_LS_CFG: u32 = 0xc0011020;
pub const MSR_AMD64_DC_CFG: u32 = 0xc0011022;
Expand Down
17 changes: 9 additions & 8 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use crate::device_manager::{
AttachDeviceError, DeviceManager, DeviceManagerCreateError, DevicePersistError,
DeviceRestoreArgs,
};
use crate::devices::acpi::vmgenid::VmGenIdError;
use crate::devices::virtio::balloon::Balloon;
use crate::devices::virtio::block::device::Block;
use crate::devices::virtio::net::Net;
Expand Down Expand Up @@ -76,8 +75,6 @@ pub enum StartMicrovmError {
/// Error creating legacy device: {0}
#[cfg(target_arch = "x86_64")]
CreateLegacyDevice(device_manager::legacy::LegacyDeviceError),
/// Error creating VMGenID device: {0}
CreateVMGenID(VmGenIdError),
/// Error enabling PCIe support: {0}
EnablePciDevices(#[from] PciManagerError),
/// Error enabling pvtime on vcpu: {0}
Expand Down Expand Up @@ -258,7 +255,9 @@ pub fn build_microvm_for_boot(
vm_resources.serial_out_path.as_ref(),
)?;

device_manager.attach_vmgenid_device(vm.guest_memory(), &vm)?;
device_manager.attach_vmgenid_device(&vm)?;
#[cfg(target_arch = "x86_64")]
device_manager.attach_vmclock_device(&vm)?;

#[cfg(target_arch = "aarch64")]
if vcpus[0].kvm_vcpu.supports_pvtime() {
Expand Down Expand Up @@ -944,10 +943,12 @@ pub(crate) mod tests {

#[cfg(target_arch = "x86_64")]
pub(crate) fn insert_vmgenid_device(vmm: &mut Vmm) {
vmm.device_manager
.attach_vmgenid_device(vmm.vm.guest_memory(), &vmm.vm)
.unwrap();
assert!(vmm.device_manager.acpi_devices.vmgenid.is_some());
vmm.device_manager.attach_vmgenid_device(&vmm.vm).unwrap();
}

#[cfg(target_arch = "x86_64")]
pub(crate) fn insert_vmclock_device(vmm: &mut Vmm) {
vmm.device_manager.attach_vmclock_device(&vmm.vm).unwrap();
}

pub(crate) fn insert_balloon_device(
Expand Down
128 changes: 70 additions & 58 deletions src/vmm/src/device_manager/acpi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,84 +2,96 @@
// SPDX-License-Identifier: Apache-2.0

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;

#[derive(Debug, Default)]
#[derive(Debug, thiserror::Error, displaydoc::Display)]
pub enum ACPIDeviceError {
/// Could not register GSI with KVM: {0}
RegisterIrq(#[from] kvm_ioctls::Error),
/// Could not write to guest memory: {0}
WriteGuestMemory(#[from] GuestMemoryError),
}

#[derive(Debug)]
pub struct ACPIDeviceManager {
/// VMGenID device
pub vmgenid: Option<VmGenId>,
pub vmgenid: VmGenId,
/// VMclock device
#[cfg(target_arch = "x86_64")]
pub vmclock: VmClock,
}

impl ACPIDeviceManager {
/// Create a new ACPIDeviceManager object
pub fn new() -> Self {
Default::default()
pub fn new(resource_allocator: &mut ResourceAllocator) -> Self {
ACPIDeviceManager {
vmgenid: VmGenId::new(resource_allocator),
#[cfg(target_arch = "x86_64")]
vmclock: VmClock::new(resource_allocator),
}
}

/// Attach a new VMGenID device to the microVM
///
/// This will register the device's interrupt with KVM
pub fn attach_vmgenid(&mut self, vmgenid: VmGenId, vm: &Vm) -> Result<(), kvm_ioctls::Error> {
vm.register_irq(&vmgenid.interrupt_evt, vmgenid.gsi)?;
self.vmgenid = Some(vmgenid);
pub fn attach_vmgenid(&self, vm: &Vm) -> Result<(), ACPIDeviceError> {
vm.register_irq(&self.vmgenid.interrupt_evt, self.vmgenid.gsi)?;
self.vmgenid.activate(vm.guest_memory())?;
Ok(())
}

/// If it exists, notify guest VMGenID device that we have resumed from a snapshot.
pub fn notify_vmgenid(&mut self) -> Result<(), std::io::Error> {
if let Some(vmgenid) = &mut self.vmgenid {
vmgenid.notify_guest()?;
}
#[cfg(target_arch = "x86_64")]
pub fn attach_vmclock(&self, vm: &Vm) -> Result<(), ACPIDeviceError> {
self.vmclock.activate(vm.guest_memory())?;
Ok(())
}
}

impl Aml for ACPIDeviceManager {
fn append_aml_bytes(&self, v: &mut Vec<u8>) -> Result<(), aml::AmlError> {
// If we have a VMGenID device, create the AML for the device and GED interrupt handler
match self.vmgenid.as_ref() {
Some(vmgenid) => {
// AML for GED
aml::Device::new(
"_SB_.GED_".try_into()?,
vec![
&aml::Name::new("_HID".try_into()?, &"ACPI0013")?,
&aml::Name::new(
"_CRS".try_into()?,
&aml::ResourceTemplate::new(vec![&aml::Interrupt::new(
true,
true,
false,
false,
vmgenid.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), &(vmgenid.gsi as u8)),
vec![&aml::Notify::new(
&aml::Path::new("\\_SB_.VGEN")?,
&0x80usize,
)],
)],
),
],
)
.append_aml_bytes(v)?;
// AML for VMGenID itself.
vmgenid.append_aml_bytes(v)
}
None => Ok(()),
}
// AML for [`VmGenId`] device.
self.vmgenid.append_aml_bytes(v)?;
// AML for [`VmClock`] device.
#[cfg(target_arch = "x86_64")]
self.vmclock.append_aml_bytes(v)?;

// Create the AML for the GED interrupt handler
aml::Device::new(
"_SB_.GED_".try_into()?,
vec![
&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::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,
)],
)],
),
],
)
.append_aml_bytes(v)
}
}
Loading
Loading