summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/intr.c10
-rw-r--r--sys/arch/amd64/amd64/vector.S10
-rw-r--r--sys/arch/amd64/include/intr.h4
-rw-r--r--sys/arch/i386/i386/apicvec.s12
-rw-r--r--sys/arch/i386/i386/ioapic.c4
-rw-r--r--sys/arch/i386/i386/machdep.c8
-rw-r--r--sys/arch/i386/i386/vector.s8
-rw-r--r--sys/arch/i386/include/psl.h4
-rw-r--r--sys/arch/i386/isa/isa_machdep.c4
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;