Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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.
  • Loading branch information...
commit 9c8c76f921175f7cebcd3cd61d9086c333b96e35 1 parent aed205d
gibbs authored
3  sys/amd64/include/pcpu.h
@@ -62,7 +62,8 @@
62 62 u_int pc_cmci_mask; /* MCx banks for CMCI */ \
63 63 uint64_t pc_dbreg[16]; /* ddb debugging regs */ \
64 64 int pc_dbreg_cmd; /* ddb debugging reg cmd */ \
65   - char __pad[161] /* be divisor of PAGE_SIZE \
  65 + u_int pc_vcpu_id; /* Xen vCPU ID */ \
  66 + char __pad[157] /* be divisor of PAGE_SIZE \
66 67 after cache alignment */
67 68
68 69 #define PC_DBREG_CMD_NONE 0
4 sys/dev/xen/timer/timer.c
@@ -396,7 +396,7 @@ xentimer_et_start(struct eventtimer *et,
396 396 {
397 397 int error = 0, i = 0;
398 398 struct xentimer_softc *sc = et->et_priv;
399   - int cpu = PCPU_GET(acpi_id);
  399 + int cpu = PCPU_GET(vcpu_id);
400 400 struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu);
401 401 uint64_t first_in_ns, next_time;
402 402
@@ -433,7 +433,7 @@ xentimer_et_start(struct eventtimer *et,
433 433 static int
434 434 xentimer_et_stop(struct eventtimer *et)
435 435 {
436   - int cpu = PCPU_GET(acpi_id);
  436 + int cpu = PCPU_GET(vcpu_id);
437 437 struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu);
438 438
439 439 pcpu->timer = 0;
7 sys/i386/include/pcpu.h
@@ -62,13 +62,13 @@ struct shadow_time_info {
62 62 vm_paddr_t *pc_pdir_shadow; \
63 63 uint64_t pc_processed_system_time; \
64 64 struct shadow_time_info pc_shadow_time; \
65   - char __pad[189]
  65 + char __pad[185]
66 66
67 67 #else /* !XEN */
68 68
69 69 #define PCPU_XEN_FIELDS \
70 70 ; \
71   - char __pad[237]
  71 + char __pad[233]
72 72
73 73 #endif
74 74
@@ -84,7 +84,8 @@ struct shadow_time_info {
84 84 u_int pc_acpi_id; /* ACPI CPU id */ \
85 85 u_int pc_apic_id; \
86 86 int pc_private_tss; /* Flag indicating private tss*/\
87   - u_int pc_cmci_mask /* MCx banks for CMCI */ \
  87 + u_int pc_cmci_mask; /* MCx banks for CMCI */ \
  88 + u_int pc_vcpu_id /* Xen vCPU ID */ \
88 89 PCPU_XEN_FIELDS
89 90
90 91 #ifdef _KERNEL
8 sys/i386/xen/mp_machdep.c
@@ -783,13 +783,7 @@ start_all_aps(void)
783 783 dpcpu_init((void *)kmem_malloc(kernel_arena, DPCPU_SIZE,
784 784 M_WAITOK | M_ZERO), bootAP);
785 785 pc->pc_apic_id = cpu_apic_ids[bootAP];
786   - /*
787   - * The i386 PV port uses the apic_id as vCPU id, but the
788   - * PVHVM port needs to use the acpi_id, so set it for PV
789   - * also in order to work with shared devices between PV
790   - * and PVHVM.
791   - */
792   - pc->pc_acpi_id = cpu_apic_ids[bootAP];
  786 + pc->pc_vcpu_id = cpu_apic_ids[bootAP];
793 787 pc->pc_prvspace = pc;
794 788 pc->pc_curthread = 0;
795 789
2  sys/i386/xen/mptable.c
@@ -88,7 +88,7 @@ mptable_setup_local(void)
88 88 {
89 89
90 90 PCPU_SET(apic_id, 0);
91   - PCPU_SET(acpi_id, 0);
  91 + PCPU_SET(vcpu_id, 0);
92 92 return (0);
93 93 }
94 94
2  sys/x86/acpica/madt.c
@@ -575,4 +575,4 @@ madt_set_ids(void *dummy)
575 575 la->la_acpi_id);
576 576 }
577 577 }
578   -SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_ANY, madt_set_ids, NULL);
  578 +SYSINIT(madt_set_ids, SI_SUB_CPU, SI_ORDER_MIDDLE, madt_set_ids, NULL);
