Date: Sun, 5 Jul 2009 23:38:38 GMT From: Arnar Mar Sig <antab@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 165661 for review Message-ID: <200907052338.n65NcccH045645@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165661 Change 165661 by antab@antab_farm on 2009/07/05 23:37:54 * Add fault handling to copyin/out, fu- and su-byte/word * Add sigcode Affected files ... .. //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#5 edit .. //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#21 edit .. //depot/projects/avr32/src/sys/avr32/avr32/support.S#13 edit .. //depot/projects/avr32/src/sys/avr32/avr32/switch.S#15 edit .. //depot/projects/avr32/src/sys/avr32/avr32/trap.c#13 edit .. //depot/projects/avr32/src/sys/avr32/include/asm.h#8 edit .. //depot/projects/avr32/src/sys/avr32/include/pcb.h#6 edit Differences ... ==== //depot/projects/avr32/src/sys/avr32/avr32/genassym.c#5 (text+ko) ==== @@ -36,6 +36,8 @@ #include <vm/vm.h> #include <vm/pmap.h> #include <machine/frame.h> +#include <machine/pcb.h> +#include <machine/vmparam.h> ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); @@ -49,3 +51,9 @@ ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); + +ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb)); +ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault)); + +ASSYM(VM_MAXUSER_ADDRESS,VM_MAXUSER_ADDRESS); + ==== //depot/projects/avr32/src/sys/avr32/avr32/pmap.c#21 (text+ko) ==== @@ -319,6 +319,7 @@ PMAP_LOCK(pmap); + pte = pmap_pte(pmap, va); if (wired && ((*pte & PTE_WIRED) == 0)) { pmap->pm_stats.wired_count++; } @@ -1331,8 +1332,6 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, vm_offset_t *addr, vm_size_t size) { - // Not sure what to do here, unimplemented in ARM - avr32_debug("pmap_align_superpage: Needs implementing?\n"); } /* ==== //depot/projects/avr32/src/sys/avr32/avr32/support.S#13 (text+ko) ==== @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD: $"); .data - .globl intrcnt, eintrcnt intrcnt: .space IRQ_COUNT * 4 @@ -48,6 +47,9 @@ eintrnames: .text +curpcb: + .word _C_LABEL(__pcpu) + PC_CURPCB + /* * memcpy/bcopy and bzero use byte access, this is slow and needs rewriting * later on @@ -129,23 +131,24 @@ * r10: unsigned len; */ ENTRY(copyin) + /** + * r9: Temp for user/kernel memory split + * r8: Temp for from + len + */ stm --sp, r7,lr /* Create call frame */ mov r7, sp /* Set framepointer */ + PCB_SET_ONFAULT(copy_fault_addr) - lddpc r9, copyin_split /* Load max userspace address */ - cp.w r9, r12 /* Is to address within user space ? */ - brge copyin_fault /* No */ + add r8, r12, r10 /* from + len */ + lddpc r9, copy_split /* Load max userspace address */ + cp.w r9, r8 /* Is to address within user space ? */ + brge copy_fault /* No */ call bcopy /* bcopy does all the work */ + + PCB_CLEAR_ONFAULT() mov r12, 0 /* Return 0 */ ldm sp++, r7,pc /* Restore framepoiner and return */ - -copyin_fault: - mov r12, EFAULT - ldm sp++, r7,pc /* Restore framepoiner and return */ - -copyin_split: - .long 0x80000000 /* Max userspace address */ END(copyin) /** @@ -156,28 +159,26 @@ * r10: unsigned len; */ ENTRY(copyout) + /** + * r9: Temp for user/kernel memory split + * r8: Temp for to + len + */ stm --sp, r7,lr /* Create call frame */ mov r7, sp /* Set framepointer */ + PCB_SET_ONFAULT(copy_fault_addr) - lddpc r9, copyout_split /* Load max userspace address */ - cp.w r9, r11 /* Is to address within user space ? */ - brge copyout_fault /* No */ + add r8, r11, r10 /* to + len */ + lddpc r9, copy_split /* Load max userspace address */ + cp.w r9, r8 /* Is to address within user space ? */ + brge copy_fault /* No */ call bcopy /* bcopy does all the work */ + + PCB_CLEAR_ONFAULT() mov r12, 0 /* Return 0 */ ldm sp++, r7,pc /* Restore framepoiner and return */ - -copyout_fault: - mov r12, EFAULT - ldm sp++, r7,pc /* Restore framepoiner and return */ - -copyout_split: - .long 0x80000000 /* Max userspace address */ END(copyout) - - - /** * Copy a null terminated string from the kernel address space into * the user address space. @@ -228,19 +229,48 @@ 4: retal r9 /* Return r9, is 0 or ENAMETOOLONG */ END(copystr) +/** + * Onfault for copy<in/out> functions + */ +copy_fault: + breakpoint + PCB_CLEAR_ONFAULT() + mov r12, EFAULT /* Return EFAULT */ + ldm sp++, r7,pc /* Restore framepointer and return */ +copy_fault_addr: + .long copy_fault -/* - * Fetch (load) a 32-bit word, a 16-bit word, or an 8-bit byte from user - * memory. All these functions are MPSAFE. +copy_split: + .long VM_MAXUSER_ADDRESS + +/** + * Fetch (load) a 8-bit byte from user memory + * r12: const void *base */ ENTRY(fubyte) + PCB_SET_ONFAULT(fusu_fault_addr) + lddpc r11, fusubyte_split + cp.w r12, r11 + brgt fusu_fault + ld.ub r12, r12 + PCB_CLEAR_ONFAULT() retal r12 END(fubyte) +/** + * Fetch (load) a 32-bit word from user memory + * r12: const void *base + */ ENTRY(fuword) ENTRY(fuword32) + PCB_SET_ONFAULT(fusu_fault_addr) + lddpc r11, fusuword32_split + cp.w r12, r11 + brgt fusu_fault + ld.w r12, r12 + PCB_CLEAR_ONFAULT() retal r12 END(fuword32) @@ -249,17 +279,35 @@ END(fuword64) /* - * Store a 32-bit word, a 16-bit word, or an 8-bit byte to user memory. - * All these functions are MPSAFE. + * Store a 8-bit byte to user memory. + * r12: void *base + * r11: int byte */ ENTRY(subyte) + PCB_SET_ONFAULT(fusu_fault_addr) + lddpc r10, fusubyte_split + cp.w r12, r10 + brgt fusu_fault + st.b r12, r11 + PCB_CLEAR_ONFAULT() retal sp END(subyte) +/* + * Store a 32-bit word to user memory. + * r12: void *base + * r11: int word + */ ENTRY(suword) ENTRY(suword32) + PCB_SET_ONFAULT(fusu_fault_addr) + lddpc r10, fusuword32_split + cp.w r12, r10 + brgt fusu_fault + st.w r12, r11 + PCB_CLEAR_ONFAULT() retal sp END(suword) @@ -280,7 +328,6 @@ breakpoint END(suswintr) - /* * casuword. Compare and set user word. Returns -1 or the current value. */ @@ -289,7 +336,24 @@ breakpoint END(casuword) +/** + * Fault hander for all su/fu/casu functions + */ +fusu_fault: + breakpoint + PCB_CLEAR_ONFAULT() + retal -1 +fusu_fault_addr: + .long fusu_fault +/* + * For testing if address is within userspace + */ +fusubyte_split: + .long VM_MAXUSER_ADDRESS - 1 +fusuword32_split: + .long VM_MAXUSER_ADDRESS - 4 + /** * Set jump buffer * r12: Pointer to jump buffer @@ -326,7 +390,7 @@ bfins r11, r12, 0, 8 /* Insert address into mfsr instruction */ st.w r10, r11 /* Store new */ - cache r10, 0x0C /* Clean DCache + cache r10, 0x0C /* Clean DCache */ sync 0 /* Flush write buffer */ cache r10, 0x01 /* Invalidate ICache */ mov pc, r10 /* Unpredictable jump, flushing the pipeline */ ==== //depot/projects/avr32/src/sys/avr32/avr32/switch.S#15 (text+ko) ==== @@ -26,7 +26,7 @@ */ #include "opt_global.h" - +#include <sys/syscall.h> #include <machine/asm.h> #include <machine/param.h> #include <machine/reg.h> @@ -171,7 +171,9 @@ .text .global _C_LABEL(sigcode) _C_LABEL(sigcode): - breakpoint + mov r12, sp + SCALL(sigreturn) + SCALL(exit) _C_LABEL(esigcode): .data ==== //depot/projects/avr32/src/sys/avr32/avr32/trap.c#13 (text+ko) ==== @@ -77,6 +77,7 @@ #include <machine/tlb.h> #include <machine/trap.h> #include <machine/pmap.h> +#include <machine/pcb.h> #include <machine/debug.h> #include <machine/reg.h> #include <machine/reg_sys.h> @@ -243,7 +244,7 @@ printf("Sending signal %d (%d) to process %d (trap: %d (%s), addr: 0x%x, pc: 0x%x, lr: 0x%x)\n", signo, ucode, p->p_pid, type, trap_name(type), addr, frame->regs.pc, frame->regs.lr); - trap_breakpoint(type, frame); +// trap_breakpoint(type, frame); ksiginfo_init_trap(&ksi); ksi.ksi_signo = signo; ksi.ksi_code = ucode; @@ -373,6 +374,11 @@ } if (!TRAPF_USERMODE(frame)) { + if (td->td_intr_nesting_level == 0 && + PCPU_GET(curpcb)->pcb_onfault != NULL) { + frame->regs.pc = (register_t)PCPU_GET(curpcb)->pcb_onfault; + return (KERN_SUCCESS); + } trap_fatal(type, frame); return (SIGSEGV); } ==== //depot/projects/avr32/src/sys/avr32/include/asm.h#8 (text+ko) ==== @@ -170,5 +170,16 @@ #define PIC_GOT(x) x #endif +#define PCB_SET_ONFAULT(addr) \ + lddpc r8, addr ;\ + lddpc r9, curpcb ;\ + ld.w r9, r9 ;\ + st.w r9[PCB_ONFAULT], r8 + +#define PCB_CLEAR_ONFAULT() \ + mov r8, 0 ;\ + lddpc r9, curpcb ;\ + ld.w r9, r9 ;\ + st.w r9[PCB_ONFAULT], r8 #endif /* !_MACHINE_ASM_H_ */ ==== //depot/projects/avr32/src/sys/avr32/include/pcb.h#6 (text+ko) ==== @@ -46,6 +46,8 @@ register_t r2; register_t r1; register_t r0; + + caddr_t pcb_onfault; /* On fault handler */ }; #ifdef _KERNEL
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907052338.n65NcccH045645>