Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Feb 2008 12:42:12 GMT
From:      "Randall R. Stewart" <rrs@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 136077 for review
Message-ID:  <200802241242.m1OCgCGQ032025@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=136077

Change 136077 by rrs@rrs-mips2-jnpr on 2008/02/24 12:41:22

	Fixes signal handling code. When a system call completes
	       we need to check to see if a ast() is needed, just like
	       the out: label does. Now a caught signal handler no longer
	       causes an infinite loop of syscall/intr/syscall/intr...

Affected files ...

.. //depot/projects/mips2-jnpr/src/sys/mips/mips/trap.c#13 edit

Differences ...

==== //depot/projects/mips2-jnpr/src/sys/mips/mips/trap.c#13 (text+ko) ====

@@ -98,6 +98,7 @@
 
 #ifdef TRAP_DEBUG
 int trap_debug = 1;
+
 #endif
 
 extern unsigned onfault_table[];
@@ -113,82 +114,84 @@
 static void log_bad_page_fault(char *, struct trapframe *, int);
 static void log_frame_dump(struct trapframe *frame);
 static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **);
+
 #ifdef TRAP_DEBUG
 static void trap_frame_dump(struct trapframe *frame);
+
 #endif
 extern char edata[];
 
-void (*machExceptionTable[])(void) = {
+void (*machExceptionTable[]) (void)= {
 /*
  * The kernel exception handlers.
  */
-	MipsKernIntr,			/* external interrupt */
-	MipsKernGenException,		/* TLB modification */
+	MipsKernIntr,		/* external interrupt */
+	MipsKernGenException,	/* TLB modification */
 	MipsKernTLBInvalidException,	/* TLB miss (load or instr. fetch) */
 	MipsKernTLBInvalidException,	/* TLB miss (store) */
-	MipsKernGenException,		/* address error (load or I-fetch) */
-	MipsKernGenException,		/* address error (store) */
-	MipsKernGenException,		/* bus error (I-fetch) */
-	MipsKernGenException,		/* bus error (load or store) */
-	MipsKernGenException,		/* system call */
-	MipsKernGenException,		/* breakpoint */
-	MipsKernGenException,		/* reserved instruction */
-	MipsKernGenException,		/* coprocessor unusable */
-	MipsKernGenException,		/* arithmetic overflow */
-	MipsKernGenException,		/* trap exception */
-	MipsKernGenException,		/* viritual coherence exception inst */
-	MipsKernGenException,		/* floating point exception */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* watch exception */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* reserved */
-	MipsKernGenException,		/* viritual coherence exception data */
+	MipsKernGenException,	/* address error (load or I-fetch) */
+	MipsKernGenException,	/* address error (store) */
+	MipsKernGenException,	/* bus error (I-fetch) */
+	MipsKernGenException,	/* bus error (load or store) */
+	MipsKernGenException,	/* system call */
+	MipsKernGenException,	/* breakpoint */
+	MipsKernGenException,	/* reserved instruction */
+	MipsKernGenException,	/* coprocessor unusable */
+	MipsKernGenException,	/* arithmetic overflow */
+	MipsKernGenException,	/* trap exception */
+	MipsKernGenException,	/* viritual coherence exception inst */
+	MipsKernGenException,	/* floating point exception */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* watch exception */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* reserved */
+	MipsKernGenException,	/* viritual coherence exception data */
 /*
  * The user exception handlers.
  */
-	MipsUserIntr,			/*  0 */
-	MipsUserGenException,		/*  1 */
-	MipsUserTLBInvalidException,	/*  2 */
-	MipsUserTLBInvalidException,	/*  3 */
-	MipsUserGenException,		/*  4 */
-	MipsUserGenException,		/*  5 */
-	MipsUserGenException,		/*  6 */
-	MipsUserGenException,		/*  7 */
-	MipsUserGenException,		/*  8 */
-	MipsUserGenException,		/*  9 */
-	MipsUserGenException,		/* 10 */
-	MipsUserGenException,		/* 11 */
-	MipsUserGenException,		/* 12 */
-	MipsUserGenException,		/* 13 */
-	MipsUserGenException,		/* 14 */
-	MipsUserGenException,		/* 15 */
-	MipsUserGenException,		/* 16 */
-	MipsUserGenException,		/* 17 */
-	MipsUserGenException,		/* 18 */
-	MipsUserGenException,		/* 19 */
-	MipsUserGenException,		/* 20 */
-	MipsUserGenException,		/* 21 */
-	MipsUserGenException,		/* 22 */
-	MipsUserGenException,		/* 23 */
-	MipsUserGenException,		/* 24 */
-	MipsUserGenException,		/* 25 */
-	MipsUserGenException,		/* 26 */
-	MipsUserGenException,		/* 27 */
-	MipsUserGenException,		/* 28 */
-	MipsUserGenException,		/* 29 */
-	MipsUserGenException,		/* 20 */
-	MipsUserGenException,		/* 31 */
+	MipsUserIntr,		/* 0 */
+	MipsUserGenException,	/* 1 */
+	MipsUserTLBInvalidException,	/* 2 */
+	MipsUserTLBInvalidException,	/* 3 */
+	MipsUserGenException,	/* 4 */
+	MipsUserGenException,	/* 5 */
+	MipsUserGenException,	/* 6 */
+	MipsUserGenException,	/* 7 */
+	MipsUserGenException,	/* 8 */
+	MipsUserGenException,	/* 9 */
+	MipsUserGenException,	/* 10 */
+	MipsUserGenException,	/* 11 */
+	MipsUserGenException,	/* 12 */
+	MipsUserGenException,	/* 13 */
+	MipsUserGenException,	/* 14 */
+	MipsUserGenException,	/* 15 */
+	MipsUserGenException,	/* 16 */
+	MipsUserGenException,	/* 17 */
+	MipsUserGenException,	/* 18 */
+	MipsUserGenException,	/* 19 */
+	MipsUserGenException,	/* 20 */
+	MipsUserGenException,	/* 21 */
+	MipsUserGenException,	/* 22 */
+	MipsUserGenException,	/* 23 */
+	MipsUserGenException,	/* 24 */
+	MipsUserGenException,	/* 25 */
+	MipsUserGenException,	/* 26 */
+	MipsUserGenException,	/* 27 */
+	MipsUserGenException,	/* 28 */
+	MipsUserGenException,	/* 29 */
+	MipsUserGenException,	/* 20 */
+	MipsUserGenException,	/* 31 */
 };
 
 char *trap_type[] = {
@@ -228,18 +231,21 @@
 
 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
 struct trapdebug trapdebug[TRAPSIZE], *trp = trapdebug;
+
 #endif
 
 #if defined(DDB) || defined(DEBUG)
 void stacktrace(struct trapframe *);
 void logstacktrace(struct trapframe *);
-int  kdbpeek(int *);
+int kdbpeek(int *);
+
 /* extern functions printed by name in stack backtraces */
 extern void MipsTLBMiss(void);
 extern void MipsUserSyscallException(void);
 extern char _locore[];
 extern char _locoreEnd[];
-#endif	/* DDB || DEBUG */
+
+#endif				/* DDB || DEBUG */
 
 extern void MipsSwitchFPState(struct thread *, struct trapframe *);
 extern void MipsFPTrap(u_int, u_int, u_int);
@@ -328,12 +334,12 @@
 	}
 
 	/*
-	 * Enable hardware interrupts if they were on before the trap.
-	 * If it was off disable all (splhigh) so we don't accidently
-	 * enable it when doing a spllower().
+	 * Enable hardware interrupts if they were on before the trap. If it
+	 * was off disable all (splhigh) so we don't accidently enable it
+	 * when doing a spllower().
 	 */
 /*XXX do in locore? */
-	if(trapframe->sr & SR_INT_ENAB) {
+	if (trapframe->sr & SR_INT_ENAB) {
 		set_intr_mask(~(trapframe->sr & ALL_INT_MASK));
 		enableintr();
 	} else {
@@ -348,7 +354,7 @@
 		u_int32_t pid;
 
 		printf("trap type %x (%s - ", type,
-			trap_type[type & (~T_USER)]);
+		    trap_type[type & (~T_USER)]);
 
 		if (type & T_USER)
 			printf("user mode)\n");
@@ -359,12 +365,12 @@
 		printf("cpuid = %d\n", PCPU_GET(cpuid));
 #endif
 		MachTLBGetPID(pid);
- 		printf("badaddr = %p, pc = %p, ra = %p, sp = %p, sr = 0x%x, pid = %d, ASID = 0x%x\n",
+		printf("badaddr = %p, pc = %p, ra = %p, sp = %p, sr = 0x%x, pid = %d, ASID = 0x%x\n",
 		    trapframe->badvaddr, trapframe->pc, trapframe->ra,
 		    trapframe->sp, trapframe->sr,
 		    (curproc ? curproc->p_pid : -1), pid);
 
-		switch(type & ~T_USER) {
+		switch (type & ~T_USER) {
 		case T_TLB_MOD:
 		case T_TLB_LD_MISS:
 		case T_TLB_ST_MISS:
@@ -380,7 +386,7 @@
 			break;
 		}
 		if ((last_badvaddr == this_badvaddr) &&
-				((type & ~T_USER) != T_SYSCALL)) {
+		    ((type & ~T_USER) != T_SYSCALL)) {
 			if (++count == 3) {
 				trap_frame_dump(trapframe);
 				panic("too many faults at %p\n", last_badvaddr);
@@ -391,14 +397,13 @@
 		}
 	}
 #endif
-
 	switch (type) {
 	case T_MCHECK:
 #ifdef DDB
-	  kdb_trap(type, 0, trapframe);
+		kdb_trap(type, 0, trapframe);
 #endif
-	  panic("MCHECK\n");	  
-	  break;
+		panic("MCHECK\n");
+		break;
 	case T_TLB_MOD:
 		/* check for kernel address */
 		if (KERNLAND(trapframe->badvaddr)) {
@@ -406,7 +411,7 @@
 
 			PMAP_LOCK(kernel_pmap);
 			if (!(pte = pmap_segmap(kernel_pmap,
-					trapframe->badvaddr)))
+			    trapframe->badvaddr)))
 				panic("trap: ktlbmod: invalid segmap");
 			pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
 			entry = *pte;
@@ -442,52 +447,54 @@
 		}
 		/* FALLTHROUGH */
 
-	case T_TLB_MOD+T_USER:
-	    {
-		vm_offset_t pa;
-		pmap = &p->p_vmspace->vm_pmap;
+	case T_TLB_MOD + T_USER:
+		{
+			vm_offset_t pa;
+
+			pmap = &p->p_vmspace->vm_pmap;
 
-		PMAP_LOCK(pmap);
-		if (!(pte = pmap_segmap(pmap, trapframe->badvaddr)))
-			panic("trap: utlbmod: invalid segmap");
-		pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
-		entry = *pte;
+			PMAP_LOCK(pmap);
+			if (!(pte = pmap_segmap(pmap, trapframe->badvaddr)))
+				panic("trap: utlbmod: invalid segmap");
+			pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1);
+			entry = *pte;
 #ifdef SMP
-		/* It is possible that some other CPU changed m-bit */
-		if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
+			/* It is possible that some other CPU changed m-bit */
+			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
+				trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
+				pmap_update_page(pmap, trapframe->badvaddr, entry);
+				PMAP_UNLOCK(pmap);
+				goto out;
+			}
+#else
+			if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
+				panic("trap: utlbmod: invalid pte");
+			}
+#endif
+
+			if (entry & mips_pg_ro_bit()) {
+				/* write to read only page */
+				ftype = VM_PROT_WRITE;
+				PMAP_UNLOCK(pmap);
+				goto dofault;
+			}
+			entry |= mips_pg_m_bit();
+			*pte = entry;
 			trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
 			pmap_update_page(pmap, trapframe->badvaddr, entry);
+			trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT);
+			pa = mips_tlbpfn_to_paddr(entry);
+			if (!page_is_managed(pa))
+				panic("trap: utlbmod: unmanaged page");
+			pmap_set_modified(pa);
+
 			PMAP_UNLOCK(pmap);
