List Info

Thread: interrupt stack




interrupt stack
user name
2006-11-23 20:05:05
unless anyone objects, i'll make i386 and xen use interrupt
stack.

the attached patch is not tested on amd64 yet.
(amd64 part merely changes how to pass intrframe.)

YAMAMOTO Takashi
Index: amd64/amd64/vector.S
============================================================
=======
--- amd64/amd64/vector.S	(revision 1464)
+++ amd64/amd64/vector.S	(working copy)
 -360,6
+360,7  IDTVEC(resume_lapic_ltimer)
 	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
 	sti
 	pushq	%rbx
+	movq	%rsp,%rsi
 	xorq	%rdi,%rdi
 	call	_C_LABEL(lapic_clockintr)
 	jmp	_C_LABEL(Xdoreti)
 -415,6
+416,7  IDTVEC(intr_/**/name/**/num)						;
 	movl	IH_LEVEL(%rbx),%r12d					;
 	cmpl	%r13d,%r12d						;
 	jle	7f							;
+	movq	%rsp,%rsi						;
 	movq	IH_ARG(%rbx),%rdi					;
 	movl	%r12d,CPUVAR(ILEVEL)					;
 	call	*IH_FUN(%rbx)		/* call it */			;
Index: i386/include/frameasm.h
============================================================
=======
--- i386/include/frameasm.h	(revision 1407)
+++ i386/include/frameasm.h	(working copy)
 -100,4
+100,32 
 				1:
 #define	CLEAR_ASTPENDING(reg)	movl	$0, P_MD_ASTPENDING(reg)
 
+/*
+ * IDEPTH_INCR:
+ * increase ci_idepth and switch to the interrupt stack if
necessary.
+ * note that the initial value of ci_idepth is -1.
+ *
+ * => should be called with interrupt disabled.
+ * => save the old value of %esp in %eax.
+ */
+
+#define	IDEPTH_INCR 
+	incl	CPUVAR(IDEPTH); 
+	movl	%esp, %eax; 
+	jne	999f; 
+	movl	CPUVAR(INTRSTACK), %esp; 
+999:	pushl	%eax; 
+
+/*
+ * IDEPTH_DECR:
+ * decrement ci_idepth and switch back to
+ * the original stack saved by IDEPTH_INCR.
+ *
+ * => should be called with interrupt disabled.
+ */
+
+#define	IDEPTH_DECR 
+	popl	%esp; 
+	decl	CPUVAR(IDEPTH)
+
 #endif /* _I386_FRAMEASM_H_ */
Index: i386/include/param.h
============================================================
=======
--- i386/include/param.h	(revision 1776)
+++ i386/include/param.h	(working copy)
 -112,6
+112,7 
 #endif /*NOREDZONE */
 #endif /* !defined(UPAGES) */
 #define	USPACE		(UPAGES * NBPG)	/* total size of u-area */
+#define	INTRSTACKSIZE	8192
 
 #ifndef MSGBUFSIZE
 #define MSGBUFSIZE	4*NBPG		/* default message buffer size
*/
Index: i386/include/cpu.h
============================================================
=======
--- i386/include/cpu.h	(revision 1785)
+++ i386/include/cpu.h	(working copy)
 -111,6
+111,7  struct cpu_info {
 	int		ci_idepth;
 	uint32_t	ci_imask[NIPL];
 	uint32_t	ci_iunmask[NIPL];
+	void *		ci_intrstack;
 
 	paddr_t ci_idle_pcb_paddr;	/* PA of idle PCB */
 	uint32_t ci_flags;		/* flags; see below */
 -271,7
+272,7  struct clockframe {
 #define	CLKF_USERMODE(frame)	USERMODE((frame)->cf_if.if_
cs, (frame)->cf_if.if_eflags)
 #define	CLKF_BASEPRI(frame)	(0)
 #define	CLKF_PC(frame)		((frame)->cf_if.if_eip)
-#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
+#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 0)
 
 /*
  * This is used during profiling to integrate system time. 
It can safely
Index: i386/i386/spl.S
============================================================
=======
--- i386/i386/spl.S	(revision 1464)
+++ i386/i386/spl.S	(working copy)
 -102,10
+102,11  IDTVEC(spllower)
 #else /* defined(DDB) || defined(GPROF) */
 	movl	16(%esp),%ebx
 #endif /* defined(DDB) || defined(GPROF) */
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax		# get cpl
-	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
+	movl	$.Lspllower_resume,%esi		# address to resume loop at
 	cli
+.Lspllower_resume:
+	movl	%ebx,%eax		# get cpl
+	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
 	andl	CPUVAR(IPENDING),%eax		# any non-masked bits left?
 	jz	2f
 	bsrl	%eax,%eax
 -130,14
+131,16  IDTVEC(spllower)
  *   ebx - cpl to restore
  *   esi - address to resume loop at
  *   edi - scratch for Xsoftnet
+ *
+ * called with interrupt disabled.
  */
 IDTVEC(doreti)
+	IDEPTH_DECR
 	popl	%ebx			# get previous priority
-	decl	CPUVAR(IDEPTH)
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax
+	movl	$.Ldoreti_resume,%esi	# address to resume loop at
+.Ldoreti_resume:
+	movl	%ebx,%eax
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	cli
 	andl	CPUVAR(IPENDING),%eax
 	jz	2f
 	bsrl    %eax,%eax               # slow, but not worth
optimizing
Index: i386/i386/db_trace.c
============================================================
=======
--- i386/i386/db_trace.c	(revision 1912)
+++ i386/i386/db_trace.c	(working copy)
 -357,6
+357,26  db_nextframe(
 	return 1;
 }
 
+static boolean_t
+db_intrstack_p(const void *vp)
+{
+	const struct cpu_info *ci;
+	CPU_INFO_ITERATOR cii;
+
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		const char *cp = ci->ci_intrstack;
+
+		if (cp == NULL) {
+			continue;
+		}
+		if ((cp - INTRSTACKSIZE + 4) <= (const char *)vp
&&
+		    (const char *)vp <= cp) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
 void
 db_stack_trace_print(db_expr_t addr, boolean_t have_addr,
db_expr_t count,
 		     const char *modif, void (*pr)(const char *, ...))
 -514,7
+534,10  have_u:
 
 		if (INKERNEL((int)frame)) {
 			/* staying in kernel */
-			if (frame < lastframe ||
+			if (!db_intrstack_p(frame) &&
+			    db_intrstack_p(lastframe)) {
+				(*pr)("--- switch to interrupt stack ---n");
+			} else if (frame < lastframe ||
 			    (frame == lastframe && callpc ==
lastcallpc)) {
 				(*pr)("Bad frame pointer: %pn", frame);
 				break;
Index: i386/i386/vector.S
============================================================
=======
--- i386/i386/vector.S	(revision 1464)
+++ i386/i386/vector.S	(working copy)
 -165,11
+165,12  IDTVEC(intr_lapic_ipi)
 	jae	2f
 IDTVEC(resume_lapic_ipi)
 1:
-	incl	CPUVAR(IDEPTH)
-	movl	$IPL_IPI,CPUVAR(ILEVEL)
-        sti
 	pushl	%ebx
+	IDEPTH_INCR
+	movl	$IPL_IPI,CPUVAR(ILEVEL)
+	sti
 	call	_C_LABEL(x86_ipi_handler)
+	cli
 	jmp	_C_LABEL(Xdoreti)
 2:
 	orl	$(1 << LIR_IPI),CPUVAR(IPENDING)
 -215,13
+216,14  IDTVEC(intr_lapic_ltimer)
 	jae	2f
 IDTVEC(resume_lapic_ltimer)
 1:
-	incl	CPUVAR(IDEPTH)
+	pushl	%ebx
+	IDEPTH_INCR
 	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
 	sti
-	pushl	%ebx
 	pushl	$0
 	call	_C_LABEL(lapic_clockintr)
 	addl	$4,%esp		
+	cli
 	jmp	_C_LABEL(Xdoreti)
 2:
 	orl	$(1 << LIR_TIMER),CPUVAR(IPENDING)
 -270,8
+272,8  IDTVEC(intr_/**/name/**/num)						;
 1:									
 	pushl	%esi							;
 	movl	%ebx,CPUVAR(ILEVEL)					;
+	IDEPTH_INCR							;
 	sti								;
-	incl	CPUVAR(IDEPTH)						;
 	movl	IS_HANDLERS(%ebp),%ebx					;
 6:									
 	movl	IH_LEVEL(%ebx),%edi					;
 -289,14
+291,12  IDTVEC(intr_/**/name/**/num)						;
 	cli								;
 	unmask(num)			/* unmask it in hardware */	;
 	late_ack(num)							;
-	sti								;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 7:									
 	cli								;
 	orl     $(1 << num),CPUVAR(IPENDING)				;
 	level_mask(num)							;
 	late_ack(num)							;
-	sti								;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 10:									
 	cli								;
 -595,8
+595,8  _C_LABEL(ioapic_level_stubs):
 
 IDTVEC(softserial)
 	movl	$IPL_SOFTSERIAL, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -609,13
+609,14  IDTVEC(softserial)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softnet)
 	movl	$IPL_SOFTNET, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintlock)
 #endif
 -641,13
+642,14  IDTVEC(softnet)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)	
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softclock)
 	movl	$IPL_SOFTCLOCK, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintlock)
 #endif
 -661,7