19 sys/x86/xen/hvm.c
@@ -744,6 +744,22 @@ xen_hvm_sysinit(void *arg __unused)
744 744 }
745 745
746 746 static void
  747 +xen_set_vcpu_id(void)
  748 +{
  749 + struct pcpu *pc;
  750 + int i;
  751 +
  752 + /* Set vcpu_id to acpi_id */
  753 + CPU_FOREACH(i) {
  754 + pc = pcpu_find(i);
  755 + pc->pc_vcpu_id = pc->pc_acpi_id;
  756 + if (bootverbose)
  757 + printf("XEN: CPU %u has VCPU ID %u\n",
  758 + i, pc->pc_vcpu_id);
  759 + }
  760 +}
  761 +
  762 +static void
747 763 xen_hvm_cpu_init(void)
748 764 {
749 765 struct vcpu_register_vcpu_info info;
@@ -763,7 +779,7 @@ xen_hvm_cpu_init(void)
763 779 }
764 780
765 781 vcpu_info = DPCPU_PTR(vcpu_local_info);
766   - cpu = PCPU_GET(acpi_id);
  782 + cpu = PCPU_GET(vcpu_id);
767 783 info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT;
768 784 info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info));
769 785
@@ -779,3 +795,4 @@ SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL);
779 795 SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_FIRST, xen_setup_cpus, NULL);
780 796 #endif
781 797 SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL);
  798 +SYSINIT(xen_set_vcpu_id, SI_SUB_CPU, SI_ORDER_ANY, xen_set_vcpu_id, NULL);
22 sys/x86/xen/xen_intr.c
@@ -611,9 +611,9 @@ xen_rebind_ipi(struct xenisrc *isrc)
611 611 {
612 612 #ifdef SMP
613 613 int cpu = isrc->xi_cpu;
614   - int acpi_id = pcpu_find(cpu)->pc_acpi_id;
  614 + int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
615 615 int error;
616   - struct evtchn_bind_ipi bind_ipi = { .vcpu = acpi_id };
  616 + struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
617 617
618 618 error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi,
619 619 &bind_ipi);
@@ -640,10 +640,10 @@ static void
640 640 xen_rebind_virq(struct xenisrc *isrc)
641 641 {
642 642 int cpu = isrc->xi_cpu;
643   - int acpi_id = pcpu_find(cpu)->pc_acpi_id;
  643 + int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
644 644 int error;
645 645 struct evtchn_bind_virq bind_virq = { .virq = isrc->xi_virq,
646   - .vcpu = acpi_id };
  646 + .vcpu = vcpu_id };
647 647
648 648 error = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
649 649 &bind_virq);
@@ -796,7 +796,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
796 796 #ifdef SMP
797 797 struct evtchn_bind_vcpu bind_vcpu;
798 798 struct xenisrc *isrc;
799   - u_int to_cpu, acpi_id;
  799 + u_int to_cpu, vcpu_id;
800 800 int error;
801 801
802 802 #ifdef XENHVM
@@ -805,7 +805,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
805 805 #endif
806 806
807 807 to_cpu = apic_cpuid(apic_id);
808   - acpi_id = pcpu_find(to_cpu)->pc_acpi_id;
  808 + vcpu_id = pcpu_find(to_cpu)->pc_vcpu_id;
809 809 xen_intr_intrcnt_add(to_cpu);
810 810
811 811 mtx_lock(&xen_intr_isrc_lock);
@@ -830,7 +830,7 @@ xen_intr_assign_cpu(struct intsrc *base_isrc, u_int apic_id)
830 830 }
831 831
832 832 bind_vcpu.port = isrc->xi_port;
833   - bind_vcpu.vcpu = acpi_id;
  833 + bind_vcpu.vcpu = vcpu_id;
834 834
835 835 /*
836 836 * 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,
1063 1063 driver_filter_t filter, driver_intr_t handler, void *arg,
1064 1064 enum intr_type flags, xen_intr_handle_t *port_handlep)
1065 1065 {
1066   - int acpi_id = pcpu_find(cpu)->pc_acpi_id;
  1066 + int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
1067 1067 struct xenisrc *isrc;
1068   - struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = acpi_id };
  1068 + struct evtchn_bind_virq bind_virq = { .virq = virq, .vcpu = vcpu_id };
1069 1069 int error;
1070 1070
1071 1071 /* 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,
1126 1126 xen_intr_handle_t *port_handlep)
1127 1127 {
1128 1128 #ifdef SMP
1129   - int acpi_id = pcpu_find(cpu)->pc_acpi_id;
  1129 + int vcpu_id = pcpu_find(cpu)->pc_vcpu_id;
1130 1130 struct xenisrc *isrc;
1131   - struct evtchn_bind_ipi bind_ipi = { .vcpu = acpi_id };
  1131 + struct evtchn_bind_ipi bind_ipi = { .vcpu = vcpu_id };
1132 1132 int error;
1133 1133
1134 1134 /* Ensure the target CPU is ready to handle evtchn interrupts. */

0 comments on commit 9c8c76f

Please sign in to comment.
Something went wrong with that request. Please try again.