mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
x86: Support vCPU CPUID keep same topology as pCPU
At present the Guest use the cpu id (enum number) as the APIC ID in vCPU CPUID and set the different topology with pCPU. To support the feature vCPU has the same topology as pCPU, vCPU need the same APIC ID as pCPU. So let vCPU can use the APIC ID from pCPU in vCPU's CPUID and keep pCPU's topology related information (include CPU count and topology mask) unchanged. Now this change is a preliminary preparation and doesn't work. Additional feature options and corresponding CPU number and CPU affinity settings are still required. BUG=b:197875305 TEST=cargo build TEST=./test_all Change-Id: I04150ac6c35534d0ff56667b01f448da2ca9f9fc Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3217034 Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: David Stevens <stevensd@chromium.org>
This commit is contained in:
parent
535271094f
commit
4e9b1444a4
3 changed files with 30 additions and 4 deletions
|
@ -42,6 +42,7 @@ fn filter_cpuid(
|
|||
cpuid: &mut hypervisor::CpuId,
|
||||
irq_chip: &dyn IrqChipX86_64,
|
||||
no_smt: bool,
|
||||
host_cpu_topology: bool,
|
||||
) {
|
||||
let entries = &mut cpuid.cpu_id_entries;
|
||||
|
||||
|
@ -60,6 +61,12 @@ fn filter_cpuid(
|
|||
if irq_chip.check_capability(IrqChipCap::TscDeadlineTimer) {
|
||||
entry.ecx |= 1 << ECX_TSC_DEADLINE_TIMER_SHIFT;
|
||||
}
|
||||
|
||||
if host_cpu_topology {
|
||||
entry.ebx |= EBX_CLFLUSH_CACHELINE << EBX_CLFLUSH_SIZE_SHIFT;
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.ebx = (vcpu_id << EBX_CPUID_SHIFT) as u32
|
||||
| (EBX_CLFLUSH_CACHELINE << EBX_CLFLUSH_SIZE_SHIFT);
|
||||
if cpu_count > 1 {
|
||||
|
@ -82,6 +89,11 @@ fn filter_cpuid(
|
|||
entry.ecx = result.ecx;
|
||||
entry.edx = result.edx;
|
||||
}
|
||||
|
||||
if host_cpu_topology {
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.eax &= !0xFC000000;
|
||||
if cpu_count > 1 {
|
||||
let cpu_cores = if no_smt {
|
||||
|
@ -99,6 +111,9 @@ fn filter_cpuid(
|
|||
entry.ecx &= !(1 << ECX_EPB_SHIFT);
|
||||
}
|
||||
0xB | 0x1F => {
|
||||
if host_cpu_topology {
|
||||
continue;
|
||||
}
|
||||
// Extended topology enumeration / V2 Extended topology enumeration
|
||||
// NOTE: these will need to be split if any of the fields that differ between
|
||||
// the two versions are to be set.
|
||||
|
@ -145,6 +160,9 @@ fn filter_cpuid(
|
|||
/// * `vcpu` - `VcpuX86_64` for setting CPU ID.
|
||||
/// * `vcpu_id` - The vcpu index of `vcpu`.
|
||||
/// * `nrcpus` - The number of vcpus being used by this VM.
|
||||
/// * `no_smt` - The flag indicates whether vCPUs supports SMT.
|
||||
/// * `host_cpu_topology` - The flag indicates whether vCPUs use mirror CPU topology. Now
|
||||
/// `--host-cpu-topology` hasn't been supported, and just set it as false.
|
||||
pub fn setup_cpuid(
|
||||
hypervisor: &dyn HypervisorX86_64,
|
||||
irq_chip: &dyn IrqChipX86_64,
|
||||
|
@ -152,12 +170,20 @@ pub fn setup_cpuid(
|
|||
vcpu_id: usize,
|
||||
nrcpus: usize,
|
||||
no_smt: bool,
|
||||
host_cpu_topology: bool,
|
||||
) -> Result<()> {
|
||||
let mut cpuid = hypervisor
|
||||
.get_supported_cpuid()
|
||||
.map_err(Error::GetSupportedCpusFailed)?;
|
||||
|
||||
filter_cpuid(vcpu_id, nrcpus, &mut cpuid, irq_chip, no_smt);
|
||||
filter_cpuid(
|
||||
vcpu_id,
|
||||
nrcpus,
|
||||
&mut cpuid,
|
||||
irq_chip,
|
||||
no_smt,
|
||||
host_cpu_topology,
|
||||
);
|
||||
|
||||
vcpu.set_cpuid(&cpuid)
|
||||
.map_err(Error::SetSupportedCpusFailed)
|
||||
|
@ -201,7 +227,7 @@ mod tests {
|
|||
edx: 0,
|
||||
..Default::default()
|
||||
});
|
||||
filter_cpuid(1, 2, &mut cpuid, &irq_chip, false);
|
||||
filter_cpuid(1, 2, &mut cpuid, &irq_chip, false, false);
|
||||
|
||||
let entries = &mut cpuid.cpu_id_entries;
|
||||
assert_eq!(entries[0].function, 0);
|
||||
|
|
|
@ -574,7 +574,7 @@ impl arch::LinuxArch for X8664arch {
|
|||
has_bios: bool,
|
||||
no_smt: bool,
|
||||
) -> Result<()> {
|
||||
cpuid::setup_cpuid(hypervisor, irq_chip, vcpu, vcpu_id, num_cpus, no_smt)
|
||||
cpuid::setup_cpuid(hypervisor, irq_chip, vcpu, vcpu_id, num_cpus, no_smt, false)
|
||||
.map_err(Error::SetupCpuid)?;
|
||||
|
||||
if has_bios {
|
||||
|
|
|
@ -236,7 +236,7 @@ where
|
|||
.add_vcpu(0, &vcpu)
|
||||
.expect("failed to add vcpu to irqchip");
|
||||
|
||||
setup_cpuid(&hyp, &irq_chip, &vcpu, 0, 1, false).unwrap();
|
||||
setup_cpuid(&hyp, &irq_chip, &vcpu, 0, 1, false, false).unwrap();
|
||||
setup_msrs(&vcpu, END_ADDR_BEFORE_32BITS).unwrap();
|
||||
|
||||
setup_regs(
|
||||
|
|
Loading…
Reference in a new issue