+			if (!usermode) {
+				return (trapframe->pc);
+			}
 			goto out;
 		}
-#else
-		if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) {
-			panic("trap: utlbmod: invalid pte");
-		}
-#endif
 
-		if (entry & mips_pg_ro_bit()) {
-			/* write to read only page */
-			ftype = VM_PROT_WRITE;
-			PMAP_UNLOCK(pmap);
-			goto dofault;
-		}
-		entry |= mips_pg_m_bit();
-		*pte = entry;
-		trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET);
-		pmap_update_page(pmap, trapframe->badvaddr, entry);
-		trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT);
-		pa = mips_tlbpfn_to_paddr(entry);
-		if (!page_is_managed(pa))
-			panic("trap: utlbmod: unmanaged page");
-		pmap_set_modified(pa);
-
-		PMAP_UNLOCK(pmap);
-		if (!usermode)
-			return (trapframe->pc);
-		goto out;
-	    }
-
 	case T_TLB_LD_MISS:
 	case T_TLB_ST_MISS:
 		ftype = (type == T_TLB_ST_MISS) ? VM_PROT_WRITE : VM_PROT_READ;
@@ -496,7 +503,7 @@
 			vm_offset_t va;
 			int rv;
 
-		kernel_fault:
+	kernel_fault:
 			va = trunc_page((vm_offset_t)trapframe->badvaddr);
 			rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL);
 			if (rv == KERN_SUCCESS)
