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
This commit is contained in:
Mark Johnston 2021-05-31 18:51:14 -04:00
parent 4a59cbc125
commit 18f55c67f7

View File

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