KVM: x86: Software disabled APIC should still deliver NMIs
[deliverable/linux.git] / arch / x86 / kvm / lapic.c
index e7f7fc632a9b55da58fbe204f9578c0fdaebf5f5..c98b44d0ffe6aebe8e603806a415f96f30f58917 100644 (file)
@@ -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;
 
@@ -1457,6 +1464,10 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
        apic->base_address = apic->vcpu->arch.apic_base &
                             MSR_IA32_APICBASE_BASE;
 
+       if ((value & MSR_IA32_APICBASE_ENABLE) &&
+            apic->base_address != APIC_DEFAULT_PHYS_BASE)
+               pr_warn_once("APIC base relocation is unsupported by KVM");
+
        /* with FSB delivery interrupt, we can restart APIC functionality */
        apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is "
                   "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address);
This page took 0.026488 seconds and 5 git commands to generate.