@@ -514,96 +521,98 @@
 		if ((i = td->td_pcb->pcb_onfault) == 0)
 			goto err;
 		/* check for fuswintr() or suswintr() getting a page fault */
-		if (i == 4)
+		if (i == 4) {
 			return (onfault_table[i]);
+		}
 		goto dofault;
 
-	case T_TLB_LD_MISS+T_USER:
+	case T_TLB_LD_MISS + T_USER:
 		ftype = VM_PROT_READ;
 		goto dofault;
 
-	case T_TLB_ST_MISS+T_USER:
+	case T_TLB_ST_MISS + T_USER:
 		ftype = VM_PROT_WRITE;
-	dofault:
-	    {
-		vm_offset_t va;
-		struct vmspace *vm;
-		vm_map_t map;
-		int rv = 0;
-		int flag;
+dofault:
+		{
+			vm_offset_t va;
+			struct vmspace *vm;
+			vm_map_t map;
+			int rv = 0;
+			int flag;
+
+			vm = p->p_vmspace;
+			map = &vm->vm_map;
+			va = trunc_page((vm_offset_t)trapframe->badvaddr);
+			if ((vm_offset_t)trapframe->badvaddr < VM_MIN_KERNEL_ADDRESS) {
+				if (ftype & VM_PROT_WRITE)
+					flag = VM_FAULT_DIRTY;
+				else
+					flag = VM_FAULT_NORMAL;
+			} else {
+				/*
+				 * Don't allow user-mode faults in kernel
+				 * address space.
+				 */
+				goto nogo;
+			}
 
-		vm = p->p_vmspace;
-		map = &vm->vm_map;
-		va = trunc_page((vm_offset_t)trapframe->badvaddr);
-		if ((vm_offset_t)trapframe->badvaddr < VM_MIN_KERNEL_ADDRESS) {
-			if (ftype & VM_PROT_WRITE)
-				flag = VM_FAULT_DIRTY;
-			else
-				flag = VM_FAULT_NORMAL;
-		} else {
 			/*
-			 * Don't allow user-mode faults in kernel address space.
+			 * Keep swapout from messing with us during this
+			 * critical time.
 			 */
-			goto nogo;
-		}
+			PROC_LOCK(p);
+			++p->p_lock;
+			PROC_UNLOCK(p);
 
-		/*
-		 * Keep swapout from messing with us during this
-		 *	critical time.
-		 */
-		PROC_LOCK(p);
-		++p->p_lock;
-		PROC_UNLOCK(p);
+			rv = vm_fault(map, va, ftype, flag);
 
-		rv = vm_fault(map, va, ftype, flag);
-
-		PROC_LOCK(p);
-		--p->p_lock;
-		PROC_UNLOCK(p);
+			PROC_LOCK(p);
+			--p->p_lock;
+			PROC_UNLOCK(p);
 #ifdef VMFAULT_TRACE
-		printf("vm_fault(%x (pmap %x), %x (%x), %x, %d) -> %x at pc %x\n",
-		       map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, flag,
-		       rv, trapframe->pc);
+			printf("vm_fault(%x (pmap %x), %x (%x), %x, %d) -> %x at pc %x\n",
+			    map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, flag,
+			    rv, trapframe->pc);
 #endif
 
-		if (rv == KERN_SUCCESS) {
-			if (!usermode)
-				return (trapframe->pc);
-			goto out;
-		}
-nogo:
-		if (!usermode) {
-			if ((i = td->td_pcb->pcb_onfault) != 0) {
-				td->td_pcb->pcb_onfault = 0;
-				return (onfault_table[i]);
+			if (rv == KERN_SUCCESS) {
+				if (!usermode) {
+					return (trapframe->pc);
+				}
+				goto out;
+			}
+	nogo:
+			if (!usermode) {
+				if ((i = td->td_pcb->pcb_onfault) != 0) {
+					td->td_pcb->pcb_onfault = 0;
+					return (onfault_table[i]);
+				}
+				goto err;
 			}
-			goto err;
-		}
+			ucode = ftype;
+			i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+			addr = trapframe->pc;
 
-		ucode = ftype;
-		i = ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
-		addr = trapframe->pc;
+			msg = "BAD_PAGE_FAULT";
+			log_bad_page_fault(msg, trapframe, type);
 
-		msg = "BAD_PAGE_FAULT";
-		log_bad_page_fault(msg, trapframe, type);
+			break;
+		}
 
-		break;
-	    }
-
-	case T_ADDR_ERR_LD+T_USER:	/* misaligned or kseg access */
-	case T_ADDR_ERR_ST+T_USER:	/* misaligned or kseg access */
+	case T_ADDR_ERR_LD + T_USER:	/* misaligned or kseg access */
+	case T_ADDR_ERR_ST + T_USER:	/* misaligned or kseg access */
 		if (allow_unaligned_acc) {
 			int mode;
 
-			if (type == (T_ADDR_ERR_LD+T_USER))
+			if (type == (T_ADDR_ERR_LD + T_USER))
 				mode = VM_PROT_READ;
 			else
 				mode = VM_PROT_WRITE;
 
 			/*
-			 * ADDR_ERR faults have higher priority than
-			 * TLB Miss faults.  Therefore, it is necessary
-			 * to verify that the faulting address is a valid
+			 * ADDR_ERR faults have higher priority than TLB
+			 * Miss faults.  Therefore, it is necessary to
+			 * verify that the faulting address is a valid
 			 * virtual address within the process' address space
 			 * before trying to emulate the unaligned access.
 			 */
@@ -620,9 +629,9 @@
 
 		/* FALL THROUGH */
 
-	case T_BUS_ERR_IFETCH+T_USER:	/* BERR asserted to cpu */
-	case T_BUS_ERR_LD_ST+T_USER:	/* BERR asserted to cpu */
-		ucode = 0;		/* XXX should be VM_PROT_something */
+	case T_BUS_ERR_IFETCH + T_USER:	/* BERR asserted to cpu */
+	case T_BUS_ERR_LD_ST + T_USER:	/* BERR asserted to cpu */
+		ucode = 0;	/* XXX should be VM_PROT_something */
 		i = SIGBUS;
 		addr = trapframe->pc;
 		if (!msg)
@@ -630,288 +639,299 @@
 		log_bad_page_fault(msg, trapframe, type);
 		break;
 
-	case T_SYSCALL+T_USER:
+	case T_SYSCALL + T_USER:
 		{
-		struct trapframe *locr0 = td->td_frame;
-		struct sysent *callp;
-		unsigned int code;
-		unsigned int tpc;
-		int nargs, nsaved;
-		register_t args[8];
+			struct trapframe *locr0 = td->td_frame;
+			struct sysent *callp;
+			unsigned int code;
+			unsigned int tpc;
+			int nargs, nsaved;
+			register_t args[8];
 
-		/*
-		 * note: PCPU_LAZY_INC() can only be used if we can afford
-		 * occassional inaccuracy in the count.
-		 */
-		PCPU_LAZY_INC(cnt.v_syscall);
-		if (td->td_ucred != p->p_ucred)
-			cred_update_thread(td);
-#ifdef KSE
-		if (p->p_flag & P_SA)
-			thread_user_enter(td);
-#endif		
-		/* compute next PC after syscall instruction */
-		tpc = trapframe->pc; /* Remember if restart */
-		if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
-			locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
-						      0);
-		} else {
-			locr0->pc += sizeof(int);
-		}
-		code = locr0->v0;
-
-		switch (code) {
-		case SYS_syscall:
 			/*
-			 * Code is first argument, followed by actual args.
+			 * note: PCPU_LAZY_INC() can only be used if we can
+			 * afford occassional inaccuracy in the count.
 			 */
-			code = locr0->a0;
-			args[0] = locr0->a1;
-			args[1] = locr0->a2;
-			args[2] = locr0->a3;
-			nsaved = 3;
-			break;
+			PCPU_LAZY_INC(cnt.v_syscall);
+			if (td->td_ucred != p->p_ucred)
+				cred_update_thread(td);
+#ifdef KSE
+			if (p->p_flag & P_SA)
+				thread_user_enter(td);
+#endif
+			/* compute next PC after syscall instruction */
+			tpc = trapframe->pc;	/* Remember if restart */
+			if (DELAYBRANCH(trapframe->cause)) {	/* Check BD bit */
+				locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0,
+				    0);
+			} else {
+				locr0->pc += sizeof(int);
+			}
+			code = locr0->v0;
 
-		case SYS___syscall:
-			/*
-			 * Like syscall, but code is a quad, so as to maintain
-			 * quad alignment for the rest of the arguments.
-			 */
-			if (_QUAD_LOWWORD == 0) {
+			switch (code) {
+			case SYS_syscall:
+				/*
+				 * Code is first argument, followed by
+				 * actual args.
+				 */
 				code = locr0->a0;
-			} else {
-				code = locr0->a1;
+				args[0] = locr0->a1;
+				args[1] = locr0->a2;
+				args[2] = locr0->a3;
+				nsaved = 3;
+				break;
+
+			case SYS___syscall:
+				/*
+				 * Like syscall, but code is a quad, so as
+				 * to maintain quad alignment for the rest
+				 * of the arguments.
+				 */
+				if (_QUAD_LOWWORD == 0) {
+					code = locr0->a0;
+				} else {
+					code = locr0->a1;
+				}
+				args[0] = locr0->a2;
+				args[1] = locr0->a3;
+				nsaved = 2;
+				quad_syscall = 1;
+				break;
+
+			default:
+				args[0] = locr0->a0;
+				args[1] = locr0->a1;
+				args[2] = locr0->a2;
+				args[3] = locr0->a3;
+				nsaved = 4;
 			}
-			args[0] = locr0->a2;
-			args[1] = locr0->a3;
-			nsaved = 2;
-			quad_syscall = 1;
-			break;
-
-		default:
-			args[0] = locr0->a0;
-			args[1] = locr0->a1;
-			args[2] = locr0->a2;
-			args[3] = locr0->a3;
-			nsaved = 4;
-		}
-#if TRAP_DEBUG
-		printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
+#ifdef TRAP_DEBUG
+			printf("SYSCALL #%d pid:%u\n", code, p->p_pid);
 #endif
 
-		if (p->p_sysent->sv_mask)
-			code &= p->p_sysent->sv_mask;
+			if (p->p_sysent->sv_mask)
+				code &= p->p_sysent->sv_mask;
 
-		if (code >= p->p_sysent->sv_size)
-			callp = &p->p_sysent->sv_table[0];
-		else
-			callp = &p->p_sysent->sv_table[code];
+			if (code >= p->p_sysent->sv_size)
+				callp = &p->p_sysent->sv_table[0];
+			else
+				callp = &p->p_sysent->sv_table[code];
 
-		nargs = callp->sy_narg;
+			nargs = callp->sy_narg;
 
-		if (nargs > nsaved) {
-			i = copyin((caddr_t)(locr0->sp +
-			    4 * sizeof(register_t)), (caddr_t)&args[nsaved],
-			    (u_int)(nargs - nsaved) * sizeof(register_t));
-			if (i) {
-				locr0->v0 = i;
-				locr0->a3 = 1;
+			if (nargs > nsaved) {
+				i = copyin((caddr_t)(locr0->sp +
+				    4 * sizeof(register_t)), (caddr_t)&args[nsaved],
+				    (u_int)(nargs - nsaved) * sizeof(register_t));
+				if (i) {
+					locr0->v0 = i;
+					locr0->a3 = 1;
 #ifdef KTRACE
-				if (KTRPOINT(td, KTR_SYSCALL))
-					ktrsyscall(code, nargs, args);
+					if (KTRPOINT(td, KTR_SYSCALL))
+						ktrsyscall(code, nargs, args);
 #endif
-				goto done;
+					goto done;
+				}
 			}
-		}
-
 #ifdef KTRACE
-		if (KTRPOINT(td, KTR_SYSCALL))
-			ktrsyscall(code, nargs, args);
+			if (KTRPOINT(td, KTR_SYSCALL))
+				ktrsyscall(code, nargs, args);
 #endif
-		td->td_retval[0] = 0;
-		td->td_retval[1] = locr0->v1;
+			td->td_retval[0] = 0;
+			td->td_retval[1] = locr0->v1;
 
 #if !defined(SMP) && (defined(DDB) || defined(DEBUG))
-		if (trp == trapdebug)
-			trapdebug[TRAPSIZE - 1].code = code;
-		else
-			trp[-1].code = code;
+			if (trp == trapdebug)
+				trapdebug[TRAPSIZE - 1].code = code;
+			else
+				trp[-1].code = code;
 #endif
-		STOPEVENT(p, S_SCE, nargs);
+			STOPEVENT(p, S_SCE, nargs);
 
-		PTRACESTOP_SC(p, td, S_PT_SCE);
-
-		i = (*callp->sy_call)(td, args);
-
+			PTRACESTOP_SC(p, td, S_PT_SCE);
+			i = (*callp->sy_call) (td, args);
 #if 0
-		/*
-		 * Reinitialize proc pointer `p' as it may be different
-		 * if this is a child returning from fork syscall.
-		 */
-		td = curthread;
-		locr0 = td->td_frame;
+			/*
+			 * Reinitialize proc pointer `p' as it may be
+			 * different if this is a child returning from fork
+			 * syscall.
+			 */
+			td = curthread;
+			locr0 = td->td_frame;
 #endif
-		trapdebug_enter(locr0, -code);
-		switch (i) {
-		case 0:
-			if (quad_syscall && code != SYS_lseek) {
-				/*
-				 * System call invoked through the SYS___syscall
-				 * interface but the return value is really
-				 * just 32 bits.
-				 */
-				locr0->v0 = td->td_retval[0];
-				if (_QUAD_LOWWORD)
-					locr0->v1 = td->td_retval[0];
-				locr0->a3 = 0;
-			} else {
-				locr0->v0 = td->td_retval[0];
-				locr0->v1 = td->td_retval[1];
-				locr0->a3 = 0;
-			}
-			break;
+			trapdebug_enter(locr0, -code);
+			switch (i) {
+			case 0:
+				if (quad_syscall && code != SYS_lseek) {
+					/*
+					 * System call invoked through the
+					 * SYS___syscall interface but the
+					 * return value is really just 32
+					 * bits.
+					 */
+					locr0->v0 = td->td_retval[0];
+					if (_QUAD_LOWWORD)
+						locr0->v1 = td->td_retval[0];
+					locr0->a3 = 0;
+				} else {
+					locr0->v0 = td->td_retval[0];
+					locr0->v1 = td->td_retval[1];
+					locr0->a3 = 0;
+				}
+				break;
 
-		case ERESTART:
-			locr0->pc = tpc;
-			break;
+			case ERESTART:
+				locr0->pc = tpc;
+				break;
 
-		case EJUSTRETURN:
-			break;	/* nothing to do */
+			case EJUSTRETURN:
+				break;	/* nothing to do */
 
-		default:
-			if (quad_syscall && code != SYS_lseek) {
-				locr0->v0 = i;
-				if (_QUAD_LOWWORD)
-					locr0->v1 = i;
-				locr0->a3 = 1;
-			} else {
-				locr0->v0 = i;
-				locr0->a3 = 1;
+			default:
+				if (quad_syscall && code != SYS_lseek) {
+					locr0->v0 = i;
+					if (_QUAD_LOWWORD)
+						locr0->v1 = i;
+					locr0->a3 = 1;
+				} else {
+					locr0->v0 = i;
+					locr0->a3 = 1;
+				}
 			}
-		}
 
-		/*
-		 * The sync'ing of I & D caches for SYS_ptrace() is
-		 * done by procfs_domem() through procfs_rwmem() instead
-		 * of being done here under a special check for SYS_ptrace().
-		 */
+			/*
+			 * The sync'ing of I & D caches for SYS_ptrace() is
+			 * done by procfs_domem() through procfs_rwmem()
+			 * instead of being done here under a special check
+			 * for SYS_ptrace().
+			 */
 	done:
-		/*
-		 * Check for misbehavior.
-		 */
-		WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
-		    (code >= 0 && code < SYS_MAXSYSCALL) ?
-		    syscallnames[code] : "???");
-		KASSERT(td->td_critnest == 0,
-		    ("System call %s returning in a critical section",
-			(code >= 0 && code < SYS_MAXSYSCALL) ?
-			syscallnames[code] : "???"));
-		KASSERT(td->td_locks == 0,
-		    ("System call %s returning with %d locks held",
-			(code >= 0 && code < SYS_MAXSYSCALL) ?
-			syscallnames[code] : "???",
-			td->td_locks));
-
-		userret(td, trapframe);
-
+			/*
+			 * Check for misbehavior.
+			 */
+			WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
+			    (code >= 0 && code < SYS_MAXSYSCALL) ?
+			    syscallnames[code] : "???");
+			KASSERT(td->td_critnest == 0,
+			    ("System call %s returning in a critical section",
+			    (code >= 0 && code < SYS_MAXSYSCALL) ?
+			    syscallnames[code] : "???"));
+			KASSERT(td->td_locks == 0,
+			    ("System call %s returning with %d locks held",
+			    (code >= 0 && code < SYS_MAXSYSCALL) ?
+			    syscallnames[code] : "???",
+			    td->td_locks));
+			userret(td, trapframe);
 #ifdef KTRACE
-		if (KTRPOINT(p, KTR_SYSRET))
-			ktrsysret(code, i, td->td_retval[0]);
+			if (KTRPOINT(p, KTR_SYSRET))
+				ktrsysret(code, i, td->td_retval[0]);
 #endif
-		/*
-		 * This works because errno is findable through the
-		 * register set.  If we ever support an emulation where this
-		 * is not the case, this code will need to be revisited.
-		 */
-		STOPEVENT(p, S_SCX, code);
+			/*
+			 * This works because errno is findable through the
+			 * register set.  If we ever support an emulation
+			 * where this is not the case, this code will need
+			 * to be revisited.
+			 */
+			STOPEVENT(p, S_SCX, code);
 
-		PTRACESTOP_SC(p, td, S_PT_SCX);
+			PTRACESTOP_SC(p, td, S_PT_SCX);
 
-		return (trapframe->pc);
-	    }
+			mtx_assert(&Giant, MA_NOTOWNED);
+			if (curthread->td_flags & (TDF_ASTPENDING | TDF_NEEDRESCHED)) {
+				ast(trapframe);
+			}
+			return (trapframe->pc);
+		}
 
 #ifdef DDB
 	case T_BREAK:
 		kdb_trap(type, 0, trapframe);
