summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorNadav Amit2014-11-02 10:54:54 +0100
committerPaolo Bonzini2014-11-17 12:16:19 +0100
commit173beedc1601f51dae9d579aa7a414c5aa8f700b (patch)
treec5c58dc63c355445fd84ba8628fe986099ffd709 /arch/x86
parentkvm: simplify update_memslots invocation (diff)
downloadkernel-qcow2-linux-173beedc1601f51dae9d579aa7a414c5aa8f700b.tar.gz
kernel-qcow2-linux-173beedc1601f51dae9d579aa7a414c5aa8f700b.tar.xz
kernel-qcow2-linux-173beedc1601f51dae9d579aa7a414c5aa8f700b.zip
KVM: x86: Software disabled APIC should still deliver NMIs
Currently, the APIC logical map does not consider VCPUs whose local-apic is software-disabled. However, NMIs, INIT, etc. should still be delivered to such VCPUs. Therefore, the APIC mode should first be determined, and then the map, considering all VCPUs should be constructed. To address this issue, first find the APIC mode, and only then construct the logical map. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kvm/lapic.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 344e7d36d0e8..c98b44d0ffe6 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -156,8 +156,6 @@ static void recalculate_apic_map(struct kvm *kvm)
kvm_for_each_vcpu(i, vcpu, kvm) {
struct kvm_lapic *apic = vcpu->arch.apic;
- u16 cid, lid;
- u32 ldr;
if (!kvm_apic_present(vcpu))
continue;
@@ -175,13 +173,22 @@ static void recalculate_apic_map(struct kvm *kvm)
new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1;
new->lid_mask = 0xffff;
new->broadcast = X2APIC_BROADCAST;
- } else if (kvm_apic_sw_enabled(apic) &&
- !new->cid_mask /* flat mode */ &&
- kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) {
- new->cid_shift = 4;
- new->cid_mask = 0xf;
- new->lid_mask = 0xf;
+ break;
+ } else if (kvm_apic_sw_enabled(apic)) {
+ if (kvm_apic_get_reg(apic, APIC_DFR) ==
+ APIC_DFR_CLUSTER) {
+ new->cid_shift = 4;
+ new->cid_mask = 0xf;
+ new->lid_mask = 0xf;
+ }
+ break;
}
+ }
+
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ struct kvm_lapic *apic = vcpu->arch.apic;
+ u16 cid, lid;
+ u32 ldr;
new->phys_map[kvm_apic_id(apic)] = apic;