From 0f5442984803543c51ca5e62f41d2f27038e0c32 Mon Sep 17 00:00:00 2001 From: Chao Peng Date: Wed, 12 Jun 2019 13:42:31 +0000 Subject: [PATCH] vmm: Move all the CPUID related code to CpuidPatch As more CPUID handling and CpuidPatch common code being added, it's reasonable to move all the common code to the same place and in the future we may consider move it to individual file when neccesary. Signed-off-by: Chao Peng --- vmm/src/vm.rs | 136 +++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 67 deletions(-) diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index b8c78e197..d14b8dbed 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -202,6 +202,73 @@ enum CpuidReg { EDX, } +struct CpuidPatch { + function: u32, + index: u32, + flags_bit: Option, + eax_bit: Option, + ebx_bit: Option, + ecx_bit: Option, + edx_bit: Option, +} + +impl CpuidPatch { + fn set_cpuid_reg( + cpuid: &mut CpuId, + function: u32, + index: Option, + reg: CpuidReg, + value: u32, + ) { + let entries = cpuid.mut_entries_slice(); + + for entry in entries.iter_mut() { + if entry.function == function && (index == None || index.unwrap() == entry.index) { + match reg { + CpuidReg::EAX => { + entry.eax = value; + } + CpuidReg::EBX => { + entry.ebx = value; + } + CpuidReg::ECX => { + entry.ecx = value; + } + CpuidReg::EDX => { + entry.edx = value; + } + } + } + } + } + + fn patch_cpuid(cpuid: &mut CpuId, patches: Vec) { + let entries = cpuid.mut_entries_slice(); + + for entry in entries.iter_mut() { + for patch in patches.iter() { + if entry.function == patch.function && entry.index == patch.index { + if let Some(flags_bit) = patch.flags_bit { + entry.flags |= 1 << flags_bit; + } + if let Some(eax_bit) = patch.eax_bit { + entry.eax |= 1 << eax_bit; + } + if let Some(ebx_bit) = patch.ebx_bit { + entry.ebx |= 1 << ebx_bit; + } + if let Some(ecx_bit) = patch.ecx_bit { + entry.ecx |= 1 << ecx_bit; + } + if let Some(edx_bit) = patch.edx_bit { + entry.edx |= 1 << edx_bit; + } + } + } + } + } +} + /// A wrapper around creating and using a kvm-based VCPU. pub struct Vcpu { fd: VcpuFd, @@ -237,7 +304,7 @@ impl Vcpu { /// * `vm` - The virtual machine this vcpu will get attached to. pub fn configure(&mut self, kernel_start_addr: GuestAddress, vm: &Vm) -> Result<()> { let mut cpuid = vm.cpuid.clone(); - Vcpu::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(self.id)); + CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(self.id)); self.fd .set_cpuid2(&cpuid) .map_err(Error::SetSupportedCpusFailed)?; @@ -296,35 +363,6 @@ impl Vcpu { }, } } - - fn set_cpuid_reg( - cpuid: &mut CpuId, - function: u32, - index: Option, - reg: CpuidReg, - value: u32, - ) { - let entries = cpuid.mut_entries_slice(); - - for entry in entries.iter_mut() { - if entry.function == function && (index == None || index.unwrap() == entry.index) { - match reg { - CpuidReg::EAX => { - entry.eax = value; - } - CpuidReg::EBX => { - entry.ebx = value; - } - CpuidReg::ECX => { - entry.ecx = value; - } - CpuidReg::EDX => { - entry.edx = value; - } - } - } - } - } } struct DeviceManager { @@ -624,16 +662,6 @@ impl AsRawFd for EpollContext { } } -struct CpuidPatch { - function: u32, - index: u32, - flags_bit: Option, - eax_bit: Option, - ebx_bit: Option, - ecx_bit: Option, - edx_bit: Option, -} - pub struct Vm<'a> { fd: Arc, kernel: File, @@ -715,7 +743,7 @@ impl<'a> Vm<'a> { edx_bit: None, }); - Vm::patch_cpuid(&mut cpuid, cpuid_patches); + CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); // Let's allocate 64 GiB of addressable MMIO space, starting at 0. let mut allocator = SystemAllocator::new( @@ -914,32 +942,6 @@ impl<'a> Vm<'a> { pub fn get_memory(&self) -> &GuestMemoryMmap { &self.memory } - - fn patch_cpuid(cpuid: &mut CpuId, patches: Vec) { - let entries = cpuid.mut_entries_slice(); - - for entry in entries.iter_mut() { - for patch in patches.iter() { - if entry.function == patch.function && entry.index == patch.index { - if let Some(flags_bit) = patch.flags_bit { - entry.flags |= 1 << flags_bit; - } - if let Some(eax_bit) = patch.eax_bit { - entry.eax |= 1 << eax_bit; - } - if let Some(ebx_bit) = patch.ebx_bit { - entry.ebx |= 1 << ebx_bit; - } - if let Some(ecx_bit) = patch.ecx_bit { - entry.ecx |= 1 << ecx_bit; - } - if let Some(edx_bit) = patch.edx_bit { - entry.edx |= 1 << edx_bit; - } - } - } - } - } } #[allow(unused)]