PERFORCE change 165661 for review
Arnar Mar Sig
antab at FreeBSD.org
Sun Jul 5 23:38:39 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165661
Change 165661 by antab at 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
More information about the p4-projects
mailing list