mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-09-19 13:30:56 +00:00
arch: x86_64: Don't expose TSC deadline timer for MSHV guests
HV APIC(i.e., synthetic APIC controller exposed by Microsoft Hypervisor)
does not support one-shot operation using a TSC deadline value. Due to
which we see the following backtrace inside the guest when running with
hypervisor-fw/OVMF:
[ 0.560765] unchecked MSR access error: WRMSR to 0x832 (tried to
write 0x00000000000400ec) at rIP: 0xffffffff8f473594
(native_write_msr+0x4/0x30)
[ 0.560765] Call Trace:
[ 0.560765] ? native_apic_msr_write+0x2b/0x30
[ 0.560765] __setup_APIC_LVTT+0xbc/0xe0
[ 0.560765] lapic_timer_set_oneshot+0x27/0x30
[ 0.560765] clockevents_switch_state+0xaf/0xf0
[ 0.560765] tick_setup_periodic+0x47/0x90
[ 0.560765] tick_setup_device.isra.0+0x7c/0x110
[ 0.560765] tick_check_new_device+0xce/0xf0
[ 0.560765] clockevents_register_device+0x82/0x170
[ 0.560765] clockevents_config_and_register+0x2f/0x40
[ 0.560765] setup_APIC_timer+0xe1/0xf0
[ 0.560765] setup_boot_APIC_clock+0x5f/0x66
[ 0.560765] native_smp_prepare_cpus+0x1d6/0x286
[ 0.560765] kernel_init_freeable+0xcf/0x255
[ 0.560765] ? rest_init+0xb0/0xb0
[ 0.560765] kernel_init+0xe/0x110
[ 0.560765] ret_from_fork+0x22/0x40
Also, if this feature is exposed guest would not finish booting and get
stuck right before unpacking the root filesystem.
Fixes: 06e8d1c40
("hypervisor: mshv: fix topology for Intel HW on MSHV")
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
parent
efb92d409f
commit
c1f18fa634
@ -6,6 +6,7 @@ version = "0.1.0"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
kvm = []
|
||||||
sev_snp = []
|
sev_snp = []
|
||||||
tdx = []
|
tdx = []
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ use std::arch::x86_64;
|
|||||||
pub mod tdx;
|
pub mod tdx;
|
||||||
|
|
||||||
// CPUID feature bits
|
// CPUID feature bits
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit.
|
const TSC_DEADLINE_TIMER_ECX_BIT: u8 = 24; // tsc deadline timer ecx bit.
|
||||||
const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit.
|
const HYPERVISOR_ECX_BIT: u8 = 31; // Hypervisor ecx bit.
|
||||||
const MTRR_EDX_BIT: u8 = 12; // Hypervisor ecx bit.
|
const MTRR_EDX_BIT: u8 = 12; // Hypervisor ecx bit.
|
||||||
@ -619,17 +620,8 @@ pub fn generate_common_cpuid(
|
|||||||
"Generating guest CPUID for with physical address size: {}",
|
"Generating guest CPUID for with physical address size: {}",
|
||||||
config.phys_bits
|
config.phys_bits
|
||||||
);
|
);
|
||||||
let cpuid_patches = vec![
|
#[allow(unused_mut)]
|
||||||
// Patch tsc deadline timer bit
|
let mut cpuid_patches = vec![
|
||||||
CpuidPatch {
|
|
||||||
function: 1,
|
|
||||||
index: 0,
|
|
||||||
flags_bit: None,
|
|
||||||
eax_bit: None,
|
|
||||||
ebx_bit: None,
|
|
||||||
ecx_bit: Some(TSC_DEADLINE_TIMER_ECX_BIT),
|
|
||||||
edx_bit: None,
|
|
||||||
},
|
|
||||||
// Patch hypervisor bit
|
// Patch hypervisor bit
|
||||||
CpuidPatch {
|
CpuidPatch {
|
||||||
function: 1,
|
function: 1,
|
||||||
@ -652,6 +644,23 @@ pub fn generate_common_cpuid(
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
#[cfg(feature = "kvm")]
|
||||||
|
if matches!(
|
||||||
|
hypervisor.hypervisor_type(),
|
||||||
|
hypervisor::HypervisorType::Kvm
|
||||||
|
) {
|
||||||
|
// Patch tsc deadline timer bit
|
||||||
|
cpuid_patches.push(CpuidPatch {
|
||||||
|
function: 1,
|
||||||
|
index: 0,
|
||||||
|
flags_bit: None,
|
||||||
|
eax_bit: None,
|
||||||
|
ebx_bit: None,
|
||||||
|
ecx_bit: Some(TSC_DEADLINE_TIMER_ECX_BIT),
|
||||||
|
edx_bit: None,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Supported CPUID
|
// Supported CPUID
|
||||||
let mut cpuid = hypervisor
|
let mut cpuid = hypervisor
|
||||||
.get_supported_cpuid()
|
.get_supported_cpuid()
|
||||||
|
@ -7,11 +7,17 @@ version = "0.1.0"
|
|||||||
[features]
|
[features]
|
||||||
dbus_api = ["blocking", "futures", "zbus"]
|
dbus_api = ["blocking", "futures", "zbus"]
|
||||||
default = []
|
default = []
|
||||||
dhat-heap = ["dhat"] # For heap profiling
|
dhat-heap = ["dhat"] # For heap profiling
|
||||||
guest_debug = ["gdbstub", "gdbstub_arch", "kvm"]
|
guest_debug = ["gdbstub", "gdbstub_arch", "kvm"]
|
||||||
igvm = ["dep:igvm", "hex", "igvm_defs", "mshv-bindings", "range_map_vec"]
|
igvm = ["dep:igvm", "hex", "igvm_defs", "mshv-bindings", "range_map_vec"]
|
||||||
io_uring = ["block/io_uring"]
|
io_uring = ["block/io_uring"]
|
||||||
kvm = ["hypervisor/kvm", "pci/kvm", "vfio-ioctls/kvm", "vm-device/kvm"]
|
kvm = [
|
||||||
|
"arch/kvm",
|
||||||
|
"hypervisor/kvm",
|
||||||
|
"pci/kvm",
|
||||||
|
"vfio-ioctls/kvm",
|
||||||
|
"vm-device/kvm",
|
||||||
|
]
|
||||||
mshv = ["hypervisor/mshv", "pci/mshv", "vfio-ioctls/mshv", "vm-device/mshv"]
|
mshv = ["hypervisor/mshv", "pci/mshv", "vfio-ioctls/mshv", "vm-device/mshv"]
|
||||||
sev_snp = ["arch/sev_snp", "hypervisor/sev_snp", "virtio-devices/sev_snp"]
|
sev_snp = ["arch/sev_snp", "hypervisor/sev_snp", "virtio-devices/sev_snp"]
|
||||||
tdx = ["arch/tdx", "hypervisor/tdx"]
|
tdx = ["arch/tdx", "hypervisor/tdx"]
|
||||||
|
Loading…
Reference in New Issue
Block a user