Changeset View
Changeset View
Standalone View
Standalone View
head/sys/x86/x86/local_apic.c
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | |||||
SYSCTL_INT(_hw_apic, OID_AUTO, eoi_suppression, CTLFLAG_RD, | SYSCTL_INT(_hw_apic, OID_AUTO, eoi_suppression, CTLFLAG_RD, | ||||
&lapic_eoi_suppression, 0, ""); | &lapic_eoi_suppression, 0, ""); | ||||
SYSCTL_INT(_hw_apic, OID_AUTO, timer_tsc_deadline, CTLFLAG_RD, | SYSCTL_INT(_hw_apic, OID_AUTO, timer_tsc_deadline, CTLFLAG_RD, | ||||
&lapic_timer_tsc_deadline, 0, ""); | &lapic_timer_tsc_deadline, 0, ""); | ||||
static void lapic_calibrate_initcount(struct lapic *la); | static void lapic_calibrate_initcount(struct lapic *la); | ||||
static void lapic_calibrate_deadline(struct lapic *la); | static void lapic_calibrate_deadline(struct lapic *la); | ||||
static uint32_t | /* | ||||
* Use __nosanitizethread to exempt the LAPIC I/O accessors from KCSan | |||||
* instrumentation. Otherwise, if x2APIC is not available, use of the global | |||||
* lapic_map will generate a KCSan false positive. While the mapping is | |||||
* shared among all CPUs, the physical access will always take place on the | |||||
* local CPU's APIC, so there isn't in fact a race here. Furthermore, the | |||||
* KCSan warning printf can cause a panic if issued during LAPIC access, | |||||
* due to attempted recursive use of event timer resources. | |||||
*/ | |||||
static uint32_t __nosanitizethread | |||||
lapic_read32(enum LAPIC_REGISTERS reg) | lapic_read32(enum LAPIC_REGISTERS reg) | ||||
{ | { | ||||
uint32_t res; | uint32_t res; | ||||
if (x2apic_mode) { | if (x2apic_mode) { | ||||
res = rdmsr32(MSR_APIC_000 + reg); | res = rdmsr32(MSR_APIC_000 + reg); | ||||
} else { | } else { | ||||
res = *(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL); | res = *(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL); | ||||
} | } | ||||
return (res); | return (res); | ||||
} | } | ||||
static void | static void __nosanitizethread | ||||
lapic_write32(enum LAPIC_REGISTERS reg, uint32_t val) | lapic_write32(enum LAPIC_REGISTERS reg, uint32_t val) | ||||
{ | { | ||||
if (x2apic_mode) { | if (x2apic_mode) { | ||||
mfence(); | mfence(); | ||||
lfence(); | lfence(); | ||||
wrmsr(MSR_APIC_000 + reg, val); | wrmsr(MSR_APIC_000 + reg, val); | ||||
} else { | } else { | ||||
*(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL) = val; | *(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL) = val; | ||||
} | } | ||||
} | } | ||||
static void | static void __nosanitizethread | ||||
lapic_write32_nofence(enum LAPIC_REGISTERS reg, uint32_t val) | lapic_write32_nofence(enum LAPIC_REGISTERS reg, uint32_t val) | ||||
{ | { | ||||
if (x2apic_mode) { | if (x2apic_mode) { | ||||
wrmsr(MSR_APIC_000 + reg, val); | wrmsr(MSR_APIC_000 + reg, val); | ||||
} else { | } else { | ||||
*(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL) = val; | *(volatile uint32_t *)(lapic_map + reg * LAPIC_MEM_MUL) = val; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,913 Lines • Show Last 20 Lines |