aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNadav Amit <namit@cs.technion.ac.il>2014-11-02 04:54:54 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2014-11-17 06:16:19 -0500
commit173beedc1601f51dae9d579aa7a414c5aa8f700b (patch)
treec5c58dc63c355445fd84ba8628fe986099ffd709
parent5cc150279936a618187c42966a8a2f09177ac80a (diff)
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>
-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)
156 156
157 kvm_for_each_vcpu(i, vcpu, kvm) { 157 kvm_for_each_vcpu(i, vcpu, kvm) {
158 struct kvm_lapic *apic = vcpu->arch.apic; 158 struct kvm_lapic *apic = vcpu->arch.apic;
159 u16 cid, lid;
160 u32 ldr;
161 159
162 if (!kvm_apic_present(vcpu)) 160 if (!kvm_apic_present(vcpu))
163 continue; 161 continue;
@@ -175,13 +173,22 @@ static void recalculate_apic_map(struct kvm *kvm)
175 new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; 173 new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1;
176 new->lid_mask = 0xffff; 174 new->lid_mask = 0xffff;
177 new->broadcast = X2APIC_BROADCAST; 175 new->broadcast = X2APIC_BROADCAST;
178 } else if (kvm_apic_sw_enabled(apic) && 176 break;
179 !new->cid_mask /* flat mode */ && 177 } else if (kvm_apic_sw_enabled(apic)) {
180 kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { 178 if (kvm_apic_get_reg(apic, APIC_DFR) ==
181 new->cid_shift = 4; 179 APIC_DFR_CLUSTER) {
182 new->cid_mask = 0xf; 180 new->cid_shift = 4;
183 new->lid_mask = 0xf; 181 new->cid_mask = 0xf;
182 new->lid_mask = 0xf;
183 }
184 break;
184 } 185 }
186 }
187
188 kvm_for_each_vcpu(i, vcpu, kvm) {
189 struct kvm_lapic *apic = vcpu->arch.apic;
190 u16 cid, lid;
191 u32 ldr;
185 192
186 new->phys_map[kvm_apic_id(apic)] = apic; 193 new->phys_map[kvm_apic_id(apic)] = apic;
187 194