+663,8  IDTVEC(softclock)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)		
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 /*
 -766,9
+769,10  IDTVEC(trap10)
 	INTRENTRY
 	pushl	CPUVAR(ILEVEL)
 	pushl	%esp
+	pushl	$0			# dummy arg
 	incl	_C_LABEL(uvmexp)+V_TRAP
 	call	_C_LABEL(npxintr)
-	addl	$8,%esp
+	addl	$12,%esp
 	INTRFASTEXIT
 #else
 	ZTRAP(T_ARITHTRAP)
Index: i386/i386/genassym.cf
============================================================
=======
--- i386/i386/genassym.cf	(revision 1728)
+++ i386/i386/genassym.cf	(working copy)
 -304,6
+304,7  define	CPU_INFO_IUNMASK	offsetof(struct 
 define	CPU_INFO_ILEVEL		offsetof(struct cpu_info,
ci_ilevel)
 define	CPU_INFO_IDEPTH		offsetof(struct cpu_info,
ci_idepth)
 define	CPU_INFO_ISOURCES	offsetof(struct cpu_info,
ci_isources)
+define	CPU_INFO_INTRSTACK	offsetof(struct cpu_info,
ci_intrstack)
 
 if NIOAPIC > 0
 define		IOAPIC_SC_REG		offsetof(struct ioapic_softc,
sc_reg)
Index: i386/isa/npxvar.h
============================================================
=======
--- i386/isa/npxvar.h	(revision 1885)
+++ i386/isa/npxvar.h	(working copy)
 -87,4
+87,4  struct npx_softc {
 
 enum npx_type npxprobe1(bus_space_tag_t,
bus_space_handle_t, int);
 void npxattach(struct npx_softc *);
-int npxintr(void *, struct intrframe);
+int npxintr(void *, struct intrframe *);
Index: i386/isa/npx.c
============================================================
=======
--- i386/isa/npx.c	(revision 1914)
+++ i386/isa/npx.c	(working copy)
 -345,12
+345,11  npxattach(struct npx_softc *sc)
  * IRQ13 exception handling makes exceptions even less
precise than usual.
  */
 int
-npxintr(void *arg, struct intrframe iframe)
+npxintr(void *arg, struct intrframe *frame)
 {
 	struct cpu_info *ci = curcpu();
 	struct lwp *l = ci->ci_fpcurlwp;
 	union savefpu *addr;
-	struct intrframe *frame = &iframe;
 	struct npx_softc *sc;
 	ksiginfo_t ksi;
 
Index: x86/x86/intr.c
============================================================
=======
--- x86/x86/intr.c	(revision 1728)
+++ x86/x86/intr.c	(working copy)
 -119,6
+119,8  __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.2
 #include <sys/proc.h>
 #include <sys/errno.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <machine/atomic.h>
 #include <machine/i8259.h>
 #include <machine/cpu.h>
 -818,6
+820,9  cpu_intr_init(struct cpu_info *ci)
 #if NLAPIC > 0 && defined(MULTIPROCESSOR)
 	int i;
 #endif
+#if defined(INTRSTACKSIZE)
+	char *cp;
+#endif /* defined(INTRSTACKSIZE) */
 
 	MALLOC(isp, struct intrsource *, sizeof (struct
intrsource), M_DEVBUF,
 	    M_WAITOK|M_ZERO);
 -892,6
+897,11  cpu_intr_init(struct cpu_info *ci)
 
 	intr_calculatemasks(ci);
 
+#if defined(INTRSTACKSIZE)
+	cp = (char *)uvm_km_alloc(kernel_map, INTRSTACKSIZE, 0,
UVM_KMF_WIRED);
+	ci->ci_intrstack = cp + INTRSTACKSIZE -
sizeof(register_t);
+	ci->ci_idepth = -1;
+#endif /* defined(INTRSTACKSIZE) */
 }
 
 #ifdef MULTIPROCESSOR
Index: x86/x86/lapic.c
============================================================
=======
--- x86/x86/lapic.c	(revision 1915)
+++ x86/x86/lapic.c	(working copy)
 -78,7
+78,7  __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.
 void		lapic_delay(int);
 void		lapic_microtime(struct timeval *);
 static u_int32_t lapic_gettick(void);
-void		lapic_clockintr(void *, struct intrframe);
+void		lapic_clockintr(void *, struct intrframe *);
 static void 	lapic_map(paddr_t);
 
 static void lapic_hwmask(struct pic *, int);
 -238,7
+238,7  u_int64_t lapic_frac_cycle_per_usec;
 u_int32_t lapic_delaytab[26];
 
 void
-lapic_clockintr(void *arg, struct intrframe frame)
+lapic_clockintr(void *arg, struct intrframe *frame)
 {
 #if defined(I586_CPU) || defined(I686_CPU) ||
defined(__x86_64__)
 #ifndef __HAVE_TIMECOUNTER
 -333,7
+333,7  lapic_clockintr(void *arg, struct intrfr
 #endif /* !__HAVE_TIMECOUNTER */
 #endif /* I586_CPU || I686_CPU || __x86_64__ */
 
-	hardclock((struct clockframe *)&frame);
+	hardclock((struct clockframe *)frame);
 }
 
 #if !defined(__HAVE_TIMECOUNTER) && defined(NTP)
Index: x86/isa/clock.c
============================================================
=======
--- x86/isa/clock.c	(revision 1915)
+++ x86/isa/clock.c	(working copy)
 -192,7
+192,7  int		gettick(void);
 void		sysbeep(int, int);
 static void     tickle_tc(void);
 
-static int	clockintr(void *, struct intrframe);
+static int	clockintr(void *, struct intrframe *);
 static void	rtcinit(void);
 static int	rtcget(mc_todregs *);
 static void	rtcput(mc_todregs *);
 -404,11
+404,11  tickle_tc(void) 
 }
 
 static int
