mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 05:03:05 +00:00
hypervisor: add API to query VM physaddr size
Add a function that returns the size of guest physical addresses. This wraps KVM_CAP_ARM_VM_IPA_SIZE on aarch64 and CPUID to query host physical address size on x86_64. This replaces the phy_max_address_bits function from x86_64, and all callers are migrated to use the new Vm function instead. BUG=b:210727578 TEST=check on trogdor64 with debug prints Change-Id: I3107fe6357fcf166b7ad0e2a7c55919705da3b0c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3364971 Reviewed-by: Dmitry Torokhov <dtor@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Reviewed-by: Andrew Walbran <qwandor@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
f64db6a932
commit
6f4f8223b8
11 changed files with 82 additions and 62 deletions
|
@ -14,7 +14,7 @@ use devices::{
|
||||||
Bus, BusDeviceObj, BusError, IrqChip, IrqChipAArch64, PciAddress, PciConfigMmio, PciDevice,
|
Bus, BusDeviceObj, BusError, IrqChip, IrqChipAArch64, PciAddress, PciConfigMmio, PciDevice,
|
||||||
};
|
};
|
||||||
use hypervisor::{
|
use hypervisor::{
|
||||||
DeviceKind, Hypervisor, HypervisorCap, ProtectionType, VcpuAArch64, VcpuFeature, VmAArch64,
|
DeviceKind, Hypervisor, HypervisorCap, ProtectionType, VcpuAArch64, VcpuFeature, Vm, VmAArch64,
|
||||||
};
|
};
|
||||||
use minijail::Minijail;
|
use minijail::Minijail;
|
||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
|
@ -245,12 +245,8 @@ impl arch::LinuxArch for AArch64 {
|
||||||
Ok(arch_memory_regions(components.memory_size))
|
Ok(arch_memory_regions(components.memory_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_phys_max_addr() -> u64 {
|
fn create_system_allocator<V: Vm>(vm: &V) -> SystemAllocator {
|
||||||
u64::max_value()
|
Self::get_resource_allocator(vm.get_memory().memory_size())
|
||||||
}
|
|
||||||
|
|
||||||
fn create_system_allocator(guest_mem: &GuestMemory) -> SystemAllocator {
|
|
||||||
Self::get_resource_allocator(guest_mem.memory_size())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_vm<V, Vcpu>(
|
fn build_vm<V, Vcpu>(
|
||||||
|
@ -507,8 +503,8 @@ impl arch::LinuxArch for AArch64 {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_vcpu(
|
fn configure_vcpu<V: Vm>(
|
||||||
_guest_mem: &GuestMemory,
|
_vm: &V,
|
||||||
_hypervisor: &dyn Hypervisor,
|
_hypervisor: &dyn Hypervisor,
|
||||||
_irq_chip: &mut dyn IrqChipAArch64,
|
_irq_chip: &mut dyn IrqChipAArch64,
|
||||||
_vcpu: &mut dyn VcpuAArch64,
|
_vcpu: &mut dyn VcpuAArch64,
|
||||||
|
|
|
@ -148,14 +148,12 @@ pub trait LinuxArch {
|
||||||
components: &VmComponents,
|
components: &VmComponents,
|
||||||
) -> std::result::Result<Vec<(GuestAddress, u64)>, Self::Error>;
|
) -> std::result::Result<Vec<(GuestAddress, u64)>, Self::Error>;
|
||||||
|
|
||||||
/// Creates a new `SystemAllocator` that fits the given `GuestMemory`'s layout.
|
/// Creates a new `SystemAllocator` that fits the given `Vm`'s memory layout.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `guest_mem` - The memory to be used as a template for the `SystemAllocator`.
|
/// * `vm` - The virtual machine to be used as a template for the `SystemAllocator`.
|
||||||
fn create_system_allocator(guest_mem: &GuestMemory) -> SystemAllocator;
|
fn create_system_allocator<V: Vm>(vm: &V) -> SystemAllocator;
|
||||||
|
|
||||||
fn get_phys_max_addr() -> u64;
|
|
||||||
|
|
||||||
/// Takes `VmComponents` and generates a `RunnableLinuxVm`.
|
/// Takes `VmComponents` and generates a `RunnableLinuxVm`.
|
||||||
///
|
///
|
||||||
|
@ -197,15 +195,15 @@ pub trait LinuxArch {
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `guest_mem` - The memory to be used by the guest.
|
/// * `vm` - The virtual machine object.
|
||||||
/// * `hypervisor` - The `Hypervisor` that created the vcpu.
|
/// * `hypervisor` - The `Hypervisor` that created the vcpu.
|
||||||
/// * `irq_chip` - The `IrqChip` associated with this vm.
|
/// * `irq_chip` - The `IrqChip` associated with this vm.
|
||||||
/// * `vcpu` - The VCPU object to configure.
|
/// * `vcpu` - The VCPU object to configure.
|
||||||
/// * `vcpu_id` - The id of the given `vcpu`.
|
/// * `vcpu_id` - The id of the given `vcpu`.
|
||||||
/// * `num_cpus` - Number of virtual CPUs the guest will have.
|
/// * `num_cpus` - Number of virtual CPUs the guest will have.
|
||||||
/// * `has_bios` - Whether the `VmImage` is a `Bios` image
|
/// * `has_bios` - Whether the `VmImage` is a `Bios` image
|
||||||
fn configure_vcpu(
|
fn configure_vcpu<V: Vm>(
|
||||||
guest_mem: &GuestMemory,
|
vm: &V,
|
||||||
hypervisor: &dyn HypervisorArch,
|
hypervisor: &dyn HypervisorArch,
|
||||||
irq_chip: &mut dyn IrqChipArch,
|
irq_chip: &mut dyn IrqChipArch,
|
||||||
vcpu: &mut dyn VcpuArch,
|
vcpu: &mut dyn VcpuArch,
|
||||||
|
|
|
@ -40,6 +40,19 @@ impl Kvm {
|
||||||
// Use the lower 8 bits representing the IPA space as the machine type
|
// Use the lower 8 bits representing the IPA space as the machine type
|
||||||
Ok((ipa_size & KVM_VM_TYPE_ARM_IPA_SIZE_MASK) | protection_flag)
|
Ok((ipa_size & KVM_VM_TYPE_ARM_IPA_SIZE_MASK) | protection_flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the size of guest physical addresses (IPA) in bits.
|
||||||
|
pub fn get_guest_phys_addr_size(&self) -> u8 {
|
||||||
|
// Safe because we know self is a real kvm fd
|
||||||
|
let vm_ipa_size = match unsafe {
|
||||||
|
ioctl_with_val(self, KVM_CHECK_EXTENSION(), KVM_CAP_ARM_VM_IPA_SIZE.into())
|
||||||
|
} {
|
||||||
|
// Default physical address size is 40 bits if the extension is not supported.
|
||||||
|
ret if ret < 0 => 40,
|
||||||
|
ipa => ipa as u8,
|
||||||
|
};
|
||||||
|
vm_ipa_size
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KvmVm {
|
impl KvmVm {
|
||||||
|
|
|
@ -453,6 +453,10 @@ impl Vm for KvmVm {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_guest_phys_addr_size(&self) -> u8 {
|
||||||
|
self.kvm.get_guest_phys_addr_size()
|
||||||
|
}
|
||||||
|
|
||||||
fn get_memory(&self) -> &GuestMemory {
|
fn get_memory(&self) -> &GuestMemory {
|
||||||
&self.guest_mem
|
&self.guest_mem
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
use std::arch::x86_64::__cpuid;
|
||||||
|
|
||||||
use base::IoctlNr;
|
use base::IoctlNr;
|
||||||
|
|
||||||
use libc::E2BIG;
|
use libc::E2BIG;
|
||||||
|
@ -74,6 +76,20 @@ impl Kvm {
|
||||||
Err(Error::new(libc::EINVAL))
|
Err(Error::new(libc::EINVAL))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the size of guest physical addresses in bits.
|
||||||
|
pub fn get_guest_phys_addr_size(&self) -> u8 {
|
||||||
|
// Get host cpu max physical address bits.
|
||||||
|
// Assume the guest physical address size is the same as the host.
|
||||||
|
let highest_ext_function = unsafe { __cpuid(0x80000000) };
|
||||||
|
if highest_ext_function.eax >= 0x80000008 {
|
||||||
|
let addr_size = unsafe { __cpuid(0x80000008) };
|
||||||
|
// Low 8 bits of 0x80000008 leaf: host physical address size in bits.
|
||||||
|
addr_size.eax as u8
|
||||||
|
} else {
|
||||||
|
36
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HypervisorX86_64 for Kvm {
|
impl HypervisorX86_64 for Kvm {
|
||||||
|
|
|
@ -52,6 +52,9 @@ pub trait Vm: Send {
|
||||||
/// reflects the usable capabilities.
|
/// reflects the usable capabilities.
|
||||||
fn check_capability(&self, c: VmCap) -> bool;
|
fn check_capability(&self, c: VmCap) -> bool;
|
||||||
|
|
||||||
|
/// Get the guest physical address size in bits.
|
||||||
|
fn get_guest_phys_addr_size(&self) -> u8;
|
||||||
|
|
||||||
/// Gets the guest-mapped memory for the Vm.
|
/// Gets the guest-mapped memory for the Vm.
|
||||||
fn get_memory(&self) -> &GuestMemory;
|
fn get_memory(&self) -> &GuestMemory;
|
||||||
|
|
||||||
|
|
|
@ -2071,7 +2071,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
Arch::configure_vcpu(
|
Arch::configure_vcpu(
|
||||||
vm.get_memory(),
|
&vm,
|
||||||
vm.get_hypervisor(),
|
vm.get_hypervisor(),
|
||||||
irq_chip,
|
irq_chip,
|
||||||
&mut vcpu,
|
&mut vcpu,
|
||||||
|
@ -2778,7 +2778,7 @@ where
|
||||||
|
|
||||||
let exit_evt = Event::new().context("failed to create event")?;
|
let exit_evt = Event::new().context("failed to create event")?;
|
||||||
let reset_evt = Event::new().context("failed to create event")?;
|
let reset_evt = Event::new().context("failed to create event")?;
|
||||||
let mut sys_allocator = Arch::create_system_allocator(vm.get_memory());
|
let mut sys_allocator = Arch::create_system_allocator(&vm);
|
||||||
|
|
||||||
// Allocate the ramoops region first. AArch64::build_vm() assumes this.
|
// Allocate the ramoops region first. AArch64::build_vm() assumes this.
|
||||||
let ramoops_region = match &components.pstore {
|
let ramoops_region = match &components.pstore {
|
||||||
|
@ -2789,7 +2789,7 @@ where
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let phys_max_addr = Arch::get_phys_max_addr();
|
let phys_max_addr = (1u64 << vm.get_guest_phys_addr_size()) - 1;
|
||||||
let mut devices = create_devices(
|
let mut devices = create_devices(
|
||||||
&cfg,
|
&cfg,
|
||||||
&mut vm,
|
&mut vm,
|
||||||
|
|
|
@ -214,19 +214,6 @@ pub fn setup_cpuid(
|
||||||
.map_err(Error::SetSupportedCpusFailed)
|
.map_err(Error::SetSupportedCpusFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// get host cpu max physical address bits
|
|
||||||
pub fn phy_max_address_bits() -> u32 {
|
|
||||||
let mut phys_bits: u32 = 36;
|
|
||||||
|
|
||||||
let highest_ext_function = unsafe { __cpuid(0x80000000) };
|
|
||||||
if highest_ext_function.eax >= 0x80000008 {
|
|
||||||
let addr_size = unsafe { __cpuid(0x80000008) };
|
|
||||||
phys_bits = addr_size.eax & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
phys_bits
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -53,16 +53,14 @@ use std::sync::Arc;
|
||||||
use crate::bootparam::boot_params;
|
use crate::bootparam::boot_params;
|
||||||
use acpi_tables::sdt::SDT;
|
use acpi_tables::sdt::SDT;
|
||||||
use acpi_tables::{aml, aml::Aml};
|
use acpi_tables::{aml, aml::Aml};
|
||||||
use arch::{
|
use arch::{get_serial_cmdline, GetSerialCmdlineError, RunnableLinuxVm, VmComponents, VmImage};
|
||||||
get_serial_cmdline, GetSerialCmdlineError, LinuxArch, RunnableLinuxVm, VmComponents, VmImage,
|
|
||||||
};
|
|
||||||
use base::Event;
|
use base::Event;
|
||||||
use devices::serial_device::{SerialHardware, SerialParameters};
|
use devices::serial_device::{SerialHardware, SerialParameters};
|
||||||
use devices::{
|
use devices::{
|
||||||
BusDeviceObj, BusResumeDevice, IrqChip, IrqChipX86_64, PciAddress, PciConfigIo, PciConfigMmio,
|
BusDeviceObj, BusResumeDevice, IrqChip, IrqChipX86_64, PciAddress, PciConfigIo, PciConfigMmio,
|
||||||
PciDevice,
|
PciDevice,
|
||||||
};
|
};
|
||||||
use hypervisor::{HypervisorX86_64, ProtectionType, VcpuX86_64, VmX86_64};
|
use hypervisor::{HypervisorX86_64, ProtectionType, VcpuX86_64, Vm, VmX86_64};
|
||||||
use minijail::Minijail;
|
use minijail::Minijail;
|
||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
use resources::SystemAllocator;
|
use resources::SystemAllocator;
|
||||||
|
@ -370,13 +368,10 @@ impl arch::LinuxArch for X8664arch {
|
||||||
Ok(arch_memory_regions(components.memory_size, bios_size))
|
Ok(arch_memory_regions(components.memory_size, bios_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_phys_max_addr() -> u64 {
|
fn create_system_allocator<V: Vm>(vm: &V) -> SystemAllocator {
|
||||||
(1u64 << cpuid::phy_max_address_bits()) - 1
|
let guest_mem = vm.get_memory();
|
||||||
}
|
|
||||||
|
|
||||||
fn create_system_allocator(guest_mem: &GuestMemory) -> SystemAllocator {
|
|
||||||
let high_mmio_start = Self::get_high_mmio_base(guest_mem);
|
let high_mmio_start = Self::get_high_mmio_base(guest_mem);
|
||||||
let high_mmio_size = Self::get_high_mmio_size(guest_mem);
|
let high_mmio_size = Self::get_high_mmio_size(vm);
|
||||||
SystemAllocator::builder()
|
SystemAllocator::builder()
|
||||||
.add_io_addresses(0xc000, 0x1_0000)
|
.add_io_addresses(0xc000, 0x1_0000)
|
||||||
.add_low_mmio_addresses(END_ADDR_BEFORE_32BITS, PCI_MMIO_SIZE)
|
.add_low_mmio_addresses(END_ADDR_BEFORE_32BITS, PCI_MMIO_SIZE)
|
||||||
|
@ -476,6 +471,7 @@ impl arch::LinuxArch for X8664arch {
|
||||||
let max_bus = ((PCIE_CFG_MMIO_SIZE / 0x100000) - 1) as u8;
|
let max_bus = ((PCIE_CFG_MMIO_SIZE / 0x100000) - 1) as u8;
|
||||||
|
|
||||||
let (acpi_dev_resource, bat_control) = Self::setup_acpi_devices(
|
let (acpi_dev_resource, bat_control) = Self::setup_acpi_devices(
|
||||||
|
&vm,
|
||||||
&mem,
|
&mem,
|
||||||
&io_bus,
|
&io_bus,
|
||||||
system_allocator,
|
system_allocator,
|
||||||
|
@ -601,8 +597,8 @@ impl arch::LinuxArch for X8664arch {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn configure_vcpu(
|
fn configure_vcpu<V: Vm>(
|
||||||
guest_mem: &GuestMemory,
|
vm: &V,
|
||||||
hypervisor: &dyn HypervisorX86_64,
|
hypervisor: &dyn HypervisorX86_64,
|
||||||
irq_chip: &mut dyn IrqChipX86_64,
|
irq_chip: &mut dyn IrqChipX86_64,
|
||||||
vcpu: &mut dyn VcpuX86_64,
|
vcpu: &mut dyn VcpuX86_64,
|
||||||
|
@ -627,8 +623,9 @@ impl arch::LinuxArch for X8664arch {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let guest_mem = vm.get_memory();
|
||||||
let kernel_load_addr = GuestAddress(KERNEL_START_OFFSET);
|
let kernel_load_addr = GuestAddress(KERNEL_START_OFFSET);
|
||||||
regs::setup_msrs(vcpu, END_ADDR_BEFORE_32BITS).map_err(Error::SetupMsrs)?;
|
regs::setup_msrs(vm, vcpu, END_ADDR_BEFORE_32BITS).map_err(Error::SetupMsrs)?;
|
||||||
let kernel_end = guest_mem
|
let kernel_end = guest_mem
|
||||||
.checked_offset(kernel_load_addr, KERNEL_64BIT_ENTRY_OFFSET)
|
.checked_offset(kernel_load_addr, KERNEL_64BIT_ENTRY_OFFSET)
|
||||||
.ok_or(Error::KernelOffsetPastEnd)?;
|
.ok_or(Error::KernelOffsetPastEnd)?;
|
||||||
|
@ -1116,11 +1113,11 @@ impl X8664arch {
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * mem: The memory to be used by the guest
|
/// * `vm`: The virtual machine
|
||||||
fn get_high_mmio_size(mem: &GuestMemory) -> u64 {
|
fn get_high_mmio_size<V: Vm>(vm: &V) -> u64 {
|
||||||
let phys_mem_end = Self::get_phys_max_addr() + 1;
|
let phys_mem_end = 1u64 << vm.get_guest_phys_addr_size();
|
||||||
let high_mmio_end = std::cmp::min(phys_mem_end, HIGH_MMIO_MAX_END);
|
let high_mmio_end = std::cmp::min(phys_mem_end, HIGH_MMIO_MAX_END);
|
||||||
high_mmio_end - Self::get_high_mmio_base(mem)
|
high_mmio_end - Self::get_high_mmio_base(vm.get_memory())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This returns a minimal kernel command for this architecture
|
/// This returns a minimal kernel command for this architecture
|
||||||
|
@ -1204,7 +1201,8 @@ impl X8664arch {
|
||||||
/// * - `irq_chip` the IrqChip object for registering irq events
|
/// * - `irq_chip` the IrqChip object for registering irq events
|
||||||
/// * - `battery` indicate whether to create the battery
|
/// * - `battery` indicate whether to create the battery
|
||||||
/// * - `mmio_bus` the MMIO bus to add the devices to
|
/// * - `mmio_bus` the MMIO bus to add the devices to
|
||||||
fn setup_acpi_devices(
|
fn setup_acpi_devices<V: VmX86_64>(
|
||||||
|
vm: &V,
|
||||||
mem: &GuestMemory,
|
mem: &GuestMemory,
|
||||||
io_bus: &devices::Bus,
|
io_bus: &devices::Bus,
|
||||||
resources: &mut SystemAllocator,
|
resources: &mut SystemAllocator,
|
||||||
|
@ -1264,7 +1262,7 @@ impl X8664arch {
|
||||||
aml::AddressSpaceCachable::NotCacheable,
|
aml::AddressSpaceCachable::NotCacheable,
|
||||||
true,
|
true,
|
||||||
Self::get_high_mmio_base(mem),
|
Self::get_high_mmio_base(mem),
|
||||||
Self::get_high_mmio_size(mem),
|
Self::get_high_mmio_size(vm),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use std::{mem, result};
|
use std::{mem, result};
|
||||||
|
|
||||||
use base::{self, warn};
|
use base::{self, warn};
|
||||||
use hypervisor::{Fpu, Register, Regs, Sregs, VcpuX86_64};
|
use hypervisor::{Fpu, Register, Regs, Sregs, VcpuX86_64, Vm};
|
||||||
use remain::sorted;
|
use remain::sorted;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use vm_memory::{GuestAddress, GuestMemory};
|
use vm_memory::{GuestAddress, GuestMemory};
|
||||||
|
@ -93,7 +93,12 @@ fn get_mtrr_pairs(base: u64, len: u64) -> Vec<(u64, u64)> {
|
||||||
vecs
|
vecs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_mtrr_entries(vpu: &dyn VcpuX86_64, pci_start: u64, entries: &mut Vec<Register>) {
|
fn append_mtrr_entries(
|
||||||
|
vm: &dyn Vm,
|
||||||
|
vpu: &dyn VcpuX86_64,
|
||||||
|
pci_start: u64,
|
||||||
|
entries: &mut Vec<Register>,
|
||||||
|
) {
|
||||||
// Get VAR MTRR num from MSR_MTRRcap
|
// Get VAR MTRR num from MSR_MTRRcap
|
||||||
let mut msrs = vec![Register {
|
let mut msrs = vec![Register {
|
||||||
id: crate::msr_index::MSR_MTRRcap,
|
id: crate::msr_index::MSR_MTRRcap,
|
||||||
|
@ -117,7 +122,7 @@ fn append_mtrr_entries(vpu: &dyn VcpuX86_64, pci_start: u64, entries: &mut Vec<R
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let phys_mask: u64 = (1 << crate::cpuid::phy_max_address_bits()) - 1;
|
let phys_mask: u64 = (1 << vm.get_guest_phys_addr_size()) - 1;
|
||||||
for (idx, (base, len)) in vecs.iter().enumerate() {
|
for (idx, (base, len)) in vecs.iter().enumerate() {
|
||||||
let reg_idx = idx as u32 * 2;
|
let reg_idx = idx as u32 * 2;
|
||||||
entries.push(Register {
|
entries.push(Register {
|
||||||
|
@ -137,7 +142,7 @@ fn append_mtrr_entries(vpu: &dyn VcpuX86_64, pci_start: u64, entries: &mut Vec<R
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_msr_entries(vcpu: &dyn VcpuX86_64, pci_start: u64) -> Vec<Register> {
|
fn create_msr_entries(vm: &dyn Vm, vcpu: &dyn VcpuX86_64, pci_start: u64) -> Vec<Register> {
|
||||||
let mut entries = vec![
|
let mut entries = vec![
|
||||||
Register {
|
Register {
|
||||||
id: crate::msr_index::MSR_IA32_SYSENTER_CS,
|
id: crate::msr_index::MSR_IA32_SYSENTER_CS,
|
||||||
|
@ -182,7 +187,7 @@ fn create_msr_entries(vcpu: &dyn VcpuX86_64, pci_start: u64) -> Vec<Register> {
|
||||||
value: crate::msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64,
|
value: crate::msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
append_mtrr_entries(vcpu, pci_start, &mut entries);
|
append_mtrr_entries(vm, vcpu, pci_start, &mut entries);
|
||||||
entries
|
entries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,8 +196,8 @@ fn create_msr_entries(vcpu: &dyn VcpuX86_64, pci_start: u64) -> Vec<Register> {
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `vcpu` - Structure for the vcpu that holds the vcpu fd.
|
/// * `vcpu` - Structure for the vcpu that holds the vcpu fd.
|
||||||
pub fn setup_msrs(vcpu: &dyn VcpuX86_64, pci_start: u64) -> Result<()> {
|
pub fn setup_msrs(vm: &dyn Vm, vcpu: &dyn VcpuX86_64, pci_start: u64) -> Result<()> {
|
||||||
let msrs = create_msr_entries(vcpu, pci_start);
|
let msrs = create_msr_entries(vm, vcpu, pci_start);
|
||||||
vcpu.set_msrs(&msrs).map_err(Error::MsrIoctlFailed)
|
vcpu.set_msrs(&msrs).map_err(Error::MsrIoctlFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,8 @@ where
|
||||||
let arch_mem_regions = arch_memory_regions(memory_size, None);
|
let arch_mem_regions = arch_memory_regions(memory_size, None);
|
||||||
let guest_mem = GuestMemory::new(&arch_mem_regions).unwrap();
|
let guest_mem = GuestMemory::new(&arch_mem_regions).unwrap();
|
||||||
|
|
||||||
let mut resources = X8664arch::create_system_allocator(&guest_mem);
|
|
||||||
|
|
||||||
let (hyp, mut vm) = create_vm(guest_mem.clone());
|
let (hyp, mut vm) = create_vm(guest_mem.clone());
|
||||||
|
let mut resources = X8664arch::create_system_allocator(&vm);
|
||||||
let (irqchip_tube, device_tube) = Tube::pair().expect("failed to create irq tube");
|
let (irqchip_tube, device_tube) = Tube::pair().expect("failed to create irq tube");
|
||||||
|
|
||||||
let mut irq_chip = create_irq_chip(vm.try_clone().expect("failed to clone vm"), 1, device_tube);
|
let mut irq_chip = create_irq_chip(vm.try_clone().expect("failed to clone vm"), 1, device_tube);
|
||||||
|
@ -184,6 +183,7 @@ where
|
||||||
let suspend_evt = Event::new().unwrap();
|
let suspend_evt = Event::new().unwrap();
|
||||||
let mut resume_notify_devices = Vec::new();
|
let mut resume_notify_devices = Vec::new();
|
||||||
let acpi_dev_resource = X8664arch::setup_acpi_devices(
|
let acpi_dev_resource = X8664arch::setup_acpi_devices(
|
||||||
|
&vm,
|
||||||
&guest_mem,
|
&guest_mem,
|
||||||
&io_bus,
|
&io_bus,
|
||||||
&mut resources,
|
&mut resources,
|
||||||
|
@ -246,7 +246,7 @@ where
|
||||||
.expect("failed to add vcpu to irqchip");
|
.expect("failed to add vcpu to irqchip");
|
||||||
|
|
||||||
setup_cpuid(&hyp, &irq_chip, &vcpu, 0, 1, false, false).unwrap();
|
setup_cpuid(&hyp, &irq_chip, &vcpu, 0, 1, false, false).unwrap();
|
||||||
setup_msrs(&vcpu, END_ADDR_BEFORE_32BITS).unwrap();
|
setup_msrs(&vm, &vcpu, END_ADDR_BEFORE_32BITS).unwrap();
|
||||||
|
|
||||||
setup_regs(
|
setup_regs(
|
||||||
&vcpu,
|
&vcpu,
|
||||||
|
|
Loading…
Reference in a new issue