aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-05-31 22:51:14 +0000
committerMark Johnston <markj@FreeBSD.org>2021-05-31 22:51:14 +0000
commit18f55c67f746f0ad12fe972328234d340a621df9 (patch)
treea9ad82c17ceb3b0f4c6c5997409b5684cd8551ab
parent4a59cbc1253266ea70d6fa43b1a7c77cc33ec6cd (diff)
downloadsrc-18f55c67f746f0ad12fe972328234d340a621df9.tar.gz
src-18f55c67f746f0ad12fe972328234d340a621df9.zip
x86: Fix lapic_ipi_alloc() on i386
The loop which checks to see if "dynamic" IDT entries are allocated needs to compare with the trampoline address of the reserved ISR. Otherwise it will never succeed. Reported by: Harry Schmalzbauer <freebsd@omnilan.de> Tested by: Harry Schmalzbauer <freebsd@omnilan.de> Reviewed by: kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D30576
-rw-r--r--sys/x86/x86/local_apic.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 5b4910d4b891..bb575d0c601d 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -2127,6 +2127,10 @@ native_lapic_ipi_vectored(u_int vector, int dest)
#endif /* SMP */
+#ifdef __i386__
+extern uintptr_t setidt_disp;
+#endif
+
/*
* Since the IDT is shared by all CPUs the IPI slot update needs to be globally
* visible.
@@ -2155,6 +2159,9 @@ native_lapic_ipi_alloc(inthand_t *ipifunc)
for (idx = IPI_DYN_FIRST; idx <= IPI_DYN_LAST; idx++) {
ip = &idt[idx];
func = (ip->gd_hioffset << 16) | ip->gd_looffset;
+#ifdef __i386__
+ func -= setidt_disp;
+#endif
if ((!pti && func == (uintptr_t)&IDTVEC(rsvd)) ||
(pti && func == (uintptr_t)&IDTVEC(rsvd_pti))) {
vector = idx;
@@ -2178,6 +2185,9 @@ native_lapic_ipi_free(int vector)
mtx_lock_spin(&icu_lock);
ip = &idt[vector];
func = (ip->gd_hioffset << 16) | ip->gd_looffset;
+#ifdef __i386__
+ func -= setidt_disp;
+#endif
KASSERT(func != (uintptr_t)&IDTVEC(rsvd) &&
func != (uintptr_t)&IDTVEC(rsvd_pti),
("invalid idtfunc %#lx", func));