-		return(trapframe->pc);
+		return (trapframe->pc);
 #endif
 
-	case T_BREAK+T_USER:
-	    {
-		unsigned int va, instr;
+	case T_BREAK + T_USER:
+		{
+			unsigned int va, instr;
 
-		/* compute address of break instruction */
-		va = trapframe->pc;
-		if (DELAYBRANCH(trapframe->cause))
-			va += sizeof(int);
+			/* compute address of break instruction */
+			va = trapframe->pc;
+			if (DELAYBRANCH(trapframe->cause))
+				va += sizeof(int);
 
-		/* read break instruction */
-		instr = fuword((caddr_t)va);
+			/* read break instruction */
+			instr = fuword((caddr_t)va);
 #if 0
-		printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
-		    p->p_comm, p->p_pid, instr, trapframe->pc,
-		    p->p_md.md_ss_addr, p->p_md.md_ss_instr); /* XXX */
+			printf("trap: %s (%d) breakpoint %x at %x: (adr %x ins %x)\n",
+			    p->p_comm, p->p_pid, instr, trapframe->pc,
+			    p->p_md.md_ss_addr, p->p_md.md_ss_instr);	/* XXX */
 #endif
-		if (td->td_md.md_ss_addr != va || instr != BREAK_SSTEP) {
+			if (td->td_md.md_ss_addr != va || instr != BREAK_SSTEP) {
+				i = SIGTRAP;
+				addr = trapframe->pc;
+				break;
+			}
+			/*
+			 * The restoration of the original instruction and
+			 * the clearing of the berakpoint will be done later
+			 * by the call to ptrace_clear_single_step() in
+			 * issignal() when SIGTRAP is processed.
+			 */
+			addr = trapframe->pc;
 			i = SIGTRAP;
-			addr = trapframe->pc;
 			break;
 		}
 
-		/*
-		 * The restoration of the original instruction and the
-		 * clearing of the berakpoint will be done later by the
-		 * call to ptrace_clear_single_step() in issignal()
-		 * when SIGTRAP is processed.
-		 */
-		addr = trapframe->pc;
-		i = SIGTRAP;
-		break;
-	    }
+	case T_IWATCH + T_USER:
+	case T_DWATCH + T_USER:
+		{
+			unsigned int va;
 
-	case T_IWATCH+T_USER:
-	case T_DWATCH+T_USER:
-		{
-		unsigned int va;
-		/* compute address of trapped instruction */
-		va = trapframe->pc;
-		if (DELAYBRANCH(trapframe->cause))
-			va += sizeof(int);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200802241242.m1OCgCGQ032025>