git: 18f55c67f746 - main - x86: Fix lapic_ipi_alloc() on i386

Mark Johnston markj at FreeBSD.org
Mon May 31 23:09:49 UTC 2021


The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=18f55c67f746f0ad12fe972328234d340a621df9

commit 18f55c67f746f0ad12fe972328234d340a621df9
Author:     Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-05-31 22:51:14 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-05-31 22:51:14 +0000

    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 at omnilan.de>
    Tested by:      Harry Schmalzbauer <freebsd at omnilan.de>
    Reviewed by:    kib
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D30576
---
 sys/x86/x86/local_apic.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

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));


More information about the dev-commits-src-all mailing list