diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/intr.c | 10 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/vector.S | 10 | ||||
-rw-r--r-- | sys/arch/amd64/include/intr.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/i386/apicvec.s | 12 | ||||
-rw-r--r-- | sys/arch/i386/i386/ioapic.c | 4 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 8 | ||||
-rw-r--r-- | sys/arch/i386/i386/vector.s | 8 | ||||
-rw-r--r-- | sys/arch/i386/include/psl.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/isa/isa_machdep.c | 4 |
9 files changed, 50 insertions, 14 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c index 44ba2669fc1..97784f1e518 100644 --- a/sys/arch/amd64/amd64/intr.c +++ b/sys/arch/amd64/amd64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.26 2010/12/27 20:22:23 guenther Exp $ */ +/* $OpenBSD: intr.c,v 1.27 2011/04/16 00:40:56 deraadt Exp $ */ /* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */ /* @@ -351,6 +351,12 @@ found: return 0; } +/* + * True if the system has any non-level interrupts which are shared + * on the same pin. + */ +int intr_shared_edge; + void * intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level, int (*handler)(void *), void *arg, const char *what) @@ -405,6 +411,8 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level, source->is_type = type; break; case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (source->is_type == type) break; diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S index c79afcabb0c..b5350c52be8 100644 --- a/sys/arch/amd64/amd64/vector.S +++ b/sys/arch/amd64/amd64/vector.S @@ -1,4 +1,4 @@ -/* $OpenBSD: vector.S,v 1.28 2011/04/01 22:51:45 guenther Exp $ */ +/* $OpenBSD: vector.S,v 1.29 2011/04/16 00:40:56 deraadt Exp $ */ /* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */ /* @@ -483,8 +483,12 @@ IDTVEC(intr_##name##num) ;\ 8: movl %r12d,CPUVAR(ILEVEL) ;\ call *IH_FUN(%rbx) /* call it */ ;\ orq %rax,%rax /* should it be counted? */ ;\ - jz 4f ;\ - incq IH_COUNT(%rbx) ;\ + jz 4f /* no, skip it */ ;\ + incq IH_COUNT(%rbx) /* count the intrs */ ;\ + cmpl $0,_C_LABEL(intr_shared_edge) ;\ + jne 4f /* if no shared edges ... */ ;\ + orq %rax,%rax /* 1 means stop trying */ ;\ + jns 5f ;\ 4: movq IH_NEXT(%rbx),%rbx /* next handler in chain */ ;\ testq %rbx,%rbx ;\ jnz 6b ;\ diff --git a/sys/arch/amd64/include/intr.h b/sys/arch/amd64/include/intr.h index 5a6212ffcdf..fdb6d236b44 100644 --- a/sys/arch/amd64/include/intr.h +++ b/sys/arch/amd64/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.22 2011/03/23 16:54:34 pirofti Exp $ */ +/* $OpenBSD: intr.h,v 1.23 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: intr.h,v 1.2 2003/05/04 22:01:56 fvdl Exp $ */ /*- @@ -191,6 +191,8 @@ extern struct intrstub ioapic_level_stubs[]; struct cpu_info; +extern int intr_shared_edge; + extern char idt_allocmap[]; void intr_default_setup(void); diff --git a/sys/arch/i386/i386/apicvec.s b/sys/arch/i386/i386/apicvec.s index 8e30149aff3..9c55a9afaca 100644 --- a/sys/arch/i386/i386/apicvec.s +++ b/sys/arch/i386/i386/apicvec.s @@ -1,4 +1,4 @@ -/* $OpenBSD: apicvec.s,v 1.22 2010/12/21 14:56:23 claudio Exp $ */ +/* $OpenBSD: apicvec.s,v 1.23 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: apicvec.s,v 1.1.2.2 2000/02/21 21:54:01 sommerfeld Exp $ */ /*- @@ -302,8 +302,14 @@ _C_LABEL(Xintr_##name##num): \ jz 4f ;\ addl $1,IH_COUNT(%ebx) /* count the intrs */ ;\ adcl $0,IH_COUNT+4(%ebx) ;\ -4: \ - UNLOCK_KERNEL(IF_PPL(%esp)) ;\ + cmp $0,_C_LABEL(intr_shared_edge) ;\ + jne 4f /* if no shared edges ... */ ;\ + orl %eax,%eax /* ... 1 means stop trying */ ;\ + js 4f ;\ +1: UNLOCK_KERNEL(IF_PPL(%esp)) ;\ + decl CPUVAR(IDEPTH) ;\ + jmp 8f ;\ +4: UNLOCK_KERNEL(IF_PPL(%esp)) ;\ decl CPUVAR(IDEPTH) ;\ movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\ testl %ebx,%ebx ;\ diff --git a/sys/arch/i386/i386/ioapic.c b/sys/arch/i386/i386/ioapic.c index 5e61bab1aa5..7ab93fc2e46 100644 --- a/sys/arch/i386/i386/ioapic.c +++ b/sys/arch/i386/i386/ioapic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ioapic.c,v 1.25 2010/09/20 06:33:47 matthew Exp $ */ +/* $OpenBSD: ioapic.c,v 1.26 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: ioapic.c,v 1.7 2003/07/14 22:32:40 lukem Exp $ */ /*- @@ -694,6 +694,8 @@ apic_intr_establish(int irq, int type, int level, int (*ih_fun)(void *), pin->ip_type = type; break; case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type == pin->ip_type) break; diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 679b6dffb53..0700d4fdc87 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.490 2011/04/15 04:52:39 guenther Exp $ */ +/* $OpenBSD: machdep.c,v 1.491 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3780,6 +3780,12 @@ i386_softintunlock(void) #endif /* + * True if the system has any non-level interrupts which are shared + * on the same pin. + */ +int intr_shared_edge; + +/* * Software interrupt registration * * We hand-code this to ensure that it's atomic. diff --git a/sys/arch/i386/i386/vector.s b/sys/arch/i386/i386/vector.s index 60437b77380..5e043b06e12 100644 --- a/sys/arch/i386/i386/vector.s +++ b/sys/arch/i386/i386/vector.s @@ -1,4 +1,4 @@ -/* $OpenBSD: vector.s,v 1.14 2009/08/10 16:40:50 oga Exp $ */ +/* $OpenBSD: vector.s,v 1.15 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: vector.s,v 1.32 1996/01/07 21:29:47 mycroft Exp $ */ /* @@ -137,10 +137,14 @@ _C_LABEL(Xintr_##name##num): ;\ jz 5f /* no, skip it */ ;\ addl $1,IH_COUNT(%ebx) /* count the intrs */ ;\ adcl $0,IH_COUNT+4(%ebx) ;\ + cmp $0,_C_LABEL(intr_shared_edge) ;\ + jne 5f /* if no shared edges ... */ ;\ + orl %eax,%eax /* ... 1 means stop trying */ ;\ + jns 8f ;\ 5: movl IH_NEXT(%ebx),%ebx /* next handler in chain */ ;\ testl %ebx,%ebx ;\ jnz 7b ;\ - UNLOCK_KERNEL(IF_PPL(%esp)) ;\ +8: UNLOCK_KERNEL(IF_PPL(%esp)) ;\ decl CPUVAR(IDEPTH) ;\ STRAY_TEST(name,num) /* see if it's a stray */ ;\ 6: unmask(num) /* unmask it in hardware */ ;\ diff --git a/sys/arch/i386/include/psl.h b/sys/arch/i386/include/psl.h index 39b93d748d7..ad7101c3c3e 100644 --- a/sys/arch/i386/include/psl.h +++ b/sys/arch/i386/include/psl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psl.h,v 1.17 2011/03/23 16:54:35 pirofti Exp $ */ +/* $OpenBSD: psl.h,v 1.18 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: psl.h,v 1.30 1996/05/13 01:28:05 mycroft Exp $ */ /*- @@ -91,6 +91,8 @@ struct intrhand { struct evcount ih_count; }; +extern int intr_shared_edge; /* This system has shared edge interrupts */ + #endif /* _LOCORE */ #endif /* _KERNEL */ diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c index 678bf709f1b..5457f2ddd1d 100644 --- a/sys/arch/i386/isa/isa_machdep.c +++ b/sys/arch/i386/isa/isa_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isa_machdep.c,v 1.71 2010/11/20 20:58:51 miod Exp $ */ +/* $OpenBSD: isa_machdep.c,v 1.72 2011/04/16 00:40:58 deraadt Exp $ */ /* $NetBSD: isa_machdep.c,v 1.22 1997/06/12 23:57:32 thorpej Exp $ */ /*- @@ -514,6 +514,8 @@ isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level, intrtype[irq] = type; break; case IST_EDGE: + intr_shared_edge = 1; + /* FALLTHROUGH */ case IST_LEVEL: if (type == intrtype[irq]) break; |