Fix a problem with intr_unmask() that can cause a forever-loop: - When handling the source-is-masked case in the interrupt vector, set the interrupt bit in a new ci_imasked field and ensure the bit is cleared from ci_ipending. - In intr_unmask(), transfer the bit from ci_imasked to ci_ipending for non-level-sensitive interrupts (the PIC does the work for us in the level-sensitive case), and only force pending interrupts to be processed in this case. (In all cases, make sure the now-unmasked bit is cleared from ci_imasked.) Before, the bit was left in ci_ipending so as not to use edge-triggered interrupts while the source is masked, but Xspllower() relies on the pending bits getting cleared. Tested by forcing all wm(4) interrupts on my test system though an intr_mask() / softint / intr_unmask() cycle and exercising the network heavily.diff -r1.79 -r1.80 src/sys/arch/amd64/amd64/genassym.cf
(thorpej)
--- src/sys/arch/amd64/amd64/genassym.cf 2019/12/22 15:09:39 1.79
+++ src/sys/arch/amd64/amd64/genassym.cf 2019/12/30 23:32:29 1.80
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: genassym.cf,v 1.79 2019/12/22 15:09:39 thorpej Exp $ | 1 | # $NetBSD: genassym.cf,v 1.80 2019/12/30 23:32:29 thorpej Exp $ | |
2 | 2 | |||
3 | # | 3 | # | |
4 | # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. | 4 | # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | # All rights reserved. | 5 | # All rights reserved. | |
6 | # | 6 | # | |
7 | # This code is derived from software contributed to The NetBSD Foundation | 7 | # This code is derived from software contributed to The NetBSD Foundation | |
8 | # by Charles M. Hannum, and by Andrew Doran. | 8 | # by Charles M. Hannum, and by Andrew Doran. | |
9 | # | 9 | # | |
10 | # Redistribution and use in source and binary forms, with or without | 10 | # Redistribution and use in source and binary forms, with or without | |
11 | # modification, are permitted provided that the following conditions | 11 | # modification, are permitted provided that the following conditions | |
12 | # are met: | 12 | # are met: | |
13 | # 1. Redistributions of source code must retain the above copyright | 13 | # 1. Redistributions of source code must retain the above copyright | |
14 | # notice, this list of conditions and the following disclaimer. | 14 | # notice, this list of conditions and the following disclaimer. | |
@@ -242,26 +242,27 @@ define CPU_INFO_RSP0 offsetof(struct cp | @@ -242,26 +242,27 @@ define CPU_INFO_RSP0 offsetof(struct cp | |||
242 | define CPU_INFO_URSP0 offsetof(struct cpu_info, ci_svs_ursp0) | 242 | define CPU_INFO_URSP0 offsetof(struct cpu_info, ci_svs_ursp0) | |
243 | define CPU_INFO_KRSP0 offsetof(struct cpu_info, ci_svs_krsp0) | 243 | define CPU_INFO_KRSP0 offsetof(struct cpu_info, ci_svs_krsp0) | |
244 | endif | 244 | endif | |
245 | define CPU_INFO_NSYSCALL offsetof(struct cpu_info, ci_data.cpu_nsyscall) | 245 | define CPU_INFO_NSYSCALL offsetof(struct cpu_info, ci_data.cpu_nsyscall) | |
246 | define CPU_INFO_NTRAP offsetof(struct cpu_info, ci_data.cpu_ntrap) | 246 | define CPU_INFO_NTRAP offsetof(struct cpu_info, ci_data.cpu_ntrap) | |
247 | define CPU_INFO_NINTR offsetof(struct cpu_info, ci_data.cpu_nintr) | 247 | define CPU_INFO_NINTR offsetof(struct cpu_info, ci_data.cpu_nintr) | |
248 | define CPU_INFO_CURPRIORITY offsetof(struct cpu_info, ci_schedstate.spc_curpriority) | 248 | define CPU_INFO_CURPRIORITY offsetof(struct cpu_info, ci_schedstate.spc_curpriority) | |
249 | 249 | |||
250 | define CPU_INFO_GDT offsetof(struct cpu_info, ci_gdt) | 250 | define CPU_INFO_GDT offsetof(struct cpu_info, ci_gdt) | |
251 | define CPU_INFO_ILEVEL offsetof(struct cpu_info, ci_ilevel) | 251 | define CPU_INFO_ILEVEL offsetof(struct cpu_info, ci_ilevel) | |
252 | define CPU_INFO_IDEPTH offsetof(struct cpu_info, ci_idepth) | 252 | define CPU_INFO_IDEPTH offsetof(struct cpu_info, ci_idepth) | |
253 | if !defined(XENPV) | 253 | if !defined(XENPV) | |
254 | define CPU_INFO_IPENDING offsetof(struct cpu_info, ci_ipending) | 254 | define CPU_INFO_IPENDING offsetof(struct cpu_info, ci_ipending) | |
255 | define CPU_INFO_IMASKED offsetof(struct cpu_info, ci_imasked) | |||
255 | define CPU_INFO_IMASK offsetof(struct cpu_info, ci_imask) | 256 | define CPU_INFO_IMASK offsetof(struct cpu_info, ci_imask) | |
256 | define CPU_INFO_IUNMASK offsetof(struct cpu_info, ci_iunmask) | 257 | define CPU_INFO_IUNMASK offsetof(struct cpu_info, ci_iunmask) | |
257 | define CPU_INFO_ISOURCES offsetof(struct cpu_info, ci_isources) | 258 | define CPU_INFO_ISOURCES offsetof(struct cpu_info, ci_isources) | |
258 | endif | 259 | endif | |
259 | define CPU_INFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count) | 260 | define CPU_INFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count) | |
260 | define CPU_INFO_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl) | 261 | define CPU_INFO_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl) | |
261 | define CPU_INFO_CPUID offsetof(struct cpu_info, ci_cpuid) | 262 | define CPU_INFO_CPUID offsetof(struct cpu_info, ci_cpuid) | |
262 | define CPU_INFO_ISTATE offsetof(struct cpu_info, ci_istate) | 263 | define CPU_INFO_ISTATE offsetof(struct cpu_info, ci_istate) | |
263 | define CPU_INFO_CC_SKEW offsetof(struct cpu_info, ci_data.cpu_cc_skew) | 264 | define CPU_INFO_CC_SKEW offsetof(struct cpu_info, ci_data.cpu_cc_skew) | |
264 | 265 | |||
265 | define ACPI_SUSPEND_GDT offsetof(struct cpu_info, ci_suspend_gdt) | 266 | define ACPI_SUSPEND_GDT offsetof(struct cpu_info, ci_suspend_gdt) | |
266 | define ACPI_SUSPEND_IDT offsetof(struct cpu_info, ci_suspend_idt) | 267 | define ACPI_SUSPEND_IDT offsetof(struct cpu_info, ci_suspend_idt) | |
267 | define ACPI_SUSPEND_TR offsetof(struct cpu_info, ci_suspend_tr) | 268 | define ACPI_SUSPEND_TR offsetof(struct cpu_info, ci_suspend_tr) |
--- src/sys/arch/amd64/amd64/vector.S 2019/12/22 15:09:39 1.72
+++ src/sys/arch/amd64/amd64/vector.S 2019/12/30 23:32:29 1.73
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vector.S,v 1.72 2019/12/22 15:09:39 thorpej Exp $ */ | 1 | /* $NetBSD: vector.S,v 1.73 2019/12/30 23:32:29 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 1998, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Charles M. Hannum and by Andrew Doran. | 8 | * by Charles M. Hannum and by Andrew Doran. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -382,53 +382,58 @@ IDTVEC(handle_ ## name ## num) ;\ | @@ -382,53 +382,58 @@ IDTVEC(handle_ ## name ## num) ;\ | |||
382 | movl IS_MAXLEVEL(%r14),%ebx ;\ | 382 | movl IS_MAXLEVEL(%r14),%ebx ;\ | |
383 | movl CPUVAR(ILEVEL),%r13d ;\ | 383 | movl CPUVAR(ILEVEL),%r13d ;\ | |
384 | cmpl %ebx,%r13d ;\ | 384 | cmpl %ebx,%r13d ;\ | |
385 | jae 10f /* currently masked; hold it */ ;\ | 385 | jae 10f /* currently masked; hold it */ ;\ | |
386 | incq CPUVAR(NINTR) /* statistical info */ ;\ | 386 | incq CPUVAR(NINTR) /* statistical info */ ;\ | |
387 | incq IS_EVCNT(%r14) ;\ | 387 | incq IS_EVCNT(%r14) ;\ | |
388 | 1: \ | 388 | 1: \ | |
389 | pushq %r13 /* save for Xdoreti */ ;\ | 389 | pushq %r13 /* save for Xdoreti */ ;\ | |
390 | movl %ebx,CPUVAR(ILEVEL) ;\ | 390 | movl %ebx,CPUVAR(ILEVEL) ;\ | |
391 | sti ;\ | 391 | sti ;\ | |
392 | incl CPUVAR(IDEPTH) ;\ | 392 | incl CPUVAR(IDEPTH) ;\ | |
393 | movq IS_HANDLERS(%r14),%rbx ;\ | 393 | movq IS_HANDLERS(%r14),%rbx ;\ | |
394 | cmpl $0,IS_MASK_COUNT(%r14) /* source currently masked? */ ;\ | 394 | cmpl $0,IS_MASK_COUNT(%r14) /* source currently masked? */ ;\ | |
395 | jne 7f /* yes, hold it */ ;\ | 395 | jne 12f /* yes, hold it */ ;\ | |
396 | 6: \ | 396 | 6: \ | |
397 | movl IH_LEVEL(%rbx),%r12d ;\ | 397 | movl IH_LEVEL(%rbx),%r12d ;\ | |
398 | cmpl %r13d,%r12d ;\ | 398 | cmpl %r13d,%r12d ;\ | |
399 | jle 7f ;\ | 399 | jle 7f ;\ | |
400 | movq %rsp,%rsi ;\ | 400 | movq %rsp,%rsi ;\ | |
401 | movq IH_ARG(%rbx),%rdi ;\ | 401 | movq IH_ARG(%rbx),%rdi ;\ | |
402 | movl %r12d,CPUVAR(ILEVEL) ;\ | 402 | movl %r12d,CPUVAR(ILEVEL) ;\ | |
403 | call *IH_FUN(%rbx) /* call it */ ;\ | 403 | call *IH_FUN(%rbx) /* call it */ ;\ | |
404 | movq IH_NEXT(%rbx),%rbx /* next handler in chain */ ;\ | 404 | movq IH_NEXT(%rbx),%rbx /* next handler in chain */ ;\ | |
405 | testq %rbx,%rbx ;\ | 405 | testq %rbx,%rbx ;\ | |
406 | jnz 6b ;\ | 406 | jnz 6b ;\ | |
407 | 5: \ | 407 | 5: \ | |
408 | cmpl $0,IS_MASK_COUNT(%r14) /* source now masked? */ ;\ | 408 | cmpl $0,IS_MASK_COUNT(%r14) /* source now masked? */ ;\ | |
409 | jne 7f /* yes, deal */ ;\ | 409 | jne 12f /* yes, deal */ ;\ | |
410 | cli ;\ | 410 | cli ;\ | |
411 | unmask(num) /* unmask it in hardware */ ;\ | 411 | unmask(num) /* unmask it in hardware */ ;\ | |
412 | late_ack(num) ;\ | 412 | late_ack(num) ;\ | |
413 | sti ;\ | 413 | sti ;\ | |
414 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | 414 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | |
415 | 7: \ | 415 | 7: \ | |
416 | cli ;\ | 416 | cli ;\ | |
417 | orl $(1 << num),CPUVAR(IPENDING) ;\ | 417 | orl $(1 << num),CPUVAR(IPENDING) ;\ | |
418 | level_mask(num) ;\ | 418 | 8: level_mask(num) ;\ | |
419 | late_ack(num) ;\ | 419 | late_ack(num) ;\ | |
420 | sti ;\ | 420 | sti ;\ | |
421 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | 421 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | |
422 | 12: \ | |||
423 | cli ;\ | |||
424 | orl $(1 << num),CPUVAR(IMASKED) ;\ | |||
425 | btrl $(num),CPUVAR(IPENDING) ;\ | |||
426 | jmp 8b ;\ | |||
422 | 10: \ | 427 | 10: \ | |
423 | cli ;\ | 428 | cli ;\ | |
424 | orl $(1 << num),CPUVAR(IPENDING) ;\ | 429 | orl $(1 << num),CPUVAR(IPENDING) ;\ | |
425 | level_mask(num) ;\ | 430 | level_mask(num) ;\ | |
426 | late_ack(num) ;\ | 431 | late_ack(num) ;\ | |
427 | INTRFASTEXIT ;\ | 432 | INTRFASTEXIT ;\ | |
428 | 9: \ | 433 | 9: \ | |
429 | unmask(num) ;\ | 434 | unmask(num) ;\ | |
430 | late_ack(num) ;\ | 435 | late_ack(num) ;\ | |
431 | INTRFASTEXIT ;\ | 436 | INTRFASTEXIT ;\ | |
432 | IDTVEC_END(handle_ ## name ## num) ;\ | 437 | IDTVEC_END(handle_ ## name ## num) ;\ | |
433 | TEXT_USER_BEGIN ;\ | 438 | TEXT_USER_BEGIN ;\ | |
434 | IDTVEC(intr_ ## name ## num) ;\ | 439 | IDTVEC(intr_ ## name ## num) ;\ |
--- src/sys/arch/i386/i386/genassym.cf 2019/12/22 15:09:39 1.116
+++ src/sys/arch/i386/i386/genassym.cf 2019/12/30 23:32:29 1.117
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | # $NetBSD: genassym.cf,v 1.116 2019/12/22 15:09:39 thorpej Exp $ | 1 | # $NetBSD: genassym.cf,v 1.117 2019/12/30 23:32:29 thorpej Exp $ | |
2 | 2 | |||
3 | # | 3 | # | |
4 | # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. | 4 | # Copyright (c) 1998, 2006, 2007, 2008 The NetBSD Foundation, Inc. | |
5 | # All rights reserved. | 5 | # All rights reserved. | |
6 | # | 6 | # | |
7 | # This code is derived from software contributed to The NetBSD Foundation | 7 | # This code is derived from software contributed to The NetBSD Foundation | |
8 | # by Charles M. Hannum, and by Andrew Doran. | 8 | # by Charles M. Hannum, and by Andrew Doran. | |
9 | # | 9 | # | |
10 | # Redistribution and use in source and binary forms, with or without | 10 | # Redistribution and use in source and binary forms, with or without | |
11 | # modification, are permitted provided that the following conditions | 11 | # modification, are permitted provided that the following conditions | |
12 | # are met: | 12 | # are met: | |
13 | # 1. Redistributions of source code must retain the above copyright | 13 | # 1. Redistributions of source code must retain the above copyright | |
14 | # notice, this list of conditions and the following disclaimer. | 14 | # notice, this list of conditions and the following disclaimer. | |
@@ -264,26 +264,27 @@ define IOMAP_VALIDOFF IOMAP_VALIDOFF | @@ -264,26 +264,27 @@ define IOMAP_VALIDOFF IOMAP_VALIDOFF | |||
264 | define CPU_INFO_NSYSCALL offsetof(struct cpu_info, ci_data.cpu_nsyscall) | 264 | define CPU_INFO_NSYSCALL offsetof(struct cpu_info, ci_data.cpu_nsyscall) | |
265 | define CPU_INFO_NTRAP offsetof(struct cpu_info, ci_data.cpu_ntrap) | 265 | define CPU_INFO_NTRAP offsetof(struct cpu_info, ci_data.cpu_ntrap) | |
266 | define CPU_INFO_NINTR offsetof(struct cpu_info, ci_data.cpu_nintr) | 266 | define CPU_INFO_NINTR offsetof(struct cpu_info, ci_data.cpu_nintr) | |
267 | define CPU_INFO_CURPRIORITY offsetof(struct cpu_info, ci_schedstate.spc_curpriority) | 267 | define CPU_INFO_CURPRIORITY offsetof(struct cpu_info, ci_schedstate.spc_curpriority) | |
268 | define CPU_INFO_CC_SKEW offsetof(struct cpu_info, ci_data.cpu_cc_skew) | 268 | define CPU_INFO_CC_SKEW offsetof(struct cpu_info, ci_data.cpu_cc_skew) | |
269 | 269 | |||
270 | 270 | |||
271 | define CPU_INFO_VENDOR offsetof(struct cpu_info, ci_vendor[0]) | 271 | define CPU_INFO_VENDOR offsetof(struct cpu_info, ci_vendor[0]) | |
272 | define CPU_INFO_SIGNATURE offsetof(struct cpu_info, ci_signature) | 272 | define CPU_INFO_SIGNATURE offsetof(struct cpu_info, ci_signature) | |
273 | 273 | |||
274 | define CPU_INFO_GDT offsetof(struct cpu_info, ci_gdt) | 274 | define CPU_INFO_GDT offsetof(struct cpu_info, ci_gdt) | |
275 | if !defined(XENPV) | 275 | if !defined(XENPV) | |
276 | define CPU_INFO_IPENDING offsetof(struct cpu_info, ci_ipending) | 276 | define CPU_INFO_IPENDING offsetof(struct cpu_info, ci_ipending) | |
277 | define CPU_INFO_IMASKED offsetof(struct cpu_info, ci_imasked) | |||
277 | define CPU_INFO_IMASK offsetof(struct cpu_info, ci_imask) | 278 | define CPU_INFO_IMASK offsetof(struct cpu_info, ci_imask) | |
278 | define CPU_INFO_ISOURCES offsetof(struct cpu_info, ci_isources) | 279 | define CPU_INFO_ISOURCES offsetof(struct cpu_info, ci_isources) | |
279 | define CPU_INFO_IUNMASK offsetof(struct cpu_info, ci_iunmask) | 280 | define CPU_INFO_IUNMASK offsetof(struct cpu_info, ci_iunmask) | |
280 | endif | 281 | endif | |
281 | define CPU_INFO_ILEVEL offsetof(struct cpu_info, ci_ilevel) | 282 | define CPU_INFO_ILEVEL offsetof(struct cpu_info, ci_ilevel) | |
282 | define CPU_INFO_IDEPTH offsetof(struct cpu_info, ci_idepth) | 283 | define CPU_INFO_IDEPTH offsetof(struct cpu_info, ci_idepth) | |
283 | define CPU_INFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count) | 284 | define CPU_INFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count) | |
284 | define CPU_INFO_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl) | 285 | define CPU_INFO_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl) | |
285 | define CPU_INFO_INTRSTACK offsetof(struct cpu_info, ci_intrstack) | 286 | define CPU_INFO_INTRSTACK offsetof(struct cpu_info, ci_intrstack) | |
286 | define CPU_INFO_ISTATE offsetof(struct cpu_info, ci_istate) | 287 | define CPU_INFO_ISTATE offsetof(struct cpu_info, ci_istate) | |
287 | 288 | |||
288 | define ACPI_SUSPEND_GDT offsetof(struct cpu_info, ci_suspend_gdt) | 289 | define ACPI_SUSPEND_GDT offsetof(struct cpu_info, ci_suspend_gdt) | |
289 | define ACPI_SUSPEND_IDT offsetof(struct cpu_info, ci_suspend_idt) | 290 | define ACPI_SUSPEND_IDT offsetof(struct cpu_info, ci_suspend_idt) |
--- src/sys/arch/i386/i386/vector.S 2019/12/22 15:09:39 1.84
+++ src/sys/arch/i386/i386/vector.S 2019/12/30 23:32:29 1.85
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vector.S,v 1.84 2019/12/22 15:09:39 thorpej Exp $ */ | 1 | /* $NetBSD: vector.S,v 1.85 2019/12/30 23:32:29 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright 2002 (c) Wasabi Systems, Inc. | 4 | * Copyright 2002 (c) Wasabi Systems, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Written by Frank van der Linden for Wasabi Systems, Inc. | 7 | * Written by Frank van der Linden for Wasabi Systems, Inc. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -55,27 +55,27 @@ | @@ -55,27 +55,27 @@ | |||
55 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 55 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
56 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 56 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
57 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 57 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
58 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 58 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
59 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 59 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
60 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 60 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
61 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 61 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
62 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 62 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
63 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 63 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
64 | * POSSIBILITY OF SUCH DAMAGE. | 64 | * POSSIBILITY OF SUCH DAMAGE. | |
65 | */ | 65 | */ | |
66 | 66 | |||
67 | #include <machine/asm.h> | 67 | #include <machine/asm.h> | |
68 | __KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.84 2019/12/22 15:09:39 thorpej Exp $"); | 68 | __KERNEL_RCSID(0, "$NetBSD: vector.S,v 1.85 2019/12/30 23:32:29 thorpej Exp $"); | |
69 | 69 | |||
70 | #include "opt_ddb.h" | 70 | #include "opt_ddb.h" | |
71 | #include "opt_multiprocessor.h" | 71 | #include "opt_multiprocessor.h" | |
72 | #include "opt_xen.h" | 72 | #include "opt_xen.h" | |
73 | #include "opt_dtrace.h" | 73 | #include "opt_dtrace.h" | |
74 | 74 | |||
75 | #include <machine/i8259.h> | 75 | #include <machine/i8259.h> | |
76 | #include <machine/i82093reg.h> | 76 | #include <machine/i82093reg.h> | |
77 | #include <machine/i82489reg.h> | 77 | #include <machine/i82489reg.h> | |
78 | #include <machine/frameasm.h> | 78 | #include <machine/frameasm.h> | |
79 | #include <machine/segments.h> | 79 | #include <machine/segments.h> | |
80 | #include <machine/specialreg.h> | 80 | #include <machine/specialreg.h> | |
81 | #include <machine/trap.h> | 81 | #include <machine/trap.h> | |
@@ -399,51 +399,56 @@ IDTVEC(intr_ ## name ## num) ;\ | @@ -399,51 +399,56 @@ IDTVEC(intr_ ## name ## num) ;\ | |||
399 | jae 10f /* currently masked; hold it */ ;\ | 399 | jae 10f /* currently masked; hold it */ ;\ | |
400 | addl $1,CPUVAR(NINTR) /* statistical info */ ;\ | 400 | addl $1,CPUVAR(NINTR) /* statistical info */ ;\ | |
401 | adcl $0,CPUVAR(NINTR)+4 ;\ | 401 | adcl $0,CPUVAR(NINTR)+4 ;\ | |
402 | addl $1,IS_EVCNTLO(%ebp) /* inc event counter */ ;\ | 402 | addl $1,IS_EVCNTLO(%ebp) /* inc event counter */ ;\ | |
403 | adcl $0,IS_EVCNTHI(%ebp) ;\ | 403 | adcl $0,IS_EVCNTHI(%ebp) ;\ | |
404 | 1: \ | 404 | 1: \ | |
405 | pushl %esi /* if_ppi */ ;\ | 405 | pushl %esi /* if_ppi */ ;\ | |
406 | movl %ebx,CPUVAR(ILEVEL) ;\ | 406 | movl %ebx,CPUVAR(ILEVEL) ;\ | |
407 | /* switch stack if necessary, and push a ptr to our intrframe */ \ | 407 | /* switch stack if necessary, and push a ptr to our intrframe */ \ | |
408 | IDEPTH_INCR ;\ | 408 | IDEPTH_INCR ;\ | |
409 | sti ;\ | 409 | sti ;\ | |
410 | movl IS_HANDLERS(%ebp),%ebx ;\ | 410 | movl IS_HANDLERS(%ebp),%ebx ;\ | |
411 | cmpl $0,IS_MASK_COUNT(%ebp) /* source currently masked? */ ;\ | 411 | cmpl $0,IS_MASK_COUNT(%ebp) /* source currently masked? */ ;\ | |
412 | jne 7f /* yes, hold it */ ;\ | 412 | jne 12f /* yes, hold it */ ;\ | |
413 | 6: \ | 413 | 6: \ | |
414 | movl IH_LEVEL(%ebx),%edi ;\ | 414 | movl IH_LEVEL(%ebx),%edi ;\ | |
415 | cmpl %esi,%edi ;\ | 415 | cmpl %esi,%edi ;\ | |
416 | jle 7f ;\ | 416 | jle 7f ;\ | |
417 | pushl IH_ARG(%ebx) ;\ | 417 | pushl IH_ARG(%ebx) ;\ | |
418 | movl IH_FUN(%ebx),%eax ;\ | 418 | movl IH_FUN(%ebx),%eax ;\ | |
419 | movl %edi,CPUVAR(ILEVEL) ;\ | 419 | movl %edi,CPUVAR(ILEVEL) ;\ | |
420 | movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\ | 420 | movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\ | |
421 | call *%eax /* call it */ ;\ | 421 | call *%eax /* call it */ ;\ | |
422 | addl $4,%esp /* toss the arg */ ;\ | 422 | addl $4,%esp /* toss the arg */ ;\ | |
423 | testl %ebx,%ebx ;\ | 423 | testl %ebx,%ebx ;\ | |
424 | jnz 6b ;\ | 424 | jnz 6b ;\ | |
425 | cmpl $0,IS_MASK_COUNT(%ebp) /* source now masked? */ ;\ | 425 | cmpl $0,IS_MASK_COUNT(%ebp) /* source now masked? */ ;\ | |
426 | jne 7f /* yes, deal */ ;\ | 426 | jne 12f /* yes, deal */ ;\ | |
427 | cli ;\ | 427 | cli ;\ | |
428 | unmask(num) /* unmask it in hardware */ ;\ | 428 | unmask(num) /* unmask it in hardware */ ;\ | |
429 | late_ack(num) ;\ | 429 | late_ack(num) ;\ | |
430 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | 430 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | |
431 | 7: \ | 431 | 7: \ | |
432 | cli ;\ | 432 | cli ;\ | |
433 | orl $(1 << num),CPUVAR(IPENDING) ;\ | 433 | orl $(1 << num),CPUVAR(IPENDING) ;\ | |
434 | level_mask(num) ;\ | 434 | 8: level_mask(num) ;\ | |
435 | late_ack(num) ;\ | 435 | late_ack(num) ;\ | |
436 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | 436 | jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\ | |
437 | 12: \ | |||
438 | cli ;\ | |||
439 | orl $(1 << num),CPUVAR(IMASKED) ;\ | |||
440 | btrl $(num),CPUVAR(IPENDING) ;\ | |||
441 | jmp 8b ;\ | |||
437 | 10: \ | 442 | 10: \ | |
438 | orl $(1 << num),CPUVAR(IPENDING) ;\ | 443 | orl $(1 << num),CPUVAR(IPENDING) ;\ | |
439 | level_mask(num) ;\ | 444 | level_mask(num) ;\ | |
440 | late_ack(num) ;\ | 445 | late_ack(num) ;\ | |
441 | INTRFASTEXIT ;\ | 446 | INTRFASTEXIT ;\ | |
442 | 9: \ | 447 | 9: \ | |
443 | pushl %esp /* for unmask */ ;\ | 448 | pushl %esp /* for unmask */ ;\ | |
444 | unmask(num) ;\ | 449 | unmask(num) ;\ | |
445 | late_ack(num) ;\ | 450 | late_ack(num) ;\ | |
446 | addl $4,%esp ;\ | 451 | addl $4,%esp ;\ | |
447 | INTRFASTEXIT ;\ | 452 | INTRFASTEXIT ;\ | |
448 | IDTVEC_END(intr_ ## name ## num) | 453 | IDTVEC_END(intr_ ## name ## num) | |
449 | 454 |
--- src/sys/arch/x86/include/cpu.h 2019/12/01 15:34:46 1.115
+++ src/sys/arch/x86/include/cpu.h 2019/12/30 23:32:29 1.116
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: cpu.h,v 1.115 2019/12/01 15:34:46 ad Exp $ */ | 1 | /* $NetBSD: cpu.h,v 1.116 2019/12/30 23:32:29 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1990 The Regents of the University of California. | 4 | * Copyright (c) 1990 The Regents of the University of California. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to Berkeley by | 7 | * This code is derived from software contributed to Berkeley by | |
8 | * William Jolitz. | 8 | * William Jolitz. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -139,29 +139,31 @@ struct cpu_info { | @@ -139,29 +139,31 @@ struct cpu_info { | |||
139 | struct intrsource *ci_xsources[NIPL]; | 139 | struct intrsource *ci_xsources[NIPL]; | |
140 | uint32_t ci_xmask[NIPL]; | 140 | uint32_t ci_xmask[NIPL]; | |
141 | uint32_t ci_xunmask[NIPL]; | 141 | uint32_t ci_xunmask[NIPL]; | |
142 | uint32_t ci_xpending; /* XEN doesn't use the cmpxchg8 path */ | 142 | uint32_t ci_xpending; /* XEN doesn't use the cmpxchg8 path */ | |
143 | #endif | 143 | #endif | |
144 | 144 | |||
145 | volatile int ci_mtx_count; /* Negative count of spin mutexes */ | 145 | volatile int ci_mtx_count; /* Negative count of spin mutexes */ | |
146 | volatile int ci_mtx_oldspl; /* Old SPL at this ci_idepth */ | 146 | volatile int ci_mtx_oldspl; /* Old SPL at this ci_idepth */ | |
147 | 147 | |||
148 | /* The following must be aligned for cmpxchg8b. */ | 148 | /* The following must be aligned for cmpxchg8b. */ | |
149 | struct { | 149 | struct { | |
150 | uint32_t ipending; | 150 | uint32_t ipending; | |
151 | int ilevel; | 151 | int ilevel; | |
152 | uint32_t imasked; | |||
152 | } ci_istate __aligned(8); | 153 | } ci_istate __aligned(8); | |
153 | #define ci_ipending ci_istate.ipending | 154 | #define ci_ipending ci_istate.ipending | |
154 | #define ci_ilevel ci_istate.ilevel | 155 | #define ci_ilevel ci_istate.ilevel | |
156 | #define ci_imasked ci_istate.imasked | |||
155 | int ci_idepth; | 157 | int ci_idepth; | |
156 | void * ci_intrstack; | 158 | void * ci_intrstack; | |
157 | uint32_t ci_imask[NIPL]; | 159 | uint32_t ci_imask[NIPL]; | |
158 | uint32_t ci_iunmask[NIPL]; | 160 | uint32_t ci_iunmask[NIPL]; | |
159 | 161 | |||
160 | uint32_t ci_signature; /* X86 cpuid type (cpuid.1.%eax) */ | 162 | uint32_t ci_signature; /* X86 cpuid type (cpuid.1.%eax) */ | |
161 | uint32_t ci_vendor[4]; /* vendor string */ | 163 | uint32_t ci_vendor[4]; /* vendor string */ | |
162 | uint32_t ci_max_cpuid; /* cpuid.0:%eax */ | 164 | uint32_t ci_max_cpuid; /* cpuid.0:%eax */ | |
163 | uint32_t ci_max_ext_cpuid; /* cpuid.80000000:%eax */ | 165 | uint32_t ci_max_ext_cpuid; /* cpuid.80000000:%eax */ | |
164 | volatile uint32_t ci_lapic_counter; | 166 | volatile uint32_t ci_lapic_counter; | |
165 | 167 | |||
166 | uint32_t ci_feat_val[8]; /* X86 CPUID feature bits */ | 168 | uint32_t ci_feat_val[8]; /* X86 CPUID feature bits */ | |
167 | /* [0] basic features cpuid.1:%edx | 169 | /* [0] basic features cpuid.1:%edx |
--- src/sys/arch/x86/x86/intr.c 2019/12/22 16:50:03 1.149
+++ src/sys/arch/x86/x86/intr.c 2019/12/30 23:32:30 1.150
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: intr.c,v 1.149 2019/12/22 16:50:03 ad Exp $ */ | 1 | /* $NetBSD: intr.c,v 1.150 2019/12/30 23:32:30 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2007, 2008, 2009, 2019 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Andrew Doran, and by Jason R. Thorpe. | 8 | * by Andrew Doran, and by Jason R. Thorpe. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -123,27 +123,27 @@ | @@ -123,27 +123,27 @@ | |||
123 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 123 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
124 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 124 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
125 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 125 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
126 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 126 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
127 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 127 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
128 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 128 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
129 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 129 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
130 | * SUCH DAMAGE. | 130 | * SUCH DAMAGE. | |
131 | * | 131 | * | |
132 | * @(#)isa.c 7.2 (Berkeley) 5/13/91 | 132 | * @(#)isa.c 7.2 (Berkeley) 5/13/91 | |
133 | */ | 133 | */ | |
134 | 134 | |||
135 | #include <sys/cdefs.h> | 135 | #include <sys/cdefs.h> | |
136 | __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.149 2019/12/22 16:50:03 ad Exp $"); | 136 | __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.150 2019/12/30 23:32:30 thorpej Exp $"); | |
137 | 137 | |||
138 | #include "opt_intrdebug.h" | 138 | #include "opt_intrdebug.h" | |
139 | #include "opt_multiprocessor.h" | 139 | #include "opt_multiprocessor.h" | |
140 | #include "opt_acpi.h" | 140 | #include "opt_acpi.h" | |
141 | 141 | |||
142 | #include <sys/param.h> | 142 | #include <sys/param.h> | |
143 | #include <sys/systm.h> | 143 | #include <sys/systm.h> | |
144 | #include <sys/kernel.h> | 144 | #include <sys/kernel.h> | |
145 | #include <sys/syslog.h> | 145 | #include <sys/syslog.h> | |
146 | #include <sys/device.h> | 146 | #include <sys/device.h> | |
147 | #include <sys/kmem.h> | 147 | #include <sys/kmem.h> | |
148 | #include <sys/proc.h> | 148 | #include <sys/proc.h> | |
149 | #include <sys/errno.h> | 149 | #include <sys/errno.h> | |
@@ -1042,29 +1042,44 @@ intr_mask_xcall(void *arg1, void *arg2) | @@ -1042,29 +1042,44 @@ intr_mask_xcall(void *arg1, void *arg2) | |||
1042 | if (mask) { | 1042 | if (mask) { | |
1043 | source->is_mask_count++; | 1043 | source->is_mask_count++; | |
1044 | KASSERT(source->is_mask_count != 0); | 1044 | KASSERT(source->is_mask_count != 0); | |
1045 | if (source->is_mask_count == 1) { | 1045 | if (source->is_mask_count == 1) { | |
1046 | (*pic->pic_hwmask)(pic, ih->ih_pin); | 1046 | (*pic->pic_hwmask)(pic, ih->ih_pin); | |
1047 | } | 1047 | } | |
1048 | } else { | 1048 | } else { | |
1049 | KASSERT(source->is_mask_count != 0); | 1049 | KASSERT(source->is_mask_count != 0); | |
1050 | if (--source->is_mask_count == 0) { | 1050 | if (--source->is_mask_count == 0) { | |
1051 | /* | 1051 | /* | |
1052 | * If this interrupt source is being moved, don't | 1052 | * If this interrupt source is being moved, don't | |
1053 | * unmask it at the hw. | 1053 | * unmask it at the hw. | |
1054 | */ | 1054 | */ | |
1055 | if (! source->is_distribute_pending) | 1055 | if (! source->is_distribute_pending) { | |
1056 | (*pic->pic_hwunmask)(pic, ih->ih_pin); | 1056 | (*pic->pic_hwunmask)(pic, ih->ih_pin); | |
1057 | force_pending = true; | 1057 | } | |
1058 | ||||
1059 | /* | |||
1060 | * For level-sensitive interrupts, the hardware | |||
1061 | * will let us know. For everything else, we | |||
1062 | * need to explicitly handle interrupts that | |||
1063 | * happened when when the source was masked. | |||
1064 | */ | |||
1065 | const uint32_t bit = (1U << ih->ih_slot); | |||
1066 | if (ci->ci_imasked & bit) { | |||
1067 | ci->ci_imasked &= ~bit; | |||
1068 | if (source->is_type != IST_LEVEL) { | |||
1069 | ci->ci_ipending |= bit; | |||
1070 | force_pending = true; | |||
1071 | } | |||
1072 | } | |||
1058 | } | 1073 | } | |
1059 | } | 1074 | } | |
1060 | 1075 | |||
1061 | /* Re-enable interrupts. */ | 1076 | /* Re-enable interrupts. */ | |
1062 | x86_write_psl(psl); | 1077 | x86_write_psl(psl); | |
1063 | 1078 | |||
1064 | if (force_pending) { | 1079 | if (force_pending) { | |
1065 | /* Force processing of any pending interrupts. */ | 1080 | /* Force processing of any pending interrupts. */ | |
1066 | splx(splhigh()); | 1081 | splx(splhigh()); | |
1067 | } | 1082 | } | |
1068 | } | 1083 | } | |
1069 | 1084 | |||
1070 | static void | 1085 | static void |