Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/local_apic.c
Context not available. | |||||
IDTVEC(apic_isr7), /* 224 - 255 */ | IDTVEC(apic_isr7), /* 224 - 255 */ | ||||
}; | }; | ||||
static inthand_t *ioint_pti_handlers[] = { | |||||
NULL, /* 0 - 31 */ | |||||
IDTVEC(apic_isr1_pti), /* 32 - 63 */ | |||||
IDTVEC(apic_isr2_pti), /* 64 - 95 */ | |||||
IDTVEC(apic_isr3_pti), /* 96 - 127 */ | |||||
IDTVEC(apic_isr4_pti), /* 128 - 159 */ | |||||
IDTVEC(apic_isr5_pti), /* 160 - 191 */ | |||||
IDTVEC(apic_isr6_pti), /* 192 - 223 */ | |||||
IDTVEC(apic_isr7_pti), /* 224 - 255 */ | |||||
}; | |||||
static u_int32_t lapic_timer_divisors[] = { | static u_int32_t lapic_timer_divisors[] = { | ||||
APIC_TDCR_1, APIC_TDCR_2, APIC_TDCR_4, APIC_TDCR_8, APIC_TDCR_16, | APIC_TDCR_1, APIC_TDCR_2, APIC_TDCR_4, APIC_TDCR_8, APIC_TDCR_16, | ||||
APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128 | APIC_TDCR_32, APIC_TDCR_64, APIC_TDCR_128 | ||||
}; | }; | ||||
extern inthand_t IDTVEC(rsvd); | extern inthand_t IDTVEC(rsvd_pti), IDTVEC(rsvd); | ||||
volatile char *lapic_map; | volatile char *lapic_map; | ||||
vm_paddr_t lapic_paddr; | vm_paddr_t lapic_paddr; | ||||
Context not available. | |||||
PCPU_SET(apic_id, lapic_id()); | PCPU_SET(apic_id, lapic_id()); | ||||
/* Local APIC timer interrupt. */ | /* Local APIC timer interrupt. */ | ||||
setidt(APIC_TIMER_INT, IDTVEC(timerint), SDT_APIC, SEL_KPL, GSEL_APIC); | setidt(APIC_TIMER_INT, pti ? IDTVEC(timerint_pti) : IDTVEC(timerint), | ||||
SDT_APIC, SEL_KPL, GSEL_APIC); | |||||
/* Local APIC error interrupt. */ | /* Local APIC error interrupt. */ | ||||
setidt(APIC_ERROR_INT, IDTVEC(errorint), SDT_APIC, SEL_KPL, GSEL_APIC); | setidt(APIC_ERROR_INT, pti ? IDTVEC(errorint_pti) : IDTVEC(errorint), | ||||
SDT_APIC, SEL_KPL, GSEL_APIC); | |||||
/* XXX: Thermal interrupt */ | /* XXX: Thermal interrupt */ | ||||
/* Local APIC CMCI. */ | /* Local APIC CMCI. */ | ||||
setidt(APIC_CMC_INT, IDTVEC(cmcint), SDT_APICT, SEL_KPL, GSEL_APIC); | setidt(APIC_CMC_INT, pti ? IDTVEC(cmcint_pti) : IDTVEC(cmcint), | ||||
SDT_APICT, SEL_KPL, GSEL_APIC); | |||||
if ((resource_int_value("apic", 0, "clock", &i) != 0 || i != 0)) { | if ((resource_int_value("apic", 0, "clock", &i) != 0 || i != 0)) { | ||||
arat = 0; | arat = 0; | ||||
Context not available. | |||||
KASSERT(vector != IDT_DTRACE_RET, | KASSERT(vector != IDT_DTRACE_RET, | ||||
("Attempt to overwrite DTrace entry")); | ("Attempt to overwrite DTrace entry")); | ||||
#endif | #endif | ||||
setidt(vector, ioint_handlers[vector / 32], SDT_APIC, SEL_KPL, | setidt(vector, (pti ? ioint_pti_handlers : ioint_handlers)[vector / 32], | ||||
GSEL_APIC); | SDT_APIC, SEL_KPL, GSEL_APIC); | ||||
} | } | ||||
static void | static void | ||||
Context not available. | |||||
* We can not currently clear the idt entry because other cpus | * We can not currently clear the idt entry because other cpus | ||||
* may have a valid vector at this offset. | * may have a valid vector at this offset. | ||||
*/ | */ | ||||
setidt(vector, &IDTVEC(rsvd), SDT_APICT, SEL_KPL, GSEL_APIC); | setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APICT, | ||||
SEL_KPL, GSEL_APIC); | |||||
#endif | #endif | ||||
} | } | ||||
Context not available. | |||||
* APIC page is mapped as an uncached region. In x2APIC mode there is an | * APIC page is mapped as an uncached region. In x2APIC mode there is an | ||||
* explicit 'mfence' before the ICR MSR is written. Therefore in both cases | * explicit 'mfence' before the ICR MSR is written. Therefore in both cases | ||||
* the IDT slot update is globally visible before the IPI is delivered. | * the IDT slot update is globally visible before the IPI is delivered. | ||||
* XXX pti | |||||
*/ | */ | ||||
static int | static int | ||||
native_lapic_ipi_alloc(inthand_t *ipifunc) | native_lapic_ipi_alloc(inthand_t *ipifunc) | ||||
Context not available. | |||||
long func; | long func; | ||||
int idx, vector; | int idx, vector; | ||||
KASSERT(ipifunc != &IDTVEC(rsvd), ("invalid ipifunc %p", ipifunc)); | KASSERT(ipifunc != &IDTVEC(rsvd) && ipifunc != &IDTVEC(rsvd_pti), | ||||
("invalid ipifunc %p", ipifunc)); | |||||
vector = -1; | vector = -1; | ||||
mtx_lock_spin(&icu_lock); | mtx_lock_spin(&icu_lock); | ||||
Context not available. | |||||
mtx_lock_spin(&icu_lock); | mtx_lock_spin(&icu_lock); | ||||
ip = &idt[vector]; | ip = &idt[vector]; | ||||
func = (ip->gd_hioffset << 16) | ip->gd_looffset; | func = (ip->gd_hioffset << 16) | ip->gd_looffset; | ||||
KASSERT(func != (uintptr_t)&IDTVEC(rsvd), | KASSERT(func != (uintptr_t)&IDTVEC(rsvd) && | ||||
func != (uintptr_t)&IDTVEC(rsvd_pti), | |||||
("invalid idtfunc %#lx", func)); | ("invalid idtfunc %#lx", func)); | ||||
setidt(vector, &IDTVEC(rsvd), SDT_APICT, SEL_KPL, GSEL_APIC); | setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APICT, | ||||
SEL_KPL, GSEL_APIC); | |||||
mtx_unlock_spin(&icu_lock); | mtx_unlock_spin(&icu_lock); | ||||
} | } | ||||
Context not available. |