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>