-clockintr(void *arg, struct intrframe frame)
+clockintr(void *arg, struct intrframe *frame)
 {
 	tickle_tc();
 
-	hardclock((struct clockframe *)&frame);
+	hardclock((struct clockframe *)frame);
 
 #if NMCA > 0
 	if (MCA_system) {
Index: xen/include/cpu.h
============================================================
=======
--- xen/include/cpu.h	(revision 1571)
+++ xen/include/cpu.h	(working copy)
 -114,6
+114,7  struct cpu_info {
 	u_int32_t	ci_imask[NIPL];
 #endif
 	u_int32_t	ci_iunmask[NIPL];
+	void *		ci_intrstack;
 
 	paddr_t ci_idle_pcb_paddr;	/* PA of idle PCB */
 	u_int32_t ci_flags;		/* flags; see below */
 -271,7
+272,7  struct clockframe {
 #define	CLKF_USERMODE(frame)	USERMODE((frame)->cf_if.if_
cs, (frame)->cf_if.if_eflags)
 #define	CLKF_BASEPRI(frame)	(0)
 #define	CLKF_PC(frame)		((frame)->cf_if.if_eip)
-#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
+#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 0)
 
 /*
  * This is used during profiling to integrate system time. 
It can safely
Index: xen/include/evtchn.h
============================================================
=======
--- xen/include/evtchn.h	(revision 1799)
+++ xen/include/evtchn.h	(working copy)
 -41,6
+41,7  extern struct evtsource *evtsource[];
 void events_default_setup(void);
 void init_events(void);
 unsigned int evtchn_do_event(int, struct intrframe *);
+void call_evtchn_do_event(int, struct intrframe *);
 int event_set_handler(int, int (*func)(void *), void *,
int, const char *);
 int event_remove_handler(int, int (*func)(void *), void *);
 
Index: xen/x86/intr.c
============================================================
=======
--- xen/x86/intr.c	(revision 1848)
+++ xen/x86/intr.c	(working copy)
 -120,6
+120,8  __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.1
 #include <sys/proc.h>
 #include <sys/errno.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <machine/atomic.h>
 #include <machine/i8259.h>
 #include <machine/cpu.h>
 -206,6
+208,7  void
 cpu_intr_init(struct cpu_info *ci)
 {
 	struct iplsource *ipl;
+	char *cp;
 	int i;
 
 	ci->ci_iunmask[0] = 0xfffffffe;
 -261,6
+264,10  cpu_intr_init(struct cpu_info *ci)
 	evcnt_attach_dynamic(&softxenevt_evtcnt,
EVCNT_TYPE_INTR, NULL,
 	    ci->ci_dev->dv_xname, "xenevt");
 #endif /* defined(DOM0OPS) */
+
+	cp = (char *)uvm_km_alloc(kernel_map, INTRSTACKSIZE, 0,
UVM_KMF_WIRED);
+	ci->ci_intrstack = cp + INTRSTACKSIZE -
sizeof(register_t);
+	ci->ci_idepth = -1;
 }
 
 #if NPCI > 0 || NISA > 0
Index: xen/i386/npx.c
============================================================
=======
--- xen/i386/npx.c	(revision 1609)
+++ xen/i386/npx.c	(working copy)
 -368,12
+368,11  npxattach(struct npx_softc *sc)
  * IRQ13 exception handling makes exceptions even less
precise than usual.
  */
 int
-npxintr(void *arg, struct intrframe iframe)
+npxintr(void *arg, struct intrframe *frame)
 {
 	struct cpu_info *ci = curcpu();
 	struct lwp *l = ci->ci_fpcurlwp;
 	union savefpu *addr;
-	struct intrframe *frame = &iframe;
 	struct npx_softc *sc;
 	ksiginfo_t ksi;
 
Index: xen/i386/spl.S
============================================================
=======
--- xen/i386/spl.S	(revision 1464)
+++ xen/i386/spl.S	(working copy)
 -105,11
+105,13  IDTVEC(spllower)
 #else /* defined(DDB) || defined(GPROF) */
 	movl	20(%esp),%ebx
 #endif /* defined(DDB) || defined(GPROF) */
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax		# get cpl
+	movl	$.Lspllower_resume,%esi	# address to resume loop at
+1:
+	CLI(%eax)
+.Lspllower_resume:
+	movl	%ebx,%eax		# get cpl
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	CLI(%ecx)
-	andl	CPUVAR(IPENDING),%eax		# any non-masked bits left?
+	andl	CPUVAR(IPENDING),%eax	# any non-masked bits left?
 	jz	2f
 	bsrl	%eax,%eax
 	btrl	%eax,CPUVAR(IPENDING)
 -138,15
+140,16  IDTVEC(spllower)
  *   ebx - cpl to restore
  *   esi - address to resume loop at
  *   edi - scratch for Xsoftnet
+ *
+ * called with interrupt disabled.
  */
 IDTVEC(doreti)
+	IDEPTH_DECR
 	popl	%ebx			# get previous priority
-	decl	CPUVAR(IDEPTH)
-	movl	$1f,%esi		# address to resume loop at
-8:
-1:	movl	%ebx,%eax
+	movl	$.Ldoreti_resume,%esi	# address to resume loop at
+.Ldoreti_resume:
+	movl	%ebx,%eax
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	CLI(%ecx)
 	andl	CPUVAR(IPENDING),%eax
 	jz	2f
 	bsrl    %eax,%eax               # slow, but not worth
optimizing
 -176,7
+179,7  doreti_checkast:
 	call	_C_LABEL(trap)
 	addl	$4,%esp
 	CLI(%ecx)
-	jmp	5b
+	jmp	.Ldoreti_resume
 3:
 	CHECK_DEFERRED_SWITCH(%eax)
 	jnz	9f
 -184,7
+187,8  doreti_checkast:
     	jz	4f
 	call	_C_LABEL(stipending)
 	testl	%eax,%eax
-	jnz	8b
+	CLI(%eax)
+	jnz	.Ldoreti_resume
 4:
 	INTRFASTEXIT
 9:
 -192,3
+196,19  doreti_checkast:
 	call	_C_LABEL(pmap_load)
 	CLI(%ecx)
 	jmp	doreti_checkast	/* recheck ASTs */
+
+/*
+ * void evtchn_do_event(int evtch, struct intrframe *regs)
+ */
+
+NENTRY(call_evtchn_do_event)
+	IDEPTH_INCR
+	/*
+	 * IDEPTH_INCR leaves old %esp in %eax.
+	 */
+	pushl	8(%eax)	/* regs */
+	pushl	4(%eax)	/* evtch */
+	call	_C_LABEL(evtchn_do_event)
+	addl	$8, %esp
+	IDEPTH_DECR
+	ret
Index: xen/i386/vector.S
============================================================
=======
--- xen/i386/vector.S	(revision 1540)
+++ xen/i386/vector.S	(working copy)
 -202,15
+202,14  IDTVEC(resume_/**/name/**/num)						
 1:									
 	pushl	%esi							;
 	movl	$num,CPUVAR(ILEVEL)					;
+	IDEPTH_INCR /* leaves old %esp on stack	*/			;
 	STI(%eax)							;
-	incl	CPUVAR(IDEPTH)						;
 	movl	IS_HANDLERS(%ebp),%ebx					;
 	LOCK_KERNEL							;
 6:									
-	pushl	%esp							;
 	pushl	IH_ARG(%ebx)						;
 	call	*IH_FUN(%ebx)		/* call it */			;
-	addl	$8,%esp			/* toss the arg */		;
+	addl	$4,%esp			/* toss the arg */		;
 	movl	IH_IPL_NEXT(%ebx),%ebx	/* next handler in chain */	;
 	testl	%ebx,%ebx						;
 	jnz	6b							;
 -219,7
+218,6  IDTVEC(resume_/**/name/**/num)						
 	CLI(%eax)							;
 	unmask(num)			/* unmask it in hardware */	;
 	late_ack(num)							;
-	STI(%eax)							;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 
 # Just unmasking the event isn't enouth, we also need to
 -306,8
+304,8  _C_LABEL(xenev_stubs):
 #define EVCNTHI(x) _C_LABEL(x) + EV_EVCNTHI
 IDTVEC(softserial)
 	movl	$IPL_SOFTSERIAL, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -319,13
+317,14  IDTVEC(softserial)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softnet)
 	movl	$IPL_SOFTNET, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -349,13
+348,14  IDTVEC(softnet)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softclock)
 	movl	$IPL_SOFTCLOCK, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -368,14
+368,15  IDTVEC(softclock)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 #if defined(DOM0OPS)
 IDTVEC(softxenevt)
 	movl	$IPL_SOFTXENEVT, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -385,7
+386,8  IDTVEC(softxenevt)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 #endif /* defined(DOM0OPS) */
 
 -486,9
+488,10  IDTVEC(trap10)
 	INTRENTRY
 	pushl	CPUVAR(ILEVEL)
 	pushl	%esp
+	pushl	$0			# dummy arg
 	incl	_C_LABEL(uvmexp)+V_TRAP
 	call	_C_LABEL(npxintr)
-	addl	$8,%esp
+	addl	$12,%esp
 	INTRFASTEXIT
 #else
 	ZTRAP(T_ARITHTRAP)
Index: xen/i386/hypervisor_machdep.c
============================================================
=======
--- xen/i386/hypervisor_machdep.c	(revision 1540)
+++ xen/i386/hypervisor_machdep.c	(working copy)
 -215,7
+215,7  do_hypervisor_callback(struct intrframe 
 					printf("do_hypervisor_callback event %dn",
port);
 #endif
 				if (evtsource[port])
-					evtchn_do_event(port, regs);
+					call_evtchn_do_event(port, regs);
 #ifdef DOM0OPS
 				else
 					xenevt_event(port);
Index: xen/i386/genassym.cf
============================================================
=======
--- xen/i386/genassym.cf	(revision 1657)
+++ xen/i386/genassym.cf	(working copy)
 -271,6
+271,7  define	CPU_INFO_IUNMASK	offsetof(struct 
 define	CPU_INFO_ILEVEL		offsetof(struct cpu_info,
ci_ilevel)
 define	CPU_INFO_IDEPTH		offsetof(struct cpu_info,
ci_idepth)
 define	CPU_INFO_ISOURCES	offsetof(struct cpu_info,
ci_isources)
+define	CPU_INFO_INTRSTACK	offsetof(struct cpu_info,
ci_intrstack)
 
 define	SIZEOF_CPU_INFO		sizeof(struct cpu_info)
 
Index: xen/xen/evtchn.c
============================================================
=======
--- xen/xen/evtchn.c	(revision 1799)
+++ xen/xen/evtchn.c	(working copy)
 -234,7
+234,6  evtchn_do_event(int evtch, struct intrfr
 	ci->ci_ilevel = evtsource[evtch]->ev_maxlevel;
 	iplmask = evtsource[evtch]->ev_imask;
 	sti();
-	ci->ci_idepth++;
 #ifdef MULTIPROCESSOR
 	x86_intlock(regs);
 #endif
 -252,7
+251,6  evtchn_do_event(int evtch, struct intrfr
 			hypervisor_set_ipending(iplmask,
 			    evtch / 32, evtch % 32);
 			/* leave masked */
-			ci->ci_idepth--;
 			splx(ilevel);
 			return 0;
 		}
 -267,7
+265,6  evtchn_do_event(int evtch, struct intrfr
 	x86_intunlock(regs);
 #endif
 	hypervisor_enable_event(evtch);
-	ci->ci_idepth--;
 	splx(ilevel);
 
 	return 0;
interrupt stack
user name
2006-11-23 20:51:05
On Fri, Nov 24, 2006 at 05:05:05AM +0900, YAMAMOTO Takashi
wrote:
> unless anyone objects, i'll make i386 and xen use
interrupt stack.

Looks good for Xen. Thanks !

-- 
Manuel Bouyer <bouyerantioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la
difference
--
interrupt stack
user name
2006-11-23 20:51:05
On Fri, Nov 24, 2006 at 05:05:05AM +0900, YAMAMOTO Takashi
wrote:
> unless anyone objects, i'll make i386 and xen use
interrupt stack.

Looks good for Xen. Thanks !

-- 
Manuel Bouyer <bouyerantioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la
difference
--
interrupt stack
user name
2006-11-24 15:06:19
> unless anyone objects, i'll make i386 and xen use
interrupt stack.
> 
> the attached patch is not tested on amd64 yet.
> (amd64 part merely changes how to pass intrframe.)

oops, it was an old patch with known bugs.

the new one is here.

YAMAMOTO Takashi
Index: amd64/amd64/vector.S
============================================================
=======
--- amd64/amd64/vector.S	(revision 1464)
+++ amd64/amd64/vector.S	(working copy)
 -360,6
+360,7  IDTVEC(resume_lapic_ltimer)
 	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
 	sti
 	pushq	%rbx
+	movq	%rsp,%rsi
 	xorq	%rdi,%rdi
 	call	_C_LABEL(lapic_clockintr)
 	jmp	_C_LABEL(Xdoreti)
 -415,6
+416,7  IDTVEC(intr_/**/name/**/num)						;
 	movl	IH_LEVEL(%rbx),%r12d					;
 	cmpl	%r13d,%r12d						;
 	jle	7f							;
+	movq	%rsp,%rsi						;
 	movq	IH_ARG(%rbx),%rdi					;
 	movl	%r12d,CPUVAR(ILEVEL)					;
 	call	*IH_FUN(%rbx)		/* call it */			;
Index: i386/include/frameasm.h
============================================================
=======
--- i386/include/frameasm.h	(revision 1407)
+++ i386/include/frameasm.h	(working copy)
 -100,4
+100,32 
 				1:
 #define	CLEAR_ASTPENDING(reg)	movl	$0, P_MD_ASTPENDING(reg)
 
+/*
+ * IDEPTH_INCR:
+ * increase ci_idepth and switch to the interrupt stack if
necessary.
+ * note that the initial value of ci_idepth is -1.
+ *
+ * => should be called with interrupt disabled.
+ * => save the old value of %esp in %eax.
+ */
+
+#define	IDEPTH_INCR 
+	incl	CPUVAR(IDEPTH); 
+	movl	%esp, %eax; 
+	jne	999f; 
+	movl	CPUVAR(INTRSTACK), %esp; 
+999:	pushl	%eax; 
+
+/*
+ * IDEPTH_DECR:
+ * decrement ci_idepth and switch back to
+ * the original stack saved by IDEPTH_INCR.
+ *
+ * => should be called with interrupt disabled.
+ */
+
+#define	IDEPTH_DECR 
+	popl	%esp; 
+	decl	CPUVAR(IDEPTH)
+
 #endif /* _I386_FRAMEASM_H_ */
Index: i386/include/i82093reg.h
============================================================
=======
--- i386/include/i82093reg.h	(revision 1407)
+++ i386/include/i82093reg.h	(working copy)
 -50,7
+50,8 
  * XXX this is not obvious
  */
 #define ioapic_unmask(num) 
-	cmpl    $IREENT_MAGIC,(TF_ERR+4)(%esp)			;
+	movl    (%esp),%eax					;
+	cmpl    $IREENT_MAGIC,(TF_ERR+4)(%eax)			;
 	jne     79f						;
 	movl	IS_PIC(%ebp),%edi				;
 	ioapic_asm_lock(num)					;
Index: i386/include/param.h
============================================================
=======
--- i386/include/param.h	(revision 1776)
+++ i386/include/param.h	(working copy)
 -112,6
+112,7 
 #endif /*NOREDZONE */
 #endif /* !defined(UPAGES) */
 #define	USPACE		(UPAGES * NBPG)	/* total size of u-area */
+#define	INTRSTACKSIZE	8192
 
 #ifndef MSGBUFSIZE
 #define MSGBUFSIZE	4*NBPG		/* default message buffer size
*/
Index: i386/include/cpu.h
============================================================
=======
--- i386/include/cpu.h	(revision 1785)
+++ i386/include/cpu.h	(working copy)
 -111,6
+111,7  struct cpu_info {
 	int		ci_idepth;
 	uint32_t	ci_imask[NIPL];
 	uint32_t	ci_iunmask[NIPL];
+	void *		ci_intrstack;
 
 	paddr_t ci_idle_pcb_paddr;	/* PA of idle PCB */
 	uint32_t ci_flags;		/* flags; see below */
 -271,7
+272,7  struct clockframe {
 #define	CLKF_USERMODE(frame)	USERMODE((frame)->cf_if.if_
cs, (frame)->cf_if.if_eflags)
 #define	CLKF_BASEPRI(frame)	(0)
 #define	CLKF_PC(frame)		((frame)->cf_if.if_eip)
-#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
+#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 0)
 
 /*
  * This is used during profiling to integrate system time. 
It can safely
Index: i386/i386/spl.S
============================================================
=======
--- i386/i386/spl.S	(revision 1464)
+++ i386/i386/spl.S	(working copy)
 -102,10
+102,17  IDTVEC(spllower)
 #else /* defined(DDB) || defined(GPROF) */
 	movl	16(%esp),%ebx
 #endif /* defined(DDB) || defined(GPROF) */
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax		# get cpl
-	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
+	movl	$.Lspllower_resume,%esi		# address to resume loop at
 	cli
+.Lspllower_resume:
+#if defined(DEBUG)
+	pushf
+	popl	%eax
+	testl	$PSL_I,%eax
+	jnz	.Lspllower_panic
+#endif /* defined(DEBUG) */
+	movl	%ebx,%eax		# get cpl
+	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
 	andl	CPUVAR(IPENDING),%eax		# any non-masked bits left?
 	jz	2f
 	bsrl	%eax,%eax
 -122,6
+129,12  IDTVEC(spllower)
 	leave
 #endif /* defined(DDB) || defined(GPROF) */
 	ret
+#if defined(DEBUG)
+.Lspllower_panic:
+	pushl	$1f
+	call	_C_LABEL(panic)
+1:	.asciz	"SPLLOWER: INTERRUPT ENABLED"
+#endif /* defined(DEBUG) */
 
 /*
  * Handle return from interrupt after device handler
finishes.
 -130,14
+143,22  IDTVEC(spllower)
  *   ebx - cpl to restore
  *   esi - address to resume loop at
  *   edi - scratch for Xsoftnet
+ *
+ * called with interrupt disabled.
  */
 IDTVEC(doreti)
+	IDEPTH_DECR
 	popl	%ebx			# get previous priority
-	decl	CPUVAR(IDEPTH)
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax
+	movl	$.Ldoreti_resume,%esi	# address to resume loop at
+.Ldoreti_resume:
+#if defined(DEBUG)
+	pushf
+	popl	%eax
+	testl	$PSL_I,%eax
+	jnz	.Ldoreti_panic
+#endif /* defined(DEBUG) */
+	movl	%ebx,%eax
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	cli
 	andl	CPUVAR(IPENDING),%eax
 	jz	2f
 	bsrl    %eax,%eax               # slow, but not worth
optimizing
 -177,3
+198,9  IDTVEC(doreti)
 	call	_C_LABEL(pmap_load)
 	cli
 	jmp	.Ldoreti_checkast	/* recheck ASTs */
+#if defined(DEBUG)
+.Ldoreti_panic:
+	pushl	$1f
+	call	_C_LABEL(panic)
+1:	.asciz	"DORETI: INTERRUPT ENABLED"
+#endif /* defined(DEBUG) */
Index: i386/i386/db_trace.c
============================================================
=======
--- i386/i386/db_trace.c	(revision 1912)
+++ i386/i386/db_trace.c	(working copy)
 -357,6
+357,26  db_nextframe(
 	return 1;
 }
 
+static boolean_t
+db_intrstack_p(const void *vp)
+{
+	const struct cpu_info *ci;
+	CPU_INFO_ITERATOR cii;
+
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		const char *cp = ci->ci_intrstack;
+
+		if (cp == NULL) {
+			continue;
+		}
+		if ((cp - INTRSTACKSIZE + 4) <= (const char *)vp
&&
+		    (const char *)vp <= cp) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
 void
 db_stack_trace_print(db_expr_t addr, boolean_t have_addr,
db_expr_t count,
 		     const char *modif, void (*pr)(const char *, ...))
 -514,7
+534,10  have_u:
 
 		if (INKERNEL((int)frame)) {
 			/* staying in kernel */
-			if (frame < lastframe ||
+			if (!db_intrstack_p(frame) &&
+			    db_intrstack_p(lastframe)) {
+				(*pr)("--- switch to interrupt stack ---n");
+			} else if (frame < lastframe ||
 			    (frame == lastframe && callpc ==
lastcallpc)) {
 				(*pr)("Bad frame pointer: %pn", frame);
 				break;
Index: i386/i386/vector.S
============================================================
=======
--- i386/i386/vector.S	(revision 1464)
+++ i386/i386/vector.S	(working copy)
 -165,11
+165,12  IDTVEC(intr_lapic_ipi)
 	jae	2f
 IDTVEC(resume_lapic_ipi)
 1:
-	incl	CPUVAR(IDEPTH)
-	movl	$IPL_IPI,CPUVAR(ILEVEL)
-        sti
 	pushl	%ebx
+	IDEPTH_INCR
+	movl	$IPL_IPI,CPUVAR(ILEVEL)
+	sti
 	call	_C_LABEL(x86_ipi_handler)
+	cli
 	jmp	_C_LABEL(Xdoreti)
 2:
 	orl	$(1 << LIR_IPI),CPUVAR(IPENDING)
 -215,13
+216,14  IDTVEC(intr_lapic_ltimer)
 	jae	2f
 IDTVEC(resume_lapic_ltimer)
 1:
-	incl	CPUVAR(IDEPTH)
+	pushl	%ebx
+	IDEPTH_INCR
 	movl	$IPL_CLOCK,CPUVAR(ILEVEL)
 	sti
-	pushl	%ebx
 	pushl	$0
 	call	_C_LABEL(lapic_clockintr)
 	addl	$4,%esp		
+	cli
 	jmp	_C_LABEL(Xdoreti)
 2:
 	orl	$(1 << LIR_TIMER),CPUVAR(IPENDING)
 -270,8
+272,8  IDTVEC(intr_/**/name/**/num)						;
 1:									
 	pushl	%esi							;
 	movl	%ebx,CPUVAR(ILEVEL)					;
+	IDEPTH_INCR							;
 	sti								;
-	incl	CPUVAR(IDEPTH)						;
 	movl	IS_HANDLERS(%ebp),%ebx					;
 6:									
 	movl	IH_LEVEL(%ebx),%edi					;
 -285,29
+287,26  IDTVEC(intr_/**/name/**/num)						;
 	addl	$4,%esp			/* toss the arg */		;
 	testl	%ebx,%ebx						;
 	jnz	6b							;
-5:									
 	cli								;
 	unmask(num)			/* unmask it in hardware */	;
 	late_ack(num)							;
-	sti								;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 7:									
 	cli								;
 	orl     $(1 << num),CPUVAR(IPENDING)				;
 	level_mask(num)							;
 	late_ack(num)							;
-	sti								;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 10:									
-	cli								;
 	orl     $(1 << num),CPUVAR(IPENDING)				;
 	level_mask(num)							;
 	late_ack(num)							;
-	sti								;
 	INTRFASTEXIT							;
 9:									
+	pushl	%esp			/* for unmask */		;
 	unmask(num)							;
 	late_ack(num)							;
+	addl	$4,%esp							;
 	INTRFASTEXIT
 
 #define ICUADDR IO_ICU1
 -595,8
+594,8  _C_LABEL(ioapic_level_stubs):
 
 IDTVEC(softserial)
 	movl	$IPL_SOFTSERIAL, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -609,13
+608,14  IDTVEC(softserial)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softnet)
 	movl	$IPL_SOFTNET, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintlock)
 #endif
 -641,13
+641,14  IDTVEC(softnet)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)	
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softclock)
 	movl	$IPL_SOFTCLOCK, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	sti
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintlock)
 #endif
 -661,7
+662,8  IDTVEC(softclock)
 #ifdef MULTIPROCESSOR	
 	call	_C_LABEL(x86_softintunlock)		
 #endif
-	decl	CPUVAR(IDEPTH)
+	cli
+	IDEPTH_DECR
 	jmp	*%esi
 
 /*
 -766,9
+768,10  IDTVEC(trap10)
 	INTRENTRY
 	pushl	CPUVAR(ILEVEL)
 	pushl	%esp
+	pushl	$0			# dummy arg
 	incl	_C_LABEL(uvmexp)+V_TRAP
 	call	_C_LABEL(npxintr)
-	addl	$8,%esp
+	addl	$12,%esp
 	INTRFASTEXIT
 #else
 	ZTRAP(T_ARITHTRAP)
Index: i386/i386/genassym.cf
============================================================
=======
--- i386/i386/genassym.cf	(revision 1728)
+++ i386/i386/genassym.cf	(working copy)
 -304,6
+304,7  define	CPU_INFO_IUNMASK	offsetof(struct 
 define	CPU_INFO_ILEVEL		offsetof(struct cpu_info,
ci_ilevel)
 define	CPU_INFO_IDEPTH		offsetof(struct cpu_info,
ci_idepth)
 define	CPU_INFO_ISOURCES	offsetof(struct cpu_info,
ci_isources)
+define	CPU_INFO_INTRSTACK	offsetof(struct cpu_info,
ci_intrstack)
 
 if NIOAPIC > 0
 define		IOAPIC_SC_REG		offsetof(struct ioapic_softc,
sc_reg)
 -366,3
+367,4  define	PSL_AC			PSL_AC
 define	PSL_MBO			PSL_MBO
 define	PSL_ID			PSL_ID
 define	PSL_VM			PSL_VM
+define	PSL_I			PSL_I
Index: i386/isa/npxvar.h
============================================================
=======
--- i386/isa/npxvar.h	(revision 1885)
+++ i386/isa/npxvar.h	(working copy)
 -87,4
+87,4  struct npx_softc {
 
 enum npx_type npxprobe1(bus_space_tag_t,
bus_space_handle_t, int);
 void npxattach(struct npx_softc *);
-int npxintr(void *, struct intrframe);
+int npxintr(void *, struct intrframe *);
Index: i386/isa/npx.c
============================================================
=======
--- i386/isa/npx.c	(revision 1914)
+++ i386/isa/npx.c	(working copy)
 -345,12
+345,11  npxattach(struct npx_softc *sc)
  * IRQ13 exception handling makes exceptions even less
precise than usual.
  */
 int
-npxintr(void *arg, struct intrframe iframe)
+npxintr(void *arg, struct intrframe *frame)
 {
 	struct cpu_info *ci = curcpu();
 	struct lwp *l = ci->ci_fpcurlwp;
 	union savefpu *addr;
-	struct intrframe *frame = &iframe;
 	struct npx_softc *sc;
 	ksiginfo_t ksi;
 
Index: x86/x86/intr.c
============================================================
=======
--- x86/x86/intr.c	(revision 1728)
+++ x86/x86/intr.c	(working copy)
 -119,6
+119,8  __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.2
 #include <sys/proc.h>
 #include <sys/errno.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <machine/atomic.h>
 #include <machine/i8259.h>
 #include <machine/cpu.h>
 -818,6
+820,9  cpu_intr_init(struct cpu_info *ci)
 #if NLAPIC > 0 && defined(MULTIPROCESSOR)
 	int i;
 #endif
+#if defined(INTRSTACKSIZE)
+	char *cp;
+#endif /* defined(INTRSTACKSIZE) */
 
 	MALLOC(isp, struct intrsource *, sizeof (struct
intrsource), M_DEVBUF,
 	    M_WAITOK|M_ZERO);
 -892,6
+897,11  cpu_intr_init(struct cpu_info *ci)
 
 	intr_calculatemasks(ci);
 
+#if defined(INTRSTACKSIZE)
+	cp = (char *)uvm_km_alloc(kernel_map, INTRSTACKSIZE, 0,
UVM_KMF_WIRED);
+	ci->ci_intrstack = cp + INTRSTACKSIZE -
sizeof(register_t);
+	ci->ci_idepth = -1;
+#endif /* defined(INTRSTACKSIZE) */
 }
 
 #ifdef MULTIPROCESSOR
Index: x86/x86/lapic.c
============================================================
=======
--- x86/x86/lapic.c	(revision 1915)
+++ x86/x86/lapic.c	(working copy)
 -78,7
+78,7  __KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.
 void		lapic_delay(int);
 void		lapic_microtime(struct timeval *);
 static u_int32_t lapic_gettick(void);
-void		lapic_clockintr(void *, struct intrframe);
+void		lapic_clockintr(void *, struct intrframe *);
 static void 	lapic_map(paddr_t);
 
 static void lapic_hwmask(struct pic *, int);
 -238,7
+238,7  u_int64_t lapic_frac_cycle_per_usec;
 u_int32_t lapic_delaytab[26];
 
 void
-lapic_clockintr(void *arg, struct intrframe frame)
+lapic_clockintr(void *arg, struct intrframe *frame)
 {
 #if defined(I586_CPU) || defined(I686_CPU) ||
defined(__x86_64__)
 #ifndef __HAVE_TIMECOUNTER
 -333,7
+333,7  lapic_clockintr(void *arg, struct intrfr
 #endif /* !__HAVE_TIMECOUNTER */
 #endif /* I586_CPU || I686_CPU || __x86_64__ */
 
-	hardclock((struct clockframe *)&frame);
+	hardclock((struct clockframe *)frame);
 }
 
 #if !defined(__HAVE_TIMECOUNTER) && defined(NTP)
Index: x86/isa/clock.c
============================================================
=======
--- x86/isa/clock.c	(revision 1915)
+++ x86/isa/clock.c	(working copy)
 -192,7
+192,7  int		gettick(void);
 void		sysbeep(int, int);
 static void     tickle_tc(void);
 
-static int	clockintr(void *, struct intrframe);
+static int	clockintr(void *, struct intrframe *);
 static void	rtcinit(void);
 static int	rtcget(mc_todregs *);
 static void	rtcput(mc_todregs *);
 -404,11
+404,11  tickle_tc(void) 
 }
 
 static int
-clockintr(void *arg, struct intrframe frame)
+clockintr(void *arg, struct intrframe *frame)
 {
 	tickle_tc();
 
-	hardclock((struct clockframe *)&frame);
+	hardclock((struct clockframe *)frame);
 
 #if NMCA > 0
 	if (MCA_system) {
Index: xen/include/cpu.h
============================================================
=======
--- xen/include/cpu.h	(revision 1571)
+++ xen/include/cpu.h	(working copy)
 -114,6
+114,7  struct cpu_info {
 	u_int32_t	ci_imask[NIPL];
 #endif
 	u_int32_t	ci_iunmask[NIPL];
+	void *		ci_intrstack;
 
 	paddr_t ci_idle_pcb_paddr;	/* PA of idle PCB */
 	u_int32_t ci_flags;		/* flags; see below */
 -271,7
+272,7  struct clockframe {
 #define	CLKF_USERMODE(frame)	USERMODE((frame)->cf_if.if_
cs, (frame)->cf_if.if_eflags)
 #define	CLKF_BASEPRI(frame)	(0)
 #define	CLKF_PC(frame)		((frame)->cf_if.if_eip)
-#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 1)
+#define	CLKF_INTR(frame)	(curcpu()->ci_idepth > 0)
 
 /*
  * This is used during profiling to integrate system time. 
It can safely
Index: xen/include/evtchn.h
============================================================
=======
--- xen/include/evtchn.h	(revision 1799)
+++ xen/include/evtchn.h	(working copy)
 -41,6
+41,7  extern struct evtsource *evtsource[];
 void events_default_setup(void);
 void init_events(void);
 unsigned int evtchn_do_event(int, struct intrframe *);
+void call_evtchn_do_event(int, struct intrframe *);
 int event_set_handler(int, int (*func)(void *), void *,
int, const char *);
 int event_remove_handler(int, int (*func)(void *), void *);
 
Index: xen/x86/intr.c
============================================================
=======
--- xen/x86/intr.c	(revision 1848)
+++ xen/x86/intr.c	(working copy)
 -120,6
+120,8  __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.1
 #include <sys/proc.h>
 #include <sys/errno.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <machine/atomic.h>
 #include <machine/i8259.h>
 #include <machine/cpu.h>
 -206,6
+208,7  void
 cpu_intr_init(struct cpu_info *ci)
 {
 	struct iplsource *ipl;
+	char *cp;
 	int i;
 
 	ci->ci_iunmask[0] = 0xfffffffe;
 -261,6
+264,10  cpu_intr_init(struct cpu_info *ci)
 	evcnt_attach_dynamic(&softxenevt_evtcnt,
EVCNT_TYPE_INTR, NULL,
 	    ci->ci_dev->dv_xname, "xenevt");
 #endif /* defined(DOM0OPS) */
+
+	cp = (char *)uvm_km_alloc(kernel_map, INTRSTACKSIZE, 0,
UVM_KMF_WIRED);
+	ci->ci_intrstack = cp + INTRSTACKSIZE -
sizeof(register_t);
+	ci->ci_idepth = -1;
 }
 
 #if NPCI > 0 || NISA > 0
Index: xen/i386/npx.c
============================================================
=======
--- xen/i386/npx.c	(revision 1609)
+++ xen/i386/npx.c	(working copy)
 -368,12
+368,11  npxattach(struct npx_softc *sc)
  * IRQ13 exception handling makes exceptions even less
precise than usual.
  */
 int
-npxintr(void *arg, struct intrframe iframe)
+npxintr(void *arg, struct intrframe *frame)
 {
 	struct cpu_info *ci = curcpu();
 	struct lwp *l = ci->ci_fpcurlwp;
 	union savefpu *addr;
-	struct intrframe *frame = &iframe;
 	struct npx_softc *sc;
 	ksiginfo_t ksi;
 
Index: xen/i386/spl.S
============================================================
=======
--- xen/i386/spl.S	(revision 1464)
+++ xen/i386/spl.S	(working copy)
 -105,11
+105,13  IDTVEC(spllower)
 #else /* defined(DDB) || defined(GPROF) */
 	movl	20(%esp),%ebx
 #endif /* defined(DDB) || defined(GPROF) */
-	movl	$1f,%esi		# address to resume loop at
-1:	movl	%ebx,%eax		# get cpl
+	movl	$.Lspllower_resume,%esi	# address to resume loop at
+1:
+	CLI(%eax)
+.Lspllower_resume:
+	movl	%ebx,%eax		# get cpl
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	CLI(%ecx)
-	andl	CPUVAR(IPENDING),%eax		# any non-masked bits left?
+	andl	CPUVAR(IPENDING),%eax	# any non-masked bits left?
 	jz	2f
 	bsrl	%eax,%eax
 	btrl	%eax,CPUVAR(IPENDING)
 -138,15
+140,16  IDTVEC(spllower)
  *   ebx - cpl to restore
  *   esi - address to resume loop at
  *   edi - scratch for Xsoftnet
+ *
+ * called with interrupt disabled.
  */
 IDTVEC(doreti)
+	IDEPTH_DECR
 	popl	%ebx			# get previous priority
-	decl	CPUVAR(IDEPTH)
-	movl	$1f,%esi		# address to resume loop at
-8:
-1:	movl	%ebx,%eax
+	movl	$.Ldoreti_resume,%esi	# address to resume loop at
+.Ldoreti_resume:
+	movl	%ebx,%eax
 	movl	CPUVAR(IUNMASK)(,%eax,4),%eax
-	CLI(%ecx)
 	andl	CPUVAR(IPENDING),%eax
 	jz	2f
 	bsrl    %eax,%eax               # slow, but not worth
optimizing
 -176,7
+179,7  doreti_checkast:
 	call	_C_LABEL(trap)
 	addl	$4,%esp
 	CLI(%ecx)
-	jmp	5b
+	jmp	.Ldoreti_resume
 3:
 	CHECK_DEFERRED_SWITCH(%eax)
 	jnz	9f
 -184,7
+187,8  doreti_checkast:
     	jz	4f
 	call	_C_LABEL(stipending)
 	testl	%eax,%eax
-	jnz	8b
+	CLI(%eax)
+	jnz	.Ldoreti_resume
 4:
 	INTRFASTEXIT
 9:
 -192,3
+196,19  doreti_checkast:
 	call	_C_LABEL(pmap_load)
 	CLI(%ecx)
 	jmp	doreti_checkast	/* recheck ASTs */
+
+/*
+ * void evtchn_do_event(int evtch, struct intrframe *regs)
+ */
+
+NENTRY(call_evtchn_do_event)
+	IDEPTH_INCR
+	/*
+	 * IDEPTH_INCR leaves old %esp in %eax.
+	 */
+	pushl	8(%eax)	/* regs */
+	pushl	4(%eax)	/* evtch */
+	call	_C_LABEL(evtchn_do_event)
+	addl	$8, %esp
+	IDEPTH_DECR
+	ret
Index: xen/i386/vector.S
============================================================
=======
--- xen/i386/vector.S	(revision 1540)
+++ xen/i386/vector.S	(working copy)
 -202,15
+202,14  IDTVEC(resume_/**/name/**/num)						
 1:									
 	pushl	%esi							;
 	movl	$num,CPUVAR(ILEVEL)					;
+	IDEPTH_INCR /* leaves old %esp on stack	*/			;
 	STI(%eax)							;
-	incl	CPUVAR(IDEPTH)						;
 	movl	IS_HANDLERS(%ebp),%ebx					;
 	LOCK_KERNEL							;
 6:									
-	pushl	%esp							;
 	pushl	IH_ARG(%ebx)						;
 	call	*IH_FUN(%ebx)		/* call it */			;
-	addl	$8,%esp			/* toss the arg */		;
+	addl	$4,%esp			/* toss the arg */		;
 	movl	IH_IPL_NEXT(%ebx),%ebx	/* next handler in chain */	;
 	testl	%ebx,%ebx						;
 	jnz	6b							;
 -219,7
+218,6  IDTVEC(resume_/**/name/**/num)						
 	CLI(%eax)							;
 	unmask(num)			/* unmask it in hardware */	;
 	late_ack(num)							;
-	STI(%eax)							;
 	jmp	_C_LABEL(Xdoreti)	/* lower spl and do ASTs */	;
 
 # Just unmasking the event isn't enouth, we also need to
 -306,8
+304,8  _C_LABEL(xenev_stubs):
 #define EVCNTHI(x) _C_LABEL(x) + EV_EVCNTHI
 IDTVEC(softserial)
 	movl	$IPL_SOFTSERIAL, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -319,13
+317,14  IDTVEC(softserial)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softnet)
 	movl	$IPL_SOFTNET, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -349,13
+348,14  IDTVEC(softnet)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 IDTVEC(softclock)
 	movl	$IPL_SOFTCLOCK, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -368,14
+368,15  IDTVEC(softclock)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 
 #if defined(DOM0OPS)
 IDTVEC(softxenevt)
 	movl	$IPL_SOFTXENEVT, CPUVAR(ILEVEL)
+	IDEPTH_INCR
 	STI(%eax)
-	incl	CPUVAR(IDEPTH)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintlock)
 #endif
 -385,7
+386,8  IDTVEC(softxenevt)
 #ifdef MULTIPROCESSOR
 	call	_C_LABEL(x86_softintunlock)
 #endif
-	decl	CPUVAR(IDEPTH)
+	CLI(%eax)
+	IDEPTH_DECR
 	jmp	*%esi
 #endif /* defined(DOM0OPS) */
 
 -486,9
+488,10  IDTVEC(trap10)
 	INTRENTRY
 	pushl	CPUVAR(ILEVEL)
 	pushl	%esp
+	pushl	$0			# dummy arg
 	incl	_C_LABEL(uvmexp)+V_TRAP
 	call	_C_LABEL(npxintr)
-	addl	$8,%esp
+	addl	$12,%esp
 	INTRFASTEXIT
 #else
 	ZTRAP(T_ARITHTRAP)
Index: xen/i386/hypervisor_machdep.c
============================================================
=======
--- xen/i386/hypervisor_machdep.c	(revision 1540)
+++ xen/i386/hypervisor_machdep.c	(working copy)
 -215,7
+215,7  do_hypervisor_callback(struct intrframe 
 					printf("do_hypervisor_callback event %dn",
port);
 #endif
 				if (evtsource[port])
-					evtchn_do_event(port, regs);
+					call_evtchn_do_event(port, regs);
 #ifdef DOM0OPS
 				else
 					xenevt_event(port);
Index: xen/i386/genassym.cf
============================================================
=======
--- xen/i386/genassym.cf	(revision 1657)
+++ xen/i386/genassym.cf	(working copy)
 -271,6
+271,7  define	CPU_INFO_IUNMASK	offsetof(struct 
 define	CPU_INFO_ILEVEL		offsetof(struct cpu_info,
ci_ilevel)
 define	CPU_INFO_IDEPTH		offsetof(struct cpu_info,
ci_idepth)
 define	CPU_INFO_ISOURCES	offsetof(struct cpu_info,
ci_isources)
+define	CPU_INFO_INTRSTACK	offsetof(struct cpu_info,
ci_intrstack)
 
 define	SIZEOF_CPU_INFO		sizeof(struct cpu_info)
 
Index: xen/xen/evtchn.c
============================================================
=======
--- xen/xen/evtchn.c	(revision 1799)
+++ xen/xen/evtchn.c	(working copy)
 -234,7
+234,6  evtchn_do_event(int evtch, struct intrfr
 	ci->ci_ilevel = evtsource[evtch]->ev_maxlevel;
 	iplmask = evtsource[evtch]->ev_imask;
 	sti();
-	ci->ci_idepth++;
 #ifdef MULTIPROCESSOR
 	x86_intlock(regs);
 #endif
 -252,7
+251,6  evtchn_do_event(int evtch, struct intrfr
 			hypervisor_set_ipending(iplmask,
 			    evtch / 32, evtch % 32);
 			/* leave masked */
-			ci->ci_idepth--;
 			splx(ilevel);
 			return 0;
 		}
 -267,7
+265,6  evtchn_do_event(int evtch, struct intrfr
 	x86_intunlock(regs);
 #endif
 	hypervisor_enable_event(evtch);
-	ci->ci_idepth--;
 	splx(ilevel);
 
 	return 0;
[1-4]

about | contact  Other archives ( Real Estate discussion Medical topics )