diff options
author | Jim Mattson <jmattson@google.com> | 2016-11-09 12:50:11 -0500 |
---|---|---|
committer | Radim Krčmář <rkrcmar@redhat.com> | 2016-11-22 08:51:55 -0500 |
commit | c7dd15b33707e99c2b66da44a2a280638b4cd14f (patch) | |
tree | d6cc45d3e106def8da15697955e3a5cd98ccfc83 | |
parent | 4504b5c9414c55da37f26b1faf49c09a2acbf255 (diff) |
kvm: x86: CPUID.01H:EDX.APIC[bit 9] should mirror IA32_APIC_BASE[11]
From the Intel SDM, volume 3, section 10.4.3, "Enabling or Disabling the
Local APIC,"
When IA32_APIC_BASE[11] is 0, the processor is functionally equivalent
to an IA-32 processor without an on-chip APIC. The CPUID feature flag
for the APIC (see Section 10.4.2, "Presence of the Local APIC") is
also set to 0.
Signed-off-by: Jim Mattson <jmattson@google.com>
[Changed subject tag from nVMX to x86.]
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
-rw-r--r-- | arch/x86/kvm/cpuid.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 11 |
2 files changed, 11 insertions, 4 deletions
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index a982fd80bceb..25f0f15fab1a 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
@@ -87,6 +87,10 @@ int kvm_update_cpuid(struct kvm_vcpu *vcpu) | |||
87 | best->ecx |= F(OSXSAVE); | 87 | best->ecx |= F(OSXSAVE); |
88 | } | 88 | } |
89 | 89 | ||
90 | best->edx &= ~F(APIC); | ||
91 | if (vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE) | ||
92 | best->edx |= F(APIC); | ||
93 | |||
90 | if (apic) { | 94 | if (apic) { |
91 | if (best->ecx & F(TSC_DEADLINE_TIMER)) | 95 | if (best->ecx & F(TSC_DEADLINE_TIMER)) |
92 | apic->lapic_timer.timer_mode_mask = 3 << 17; | 96 | apic->lapic_timer.timer_mode_mask = 3 << 17; |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 890f218ddd7a..09edd32b8e42 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1806,14 +1806,17 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
1806 | u64 old_value = vcpu->arch.apic_base; | 1806 | u64 old_value = vcpu->arch.apic_base; |
1807 | struct kvm_lapic *apic = vcpu->arch.apic; | 1807 | struct kvm_lapic *apic = vcpu->arch.apic; |
1808 | 1808 | ||
1809 | if (!apic) { | 1809 | if (!apic) |
1810 | value |= MSR_IA32_APICBASE_BSP; | 1810 | value |= MSR_IA32_APICBASE_BSP; |
1811 | vcpu->arch.apic_base = value; | ||
1812 | return; | ||
1813 | } | ||
1814 | 1811 | ||
1815 | vcpu->arch.apic_base = value; | 1812 | vcpu->arch.apic_base = value; |
1816 | 1813 | ||
1814 | if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) | ||
1815 | kvm_update_cpuid(vcpu); | ||
1816 | |||
1817 | if (!apic) | ||
1818 | return; | ||
1819 | |||
1817 | /* update jump label if enable bit changes */ | 1820 | /* update jump label if enable bit changes */ |
1818 | if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) { | 1821 | if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) { |
1819 | if (value & MSR_IA32_APICBASE_ENABLE) { | 1822 | if (value & MSR_IA32_APICBASE_ENABLE) { |