@@ -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;
@@ -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++;
}
@@ -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);
}
@@ -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