In order to test external interrupts using a destination ID > 255.
Also start vCPUs with the APIC in x2APIC mode.
---
 xen/arch/x86/cpuid.c                  | 12 +++++++++++-
 xen/arch/x86/hvm/dom0_build.c         |  3 ++-
 xen/arch/x86/hvm/vlapic.c             | 14 ++++++++++++--
 xen/arch/x86/include/asm/hvm/vlapic.h |  2 ++
 4 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 0407a54626..01dcd474e8 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -8,6 +8,7 @@
 #include <asm/hvm/nestedhvm.h>
 #include <asm/hvm/svm/svm.h>
 #include <asm/hvm/viridian.h>
+#include <asm/hvm/vlapic.h>
 #include <asm/hvm/vmx/vmcs.h>
 #include <asm/paging.h>
 #include <asm/processor.h>
@@ -876,7 +877,14 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
         /* TODO: Rework topology logic. */
         res->b &= 0x00ffffffu;
         if ( is_hvm_domain(d) )
-            res->b |= (v->vcpu_id * 2) << 24;
+        {
+            unsigned int id = v->vcpu_id * 2;
+
+            if ( id )
+                id += opt_x2apic_id_offset;
+
+            res->b |= id << 24;
+        }
 
         /* TODO: Rework vPMU control in terms of toolstack choices. */
         if ( vpmu_available(v) &&
@@ -1058,6 +1066,8 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
 
             /* Fix the x2APIC identifier. */
             res->d = v->vcpu_id * 2;
+            if ( res->d )
+                res->d += opt_x2apic_id_offset;
         }
         break;
 
diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index 43e1bf1248..b00e45885c 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -30,6 +30,7 @@
 #include <asm/bzimage.h>
 #include <asm/dom0_build.h>
 #include <asm/hvm/support.h>
+#include <asm/hvm/vlapic.h>
 #include <asm/io_apic.h>
 #include <asm/p2m.h>
 #include <asm/paging.h>
@@ -845,7 +846,7 @@ static int __init pvh_setup_acpi_madt(struct domain *d, 
paddr_t *addr)
         x2apic->header.type = ACPI_MADT_TYPE_LOCAL_X2APIC;
         x2apic->header.length = sizeof(*x2apic);
         x2apic->uid = i;
-        x2apic->local_apic_id = i * 2;
+        x2apic->local_apic_id = i * 2 + (i ? opt_x2apic_id_offset : 0);
         x2apic->lapic_flags = ACPI_MADT_ENABLED;
         x2apic++;
     }
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index b8c84458ff..34209d5378 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -24,6 +24,7 @@
 #include <xen/domain_page.h>
 #include <xen/event.h>
 #include <xen/nospec.h>
+#include <xen/param.h>
 #include <xen/trace.h>
 #include <xen/lib.h>
 #include <xen/sched.h>
@@ -53,6 +54,9 @@
     (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY |\
     APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
 
+unsigned int opt_x2apic_id_offset;
+integer_param("x2apic_id_offset", opt_x2apic_id_offset);
+
 static const unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
 {
      /* LVTT */
@@ -1073,7 +1077,7 @@ static void set_x2apic_id(struct vlapic *vlapic)
     u32 id = vlapic_vcpu(vlapic)->vcpu_id;
     u32 ldr = ((id & ~0xf) << 12) | (1 << (id & 0xf));
 
-    vlapic_set_reg(vlapic, APIC_ID, id * 2);
+    vlapic_set_reg(vlapic, APIC_ID, id * 2 + (id ? opt_x2apic_id_offset : 0));
     vlapic_set_reg(vlapic, APIC_LDR, ldr);
 }
 
@@ -1443,7 +1447,13 @@ void vlapic_reset(struct vlapic *vlapic)
     if ( v->vcpu_id == 0 )
         vlapic->hw.apic_base_msr |= APIC_BASE_BSP;
 
-    vlapic_set_reg(vlapic, APIC_ID, (v->vcpu_id * 2) << 24);
+    /* start in x2APIC mode. */
+    vlapic->hw.apic_base_msr |= APIC_BASE_EXTD;
+    set_x2apic_id(vlapic);
+#if 0
+    vlapic_set_reg(vlapic, APIC_ID, id << 24);
+#endif
+
     vlapic_do_init(vlapic);
 }
 
diff --git a/xen/arch/x86/include/asm/hvm/vlapic.h 
b/xen/arch/x86/include/asm/hvm/vlapic.h
index 8f908928c3..6e837cb5bf 100644
--- a/xen/arch/x86/include/asm/hvm/vlapic.h
+++ b/xen/arch/x86/include/asm/hvm/vlapic.h
@@ -91,6 +91,8 @@ struct vlapic {
     } init_sipi;
 };
 
+extern unsigned int opt_x2apic_id_offset;
+
 /* vlapic's frequence is 100 MHz */
 #define APIC_BUS_CYCLE_NS               10
 
-- 
2.34.1


Reply via email to