Index: sys/arm/arm/bcopyinout.S =================================================================== --- sys/arm/arm/bcopyinout.S +++ sys/arm/arm/bcopyinout.S @@ -94,6 +94,15 @@ moveq r0, #0 RETeq + adds r3, r0, r2 + movcs r0, #EFAULT + RETc(cs) + + ldr r12, =(VM_MAXUSER_ADDRESS + 1) + cmp r3, r12 + movcs r0, #EFAULT + RETc(cs) + ldr r3, .L_arm_memcpy ldr r3, [r3] cmp r3, #0 @@ -332,6 +341,15 @@ moveq r0, #0 RETeq + adds r3, r1, r2 + movcs r0, #EFAULT + RETc(cs) + + ldr r12, =(VM_MAXUSER_ADDRESS + 1) + cmp r3, r12 + movcs r0, #EFAULT + RETc(cs) + ldr r3, .L_arm_memcpy ldr r3, [r3] cmp r3, #0 Index: sys/arm/arm/bcopyinout_xscale.S =================================================================== --- sys/arm/arm/bcopyinout_xscale.S +++ sys/arm/arm/bcopyinout_xscale.S @@ -67,6 +67,15 @@ movle r0, #0x00 movle pc, lr /* Bail early if length is <= 0 */ + adds r3, r0, r2 + movcs r0, #EFAULT + movcs pc, lr + + ldr r12, =(VM_MAXUSER_ADDRESS + 1) + cmp r3, r12 + movcs r0, #EFAULT + movcs pc, lr + ldr r3, .L_arm_memcpy ldr r3, [r3] cmp r3, #0 @@ -509,6 +518,15 @@ movle r0, #0x00 movle pc, lr /* Bail early if length is <= 0 */ + adds r3, r1, r2 + movcs r0, #EFAULT + movcs pc, lr + + ldr r12, =(VM_MAXUSER_ADDRESS + 1) + cmp r3, r12 + movcs r0, #EFAULT + movcs pc, lr + ldr r3, .L_arm_memcpy ldr r3, [r3] cmp r3, #0 Index: sys/arm/arm/copystr.S =================================================================== --- sys/arm/arm/copystr.S +++ sys/arm/arm/copystr.S @@ -113,6 +113,8 @@ moveq r0, #ENAMETOOLONG beq 2f + ldr r12, =VM_MAXUSER_ADDRESS + GET_PCB(r4) ldr r4, [r4] @@ -124,7 +126,10 @@ adr r5, .Lcopystrfault str r5, [r4, #PCB_ONFAULT] -1: ldrbt r5, [r0], #0x0001 +1: + cmp r0, r12 + bcs .Lcopystrfault + ldrbt r5, [r0], #0x0001 add r6, r6, #0x00000001 teq r5, #0x00000000 strb r5, [r1], #0x0001 @@ -161,6 +166,8 @@ moveq r0, #ENAMETOOLONG beq 2f + ldr r12, =VM_MAXUSER_ADDRESS + GET_PCB(r4) ldr r4, [r4] @@ -172,7 +179,10 @@ adr r5, .Lcopystrfault str r5, [r4, #PCB_ONFAULT] -1: ldrb r5, [r0], #0x0001 +1: + cmp r0, r12 + bcs .Lcopystrfault + ldrb r5, [r0], #0x0001 add r6, r6, #0x00000001 teq r5, #0x00000000 strbt r5, [r1], #0x0001 @@ -195,9 +205,10 @@ /* A fault occurred during the copy */ .Lcopystrfault: - mov r0, #EFAULT mov r1, #0x00000000 str r1, [r4, #PCB_ONFAULT] +.Lcopystrfaultnopcb: + mov r0, #EFAULT RESTORE_REGS RET Index: sys/arm/arm/fusu.S =================================================================== --- sys/arm/arm/fusu.S +++ sys/arm/arm/fusu.S @@ -53,49 +53,59 @@ #endif /* - * fuword(caddr_t uaddr); - * Fetch an int from the user's address space. + * casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, + * uint32_t newval); */ -ENTRY(casuword) -EENTRY_NP(casuword32) - GET_PCB(r3) - ldr r3, [r3] +ENTRY(casueword) +EENTRY_NP(casueword32) + stmfd sp!, {r4, r5, r6} + + ldr r4, =(VM_MAXUSER_ADDRESS-3) + cmp r0, r4 + mvncs r0, #1 + bcs 4f + + GET_PCB(r6) + ldr r6, [r6] #ifdef DIAGNOSTIC - teq r3, #0x00000000 + teq r6, #0x00000000 + ldmfd sp!, {r4, r5, r6} beq .Lfusupcbfault #endif - stmfd sp!, {r4, r5} + adr r4, .Lcasuwordfault - str r4, [r3, #PCB_ONFAULT] + str r4, [r6, #PCB_ONFAULT] + #if __ARM_ARCH >= 6 1: - cmp r0, #KERNBASE - mvnhs r0, #0 - bhs 2f - - ldrex r5, [r0] - cmp r5, r1 - movne r0, r5 + ldrex r4, [r0] + cmp r4, r1 bne 2f - strex r5, r2, [r0] + strex r5, r3, [r0] cmp r5, #0 - bne 1b + bne 1b + str r4, [r2] + b 3f +2: + clrex + str r4, [r2] +3: #else ldrt r5, [r0] cmp r5, r1 - movne r0, r5 - strteq r2, [r0] + mov r0, r5 + strteq r3, [r0] + str r5, [r2] #endif - moveq r0, r1 -2: - ldmfd sp!, {r4, r5} - mov r1, #0x00000000 - str r1, [r3, #PCB_ONFAULT] + mov r0, #0 + str r0, [r6, #PCB_ONFAULT] +4: + ldmfd sp!, {r4, r5, r6} RET -EEND(casuword32) -END(casuword) +EEND(casueword32) +END(casueword) /* * Handle faults from casuword. Clean up and return -1. @@ -103,18 +113,23 @@ .Lcasuwordfault: mov r0, #0x00000000 - str r0, [r3, #PCB_ONFAULT] - mvn r0, #0x00000000 - ldmfd sp!, {r4, r5} + str r0, [r6, #PCB_ONFAULT] + mvn r0, #1 + ldmfd sp!, {r4, r5, r6} RET /* - * fuword(caddr_t uaddr); + * fueword(caddr_t uaddr, long *val); * Fetch an int from the user's address space. */ -ENTRY(fuword) -EENTRY_NP(fuword32) +ENTRY(fueword) +EENTRY_NP(fueword32) + ldr r3, =(VM_MAXUSER_ADDRESS-3) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] @@ -123,14 +138,14 @@ beq .Lfusupcbfault #endif - adr r1, .Lfusufault - str r1, [r2, #PCB_ONFAULT] + adr r3, .Lfusufault + str r3, [r2, #PCB_ONFAULT] ldrt r3, [r0] + str r3, [r1] - mov r1, #0x00000000 - str r1, [r2, #PCB_ONFAULT] - mov r0, r3 + mov r0, #0x00000000 + str r0, [r2, #PCB_ONFAULT] RET EEND(fuword32) END(fuword) @@ -141,6 +156,11 @@ */ ENTRY(fusword) + ldr r3, =(VM_MAXUSER_ADDRESS-1) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] @@ -171,6 +191,11 @@ */ ENTRY(fuswintr) + ldr r3, =(VM_MAXUSER_ADDRESS-1) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + ldr r2, Lblock_userspace_access ldr r2, [r2] teq r2, #0 @@ -217,6 +242,11 @@ */ ENTRY(fubyte) + ldr r3, =VM_MAXUSER_ADDRESS + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] @@ -282,6 +312,11 @@ ENTRY(suword) EENTRY_NP(suword32) + ldr r3, =(VM_MAXUSER_ADDRESS-3) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] @@ -308,6 +343,11 @@ */ ENTRY(suswintr) + ldr r3, =(VM_MAXUSER_ADDRESS-1) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + ldr r2, Lblock_userspace_access ldr r2, [r2] teq r2, #0 @@ -345,6 +385,11 @@ */ ENTRY(susword) + ldr r3, =(VM_MAXUSER_ADDRESS-1) + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] @@ -376,6 +421,11 @@ */ ENTRY(subyte) + ldr r3, =VM_MAXUSER_ADDRESS + cmp r0, r3 + mvncs r0, #1 + RETc(cs) + GET_PCB(r2) ldr r2, [r2] Index: sys/arm/arm/genassym.c =================================================================== --- sys/arm/arm/genassym.c +++ sys/arm/arm/genassym.c @@ -161,6 +161,7 @@ ASSYM(VM_PMAP, offsetof(struct vmspace, vm_pmap)); ASSYM(PM_ACTIVE, offsetof(struct pmap, pm_active)); ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid)); +ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(DCACHE_LINE_SIZE, offsetof(struct cpuinfo, dcache_line_size)); ASSYM(DCACHE_LINE_MASK, offsetof(struct cpuinfo, dcache_line_mask)); Index: sys/arm/include/param.h =================================================================== --- sys/arm/include/param.h +++ sys/arm/include/param.h @@ -149,8 +149,4 @@ #define pgtok(x) ((x) * (PAGE_SIZE / 1024)) -#ifdef _KERNEL -#define NO_FUEWORD 1 -#endif - #endif /* !_ARM_INCLUDE_PARAM_H_ */