mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-30 16:35:31 +00:00
vmm: Set the APIC ID in the extended topology
KVM exposes CPUID 0BH when host supports that, but the APIC ID that KVM provides is the host APIC ID so we need replace that with ours. Without this Linux guest reports something like: [Firmware Bug]: CPU1: APIC id mismatch. Firmware: 1 APIC: 21 Fixes #42 Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
This commit is contained in:
parent
0d0d19e223
commit
a0f4376eb0
@ -202,6 +202,13 @@ mod tests {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn get_initial_apicid() -> u32 {
|
||||
ssh_command("grep \"initial apicid\" /proc/cpuinfo | grep -o \"[0-9]*\"")
|
||||
.trim()
|
||||
.parse()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn get_total_memory() -> u32 {
|
||||
ssh_command("grep MemTotal /proc/meminfo | grep -o \"[0-9]*\"")
|
||||
.trim()
|
||||
@ -232,6 +239,7 @@ mod tests {
|
||||
thread::sleep(std::time::Duration::new(10, 0));
|
||||
|
||||
aver_eq!(tb, get_cpu_count(), 1);
|
||||
aver_eq!(tb, get_initial_apicid(), 0);
|
||||
aver!(tb, get_total_memory() > 496_000);
|
||||
aver!(tb, get_entropy() >= 1000);
|
||||
|
||||
|
@ -193,6 +193,15 @@ pub enum DeviceManagerError {
|
||||
}
|
||||
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Copy, Clone)]
|
||||
enum CpuidReg {
|
||||
EAX,
|
||||
EBX,
|
||||
ECX,
|
||||
EDX,
|
||||
}
|
||||
|
||||
/// A wrapper around creating and using a kvm-based VCPU.
|
||||
pub struct Vcpu {
|
||||
fd: VcpuFd,
|
||||
@ -227,8 +236,10 @@ impl Vcpu {
|
||||
/// * `kernel_start_addr` - Offset from `guest_mem` at which the kernel starts.
|
||||
/// * `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));
|
||||
self.fd
|
||||
.set_cpuid2(&vm.cpuid)
|
||||
.set_cpuid2(&cpuid)
|
||||
.map_err(Error::SetSupportedCpusFailed)?;
|
||||
|
||||
arch::x86_64::regs::setup_msrs(&self.fd).map_err(Error::MSRSConfiguration)?;
|
||||
@ -285,6 +296,35 @@ impl Vcpu {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cpuid_reg(
|
||||
cpuid: &mut CpuId,
|
||||
function: u32,
|
||||
index: Option<u32>,
|
||||
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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user