x86/MCE: sanitize domain/vcpu ID handling
authorJan Beulich <jbeulich@suse.com>
Wed, 8 Mar 2017 14:07:41 +0000 (15:07 +0100)
committerJan Beulich <jbeulich@suse.com>
Wed, 8 Mar 2017 14:07:41 +0000 (15:07 +0100)
Storing -1 into both fields was misleading consumers: We really should
have a manifest constant for "invalid vCPU" here, and the already
existing DOMID_INVALID should be used.

Also correct a bogus (dead code) check in mca_init_global(), at once
introducing a manifest constant for the early boot "invalid vCPU"
pointer (avoiding proliferation of the open coding). Make that pointer
a non-canonical address at once.

Finally, don't leave mc_domid uninitialized in mca_init_bank().

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/cpu/mcheck/mcaction.c
xen/arch/x86/cpu/mcheck/mce.c
xen/arch/x86/cpu/mcheck/vmce.c
xen/arch/x86/domain_page.c
xen/arch/x86/setup.c
xen/include/asm-x86/setup.h
xen/include/public/arch-x86/xen-mca.h

index 9cf2499b3bc16d5cd74fcc5b68949ff57daf4078..322163a3b24a1c36480650d5ad7abdda5dbf7191 100644 (file)
@@ -100,7 +100,8 @@ mc_memerr_dhandler(struct mca_binfo *binfo,
                     goto vmce_failed;
                 }
 
-                if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+                if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
+                    global->mc_vcpuid == XEN_MC_VCPUID_INVALID)
                     vmce_vcpuid = VMCE_INJECT_BROADCAST;
                 else
                     vmce_vcpuid = global->mc_vcpuid;
index bc5b79ec9345b9ed3711b2e3be47f7657bd5bfb2..191a35adc40c9447fc18153eb84be7285b3a7f9b 100644 (file)
@@ -18,6 +18,7 @@
 #include <xen/cpu.h>
 
 #include <asm/processor.h>
+#include <asm/setup.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/msr.h>
@@ -215,6 +216,7 @@ static void mca_init_bank(enum mca_source who,
     mib->common.type = MC_TYPE_BANK;
     mib->common.size = sizeof (struct mcinfo_bank);
     mib->mc_bank = bank;
+    mib->mc_domid = DOMID_INVALID;
 
     if (mib->mc_status & MCi_STATUS_MISCV)
         mib->mc_misc = mca_rdmsr(MSR_IA32_MCx_MISC(bank));
@@ -245,15 +247,15 @@ static int mca_init_global(uint32_t flags, struct mcinfo_global *mig)
 {
     uint64_t status;
     int cpu_nr;
-    struct vcpu *v = current;
-    struct domain *d;
+    const struct vcpu *curr = current;
 
     /* Set global information */
     mig->common.type = MC_TYPE_GLOBAL;
     mig->common.size = sizeof (struct mcinfo_global);
     status = mca_rdmsr(MSR_IA32_MCG_STATUS);
     mig->mc_gstatus = status;
-    mig->mc_domid = mig->mc_vcpuid = -1;
+    mig->mc_domid = DOMID_INVALID;
+    mig->mc_vcpuid = XEN_MC_VCPUID_INVALID;
     mig->mc_flags = flags;
     cpu_nr = smp_processor_id();
     /* Retrieve detector information */
@@ -261,13 +263,9 @@ static int mca_init_global(uint32_t flags, struct mcinfo_global *mig)
                         &mig->mc_coreid, &mig->mc_core_threadid,
                         &mig->mc_apicid, NULL, NULL, NULL);
 
-    /* This is really meaningless */
-    if (v != NULL && ((d = v->domain) != NULL)) {
-        mig->mc_domid = d->domain_id;
-        mig->mc_vcpuid = v->vcpu_id;
-    } else {
-        mig->mc_domid = -1;
-        mig->mc_vcpuid = -1;
+    if (curr != INVALID_VCPU) {
+        mig->mc_domid = curr->domain->domain_id;
+        mig->mc_vcpuid = curr->vcpu_id;
     }
 
     return 0;
index 8b727b4c77e75fb50881723bc57b57a3b622b0dd..7dde4571cc6031b47294b2fd122ac21d770224ee 100644 (file)
@@ -391,7 +391,7 @@ int fill_vmsr_data(struct mcinfo_bank *mc_bank, struct domain *d,
 {
     struct vcpu *v = d->vcpu[0];
 
-    if ( mc_bank->mc_domid != (uint16_t)~0 )
+    if ( mc_bank->mc_domid != DOMID_INVALID )
     {
         if ( v->arch.vmce.mcg_status & MCG_STATUS_MCIP )
         {
index a58ef8e2bac57475c56140b1bd7d7c50d2d8f8ce..71baedea96ec2d830abbeb39d3510c7bcad38a0f 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/current.h>
 #include <asm/flushtlb.h>
 #include <asm/hardirq.h>
+#include <asm/setup.h>
 
 static struct vcpu *__read_mostly override;
 
@@ -28,7 +29,7 @@ static inline struct vcpu *mapcache_current_vcpu(void)
      * When current isn't properly set up yet, this is equivalent to
      * running in an idle vCPU (callers must check for NULL).
      */
-    if ( v == (struct vcpu *)0xfffff000 )
+    if ( v == INVALID_VCPU )
         return NULL;
 
     /*
index dab67d54917d57cc0330d69d134fbea433a435f2..5bb387be8a63809f5cdad6fea3093ea2e43039b9 100644 (file)
@@ -657,7 +657,7 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     /* Critical region without IDT or TSS.  Any fault is deadly! */
 
     set_processor_id(0);
-    set_current((struct vcpu *)0xfffff000); /* debug sanity. */
+    set_current(INVALID_VCPU); /* debug sanity. */
     idle_vcpu[0] = current;
 
     percpu_init_areas();
index 47b9442faa33420f19ad997d317304dd84d247bb..c5b3d4ef18864c617d0332a0b01735f92baaf233 100644 (file)
@@ -4,6 +4,9 @@
 #include <xen/multiboot.h>
 #include <asm/numa.h>
 
+/* vCPU pointer used prior to there being a valid one around */
+#define INVALID_VCPU ((struct vcpu *)0xccccccccccccc000UL)
+
 extern const char __2M_text_start[], __2M_text_end[];
 extern const char __2M_rodata_start[], __2M_rodata_end[];
 extern char __2M_init_start[], __2M_init_end[];
index 1868371640c3b50253a5ce6708f9a4e4323ccf38..7db990723b279b7c4d235528b25d44b8ed03a4b9 100644 (file)
@@ -88,6 +88,8 @@
 #define XEN_MC_NOTDELIVERED 0x10
 /* Note, XEN_MC_CANNOTHANDLE and XEN_MC_NOTDELIVERED are mutually exclusive. */
 
+/* Applicable to all mc_vcpuid fields below. */
+#define XEN_MC_VCPUID_INVALID 0xffff
 
 #ifndef __ASSEMBLY__