Module Name: src
Committed By: bouyer
Date: Sat Apr 11 18:26:08 UTC 2020
Modified Files:
src/sys/arch/amd64/amd64 [bouyer-xenpvh]: lock_stubs.S spl.S
src/sys/arch/i386/i386 [bouyer-xenpvh]: spl.S
src/sys/arch/x86/conf [bouyer-xenpvh]: files.x86
src/sys/arch/x86/include [bouyer-xenpvh]: intr.h
src/sys/arch/x86/x86 [bouyer-xenpvh]: intr.c x86_machdep.c
src/sys/arch/xen/conf [bouyer-xenpvh]: files.xen
src/sys/arch/xen/include [bouyer-xenpvh]: intrdefs.h
src/sys/arch/xen/x86 [bouyer-xenpvh]: xen_ipi.c xenfunc.c
src/sys/arch/xen/xen [bouyer-xenpvh]: clock.c
Added Files:
src/sys/arch/x86/x86 [bouyer-xenpvh]: x86_softintr.c
Log Message:
Move softint and preemtion-related functions out of x86/x86/intr.c to
its own file, x86/x86/x86_softintr.c
Add x86/x86/x86_softintr.c for native and XenPV
Make sure XenPV also check ci_ioending, which is used for softints.
Switch XenPV to fast softints and allow kernel preemption.
kpreempt_disable() before calling pmap_changeprot_local()
run xen_wallclock_time() and xen_global_systime_ns() at splshed() to
avoid being interrupted.
XXX amd64 lock stubs are racy for XPENDING
To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.35.6.1 src/sys/arch/amd64/amd64/lock_stubs.S
cvs rdiff -u -r1.43.4.4 -r1.43.4.5 src/sys/arch/amd64/amd64/spl.S
cvs rdiff -u -r1.50.4.3 -r1.50.4.4 src/sys/arch/i386/i386/spl.S
cvs rdiff -u -r1.107 -r1.107.10.1 src/sys/arch/x86/conf/files.x86
cvs rdiff -u -r1.61.6.1 -r1.61.6.2 src/sys/arch/x86/include/intr.h
cvs rdiff -u -r1.150 -r1.150.6.1 src/sys/arch/x86/x86/intr.c
cvs rdiff -u -r1.137.2.2 -r1.137.2.3 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r0 -r1.1.2.1 src/sys/arch/x86/x86/x86_softintr.c
cvs rdiff -u -r1.180 -r1.180.2.1 src/sys/arch/xen/conf/files.xen
cvs rdiff -u -r1.15 -r1.15.2.1 src/sys/arch/xen/include/intrdefs.h
cvs rdiff -u -r1.35 -r1.35.6.1 src/sys/arch/xen/x86/xen_ipi.c
cvs rdiff -u -r1.26 -r1.26.8.1 src/sys/arch/xen/x86/xenfunc.c
cvs rdiff -u -r1.80 -r1.80.6.1 src/sys/arch/xen/xen/clock.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/amd64/amd64/lock_stubs.S
diff -u src/sys/arch/amd64/amd64/lock_stubs.S:1.35 src/sys/arch/amd64/amd64/lock_stubs.S:1.35.6.1
--- src/sys/arch/amd64/amd64/lock_stubs.S:1.35 Sun Dec 8 20:00:56 2019
+++ src/sys/arch/amd64/amd64/lock_stubs.S Sat Apr 11 18:26:06 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: lock_stubs.S,v 1.35 2019/12/08 20:00:56 ad Exp $ */
+/* $NetBSD: lock_stubs.S,v 1.35.6.1 2020/04/11 18:26:06 bouyer Exp $ */
/*
* Copyright (c) 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -126,15 +126,12 @@ ENTRY(mutex_spin_exit)
jnz 1f
cmpl CPU_INFO_ILEVEL(%r8), %edi
jae 1f
-#if !defined(XENPV)
movl CPU_INFO_IUNMASK(%r8,%rdi,4), %esi
CLI(ax)
testl CPU_INFO_IPENDING(%r8), %esi
jnz _C_LABEL(Xspllower)
-#endif
#if defined(XEN)
movl CPU_INFO_XUNMASK(%r8,%rdi,4), %esi
- CLI(ax)
testl CPU_INFO_XPENDING(%r8), %esi
jnz _C_LABEL(Xspllower)
#endif
@@ -155,14 +152,12 @@ ENTRY(mutex_spin_exit)
cmpl %edx,%ecx /* new level is lower? */
jae 2f
1:
-#if !defined(XENPV)
movl CPU_INFO_IPENDING(%rsi),%eax
testl %eax,CPU_INFO_IUNMASK(%rsi,%rcx,4)/* deferred interrupts? */
jnz 3f
movl %eax,%ebx
cmpxchg8b CPU_INFO_ISTATE(%rsi) /* swap in new ilevel */
jnz 4f
-#endif
#if defined(XEN)
movl CPU_INFO_XPENDING(%rsi),%eax
testl %eax,CPU_INFO_XUNMASK(%rsi,%rcx,4)/* deferred interrupts? */
Index: src/sys/arch/amd64/amd64/spl.S
diff -u src/sys/arch/amd64/amd64/spl.S:1.43.4.4 src/sys/arch/amd64/amd64/spl.S:1.43.4.5
--- src/sys/arch/amd64/amd64/spl.S:1.43.4.4 Sat Apr 11 10:11:30 2020
+++ src/sys/arch/amd64/amd64/spl.S Sat Apr 11 18:26:06 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: spl.S,v 1.43.4.4 2020/04/11 10:11:30 bouyer Exp $ */
+/* $NetBSD: spl.S,v 1.43.4.5 2020/04/11 18:26:06 bouyer Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@@ -91,7 +91,6 @@ ENTRY(splraise)
ret
END(splraise)
-#ifndef XENPV
/*
* Xsoftintr()
*
@@ -148,11 +147,11 @@ IDTVEC(softintr)
movq PCB_RSP0(%rdx),%rsp
/* dispatch */
- sti
+ STI(di)
movq %r15,%rdi /* interrupted LWP */
movl IS_MAXLEVEL(%rax),%esi /* ipl to run at */
call _C_LABEL(softint_dispatch)/* run handlers */
- cli
+ CLI(di)
/* restore old context */
movq L_PCB(%r15),%rcx
@@ -174,7 +173,7 @@ IDTVEC_END(softintr)
*/
ENTRY(softintr_ret)
incl CPUVAR(MTX_COUNT) /* re-adjust after mi_switch */
- cli
+ CLI(ax) /* %rax not used by Xspllower/Xdoreti */
jmp *%r13 /* back to Xspllower/Xdoreti */
END(softintr_ret)
@@ -196,11 +195,11 @@ END(softint_trigger)
*/
IDTVEC(recurse_preempt)
movl $IPL_PREEMPT,CPUVAR(ILEVEL)
- sti
+ STI(di)
xorq %rdi,%rdi
KMSAN_INIT_ARG(8)
call _C_LABEL(kpreempt)
- cli
+ CLI(di)
jmp *%r13 /* back to Xspllower */
IDTVEC_END(recurse_preempt)
@@ -211,20 +210,19 @@ IDTVEC_END(recurse_preempt)
*/
IDTVEC(resume_preempt)
movl $IPL_PREEMPT,CPUVAR(ILEVEL)
- sti
+ STI(ax)
testq $SEL_RPL,TF_CS(%rsp)
jnz 1f
movq TF_RIP(%rsp),%rdi
KMSAN_INIT_ARG(8)
call _C_LABEL(kpreempt) /* from kernel */
- cli
+ CLI(ax)
jmp *%r13 /* back to Xdoreti */
1:
call _C_LABEL(preempt) /* from user */
- cli
+ CLI(ax)
jmp *%r13 /* back to Xdoreti */
IDTVEC_END(resume_preempt)
-#endif /* XEN */
/*
* void spllower(int s);
@@ -336,7 +334,6 @@ IDTVEC(spllower)
movl %edi,%ebx
leaq 1f(%rip),%r13 /* address to resume loop at */
1:
-#if !defined(XENPV)
movl %ebx,%eax /* get cpl */
movl CPUVAR(IUNMASK)(,%rax,4),%eax
CLI(si)
@@ -346,7 +343,6 @@ IDTVEC(spllower)
btrl %eax,CPUVAR(IPENDING)
movq CPUVAR(ISOURCES)(,%rax,8),%rax
jmp *IS_RECURSE(%rax)
-#endif
2:
#if defined(XEN)
movl %ebx,%eax /* get cpl */
@@ -382,7 +378,6 @@ IDTVEC(doreti)
decl CPUVAR(IDEPTH)
leaq 1f(%rip),%r13
1:
-#if !defined(XENPV)
movl %ebx,%eax
movl CPUVAR(IUNMASK)(,%rax,4),%eax
CLI(si)
@@ -392,7 +387,6 @@ IDTVEC(doreti)
btrl %eax,CPUVAR(IPENDING)
movq CPUVAR(ISOURCES)(,%rax,8),%rax
jmp *IS_RESUME(%rax)
-#endif
2:
#if defined(XEN)
movl %ebx,%eax
Index: src/sys/arch/i386/i386/spl.S
diff -u src/sys/arch/i386/i386/spl.S:1.50.4.3 src/sys/arch/i386/i386/spl.S:1.50.4.4
--- src/sys/arch/i386/i386/spl.S:1.50.4.3 Sat Apr 11 12:01:42 2020
+++ src/sys/arch/i386/i386/spl.S Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: spl.S,v 1.50.4.3 2020/04/11 12:01:42 bouyer Exp $ */
+/* $NetBSD: spl.S,v 1.50.4.4 2020/04/11 18:26:07 bouyer Exp $ */
/*
* Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <machine/asm.h>
-__KERNEL_RCSID(0, "$NetBSD: spl.S,v 1.50.4.3 2020/04/11 12:01:42 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spl.S,v 1.50.4.4 2020/04/11 18:26:07 bouyer Exp $");
#include "opt_ddb.h"
#include "opt_spldebug.h"
@@ -213,7 +213,6 @@ IDTVEC(spllower)
jz .Lspllower_panic
#endif /* XENPV */
#endif /* defined(DEBUG) */
-#if !defined(XENPV)
movl %ebx,%eax /* get cpl */
movl CPUVAR(IUNMASK)(,%eax,4),%eax
andl CPUVAR(IPENDING),%eax /* any non-masked bits left? */
@@ -222,7 +221,6 @@ IDTVEC(spllower)
btrl %eax,CPUVAR(IPENDING)
movl CPUVAR(ISOURCES)(,%eax,4),%eax
jmp *IS_RECURSE(%eax)
-#endif
2:
#if defined(XEN)
movl %ebx,%eax /* get cpl */
@@ -361,7 +359,6 @@ END(doreti_checkast)
#endif
IDTVEC_END(doreti)
-#ifndef XENPV
/*
* Xsoftintr()
*
@@ -379,6 +376,7 @@ IDTVEC(softintr)
pushl %esi
pushl %edi
movl $IPL_HIGH,CPUVAR(ILEVEL)
+ STI(%esi)
movl CPUVAR(CURLWP),%esi
movl IS_LWP(%eax),%edi /* switch to handler LWP */
movl %edi,CPUVAR(CURLWP)
@@ -387,12 +385,11 @@ IDTVEC(softintr)
movl %esp,PCB_ESP(%ecx)
movl %ebp,PCB_EBP(%ecx)
movl PCB_ESP0(%edx),%esp /* onto new stack */
- sti
pushl IS_MAXLEVEL(%eax) /* ipl to run at */
pushl %esi
call _C_LABEL(softint_dispatch)/* run handlers */
addl $8,%esp
- cli
+ CLI(%ecx)
movl L_PCB(%esi),%ecx
movl PCB_ESP(%ecx),%esp
xchgl %esi,CPUVAR(CURLWP) /* must be globally visible */
@@ -412,7 +409,7 @@ IDTVEC_END(softintr)
*/
ENTRY(softintr_ret)
incl CPUVAR(MTX_COUNT) /* re-adjust after mi_switch */
- cli
+ CLI(%eax)
jmp *%esi /* back to splx/doreti */
END(softintr_ret)
@@ -434,11 +431,11 @@ END(softint_trigger)
*/
IDTVEC(recurse_preempt)
movl $IPL_PREEMPT,CPUVAR(ILEVEL)
- sti
+ STI(%eax)
pushl $0
call _C_LABEL(kpreempt)
addl $4,%esp
- cli
+ CLI(%eax)
jmp *%esi
IDTVEC_END(recurse_preempt)
@@ -449,18 +446,17 @@ IDTVEC_END(recurse_preempt)
*/
IDTVEC(resume_preempt)
movl $IPL_PREEMPT,CPUVAR(ILEVEL)
- sti
+ STI(%eax)
testb $CHK_UPL,TF_CS(%esp)
jnz 1f
movl TF_EIP(%esp),%eax
pushl %eax
call _C_LABEL(kpreempt) /* from kernel */
addl $4,%esp
- cli
+ CLI(%eax)
jmp *%esi
1:
call _C_LABEL(preempt) /* from user */
- cli
+ CLI(%eax)
jmp *%esi
IDTVEC_END(resume_preempt)
-#endif /* !XENPV */
Index: src/sys/arch/x86/conf/files.x86
diff -u src/sys/arch/x86/conf/files.x86:1.107 src/sys/arch/x86/conf/files.x86:1.107.10.1
--- src/sys/arch/x86/conf/files.x86:1.107 Fri Feb 15 08:54:01 2019
+++ src/sys/arch/x86/conf/files.x86 Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.x86,v 1.107 2019/02/15 08:54:01 nonaka Exp $
+# $NetBSD: files.x86,v 1.107.10.1 2020/04/11 18:26:07 bouyer Exp $
# options for MP configuration through the MP spec
defflag opt_mpbios.h MPBIOS MPDEBUG MPBIOS_SCANPCI
@@ -93,6 +93,7 @@ file arch/x86/x86/genfb_machdep.c machde
file arch/x86/x86/identcpu.c machdep
file arch/x86/x86/i8259.c machdep
file arch/x86/x86/intr.c machdep
+file arch/x86/x86/x86_softintr.c machdep
file arch/x86/x86/kgdb_machdep.c kgdb
file arch/x86/x86/nmi.c machdep
file arch/x86/x86/idt.c machdep
Index: src/sys/arch/x86/include/intr.h
diff -u src/sys/arch/x86/include/intr.h:1.61.6.1 src/sys/arch/x86/include/intr.h:1.61.6.2
--- src/sys/arch/x86/include/intr.h:1.61.6.1 Fri Apr 10 14:42:00 2020
+++ src/sys/arch/x86/include/intr.h Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.61.6.1 2020/04/10 14:42:00 bouyer Exp $ */
+/* $NetBSD: intr.h,v 1.61.6.2 2020/04/11 18:26:07 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2001, 2006, 2007, 2008, 2019 The NetBSD Foundation, Inc.
@@ -32,12 +32,10 @@
#ifndef _X86_INTR_H_
#define _X86_INTR_H_
-#if !defined(XENPV)
#define __HAVE_FAST_SOFTINTS
#if !defined(NO_PREEMPTION)
#define __HAVE_PREEMPTION
#endif /* !defined(NO_PREEMPTION) */
-#endif /* !defined(XENPV) */
#ifdef _KERNEL
#include <sys/types.h>
@@ -239,6 +237,9 @@ const char *intr_create_intrid(int, stru
struct intrsource *intr_allocate_io_intrsource(const char *);
void intr_free_io_intrsource(const char *);
+void x86_init_preempt(struct cpu_info *);
+void x86_intr_calculatemasks(struct cpu_info *);
+
int x86_send_ipi(struct cpu_info *, int);
void x86_broadcast_ipi(int);
void x86_ipi_handler(void);
Index: src/sys/arch/x86/x86/intr.c
diff -u src/sys/arch/x86/x86/intr.c:1.150 src/sys/arch/x86/x86/intr.c:1.150.6.1
--- src/sys/arch/x86/x86/intr.c:1.150 Mon Dec 30 23:32:30 2019
+++ src/sys/arch/x86/x86/intr.c Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.150 2019/12/30 23:32:30 thorpej Exp $ */
+/* $NetBSD: intr.c,v 1.150.6.1 2020/04/11 18:26:07 bouyer Exp $ */
/*
* Copyright (c) 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
@@ -133,7 +133,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.150 2019/12/30 23:32:30 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.150.6.1 2020/04/11 18:26:07 bouyer Exp $");
#include "opt_intrdebug.h"
#include "opt_multiprocessor.h"
@@ -207,16 +207,6 @@ extern void Xrecurse_hyperv_hypercall(vo
#define DPRINTF(msg)
#endif
-struct pic softintr_pic = {
- .pic_name = "softintr_fakepic",
- .pic_type = PIC_SOFT,
- .pic_vecbase = 0,
- .pic_apicid = 0,
- .pic_lock = __SIMPLELOCK_UNLOCKED,
-};
-
-static void intr_calculatemasks(struct cpu_info *);
-
static SIMPLEQ_HEAD(, intrsource) io_interrupt_sources =
SIMPLEQ_HEAD_INITIALIZER(io_interrupt_sources);
@@ -290,73 +280,6 @@ x86_nmi(void)
}
/*
- * Recalculate the interrupt masks from scratch.
- * During early boot, anything goes and we are always called on the BP.
- * When the system is up and running:
- *
- * => called with ci == curcpu()
- * => cpu_lock held by the initiator
- * => interrupts disabled on-chip (PSL_I)
- *
- * Do not call printf(), kmem_free() or other "heavyweight" routines
- * from here. This routine must be quick and must not block.
- */
-static void
-intr_calculatemasks(struct cpu_info *ci)
-{
- int irq, level, unusedirqs, intrlevel[MAX_INTR_SOURCES];
- struct intrhand *q;
-
- /* First, figure out which levels each IRQ uses. */
- unusedirqs = 0xffffffff;
- for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
- int levels = 0;
-
- if (ci->ci_isources[irq] == NULL) {
- intrlevel[irq] = 0;
- continue;
- }
- for (q = ci->ci_isources[irq]->is_handlers; q; q = q->ih_next)
- levels |= 1U << q->ih_level;
- intrlevel[irq] = levels;
- if (levels)
- unusedirqs &= ~(1U << irq);
- }
-
- /* Then figure out which IRQs use each level. */
- for (level = 0; level < NIPL; level++) {
- int irqs = 0;
- for (irq = 0; irq < MAX_INTR_SOURCES; irq++)
- if (intrlevel[irq] & (1U << level))
- irqs |= 1U << irq;
- ci->ci_imask[level] = irqs | unusedirqs;
- }
-
- for (level = 0; level<(NIPL-1); level++)
- ci->ci_imask[level+1] |= ci->ci_imask[level];
-
- for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
- int maxlevel = IPL_NONE;
- int minlevel = IPL_HIGH;
-
- if (ci->ci_isources[irq] == NULL)
- continue;
- for (q = ci->ci_isources[irq]->is_handlers; q;
- q = q->ih_next) {
- if (q->ih_level < minlevel)
- minlevel = q->ih_level;
- if (q->ih_level > maxlevel)
- maxlevel = q->ih_level;
- }
- ci->ci_isources[irq]->is_maxlevel = maxlevel;
- ci->ci_isources[irq]->is_minlevel = minlevel;
- }
-
- for (level = 0; level < NIPL; level++)
- ci->ci_iunmask[level] = ~ci->ci_imask[level];
-}
-
-/*
* Create an interrupt id such as "ioapic0 pin 9". This interrupt id is used
* by MI code and intrctl(8).
*/
@@ -801,7 +724,7 @@ intr_establish_xcall(void *arg1, void *a
/* Link in the handler and re-calculate masks. */
*(ih->ih_prevp) = ih;
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
/* Hook in new IDT vector and SPL state. */
if (source->is_resume == NULL || source->is_idtvec != idt_vec) {
@@ -1186,7 +1109,7 @@ intr_disestablish_xcall(void *arg1, void
*p = q->ih_next;
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
/*
* If there is no any handler, 1) do delroute because it has no
* any source and 2) dont' hwunmask to prevent spurious interrupt.
@@ -1327,15 +1250,10 @@ intr_string(intr_handle_t ih, char *buf,
/*
* Fake interrupt handler structures for the benefit of symmetry with
- * other interrupt sources, and the benefit of intr_calculatemasks()
+ * other interrupt sources, and the benefit of x86_intr_calculatemasks()
*/
-struct intrhand fake_softclock_intrhand;
-struct intrhand fake_softnet_intrhand;
-struct intrhand fake_softserial_intrhand;
-struct intrhand fake_softbio_intrhand;
struct intrhand fake_timer_intrhand;
struct intrhand fake_ipi_intrhand;
-struct intrhand fake_preempt_intrhand;
#if NHYPERV > 0
struct intrhand fake_hyperv_intrhand;
#endif
@@ -1369,7 +1287,7 @@ redzone_const_or_zero(int x)
void
cpu_intr_init(struct cpu_info *ci)
{
-#if (NLAPIC > 0) || defined(MULTIPROCESSOR) || defined(__HAVE_PREEMPTION) || \
+#if (NLAPIC > 0) || defined(MULTIPROCESSOR) || \
(NHYPERV > 0)
struct intrsource *isp;
#endif
@@ -1423,16 +1341,10 @@ cpu_intr_init(struct cpu_info *ci)
#endif
#if defined(__HAVE_PREEMPTION)
- isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
- isp->is_recurse = Xrecurse_preempt;
- isp->is_resume = Xresume_preempt;
- fake_preempt_intrhand.ih_level = IPL_PREEMPT;
- isp->is_handlers = &fake_preempt_intrhand;
- isp->is_pic = &softintr_pic;
- ci->ci_isources[SIR_PREEMPT] = isp;
+ x86_init_preempt(ci);
#endif
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
#if defined(INTRSTACKSIZE)
vaddr_t istack;
@@ -1521,55 +1433,6 @@ intr_printconfig(void)
#endif
-#if defined(__HAVE_FAST_SOFTINTS)
-void
-softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep)
-{
- struct intrsource *isp;
- struct cpu_info *ci;
- u_int sir;
-
- ci = l->l_cpu;
-
- isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
- isp->is_recurse = Xsoftintr;
- isp->is_resume = Xsoftintr;
- isp->is_pic = &softintr_pic;
-
- switch (level) {
- case SOFTINT_BIO:
- sir = SIR_BIO;
- fake_softbio_intrhand.ih_level = IPL_SOFTBIO;
- isp->is_handlers = &fake_softbio_intrhand;
- break;
- case SOFTINT_NET:
- sir = SIR_NET;
- fake_softnet_intrhand.ih_level = IPL_SOFTNET;
- isp->is_handlers = &fake_softnet_intrhand;
- break;
- case SOFTINT_SERIAL:
- sir = SIR_SERIAL;
- fake_softserial_intrhand.ih_level = IPL_SOFTSERIAL;
- isp->is_handlers = &fake_softserial_intrhand;
- break;
- case SOFTINT_CLOCK:
- sir = SIR_CLOCK;
- fake_softclock_intrhand.ih_level = IPL_SOFTCLOCK;
- isp->is_handlers = &fake_softclock_intrhand;
- break;
- default:
- panic("softint_init_md");
- }
-
- KASSERT(ci->ci_isources[sir] == NULL);
-
- *machdep = (1 << sir);
- ci->ci_isources[sir] = isp;
- ci->ci_isources[sir]->is_lwp = l;
-
- intr_calculatemasks(ci);
-}
-#endif /* __HAVE_FAST_SOFTINTS */
/*
* Save current affinitied cpu's interrupt count.
*/
@@ -1628,7 +1491,7 @@ intr_redistribute_xc_t(void *arg1, void
/* Hook it in and re-calculate masks. */
ci->ci_isources[slot] = isp;
- intr_calculatemasks(curcpu());
+ x86_intr_calculatemasks(curcpu());
/* Re-enable interrupts locally. */
x86_write_psl(psl);
@@ -1682,7 +1545,7 @@ intr_redistribute_xc_s2(void *arg1, void
/* Patch out the source and re-calculate masks. */
ci->ci_isources[slot] = NULL;
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
/* Re-enable interrupts locally. */
x86_write_psl(psl);
@@ -1872,7 +1735,7 @@ intr_activate_xcall(void *arg1, void *ar
psl = x86_read_psl();
x86_disable_intr();
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
if (source->is_type == IST_LEVEL) {
stubp = &source->is_pic->pic_level_stubs[slot];
@@ -1917,7 +1780,7 @@ intr_deactivate_xcall(void *arg1, void *
ci->ci_nintrhand--;
}
- intr_calculatemasks(ci);
+ x86_intr_calculatemasks(ci);
/*
* Skip unsetgate(), because the same itd[] entry is overwritten in
Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.137.2.2 src/sys/arch/x86/x86/x86_machdep.c:1.137.2.3
--- src/sys/arch/x86/x86/x86_machdep.c:1.137.2.2 Sat Apr 11 08:06:16 2020
+++ src/sys/arch/x86/x86/x86_machdep.c Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: x86_machdep.c,v 1.137.2.2 2020/04/11 08:06:16 bouyer Exp $ */
+/* $NetBSD: x86_machdep.c,v 1.137.2.3 2020/04/11 18:26:07 bouyer Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.137.2.2 2020/04/11 08:06:16 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.137.2.3 2020/04/11 18:26:07 bouyer Exp $");
#include "opt_modular.h"
#include "opt_physmem.h"
@@ -307,7 +307,11 @@ cpu_need_resched(struct cpu_info *ci, st
#ifdef __HAVE_PREEMPTION
if ((flags & RESCHED_KPREEMPT) != 0) {
if ((flags & RESCHED_REMOTE) != 0) {
+#ifdef XENPV
+ xen_send_ipi(ci, XEN_IPI_KPREEMPT);
+#else
x86_send_ipi(ci, X86_IPI_KPREEMPT);
+#endif
} else {
softint_trigger(1 << SIR_PREEMPT);
}
Index: src/sys/arch/xen/conf/files.xen
diff -u src/sys/arch/xen/conf/files.xen:1.180 src/sys/arch/xen/conf/files.xen:1.180.2.1
--- src/sys/arch/xen/conf/files.xen:1.180 Fri Apr 3 22:45:30 2020
+++ src/sys/arch/xen/conf/files.xen Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.xen,v 1.180 2020/04/03 22:45:30 ad Exp $
+# $NetBSD: files.xen,v 1.180.2.1 2020/04/11 18:26:07 bouyer Exp $
# NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp
# NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp
@@ -148,6 +148,7 @@ file arch/xen/x86/pintr.c machdep & dom
file arch/xen/x86/xen_ipi.c multiprocessor & xenpv
file arch/x86/x86/idt.c machdep
file arch/x86/x86/intr.c machdep & xenpvhvm
+file arch/x86/x86/x86_softintr.c machdep
file arch/x86/x86/ipi.c xenpvhvm
file arch/x86/x86/pmap.c machdep
file arch/x86/x86/x86_tlb.c machdep
Index: src/sys/arch/xen/include/intrdefs.h
diff -u src/sys/arch/xen/include/intrdefs.h:1.15 src/sys/arch/xen/include/intrdefs.h:1.15.2.1
--- src/sys/arch/xen/include/intrdefs.h:1.15 Fri Apr 3 22:20:36 2020
+++ src/sys/arch/xen/include/intrdefs.h Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.15 2020/04/03 22:20:36 ad Exp $ */
+/* $NetBSD: intrdefs.h,v 1.15.2.1 2020/04/11 18:26:07 bouyer Exp $ */
/* This file co-exists, and is included via machine/intrdefs.h */
@@ -14,9 +14,10 @@
#define XEN_IPI_HVCB 0x00000010
#define XEN_IPI_GENERIC 0x00000020
#define XEN_IPI_AST 0x00000040
+#define XEN_IPI_KPREEMPT 0x00000080
/* Note: IPI_KICK does not have a handler. */
-#define XEN_NIPIS 7
+#define XEN_NIPIS 8
/* The number of 'irqs' that XEN understands */
#define NUM_XEN_IRQS 256
@@ -24,6 +25,6 @@
#define XEN_IPI_NAMES { "halt IPI", "FPU synch IPI", \
"DDB IPI", "xcall IPI", \
"HVCB IPI", "generic IPI", \
- "AST IPI" }
+ "AST IPI", "kpreempt IPI" }
#endif /* _XEN_INTRDEFS_H_ */
Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u src/sys/arch/xen/x86/xen_ipi.c:1.35 src/sys/arch/xen/x86/xen_ipi.c:1.35.6.1
--- src/sys/arch/xen/x86/xen_ipi.c:1.35 Sun Dec 1 15:34:46 2019
+++ src/sys/arch/xen/x86/xen_ipi.c Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.35.6.1 2020/04/11 18:26:07 bouyer Exp $ */
/*-
* Copyright (c) 2011, 2019 The NetBSD Foundation, Inc.
@@ -33,10 +33,10 @@
/*
* Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $");
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.1 2020/04/11 18:26:07 bouyer Exp $");
*/
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35 2019/12/01 15:34:46 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.35.6.1 2020/04/11 18:26:07 bouyer Exp $");
#include "opt_ddb.h"
@@ -72,6 +72,7 @@ static void xen_ipi_xcall(struct cpu_inf
static void xen_ipi_hvcb(struct cpu_info *, struct intrframe *);
static void xen_ipi_generic(struct cpu_info *, struct intrframe *);
static void xen_ipi_ast(struct cpu_info *, struct intrframe *);
+static void xen_ipi_kpreempt(struct cpu_info *ci, struct intrframe *);
static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
{ /* In order of priority (see: xen/include/intrdefs.h */
@@ -85,7 +86,8 @@ static void (*ipifunc[XEN_NIPIS])(struct
xen_ipi_xcall,
xen_ipi_hvcb,
xen_ipi_generic,
- xen_ipi_ast
+ xen_ipi_ast,
+ xen_ipi_kpreempt
};
static int
@@ -342,3 +344,9 @@ xen_ipi_hvcb(struct cpu_info *ci, struct
hypervisor_force_callback();
}
+
+static void
+xen_ipi_kpreempt(struct cpu_info *ci, struct intrframe * intrf)
+{
+ softint_trigger(1 << SIR_PREEMPT);
+}
Index: src/sys/arch/xen/x86/xenfunc.c
diff -u src/sys/arch/xen/x86/xenfunc.c:1.26 src/sys/arch/xen/x86/xenfunc.c:1.26.8.1
--- src/sys/arch/xen/x86/xenfunc.c:1.26 Sat May 4 11:15:49 2019
+++ src/sys/arch/xen/x86/xenfunc.c Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xenfunc.c,v 1.26 2019/05/04 11:15:49 kre Exp $ */
+/* $NetBSD: xenfunc.c,v 1.26.8.1 2020/04/11 18:26:07 bouyer Exp $ */
/*
* Copyright (c) 2004 Christian Limpach.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.26 2019/05/04 11:15:49 kre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xenfunc.c,v 1.26.8.1 2020/04/11 18:26:07 bouyer Exp $");
#include <sys/param.h>
@@ -61,6 +61,7 @@ lidt(struct region_descriptor *rd)
* will be available at the boot stage when this is called.
*/
static char xen_idt_page[PAGE_SIZE] __attribute__((__aligned__ (PAGE_SIZE)));
+ kpreempt_disable();
memset(xen_idt_page, 0, PAGE_SIZE);
struct trap_info *xen_idt = (void * )xen_idt_page;
@@ -96,6 +97,7 @@ lidt(struct region_descriptor *rd)
/* reset */
pmap_changeprot_local((vaddr_t) xen_idt, VM_PROT_READ|VM_PROT_WRITE);
#endif /* __x86_64 */
+ kpreempt_enable();
}
void
@@ -256,6 +258,12 @@ rcr2(void)
return curcpu()->ci_vcpu->arch.cr2;
}
+void
+lcr2(register_t v)
+{
+ curcpu()->ci_vcpu->arch.cr2 = v;
+}
+
#ifdef __x86_64__
void
setusergs(int gssel)
Index: src/sys/arch/xen/xen/clock.c
diff -u src/sys/arch/xen/xen/clock.c:1.80 src/sys/arch/xen/xen/clock.c:1.80.6.1
--- src/sys/arch/xen/xen/clock.c:1.80 Wed Oct 16 18:29:49 2019
+++ src/sys/arch/xen/xen/clock.c Sat Apr 11 18:26:07 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.80 2019/10/16 18:29:49 christos Exp $ */
+/* $NetBSD: clock.c,v 1.80.6.1 2020/04/11 18:26:07 bouyer Exp $ */
/*-
* Copyright (c) 2017, 2018 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
#endif
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.80 2019/10/16 18:29:49 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.80.6.1 2020/04/11 18:26:07 bouyer Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -501,6 +501,7 @@ xen_wallclock_time(struct timespec *tsp)
struct xen_wallclock_ticket ticket;
uint64_t systime_ns;
+ int s = splsched(); /* make sure we won't be interrupted */
/* Read the last wall clock sample from the hypervisor. */
do {
xen_wallclock_enter(&ticket);
@@ -510,6 +511,7 @@ xen_wallclock_time(struct timespec *tsp)
/* Get the global system time. */
systime_ns = xen_global_systime_ns();
+ splx(s);
/* Add the system time to the wall clock time. */
systime_ns += tsp->tv_nsec;
@@ -530,7 +532,6 @@ xen_global_systime_ns(void)
{
struct cpu_info *ci;
uint64_t local, global, result;
- int bound;
/*
* Find the local timecount on this CPU, and make sure it does
@@ -540,7 +541,7 @@ xen_global_systime_ns(void)
*
* XXX Can we avoid retrying if the CAS fails?
*/
- bound = curlwp_bind();
+ int s = splsched(); /* make sure we won't be interrupted */
ci = curcpu();
do {
local = xen_vcputime_systime_ns();
@@ -555,7 +556,7 @@ xen_global_systime_ns(void)
} while (atomic_cas_64(&xen_global_systime_ns_stamp, global, result)
!= global);
KASSERT(ci == curcpu());
- curlwp_bindx(bound);
+ splx(s);
return result;
}
Added files:
Index: src/sys/arch/x86/x86/x86_softintr.c
diff -u /dev/null src/sys/arch/x86/x86/x86_softintr.c:1.1.2.1
--- /dev/null Sat Apr 11 18:26:08 2020
+++ src/sys/arch/x86/x86/x86_softintr.c Sat Apr 11 18:26:07 2020
@@ -0,0 +1,289 @@
+/* $NetBSD: x86_softintr.c,v 1.1.2.1 2020/04/11 18:26:07 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Doran, and by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright 2002 (c) Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Frank van der Linden for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)isa.c 7.2 (Berkeley) 5/13/91
+ */
+
+/*-
+ * Copyright (c) 1993, 1994 Charles Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)isa.c 7.2 (Berkeley) 5/13/91
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: x86_softintr.c,v 1.1.2.1 2020/04/11 18:26:07 bouyer Exp $");
+
+#include <sys/kmem.h>
+#include <sys/proc.h>
+#include <sys/intr.h>
+
+struct pic softintr_pic = {
+ .pic_name = "softintr_fakepic",
+ .pic_type = PIC_SOFT,
+ .pic_vecbase = 0,
+ .pic_apicid = 0,
+ .pic_lock = __SIMPLELOCK_UNLOCKED,
+};
+
+/*
+ * Recalculate the interrupt masks from scratch.
+ * During early boot, anything goes and we are always called on the BP.
+ * When the system is up and running:
+ *
+ * => called with ci == curcpu()
+ * => cpu_lock held by the initiator
+ * => interrupts disabled on-chip (PSL_I)
+ *
+ * Do not call printf(), kmem_free() or other "heavyweight" routines
+ * from here. This routine must be quick and must not block.
+ */
+void
+x86_intr_calculatemasks(struct cpu_info *ci)
+{
+ int irq, level, unusedirqs, intrlevel[MAX_INTR_SOURCES];
+ struct intrhand *q;
+
+ /* First, figure out which levels each IRQ uses. */
+ unusedirqs = 0xffffffff;
+ for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
+ int levels = 0;
+
+ if (ci->ci_isources[irq] == NULL) {
+ intrlevel[irq] = 0;
+ continue;
+ }
+ for (q = ci->ci_isources[irq]->is_handlers; q; q = q->ih_next)
+ levels |= 1U << q->ih_level;
+ intrlevel[irq] = levels;
+ if (levels)
+ unusedirqs &= ~(1U << irq);
+ }
+
+ /* Then figure out which IRQs use each level. */
+ for (level = 0; level < NIPL; level++) {
+ int irqs = 0;
+ for (irq = 0; irq < MAX_INTR_SOURCES; irq++)
+ if (intrlevel[irq] & (1U << level))
+ irqs |= 1U << irq;
+ ci->ci_imask[level] = irqs | unusedirqs;
+ }
+
+ for (level = 0; level<(NIPL-1); level++)
+ ci->ci_imask[level+1] |= ci->ci_imask[level];
+
+ for (irq = 0; irq < MAX_INTR_SOURCES; irq++) {
+ int maxlevel = IPL_NONE;
+ int minlevel = IPL_HIGH;
+
+ if (ci->ci_isources[irq] == NULL)
+ continue;
+ for (q = ci->ci_isources[irq]->is_handlers; q;
+ q = q->ih_next) {
+ if (q->ih_level < minlevel)
+ minlevel = q->ih_level;
+ if (q->ih_level > maxlevel)
+ maxlevel = q->ih_level;
+ }
+ ci->ci_isources[irq]->is_maxlevel = maxlevel;
+ ci->ci_isources[irq]->is_minlevel = minlevel;
+ }
+
+ for (level = 0; level < NIPL; level++)
+ ci->ci_iunmask[level] = ~ci->ci_imask[level];
+}
+
+
+
+#if defined(__HAVE_PREEMPTION)
+struct intrhand fake_preempt_intrhand;
+
+void
+x86_init_preempt(struct cpu_info *ci)
+{
+ struct intrsource *isp;
+ isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
+ isp->is_recurse = Xrecurse_preempt;
+ isp->is_resume = Xresume_preempt;
+ fake_preempt_intrhand.ih_level = IPL_PREEMPT;
+ isp->is_handlers = &fake_preempt_intrhand;
+ isp->is_pic = &softintr_pic;
+ ci->ci_isources[SIR_PREEMPT] = isp;
+}
+#endif
+
+#if defined(__HAVE_FAST_SOFTINTS)
+struct intrhand fake_softclock_intrhand;
+struct intrhand fake_softnet_intrhand;
+struct intrhand fake_softserial_intrhand;
+struct intrhand fake_softbio_intrhand;
+
+void
+softint_init_md(lwp_t *l, u_int level, uintptr_t *machdep)
+{
+ struct intrsource *isp;
+ struct cpu_info *ci;
+ u_int sir;
+
+ ci = l->l_cpu;
+
+ isp = kmem_zalloc(sizeof(*isp), KM_SLEEP);
+ isp->is_recurse = Xsoftintr;
+ isp->is_resume = Xsoftintr;
+ isp->is_pic = &softintr_pic;
+
+ switch (level) {
+ case SOFTINT_BIO:
+ sir = SIR_BIO;
+ fake_softbio_intrhand.ih_level = IPL_SOFTBIO;
+ isp->is_handlers = &fake_softbio_intrhand;
+ break;
+ case SOFTINT_NET:
+ sir = SIR_NET;
+ fake_softnet_intrhand.ih_level = IPL_SOFTNET;
+ isp->is_handlers = &fake_softnet_intrhand;
+ break;
+ case SOFTINT_SERIAL:
+ sir = SIR_SERIAL;
+ fake_softserial_intrhand.ih_level = IPL_SOFTSERIAL;
+ isp->is_handlers = &fake_softserial_intrhand;
+ break;
+ case SOFTINT_CLOCK:
+ sir = SIR_CLOCK;
+ fake_softclock_intrhand.ih_level = IPL_SOFTCLOCK;
+ isp->is_handlers = &fake_softclock_intrhand;
+ break;
+ default:
+ panic("softint_init_md");
+ }
+
+ KASSERT(ci->ci_isources[sir] == NULL);
+
+ *machdep = (1 << sir);
+ ci->ci_isources[sir] = isp;
+ ci->ci_isources[sir]->is_lwp = l;
+
+ x86_intr_calculatemasks(ci);
+}
+#endif /* __HAVE_FAST_SOFTINTS */