PERFORCE change 136077 for review
Randall R. Stewart
rrs at FreeBSD.org
Sun Feb 24 12:42:14 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=136077
Change 136077 by rrs at 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) <<<
More information about the p4-projects
mailing list