vmm: Expose Hypervisor CPUID bit

This is required at least for kvm-clock.

Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
This commit is contained in:
Chao Peng 2019-04-25 17:10:42 +00:00 committed by Samuel Ortiz
parent 0adc3481df
commit 2a539ab176

18
vmm/src/vm.rs Normal file → Executable file
View File

@ -40,6 +40,9 @@ const DEFAULT_CMDLINE: &str = "console=ttyS0 reboot=k panic=1 nomodules \
i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd"; i8042.noaux i8042.nomux i8042.nopnp i8042.dumbkbd";
const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000); const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000);
// CPUID feature bits
const ECX_HYPERVISOR_SHIFT: u32 = 31; // Hypervisor bit.
/// Errors associated with the wrappers over KVM ioctls. /// Errors associated with the wrappers over KVM ioctls.
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
@ -388,9 +391,10 @@ impl<'a> Vm<'a> {
fd.create_pit2(pit_config).map_err(Error::VmSetup)?; fd.create_pit2(pit_config).map_err(Error::VmSetup)?;
// Supported CPUID // Supported CPUID
let cpuid = kvm let mut cpuid = kvm
.get_supported_cpuid(MAX_KVM_CPUID_ENTRIES) .get_supported_cpuid(MAX_KVM_CPUID_ENTRIES)
.map_err(Error::VmSetup)?; .map_err(Error::VmSetup)?;
Vm::patch_cpuid(&mut cpuid);
let device_manager = DeviceManager::new().map_err(|_| Error::DeviceManager)?; let device_manager = DeviceManager::new().map_err(|_| Error::DeviceManager)?;
fd.register_irqfd(device_manager.serial_evt.as_raw_fd(), 4) fd.register_irqfd(device_manager.serial_evt.as_raw_fd(), 4)
@ -619,6 +623,18 @@ impl<'a> Vm<'a> {
pub fn get_fd(&self) -> &VmFd { pub fn get_fd(&self) -> &VmFd {
&self.fd &self.fd
} }
fn patch_cpuid(cpuid: &mut CpuId) {
let entries = cpuid.mut_entries_slice();
for entry in entries.iter_mut() {
if let 1 = entry.function {
if entry.index == 0 {
entry.ecx |= 1 << ECX_HYPERVISOR_SHIFT;
}
}
}
}
} }
#[allow(unused)] #[allow(unused)]