Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/xen/xen_apic.c
Show First 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
#define XEN_APIC_UNSUPPORTED \ | #define XEN_APIC_UNSUPPORTED \ | ||||
panic("%s: not available in Xen PV port.", __func__) | panic("%s: not available in Xen PV port.", __func__) | ||||
/*--------------------------- Forward Declarations ---------------------------*/ | /*--------------------------- Forward Declarations ---------------------------*/ | ||||
#ifdef SMP | #ifdef SMP | ||||
static driver_filter_t xen_smp_rendezvous_action; | static driver_filter_t xen_smp_rendezvous_action; | ||||
#ifdef __amd64__ | |||||
static driver_filter_t xen_invlop; | |||||
#else | |||||
static driver_filter_t xen_invltlb; | static driver_filter_t xen_invltlb; | ||||
static driver_filter_t xen_invlpg; | static driver_filter_t xen_invlpg; | ||||
static driver_filter_t xen_invlrng; | static driver_filter_t xen_invlrng; | ||||
static driver_filter_t xen_invlcache; | static driver_filter_t xen_invlcache; | ||||
#endif | |||||
static driver_filter_t xen_ipi_bitmap_handler; | static driver_filter_t xen_ipi_bitmap_handler; | ||||
static driver_filter_t xen_cpustop_handler; | static driver_filter_t xen_cpustop_handler; | ||||
static driver_filter_t xen_cpususpend_handler; | static driver_filter_t xen_cpususpend_handler; | ||||
#endif | #endif | ||||
/*---------------------------------- Macros ----------------------------------*/ | /*---------------------------------- Macros ----------------------------------*/ | ||||
#define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) | #define IPI_TO_IDX(ipi) ((ipi) - APIC_IPI_INTS) | ||||
/*--------------------------------- Xen IPIs ---------------------------------*/ | /*--------------------------------- Xen IPIs ---------------------------------*/ | ||||
#ifdef SMP | #ifdef SMP | ||||
struct xen_ipi_handler | struct xen_ipi_handler | ||||
{ | { | ||||
driver_filter_t *filter; | driver_filter_t *filter; | ||||
const char *description; | const char *description; | ||||
}; | }; | ||||
static struct xen_ipi_handler xen_ipis[] = | static struct xen_ipi_handler xen_ipis[] = | ||||
{ | { | ||||
[IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, | [IPI_TO_IDX(IPI_RENDEZVOUS)] = { xen_smp_rendezvous_action, "r" }, | ||||
#ifdef __amd64__ | |||||
[IPI_TO_IDX(IPI_INVLOP)] = { xen_invlop, "itlb"}, | |||||
#else | |||||
[IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, | [IPI_TO_IDX(IPI_INVLTLB)] = { xen_invltlb, "itlb"}, | ||||
[IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, | [IPI_TO_IDX(IPI_INVLPG)] = { xen_invlpg, "ipg" }, | ||||
[IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, | [IPI_TO_IDX(IPI_INVLRNG)] = { xen_invlrng, "irg" }, | ||||
[IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, | [IPI_TO_IDX(IPI_INVLCACHE)] = { xen_invlcache, "ic" }, | ||||
#endif | |||||
[IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, | [IPI_TO_IDX(IPI_BITMAP_VECTOR)] = { xen_ipi_bitmap_handler, "b" }, | ||||
[IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, | [IPI_TO_IDX(IPI_STOP)] = { xen_cpustop_handler, "st" }, | ||||
[IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, | [IPI_TO_IDX(IPI_SUSPEND)] = { xen_cpususpend_handler, "sp" }, | ||||
}; | }; | ||||
#endif | #endif | ||||
/*------------------------------- Per-CPU Data -------------------------------*/ | /*------------------------------- Per-CPU Data -------------------------------*/ | ||||
#ifdef SMP | #ifdef SMP | ||||
▲ Show 20 Lines • Show All 346 Lines • ▼ Show 20 Lines | |||||
#ifdef COUNT_IPIS | #ifdef COUNT_IPIS | ||||
(*ipi_rendezvous_counts[PCPU_GET(cpuid)])++; | (*ipi_rendezvous_counts[PCPU_GET(cpuid)])++; | ||||
#endif /* COUNT_IPIS */ | #endif /* COUNT_IPIS */ | ||||
smp_rendezvous_action(); | smp_rendezvous_action(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | |||||
xen_invltlb(void *arg) | |||||
{ | |||||
invltlb_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
#ifdef __amd64__ | #ifdef __amd64__ | ||||
static int | static int | ||||
xen_invltlb_invpcid(void *arg) | xen_invlop(void *arg) | ||||
{ | { | ||||
invltlb_invpcid_handler(); | invlop_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | #else /* __i386__ */ | ||||
xen_invltlb_pcid(void *arg) | |||||
{ | |||||
invltlb_pcid_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
static int | static int | ||||
xen_invltlb_invpcid_pti(void *arg) | xen_invltlb(void *arg) | ||||
{ | { | ||||
invltlb_invpcid_pti_handler(); | invltlb_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | static int | ||||
xen_invlpg_invpcid_handler(void *arg) | |||||
{ | |||||
invlpg_invpcid_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
static int | |||||
xen_invlpg_pcid_handler(void *arg) | |||||
{ | |||||
invlpg_pcid_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
static int | |||||
xen_invlrng_invpcid_handler(void *arg) | |||||
{ | |||||
invlrng_invpcid_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
static int | |||||
xen_invlrng_pcid_handler(void *arg) | |||||
{ | |||||
invlrng_pcid_handler(); | |||||
return (FILTER_HANDLED); | |||||
} | |||||
#endif | |||||
static int | |||||
xen_invlpg(void *arg) | xen_invlpg(void *arg) | ||||
{ | { | ||||
invlpg_handler(); | invlpg_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | static int | ||||
xen_invlrng(void *arg) | xen_invlrng(void *arg) | ||||
{ | { | ||||
invlrng_handler(); | invlrng_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | static int | ||||
xen_invlcache(void *arg) | xen_invlcache(void *arg) | ||||
{ | { | ||||
invlcache_handler(); | invlcache_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
#endif /* __amd64__ */ | |||||
static int | static int | ||||
xen_cpustop_handler(void *arg) | xen_cpustop_handler(void *arg) | ||||
{ | { | ||||
cpustop_handler(); | cpustop_handler(); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
Show All 39 Lines | |||||
static void | static void | ||||
xen_setup_cpus(void) | xen_setup_cpus(void) | ||||
{ | { | ||||
int i; | int i; | ||||
if (!xen_vector_callback_enabled) | if (!xen_vector_callback_enabled) | ||||
return; | return; | ||||
#ifdef __amd64__ | |||||
if (pmap_pcid_enabled) { | |||||
if (pti) | |||||
xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = | |||||
invpcid_works ? xen_invltlb_invpcid_pti : | |||||
xen_invltlb_pcid; | |||||
else | |||||
xen_ipis[IPI_TO_IDX(IPI_INVLTLB)].filter = | |||||
invpcid_works ? xen_invltlb_invpcid : | |||||
xen_invltlb_pcid; | |||||
xen_ipis[IPI_TO_IDX(IPI_INVLPG)].filter = invpcid_works ? | |||||
xen_invlpg_invpcid_handler : xen_invlpg_pcid_handler; | |||||
xen_ipis[IPI_TO_IDX(IPI_INVLRNG)].filter = invpcid_works ? | |||||
xen_invlrng_invpcid_handler : xen_invlrng_pcid_handler; | |||||
} | |||||
#endif | |||||
CPU_FOREACH(i) | CPU_FOREACH(i) | ||||
xen_cpu_ipi_init(i); | xen_cpu_ipi_init(i); | ||||
/* Set the xen pv ipi ops to replace the native ones */ | /* Set the xen pv ipi ops to replace the native ones */ | ||||
if (xen_hvm_domain()) | if (xen_hvm_domain()) | ||||
apic_ops.ipi_vectored = xen_pv_lapic_ipi_vectored; | apic_ops.ipi_vectored = xen_pv_lapic_ipi_vectored; | ||||
} | } | ||||
/* Switch to using PV IPIs as soon as the vcpu_id is set. */ | /* Switch to using PV IPIs as soon as the vcpu_id is set. */ | ||||
SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_SECOND, xen_setup_cpus, NULL); | SYSINIT(xen_setup_cpus, SI_SUB_SMP, SI_ORDER_SECOND, xen_setup_cpus, NULL); | ||||
#endif /* SMP */ | #endif /* SMP */ |