summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>2013-10-05 23:11:01 +0000
committergibbs <gibbs@FreeBSD.org>2013-10-05 23:11:01 +0000
commit9c8c76f921175f7cebcd3cd61d9086c333b96e35 (patch)
treec4b59481817d15ea30e15e04f5ceb28ea7ae41a1 /sys
parentaed205d5cd3901acd2a0cf583e44ec166d99191a (diff)
downloadFreeBSD-src-9c8c76f921175f7cebcd3cd61d9086c333b96e35.zip
FreeBSD-src-9c8c76f921175f7cebcd3cd61d9086c333b96e35.tar.gz
Formalize the concept of virtual CPU ids by adding a per-cpu vcpu_id
field. Perform vcpu enumeration for Xen PV and HVM environments and convert all Xen drivers to use vcpu_id instead of a hard coded assumption of the mapping algorithm (acpi or apic ID) in use. Submitted by: Roger Pau Monné Sponsored by: Citrix Systems R&D Reviewed by: gibbs Approved by: re (blanket Xen) amd64/include/pcpu.h: i386/include/pcpu.h: Add vcpu_id to the amd64 and i386 pcpu structures. dev/xen/timer/timer.c x86/xen/xen_intr.c Use new vcpu_id instead of assuming acpi_id == vcpu_id. i386/xen/mp_machdep.c: i386/xen/mptable.c x86/xen/hvm.c: Perform Xen HVM and Xen full PV vcpu_id mapping. x86/xen/hvm.c: x86/acpica/madt.c Change SYSINIT ordering of acpi CPU enumeration so that it is guaranteed to be available at the time of Xen HVM vcpu id mapping.
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/pcpu.h3
-rw-r--r--sys/dev/xen/timer/timer.c4
-rw-r--r--sys/i386/include/pcpu.h7
-rw-r--r--sys/i386/xen/mp_machdep.c8
-rw-r--r--sys/i386/xen/mptable.c2
-rw-r--r--sys/x86/acpica/madt.c2
-rw-r--r--sys/x86/xen/hvm.c19
-rw-r--r--sys/x86/xen/xen_intr.c22
8 files changed, 40 insertions, 27 deletions
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index 3d51512..fe898e9 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -62,7 +62,8 @@
u_int pc_cmci_mask; /* MCx banks for CMCI */ \
uint64_t pc_dbreg[16]; /* ddb debugging regs */ \
int pc_dbreg_cmd; /* ddb debugging reg cmd */ \
- char __pad[161] /* be divisor of PAGE_SIZE \
+ u_int pc_vcpu_id; /* Xen vCPU ID */ \
+ char __pad[157] /* be divisor of PAGE_SIZE \
after cache alignment */
#define PC_DBREG_CMD_NONE 0
diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c
index 605e5c5..824c75b 100644
--- a/sys/dev/xen/timer/timer.c
+++ b/sys/dev/xen/timer/timer.c
@@ -396,7 +396,7 @@ xentimer_et_start(struct eventtimer *et,
{
int error = 0, i = 0;
struct xentimer_softc *sc = et->et_priv;
- int cpu = PCPU_GET(acpi_id);
+ int cpu = PCPU_GET(vcpu_id);
struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu);
uint64_t first_in_ns, next_time;
@@ -433,7 +433,7 @@ xentimer_et_start(struct eventtimer *et,
static int
xentimer_et_stop(struct eventtimer *et)
{
- int cpu = PCPU_GET(acpi_id);
+ int cpu = PCPU_GET(vcpu_id);
struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu);
pcpu->timer = 0;
diff --git a/sys/i386/include/pcpu.h b/sys/i386/include/pcpu.h
index 60e50f8..dc29b6d 100644
--- a/sys/i386/include/pcpu.h
+++ b/sys/i386/include/pcpu.h
@@ -62,13 +62,13 @@ struct shadow_time_info {
vm_paddr_t *pc_pdir_shadow; \
uint64_t pc_processed_system_time; \
struct shadow_time_info pc_shadow_time; \
- char __pad[189]
+ char __pad[185]
#else /* !XEN */
#define PCPU_XEN_FIELDS \
; \
- char __pad[237]
+ char __pad[233]
#endif
@@ -84,7 +84,8 @@ struct shadow_time_info {
u_int pc_acpi_id; /* ACPI CPU id */ \
u_int pc_apic_id; \
int pc_private_tss; /* Flag indicating private tss*/\
- u_int pc_cmci_mask /* MCx banks for CMCI */ \
+ u_int pc_cmci_mask; /* MCx banks for CMCI */ \
+ u_int pc_vcpu_id /* Xen vCPU ID */ \
PCPU_XEN_FIELDS
#ifdef _KERNEL
diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c
index ae5b5d4..c48fcb2 100644
--- a/sys/i386/xen/mp_machdep.c
+++ b/sys/i386/xen/mp_machdep.c
@@ -783,13 +783,7 @@ start_all_aps(void)
dpcpu_init((void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
M_WAITOK | M_ZERO), bootAP);
pc->pc_apic_id = cpu_apic_ids[bootAP];
- /*
- * The i386 PV port uses the apic_id as vCPU id, but the
- * PVHVM port needs to use the acpi_id, so set it for PV
- * also in order to work with shared devices between PV
- * and PVHVM.
- */
- pc->pc_acpi_id = cpu_apic_ids[bootAP];
+ pc->pc_vcpu_id = cpu_apic_ids[bootAP];
pc->pc_prvspace = pc;
pc->pc_curthread = 0;
diff --git a/sys/i386/xen/mptable.c b/sys/i386/xen/mptable.c
index 29d3b33..6682a8f 100644
--- a/sys/i386/xen/mptable.c
+++ b/sys/i386/xen/mptable.c
@@ -88,7 +88,7 @@ mptable_setup_local(void)
{
PCPU_SET(apic_id, 0);
- PCPU_SET(acpi_id, 0);
+ PCPU_SET(vcpu_id, 0);
return (0);
}
diff --git a/sys/x86/acpica/madt.c b/sys/x86/acpica/madt.c
index 66af032..85cf1da 100644
--- a/sys/x86/acpica/madt.c
+++ b/sys/x86/acpica/madt.c
@@ -575,4 +575,4 @@ madt_set_ids(void *dummy)
la->la_acpi_id);
}
}
-SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL);
+SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, madt_set_ids, NULL);
diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index 510b8b9..72811dc 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -744,6 +744,22 @@ xen_hvm_sysinit(void *arg __unused)
}
static void
+xen_set_vcpu_id(void)
+{
+ struct pcpu *pc;
+ int i;
+
+ /* Set vcpu_id to acpi_id */
+ CPU_FOREACH(i) {
+ pc = pcpu_find(i);
+ pc->pc_vcpu_id = pc->pc_acpi_id;
+ if (bootverbose)
+ printf("XEN: CPU %u has VCPU ID %u\n",
+ i, pc->pc_vcpu_id);
+ }
+}
+
+static void
xen_hvm_cpu_init(void)
{
struct vcpu_register_vcpu_info info;
@@ -763,7 +779,7 @@ xen_hvm_cpu_init(void)
}
vcpu_info = DPCPU_PTR(vcpu_local_info);
- cpu = PCPU_GET(acpi_id);
+ cpu = PCPU_GET(vcpu_id);
info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT;
info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info));
@@ -779,3 +795,4 @@ SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL);
SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_FIRST, xen_setup_cpus, NULL);
#endif
SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL);
+SYSINIT(xen_set_vcpu_id, SI_SUB_CPU, SI_ORDER_ANY, xen_set_vcpu_id, NULL);
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index b94f8d9..fd36e68 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -611,9 +611,9 @@ xen_rebind_ipi(struct xenisrc *isrc)
{
#ifdef SMP
int cpu = isrc->xi_cpu;
- int acpi_id = pcpu_find(cpu)->pc_acpi_id;
+ int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
int error;
- struct evtchn_bind_ipi bind_ipi = { .vcpu = acpi_id };
+ struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
&bind_ipi);
@@ -640,10 +640,10 @@ static void
xen_rebind_virq(struct xenisrc *isrc)
{
int cpu = isrc->xi_cpu;
- int acpi_id = pcpu_find(cpu)->pc_acpi_id;
+ int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
int error;
struct evtchn_bind_virq bind_virq = { .virq = isrc->xi_virq,
- .vcpu = acpi_id };
+ .vcpu = vcpu_id };
error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
&bind_virq);
@@ -796,7 +796,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
#ifdef SMP
struct evtchn_bind_vcpu bind_vcpu;
struct xenisrc *isrc;
- u_int to_cpu, acpi_id;
+ u_int to_cpu, vcpu_id;
int error;
#ifdef XENHVM
@@ -805,7 +805,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
#endif
to_cpu = apic_cpuid(apic_id);
- acpi_id = pcpu_find(to_cpu)->pc_acpi_id;
+ vcpu_id = pcpu_find(to_cpu)->pc_vcpu_id;
xen_intr_intrcnt_add(to_cpu);
mtx_lock(&xen_intr_isrc_lock);
@@ -830,7 +830,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
}
bind_vcpu.port = isrc->xi_port;
- bind_vcpu.vcpu = acpi_id;
+ bind_vcpu.vcpu = vcpu_id;
/*
* Allow interrupts to be fielded on the new VCPU before
@@ -1063,9 +1063,9 @@ xen_intr_bind_virq(device_t dev, u_int virq, u_int cpu,
driver_filter_t filter, driver_intr_t handler, void *arg,
enum intr_type flags, xen_intr_handle_t *port_handlep)
{
- int acpi_id = pcpu_find(cpu)->pc_acpi_id;
+ int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
struct xenisrc *isrc;
- struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = acpi_id };
+ struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = vcpu_id };
int error;
/* Ensure the target CPU is ready to handle evtchn interrupts. */
@@ -1126,9 +1126,9 @@ xen_intr_alloc_and_bind_ipi(device_t dev, u_int cpu,
xen_intr_handle_t *port_handlep)
{
#ifdef SMP
- int acpi_id = pcpu_find(cpu)->pc_acpi_id;
+ int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
struct xenisrc *isrc;
- struct evtchn_bind_ipi bind_ipi = { .vcpu = acpi_id };
+ struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
int error;
/* Ensure the target CPU is ready to handle evtchn interrupts. */
OpenPOWER on IntegriCloud