Index: head/sys/arm/arm/bcopyinout.S
===================================================================
--- head/sys/arm/arm/bcopyinout.S	(revision 289371)
+++ head/sys/arm/arm/bcopyinout.S	(revision 289372)
@@ -1,624 +1,642 @@
 /*	$NetBSD: bcopyinout.S,v 1.11 2003/10/13 21:22:40 scw Exp $	*/
 
 /*-
  * Copyright (c) 2002 Wasabi Systems, Inc.
  * All rights reserved.
  *
  * Written by Allen Briggs for Wasabi Systems, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *      This product includes software developed for the NetBSD Project by
  *      Wasabi Systems, Inc.
  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
  *    or promote products derived from this software without specific prior
  *    written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 
 #include "assym.s"
 
 #include <machine/acle-compat.h>
 #include <machine/asm.h>
 #include <sys/errno.h>
 
 .L_arm_memcpy:
 	.word	_C_LABEL(_arm_memcpy)
 .L_min_memcpy_size:
 	.word	_C_LABEL(_min_memcpy_size)
 
 __FBSDID("$FreeBSD$");
 #ifdef _ARM_ARCH_5E
 #include <arm/arm/bcopyinout_xscale.S>
 #else
 
 	.text
 	.align	2
 
 #if __ARM_ARCH >= 6
 #define GET_PCB(tmp) \
 	mrc p15, 0, tmp, c13, c0, 4; \
 	add	tmp, tmp, #(TD_PCB)
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 
 #define GET_PCB(tmp) \
 	ldr	tmp, .Lcurpcb
 #endif
 
 
 #define SAVE_REGS	stmfd	sp!, {r4-r11}; _SAVE({r4-r11})
 #define RESTORE_REGS	ldmfd	sp!, {r4-r11}
 
 #if defined(_ARM_ARCH_5E)
 #define HELLOCPP #
 #define PREFETCH(rx,o)	pld	[ rx , HELLOCPP (o) ]
 #else
 #define PREFETCH(rx,o)
 #endif
 
 /*
  * r0 = user space address
  * r1 = kernel space address
  * r2 = length
  *
  * Copies bytes from user space to kernel space
  *
  * We save/restore r4-r11:
  * r4-r11 are scratch
  */
 ENTRY(copyin)
 	/* Quick exit if length is zero */
 	teq	r2, #0
 	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
 	beq	.Lnormal
 	ldr	r3, .L_min_memcpy_size
 	ldr	r3, [r3]
 	cmp	r2, r3
 	blt	.Lnormal
 	stmfd	sp!, {r0-r2, r4, lr}
 	mov     r3, r0
 	mov     r0, r1
 	mov     r1, r3
 	mov     r3, #2 /* SRC_IS_USER */
 	ldr	r4, .L_arm_memcpy
 	mov	lr, pc
 	ldr	pc, [r4]
 	cmp     r0, #0
 	ldmfd   sp!, {r0-r2, r4, lr}
 	moveq	r0, #0
 	RETeq
 
 .Lnormal:
 	SAVE_REGS
 	GET_PCB(r4)
 	ldr	r4, [r4]
 
 
 	ldr	r5, [r4, #PCB_ONFAULT]
 	adr	r3, .Lcopyfault
 	str	r3, [r4, #PCB_ONFAULT]
 
 	PREFETCH(r0, 0)
 	PREFETCH(r1, 0)
 
 	/*
 	 * If not too many bytes, take the slow path.
 	 */
 	cmp	r2, #0x08
 	blt	.Licleanup
 
 	/*
 	 * Align destination to word boundary.
 	 */
 	and	r6, r1, #0x3
 	ldr	pc, [pc, r6, lsl #2]
 	b	.Lialend
 	.word	.Lialend
 	.word	.Lial3
 	.word	.Lial2
 	.word	.Lial1
 .Lial3:	ldrbt	r6, [r0], #1
 	sub	r2, r2, #1
 	strb	r6, [r1], #1
 .Lial2:	ldrbt	r7, [r0], #1
 	sub	r2, r2, #1
 	strb	r7, [r1], #1
 .Lial1:	ldrbt	r6, [r0], #1
 	sub	r2, r2, #1
 	strb	r6, [r1], #1
 .Lialend:
 
 	/*
 	 * If few bytes left, finish slow.
 	 */
 	cmp	r2, #0x08
 	blt	.Licleanup
 
 	/*
 	 * If source is not aligned, finish slow.
 	 */
 	ands	r3, r0, #0x03
 	bne	.Licleanup
 
 	cmp	r2, #0x60	/* Must be > 0x5f for unrolled cacheline */
 	blt	.Licleanup8
 
 	/*
 	 * Align destination to cacheline boundary.
 	 * If source and destination are nicely aligned, this can be a big
 	 * win.  If not, it's still cheaper to copy in groups of 32 even if
 	 * we don't get the nice cacheline alignment.
 	 */
 	and	r6, r1, #0x1f
 	ldr	pc, [pc, r6]
 	b	.Licaligned
 	.word	.Licaligned
 	.word	.Lical28
 	.word	.Lical24
 	.word	.Lical20
 	.word	.Lical16
 	.word	.Lical12
 	.word	.Lical8
 	.word	.Lical4
 .Lical28:ldrt	r6, [r0], #4
 	sub	r2, r2, #4
 	str	r6, [r1], #4
 .Lical24:ldrt	r7, [r0], #4
 	sub	r2, r2, #4
 	str	r7, [r1], #4
 .Lical20:ldrt	r6, [r0], #4
 	sub	r2, r2, #4
 	str	r6, [r1], #4
 .Lical16:ldrt	r7, [r0], #4
 	sub	r2, r2, #4
 	str	r7, [r1], #4
 .Lical12:ldrt	r6, [r0], #4
 	sub	r2, r2, #4
 	str	r6, [r1], #4
 .Lical8:ldrt	r7, [r0], #4
 	sub	r2, r2, #4
 	str	r7, [r1], #4
 .Lical4:ldrt	r6, [r0], #4
 	sub	r2, r2, #4
 	str	r6, [r1], #4
 
 	/*
 	 * We start with > 0x40 bytes to copy (>= 0x60 got us into this
 	 * part of the code, and we may have knocked that down by as much
 	 * as 0x1c getting aligned).
 	 *
 	 * This loop basically works out to:
 	 * do {
 	 * 	prefetch-next-cacheline(s)
 	 *	bytes -= 0x20;
 	 *	copy cacheline
 	 * } while (bytes >= 0x40);
 	 * bytes -= 0x20;
 	 * copy cacheline
 	 */
 .Licaligned:
 	PREFETCH(r0, 32)
 	PREFETCH(r1, 32)
 
 	sub	r2, r2, #0x20
 
 	/* Copy a cacheline */
 	ldrt	r10, [r0], #4
 	ldrt	r11, [r0], #4
 	ldrt	r6, [r0], #4
 	ldrt	r7, [r0], #4
 	ldrt	r8, [r0], #4
 	ldrt	r9, [r0], #4
 	stmia	r1!, {r10-r11}
 	ldrt	r10, [r0], #4
 	ldrt	r11, [r0], #4
 	stmia	r1!, {r6-r11}
 
 	cmp	r2, #0x40
 	bge	.Licaligned
 
 	sub	r2, r2, #0x20
 
 	/* Copy a cacheline */
 	ldrt	r10, [r0], #4
 	ldrt	r11, [r0], #4
 	ldrt	r6, [r0], #4
 	ldrt	r7, [r0], #4
 	ldrt	r8, [r0], #4
 	ldrt	r9, [r0], #4
 	stmia	r1!, {r10-r11}
 	ldrt	r10, [r0], #4
 	ldrt	r11, [r0], #4
 	stmia	r1!, {r6-r11}
 
 	cmp	r2, #0x08
 	blt	.Liprecleanup
 
 .Licleanup8:
 	ldrt	r8, [r0], #4
 	ldrt	r9, [r0], #4
 	sub	r2, r2, #8
 	stmia	r1!, {r8, r9}
 	cmp	r2, #8
 	bge	.Licleanup8
 
 .Liprecleanup:
 	/*
 	 * If we're done, bail.
 	 */
 	cmp	r2, #0
 	beq	.Lout
 
 .Licleanup:
 	and	r6, r2, #0x3
 	ldr	pc, [pc, r6, lsl #2]
 	b	.Licend
 	.word	.Lic4
 	.word	.Lic1
 	.word	.Lic2
 	.word	.Lic3
 .Lic4:	ldrbt	r6, [r0], #1
 	sub	r2, r2, #1
 	strb	r6, [r1], #1
 .Lic3:	ldrbt	r7, [r0], #1
 	sub	r2, r2, #1
 	strb	r7, [r1], #1
 .Lic2:	ldrbt	r6, [r0], #1
 	sub	r2, r2, #1
 	strb	r6, [r1], #1
 .Lic1:	ldrbt	r7, [r0], #1
 	subs	r2, r2, #1
 	strb	r7, [r1], #1
 .Licend:
 	bne	.Licleanup
 
 .Liout:
 	mov	r0, #0
 
 	str	r5, [r4, #PCB_ONFAULT]
 	RESTORE_REGS
 
 	RET
 
 .Lcopyfault:
 	ldr	r0, =EFAULT
 	str	r5, [r4, #PCB_ONFAULT]
 	RESTORE_REGS
 
 	RET
 END(copyin)
 
 /*
  * r0 = kernel space address
  * r1 = user space address
  * r2 = length
  *
  * Copies bytes from kernel space to user space
  *
  * We save/restore r4-r11:
  * r4-r11 are scratch
  */
 
 ENTRY(copyout)
 	/* Quick exit if length is zero */
 	teq	r2, #0
 	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
 	beq	.Lnormale
 	ldr	r3, .L_min_memcpy_size
 	ldr	r3, [r3]
 	cmp	r2, r3
 	blt	.Lnormale
 	stmfd	sp!, {r0-r2, r4, lr}
 	_SAVE({r0-r2, r4, lr})
 	mov     r3, r0
 	mov     r0, r1
 	mov     r1, r3
 	mov     r3, #1 /* DST_IS_USER */
 	ldr	r4, .L_arm_memcpy
 	mov	lr, pc
 	ldr	pc, [r4]
 	cmp     r0, #0
 	ldmfd   sp!, {r0-r2, r4, lr}
 	moveq	r0, #0
 	RETeq
 
 .Lnormale:
 	SAVE_REGS
 	GET_PCB(r4)
 	ldr	r4, [r4]
 
 	ldr	r5, [r4, #PCB_ONFAULT]
 	adr	r3, .Lcopyfault
 	str	r3, [r4, #PCB_ONFAULT]
 
 	PREFETCH(r0, 0)
 	PREFETCH(r1, 0)
 
 	/*
 	 * If not too many bytes, take the slow path.
 	 */
 	cmp	r2, #0x08
 	blt	.Lcleanup
 
 	/*
 	 * Align destination to word boundary.
 	 */
 	and	r6, r1, #0x3
 	ldr	pc, [pc, r6, lsl #2]
 	b	.Lalend
 	.word	.Lalend
 	.word	.Lal3
 	.word	.Lal2
 	.word	.Lal1
 .Lal3:	ldrb	r6, [r0], #1
 	sub	r2, r2, #1
 	strbt	r6, [r1], #1
 .Lal2:	ldrb	r7, [r0], #1
 	sub	r2, r2, #1
 	strbt	r7, [r1], #1
 .Lal1:	ldrb	r6, [r0], #1
 	sub	r2, r2, #1
 	strbt	r6, [r1], #1
 .Lalend:
 
 	/*
 	 * If few bytes left, finish slow.
 	 */
 	cmp	r2, #0x08
 	blt	.Lcleanup
 
 	/*
 	 * If source is not aligned, finish slow.
 	 */
 	ands	r3, r0, #0x03
 	bne	.Lcleanup
 
 	cmp	r2, #0x60	/* Must be > 0x5f for unrolled cacheline */
 	blt	.Lcleanup8
 
 	/*
 	 * Align source & destination to cacheline boundary.
 	 */
 	and	r6, r1, #0x1f
 	ldr	pc, [pc, r6]
 	b	.Lcaligned
 	.word	.Lcaligned
 	.word	.Lcal28
 	.word	.Lcal24
 	.word	.Lcal20
 	.word	.Lcal16
 	.word	.Lcal12
 	.word	.Lcal8
 	.word	.Lcal4
 .Lcal28:ldr	r6, [r0], #4
 	sub	r2, r2, #4
 	strt	r6, [r1], #4
 .Lcal24:ldr	r7, [r0], #4
 	sub	r2, r2, #4
 	strt	r7, [r1], #4
 .Lcal20:ldr	r6, [r0], #4
 	sub	r2, r2, #4
 	strt	r6, [r1], #4
 .Lcal16:ldr	r7, [r0], #4
 	sub	r2, r2, #4
 	strt	r7, [r1], #4
 .Lcal12:ldr	r6, [r0], #4
 	sub	r2, r2, #4
 	strt	r6, [r1], #4
 .Lcal8:	ldr	r7, [r0], #4
 	sub	r2, r2, #4
 	strt	r7, [r1], #4
 .Lcal4:	ldr	r6, [r0], #4
 	sub	r2, r2, #4
 	strt	r6, [r1], #4
 
 	/*
 	 * We start with > 0x40 bytes to copy (>= 0x60 got us into this
 	 * part of the code, and we may have knocked that down by as much
 	 * as 0x1c getting aligned).
 	 *
 	 * This loop basically works out to:
 	 * do {
 	 * 	prefetch-next-cacheline(s)
 	 *	bytes -= 0x20;
 	 *	copy cacheline
 	 * } while (bytes >= 0x40);
 	 * bytes -= 0x20;
 	 * copy cacheline
 	 */
 .Lcaligned:
 	PREFETCH(r0, 32)
 	PREFETCH(r1, 32)
 
 	sub	r2, r2, #0x20
 
 	/* Copy a cacheline */
 	ldmia	r0!, {r6-r11}
 	strt	r6, [r1], #4
 	strt	r7, [r1], #4
 	ldmia	r0!, {r6-r7}
 	strt	r8, [r1], #4
 	strt	r9, [r1], #4
 	strt	r10, [r1], #4
 	strt	r11, [r1], #4
 	strt	r6, [r1], #4
 	strt	r7, [r1], #4
 
 	cmp	r2, #0x40
 	bge	.Lcaligned
 
 	sub	r2, r2, #0x20
 
 	/* Copy a cacheline */
 	ldmia	r0!, {r6-r11}
 	strt	r6, [r1], #4
 	strt	r7, [r1], #4
 	ldmia	r0!, {r6-r7}
 	strt	r8, [r1], #4
 	strt	r9, [r1], #4
 	strt	r10, [r1], #4
 	strt	r11, [r1], #4
 	strt	r6, [r1], #4
 	strt	r7, [r1], #4
 
 	cmp	r2, #0x08
 	blt	.Lprecleanup
 
 .Lcleanup8:
 	ldmia	r0!, {r8-r9}
 	sub	r2, r2, #8
 	strt	r8, [r1], #4
 	strt	r9, [r1], #4
 	cmp	r2, #8
 	bge	.Lcleanup8
 
 .Lprecleanup:
 	/*
 	 * If we're done, bail.
 	 */
 	cmp	r2, #0
 	beq	.Lout
 
 .Lcleanup:
 	and	r6, r2, #0x3
 	ldr	pc, [pc, r6, lsl #2]
 	b	.Lcend
 	.word	.Lc4
 	.word	.Lc1
 	.word	.Lc2
 	.word	.Lc3
 .Lc4:	ldrb	r6, [r0], #1
 	sub	r2, r2, #1
 	strbt	r6, [r1], #1
 .Lc3:	ldrb	r7, [r0], #1
 	sub	r2, r2, #1
 	strbt	r7, [r1], #1
 .Lc2:	ldrb	r6, [r0], #1
 	sub	r2, r2, #1
 	strbt	r6, [r1], #1
 .Lc1:	ldrb	r7, [r0], #1
 	subs	r2, r2, #1
 	strbt	r7, [r1], #1
 .Lcend:
 	bne	.Lcleanup
 
 .Lout:
 	mov	r0, #0
 
 	str	r5, [r4, #PCB_ONFAULT]
 	RESTORE_REGS
 
 	RET
 END(copyout)
 #endif
 
 /*
  * int badaddr_read_1(const uint8_t *src, uint8_t *dest)
  *
  * Copies a single 8-bit value from src to dest, returning 0 on success,
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_1)
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
 	str	r3, [r2, #PCB_ONFAULT]
 	nop
 	nop
 	nop
 	ldrb	r3, [r0]
 	nop
 	nop
 	nop
 	strb	r3, [r1]
 	mov	r0, #0		/* No fault */
 1:	str	ip, [r2, #PCB_ONFAULT]
 	RET
 END(badaddr_read_1)
 
 /*
  * int badaddr_read_2(const uint16_t *src, uint16_t *dest)
  *
  * Copies a single 16-bit value from src to dest, returning 0 on success,
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_2)
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
 	str	r3, [r2, #PCB_ONFAULT]
 	nop
 	nop
 	nop
 	ldrh	r3, [r0]
 	nop
 	nop
 	nop
 	strh	r3, [r1]
 	mov	r0, #0		/* No fault */
 1:	str	ip, [r2, #PCB_ONFAULT]
 	RET
 END(badaddr_read_2)
 
 /*
  * int badaddr_read_4(const uint32_t *src, uint32_t *dest)
  *
  * Copies a single 32-bit value from src to dest, returning 0 on success,
  * else EFAULT if a page fault occurred.
  */
 ENTRY(badaddr_read_4)
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 	ldr	ip, [r2, #PCB_ONFAULT]
 	adr	r3, 1f
 	str	r3, [r2, #PCB_ONFAULT]
 	nop
 	nop
 	nop
 	ldr	r3, [r0]
 	nop
 	nop
 	nop
 	str	r3, [r1]
 	mov	r0, #0		/* No fault */
 1:	str	ip, [r2, #PCB_ONFAULT]
 	RET
 END(badaddr_read_4)
 
Index: head/sys/arm/arm/bcopyinout_xscale.S
===================================================================
--- head/sys/arm/arm/bcopyinout_xscale.S	(revision 289371)
+++ head/sys/arm/arm/bcopyinout_xscale.S	(revision 289372)
@@ -1,942 +1,960 @@
 /*	$NetBSD: bcopyinout_xscale.S,v 1.3 2003/12/15 09:27:18 scw Exp $	*/
 
 /*-
  * Copyright 2003 Wasabi Systems, Inc.
  * All rights reserved.
  *
  * Written by Steve C. Woodford for Wasabi Systems, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *      This product includes software developed for the NetBSD Project by
  *      Wasabi Systems, Inc.
  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
  *    or promote products derived from this software without specific prior
  *    written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <machine/asm.h>
 __FBSDID("$FreeBSD$");
 
 #include <machine/acle-compat.h>
 
 	.syntax	unified
 	.text
 	.align	2
 
 #if __ARM_ARCH >= 6
 #define GET_PCB(tmp) \
 	mrc p15, 0, tmp, c13, c0, 4; \
 	add	tmp, tmp, #(TD_PCB)
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 #define GET_PCB(tmp) \
 	ldr	tmp, .Lcurpcb
 #endif
 
 /*
  * r0 = user space address
  * r1 = kernel space address
  * r2 = length
  *
  * Copies bytes from user space to kernel space
  */
 ENTRY(copyin)
 	cmp	r2, #0x00
 	movle	r0, #0x00
 	movle	pc, lr			/* Bail early if length is <= 0 */
 
+	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
 	beq	.Lnormal
 	ldr	r3, .L_min_memcpy_size
 	ldr	r3, [r3]
 	cmp	r2, r3
 	blt	.Lnormal
 	stmfd	sp!, {r0-r2, r4, lr}
 	mov     r3, r0
 	mov     r0, r1
 	mov     r1, r3
 	mov     r3, #2 /* SRC_IS_USER */
 	ldr	r4, .L_arm_memcpy
 	mov	lr, pc
 	ldr	pc, [r4]
 	cmp     r0, #0
 	ldmfd   sp!, {r0-r2, r4, lr}
 	moveq	r0, #0
 	RETeq
 
 .Lnormal:
 	stmfd	sp!, {r10-r11, lr}
 
 	GET_PCB(r10)
 	ldr	r10, [r10]
 
 	mov	r3, #0x00
 	adr	ip, .Lcopyin_fault
 	ldr	r11, [r10, #PCB_ONFAULT]
 	str	ip, [r10, #PCB_ONFAULT]
 	bl	.Lcopyin_guts
 	str	r11, [r10, #PCB_ONFAULT]
 	mov	r0, #0x00
 	ldmfd	sp!, {r10-r11, pc}
 
 .Lcopyin_fault:
 	ldr	r0, =EFAULT
 	str	r11, [r10, #PCB_ONFAULT]
 	cmp	r3, #0x00
 	ldmfdgt	sp!, {r4-r7}		/* r3 > 0 Restore r4-r7 */
 	ldmfdlt	sp!, {r4-r9}		/* r3 < 0 Restore r4-r9 */
 	ldmfd	sp!, {r10-r11, pc}
 
 .Lcopyin_guts:
 	pld	[r0]
 	/* Word-align the destination buffer */
 	ands	ip, r1, #0x03		/* Already word aligned? */
 	beq	.Lcopyin_wordaligned	/* Yup */
 	rsb	ip, ip, #0x04
 	cmp	r2, ip			/* Enough bytes left to align it? */
 	blt	.Lcopyin_l4_2		/* Nope. Just copy bytewise */
 	sub	r2, r2, ip
 	rsbs	ip, ip, #0x03
 	addne	pc, pc, ip, lsl #3
 	nop
 	ldrbt	ip, [r0], #0x01
 	strb	ip, [r1], #0x01
 	ldrbt	ip, [r0], #0x01
 	strb	ip, [r1], #0x01
 	ldrbt	ip, [r0], #0x01
 	strb	ip, [r1], #0x01
 	cmp	r2, #0x00		/* All done? */
 	RETeq
 
 	/* Destination buffer is now word aligned */
 .Lcopyin_wordaligned:
 	ands	ip, r0, #0x03		/* Is src also word-aligned? */
 	bne	.Lcopyin_bad_align	/* Nope. Things just got bad */
 	cmp	r2, #0x08		/* Less than 8 bytes remaining? */
 	blt	.Lcopyin_w_less_than8
 
 	/* Quad-align the destination buffer */
 	tst	r1, #0x07		/* Already quad aligned? */
 	ldrtne	ip, [r0], #0x04
 	strne	ip, [r1], #0x04
 	subne	r2, r2, #0x04
 	stmfd	sp!, {r4-r9}		/* Free up some registers */
 	mov	r3, #-1			/* Signal restore r4-r9 */
 
 	/* Destination buffer quad aligned, source is word aligned */
 	subs	r2, r2, #0x80
 	blt	.Lcopyin_w_lessthan128
 
 	/* Copy 128 bytes at a time */
 .Lcopyin_w_loop128:
 	ldrt	r4, [r0], #0x04		/* LD:00-03 */
 	ldrt	r5, [r0], #0x04		/* LD:04-07 */
 	pld	[r0, #0x18]		/* Prefetch 0x20 */
 	ldrt	r6, [r0], #0x04		/* LD:08-0b */
 	ldrt	r7, [r0], #0x04		/* LD:0c-0f */
 	ldrt	r8, [r0], #0x04		/* LD:10-13 */
 	ldrt	r9, [r0], #0x04		/* LD:14-17 */
 	strd	r4, [r1], #0x08		/* ST:00-07 */
 	ldrt	r4, [r0], #0x04		/* LD:18-1b */
 	ldrt	r5, [r0], #0x04		/* LD:1c-1f */
 	strd	r6, [r1], #0x08		/* ST:08-0f */
 	ldrt	r6, [r0], #0x04		/* LD:20-23 */
 	ldrt	r7, [r0], #0x04		/* LD:24-27 */
 	pld	[r0, #0x18]		/* Prefetch 0x40 */
 	strd	r8, [r1], #0x08		/* ST:10-17 */
 	ldrt	r8, [r0], #0x04		/* LD:28-2b */
 	ldrt	r9, [r0], #0x04		/* LD:2c-2f */
 	strd	r4, [r1], #0x08		/* ST:18-1f */
 	ldrt	r4, [r0], #0x04		/* LD:30-33 */
 	ldrt	r5, [r0], #0x04		/* LD:34-37 */
 	strd	r6, [r1], #0x08		/* ST:20-27 */
 	ldrt	r6, [r0], #0x04		/* LD:38-3b */
 	ldrt	r7, [r0], #0x04		/* LD:3c-3f */
 	strd	r8, [r1], #0x08		/* ST:28-2f */
 	ldrt	r8, [r0], #0x04		/* LD:40-43 */
 	ldrt	r9, [r0], #0x04		/* LD:44-47 */
 	pld	[r0, #0x18]		/* Prefetch 0x60 */
 	strd	r4, [r1], #0x08		/* ST:30-37 */
 	ldrt	r4, [r0], #0x04		/* LD:48-4b */
 	ldrt	r5, [r0], #0x04		/* LD:4c-4f */
 	strd	r6, [r1], #0x08		/* ST:38-3f */
 	ldrt	r6, [r0], #0x04		/* LD:50-53 */
 	ldrt	r7, [r0], #0x04		/* LD:54-57 */
 	strd	r8, [r1], #0x08		/* ST:40-47 */
 	ldrt	r8, [r0], #0x04		/* LD:58-5b */
 	ldrt	r9, [r0], #0x04		/* LD:5c-5f */
 	strd	r4, [r1], #0x08		/* ST:48-4f */
 	ldrt	r4, [r0], #0x04		/* LD:60-63 */
 	ldrt	r5, [r0], #0x04		/* LD:64-67 */
 	pld	[r0, #0x18]		/* Prefetch 0x80 */
 	strd	r6, [r1], #0x08		/* ST:50-57 */
 	ldrt	r6, [r0], #0x04		/* LD:68-6b */
 	ldrt	r7, [r0], #0x04		/* LD:6c-6f */
 	strd	r8, [r1], #0x08		/* ST:58-5f */
 	ldrt	r8, [r0], #0x04		/* LD:70-73 */
 	ldrt	r9, [r0], #0x04		/* LD:74-77 */
 	strd	r4, [r1], #0x08		/* ST:60-67 */
 	ldrt	r4, [r0], #0x04		/* LD:78-7b */
 	ldrt	r5, [r0], #0x04		/* LD:7c-7f */
 	strd	r6, [r1], #0x08		/* ST:68-6f */
 	strd	r8, [r1], #0x08		/* ST:70-77 */
 	subs	r2, r2, #0x80
 	strd	r4, [r1], #0x08		/* ST:78-7f */
 	bge	.Lcopyin_w_loop128
 
 .Lcopyin_w_lessthan128:
 	adds	r2, r2, #0x80		/* Adjust for extra sub */
 	ldmfdeq	sp!, {r4-r9}
 	RETeq
 	subs	r2, r2, #0x20
 	blt	.Lcopyin_w_lessthan32
 
 	/* Copy 32 bytes at a time */
 .Lcopyin_w_loop32:
 	ldrt	r4, [r0], #0x04
 	ldrt	r5, [r0], #0x04
 	pld	[r0, #0x18]
 	ldrt	r6, [r0], #0x04
 	ldrt	r7, [r0], #0x04
 	ldrt	r8, [r0], #0x04
 	ldrt	r9, [r0], #0x04
 	strd	r4, [r1], #0x08
 	ldrt	r4, [r0], #0x04
 	ldrt	r5, [r0], #0x04
 	strd	r6, [r1], #0x08
 	strd	r8, [r1], #0x08
 	subs	r2, r2, #0x20
 	strd	r4, [r1], #0x08
 	bge	.Lcopyin_w_loop32
 
 .Lcopyin_w_lessthan32:
 	adds	r2, r2, #0x20		/* Adjust for extra sub */
 	ldmfdeq	sp!, {r4-r9}
 	RETeq				/* Return now if done */
 
 	and	r4, r2, #0x18
 	rsb	r5, r4, #0x18
 	subs	r2, r2, r4
 	add	pc, pc, r5, lsl #1
 	nop
 
 	/* At least 24 bytes remaining */
 	ldrt	r4, [r0], #0x04
 	ldrt	r5, [r0], #0x04
 	nop
 	strd	r4, [r1], #0x08
 
 	/* At least 16 bytes remaining */
 	ldrt	r4, [r0], #0x04
 	ldrt	r5, [r0], #0x04
 	nop
 	strd	r4, [r1], #0x08
 
 	/* At least 8 bytes remaining */
 	ldrt	r4, [r0], #0x04
 	ldrt	r5, [r0], #0x04
 	nop
 	strd	r4, [r1], #0x08
 
 	/* Less than 8 bytes remaining */
 	ldmfd	sp!, {r4-r9}
 	RETeq				/* Return now if done */
 	mov	r3, #0x00
 
 .Lcopyin_w_less_than8:
 	subs	r2, r2, #0x04
 	ldrtge	ip, [r0], #0x04
 	strge	ip, [r1], #0x04
 	RETeq				/* Return now if done */
 	addlt	r2, r2, #0x04
 	ldrbt	ip, [r0], #0x01
 	cmp	r2, #0x02
 	ldrbtge	r2, [r0], #0x01
 	strb	ip, [r1], #0x01
 	ldrbtgt	ip, [r0]
 	strbge	r2, [r1], #0x01
 	strbgt	ip, [r1]
 	RET
 
 /*
  * At this point, it has not been possible to word align both buffers.
  * The destination buffer (r1) is word aligned, but the source buffer
  * (r0) is not.
  */
 .Lcopyin_bad_align:
 	stmfd	sp!, {r4-r7}
 	mov	r3, #0x01
 	bic	r0, r0, #0x03
 	cmp	ip, #2
 	ldrt	ip, [r0], #0x04
 	bgt	.Lcopyin_bad3
 	beq	.Lcopyin_bad2
 	b	.Lcopyin_bad1
 
 .Lcopyin_bad1_loop16:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #8
 #else
 	mov	r4, ip, lsr #8
 #endif
 	ldrt	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldrt	r6, [r0], #0x04
 	ldrt	r7, [r0], #0x04
 	ldrt	ip, [r0], #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, r5, lsr #24
 	mov	r5, r5, lsl #8
 	orr	r5, r5, r6, lsr #24
 	mov	r6, r6, lsl #8
 	orr	r6, r6, r7, lsr #24
 	mov	r7, r7, lsl #8
 	orr	r7, r7, ip, lsr #24
 #else
 	orr	r4, r4, r5, lsl #24
 	mov	r5, r5, lsr #8
 	orr	r5, r5, r6, lsl #24
 	mov	r6, r6, lsr #8
 	orr	r6, r6, r7, lsl #24
 	mov	r7, r7, lsr #8
 	orr	r7, r7, ip, lsl #24
 #endif
 	str	r4, [r1], #0x04
 	str	r5, [r1], #0x04
 	str	r6, [r1], #0x04
 	str	r7, [r1], #0x04
 .Lcopyin_bad1:
 	subs	r2, r2, #0x10
 	bge	.Lcopyin_bad1_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x03
 	blt	.Lcopyin_l4
 
 .Lcopyin_bad1_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #8
 #else
 	mov	r4, ip, lsr #8
 #endif
 	ldrt	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #24
 #else
 	orr	r4, r4, ip, lsl #24
 #endif
 	str	r4, [r1], #0x04
 	bge	.Lcopyin_bad1_loop4
 	sub	r0, r0, #0x03
 	b	.Lcopyin_l4
 
 .Lcopyin_bad2_loop16:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #16
 #else
 	mov	r4, ip, lsr #16
 #endif
 	ldrt	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldrt	r6, [r0], #0x04
 	ldrt	r7, [r0], #0x04
 	ldrt	ip, [r0], #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, r5, lsr #16
 	mov	r5, r5, lsl #16
 	orr	r5, r5, r6, lsr #16
 	mov	r6, r6, lsl #16
 	orr	r6, r6, r7, lsr #16
 	mov	r7, r7, lsl #16
 	orr	r7, r7, ip, lsr #16
 #else
 	orr	r4, r4, r5, lsl #16
 	mov	r5, r5, lsr #16
 	orr	r5, r5, r6, lsl #16
 	mov	r6, r6, lsr #16
 	orr	r6, r6, r7, lsl #16
 	mov	r7, r7, lsr #16
 	orr	r7, r7, ip, lsl #16
 #endif
 	str	r4, [r1], #0x04
 	str	r5, [r1], #0x04
 	str	r6, [r1], #0x04
 	str	r7, [r1], #0x04
 .Lcopyin_bad2:
 	subs	r2, r2, #0x10
 	bge	.Lcopyin_bad2_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x02
 	blt	.Lcopyin_l4
 
 .Lcopyin_bad2_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #16
 #else
 	mov	r4, ip, lsr #16
 #endif
 	ldrt	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #16
 #else
 	orr	r4, r4, ip, lsl #16
 #endif
 	str	r4, [r1], #0x04
 	bge	.Lcopyin_bad2_loop4
 	sub	r0, r0, #0x02
 	b	.Lcopyin_l4
 
 .Lcopyin_bad3_loop16:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #24
 #else
 	mov	r4, ip, lsr #24
 #endif
 	ldrt	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldrt	r6, [r0], #0x04
 	ldrt	r7, [r0], #0x04
 	ldrt	ip, [r0], #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, r5, lsr #8
 	mov	r5, r5, lsl #24
 	orr	r5, r5, r6, lsr #8
 	mov	r6, r6, lsl #24
 	orr	r6, r6, r7, lsr #8
 	mov	r7, r7, lsl #24
 	orr	r7, r7, ip, lsr #8
 #else
 	orr	r4, r4, r5, lsl #8
 	mov	r5, r5, lsr #24
 	orr	r5, r5, r6, lsl #8
 	mov	r6, r6, lsr #24
 	orr	r6, r6, r7, lsl #8
 	mov	r7, r7, lsr #24
 	orr	r7, r7, ip, lsl #8
 #endif
 	str	r4, [r1], #0x04
 	str	r5, [r1], #0x04
 	str	r6, [r1], #0x04
 	str	r7, [r1], #0x04
 .Lcopyin_bad3:
 	subs	r2, r2, #0x10
 	bge	.Lcopyin_bad3_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x01
 	blt	.Lcopyin_l4
 
 .Lcopyin_bad3_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #24
 #else
 	mov	r4, ip, lsr #24
 #endif
 	ldrt	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #8
 #else
 	orr	r4, r4, ip, lsl #8
 #endif
 	str	r4, [r1], #0x04
 	bge	.Lcopyin_bad3_loop4
 	sub	r0, r0, #0x01
 
 .Lcopyin_l4:
 	ldmfd	sp!, {r4-r7}
 	mov	r3, #0x00
 	adds	r2, r2, #0x04
 	RETeq
 .Lcopyin_l4_2:
 	rsbs	r2, r2, #0x03
 	addne	pc, pc, r2, lsl #3
 	nop
 	ldrbt	ip, [r0], #0x01
 	strb	ip, [r1], #0x01
 	ldrbt	ip, [r0], #0x01
 	strb	ip, [r1], #0x01
 	ldrbt	ip, [r0]
 	strb	ip, [r1]
 	RET
 END(copyin)
 
 /*
  * r0 = kernel space address
  * r1 = user space address
  * r2 = length
  *
  * Copies bytes from kernel space to user space
  */
 ENTRY(copyout)
 	cmp	r2, #0x00
 	movle	r0, #0x00
 	movle	pc, lr			/* Bail early if length is <= 0 */
+
+	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
 	beq	.Lnormale
 	ldr	r3, .L_min_memcpy_size
 	ldr	r3, [r3]
 	cmp	r2, r3
 	blt	.Lnormale
 	stmfd	sp!, {r0-r2, r4, lr}
 	mov     r3, r0
 	mov     r0, r1
 	mov     r1, r3
 	mov     r3, #1 /* DST_IS_USER */
 	ldr	r4, .L_arm_memcpy
 	mov	lr, pc
 	ldr	pc, [r4]
 	cmp     r0, #0
 	ldmfd   sp!, {r0-r2, r4, lr}
 	moveq	r0, #0
 	RETeq
 
 .Lnormale:
 	stmfd	sp!, {r10-r11, lr}
 
 	GET_PCB(r10)
 	ldr	r10, [r10]
 
 	mov	r3, #0x00
 	adr	ip, .Lcopyout_fault
 	ldr	r11, [r10, #PCB_ONFAULT]
 	str	ip, [r10, #PCB_ONFAULT]
 	bl	.Lcopyout_guts
 	str	r11, [r10, #PCB_ONFAULT]
 	mov	r0, #0x00
 	ldmfd	sp!, {r10-r11, pc}
 
 .Lcopyout_fault:
 	ldr	r0, =EFAULT
 	str	r11, [r10, #PCB_ONFAULT]
 	cmp	r3, #0x00
 	ldmfdgt	sp!, {r4-r7}		/* r3 > 0 Restore r4-r7 */
 	ldmfdlt	sp!, {r4-r9}		/* r3 < 0 Restore r4-r9 */
 	ldmfd	sp!, {r10-r11, pc}
 
 .Lcopyout_guts:
 	pld	[r0]
 	/* Word-align the destination buffer */
 	ands	ip, r1, #0x03		/* Already word aligned? */
 	beq	.Lcopyout_wordaligned	/* Yup */
 	rsb	ip, ip, #0x04
 	cmp	r2, ip			/* Enough bytes left to align it? */
 	blt	.Lcopyout_l4_2		/* Nope. Just copy bytewise */
 	sub	r2, r2, ip
 	rsbs	ip, ip, #0x03
 	addne	pc, pc, ip, lsl #3
 	nop
 	ldrb	ip, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	ldrb	ip, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	ldrb	ip, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	cmp	r2, #0x00		/* All done? */
 	RETeq
 
 	/* Destination buffer is now word aligned */
 .Lcopyout_wordaligned:
 	ands	ip, r0, #0x03		/* Is src also word-aligned? */
 	bne	.Lcopyout_bad_align	/* Nope. Things just got bad */
 	cmp	r2, #0x08		/* Less than 8 bytes remaining? */
 	blt	.Lcopyout_w_less_than8
 
 	/* Quad-align the destination buffer */
 	tst	r0, #0x07		/* Already quad aligned? */
 	ldrne	ip, [r0], #0x04
 	subne	r2, r2, #0x04
 	strtne	ip, [r1], #0x04
 
 	stmfd	sp!, {r4-r9}		/* Free up some registers */
 	mov	r3, #-1			/* Signal restore r4-r9 */
 
 	/* Destination buffer word aligned, source is quad aligned */
 	subs	r2, r2, #0x80
 	blt	.Lcopyout_w_lessthan128
 
 	/* Copy 128 bytes at a time */
 .Lcopyout_w_loop128:
 	ldrd	r4, [r0], #0x08		/* LD:00-07 */
 	pld	[r0, #0x18]		/* Prefetch 0x20 */
 	ldrd	r6, [r0], #0x08		/* LD:08-0f */
 	ldrd	r8, [r0], #0x08		/* LD:10-17 */
 	strt	r4, [r1], #0x04		/* ST:00-03 */
 	strt	r5, [r1], #0x04		/* ST:04-07 */
 	ldrd	r4, [r0], #0x08		/* LD:18-1f */
 	strt	r6, [r1], #0x04		/* ST:08-0b */
 	strt	r7, [r1], #0x04		/* ST:0c-0f */
 	ldrd	r6, [r0], #0x08		/* LD:20-27 */
 	pld	[r0, #0x18]		/* Prefetch 0x40 */
 	strt	r8, [r1], #0x04		/* ST:10-13 */
 	strt	r9, [r1], #0x04		/* ST:14-17 */
 	ldrd	r8, [r0], #0x08		/* LD:28-2f */
 	strt	r4, [r1], #0x04		/* ST:18-1b */
 	strt	r5, [r1], #0x04		/* ST:1c-1f */
 	ldrd	r4, [r0], #0x08		/* LD:30-37 */
 	strt	r6, [r1], #0x04		/* ST:20-23 */
 	strt	r7, [r1], #0x04		/* ST:24-27 */
 	ldrd	r6, [r0], #0x08		/* LD:38-3f */
 	strt	r8, [r1], #0x04		/* ST:28-2b */
 	strt	r9, [r1], #0x04		/* ST:2c-2f */
 	ldrd	r8, [r0], #0x08		/* LD:40-47 */
 	pld	[r0, #0x18]		/* Prefetch 0x60 */
 	strt	r4, [r1], #0x04		/* ST:30-33 */
 	strt	r5, [r1], #0x04		/* ST:34-37 */
 	ldrd	r4, [r0], #0x08		/* LD:48-4f */
 	strt	r6, [r1], #0x04		/* ST:38-3b */
 	strt	r7, [r1], #0x04		/* ST:3c-3f */
 	ldrd	r6, [r0], #0x08		/* LD:50-57 */
 	strt	r8, [r1], #0x04		/* ST:40-43 */
 	strt	r9, [r1], #0x04		/* ST:44-47 */
 	ldrd	r8, [r0], #0x08		/* LD:58-4f */
 	strt	r4, [r1], #0x04		/* ST:48-4b */
 	strt	r5, [r1], #0x04		/* ST:4c-4f */
 	ldrd	r4, [r0], #0x08		/* LD:60-67 */
 	pld	[r0, #0x18]		/* Prefetch 0x80 */
 	strt	r6, [r1], #0x04		/* ST:50-53 */
 	strt	r7, [r1], #0x04		/* ST:54-57 */
 	ldrd	r6, [r0], #0x08		/* LD:68-6f */
 	strt	r8, [r1], #0x04		/* ST:58-5b */
 	strt	r9, [r1], #0x04		/* ST:5c-5f */
 	ldrd	r8, [r0], #0x08		/* LD:70-77 */
 	strt	r4, [r1], #0x04		/* ST:60-63 */
 	strt	r5, [r1], #0x04		/* ST:64-67 */
 	ldrd	r4, [r0], #0x08		/* LD:78-7f */
 	strt	r6, [r1], #0x04		/* ST:68-6b */
 	strt	r7, [r1], #0x04		/* ST:6c-6f */
 	strt	r8, [r1], #0x04		/* ST:70-73 */
 	strt	r9, [r1], #0x04		/* ST:74-77 */
 	subs	r2, r2, #0x80
 	strt	r4, [r1], #0x04		/* ST:78-7b */
 	strt	r5, [r1], #0x04		/* ST:7c-7f */
 	bge	.Lcopyout_w_loop128
 
 .Lcopyout_w_lessthan128:
 	adds	r2, r2, #0x80		/* Adjust for extra sub */
 	ldmfdeq	sp!, {r4-r9}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x20
 	blt	.Lcopyout_w_lessthan32
 
 	/* Copy 32 bytes at a time */
 .Lcopyout_w_loop32:
 	ldrd	r4, [r0], #0x08
 	pld	[r0, #0x18]
 	ldrd	r6, [r0], #0x08
 	ldrd	r8, [r0], #0x08
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	ldrd	r4, [r0], #0x08
 	strt	r6, [r1], #0x04
 	strt	r7, [r1], #0x04
 	strt	r8, [r1], #0x04
 	strt	r9, [r1], #0x04
 	subs	r2, r2, #0x20
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	bge	.Lcopyout_w_loop32
 
 .Lcopyout_w_lessthan32:
 	adds	r2, r2, #0x20		/* Adjust for extra sub */
 	ldmfdeq	sp!, {r4-r9}
 	RETeq				/* Return now if done */
 
 	and	r4, r2, #0x18
 	rsb	r5, r4, #0x18
 	subs	r2, r2, r4
 	add	pc, pc, r5, lsl #1
 	nop
 
 	/* At least 24 bytes remaining */
 	ldrd	r4, [r0], #0x08
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	nop
 
 	/* At least 16 bytes remaining */
 	ldrd	r4, [r0], #0x08
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	nop
 
 	/* At least 8 bytes remaining */
 	ldrd	r4, [r0], #0x08
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	nop
 
 	/* Less than 8 bytes remaining */
 	ldmfd	sp!, {r4-r9}
 	RETeq				/* Return now if done */
 	mov	r3, #0x00
 
 .Lcopyout_w_less_than8:
 	subs	r2, r2, #0x04
 	ldrge	ip, [r0], #0x04
 	strtge	ip, [r1], #0x04
 	RETeq				/* Return now if done */
 	addlt	r2, r2, #0x04
 	ldrb	ip, [r0], #0x01
 	cmp	r2, #0x02
 	ldrbge	r2, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	ldrbgt	ip, [r0]
 	strbtge	r2, [r1], #0x01
 	strbtgt	ip, [r1]
 	RET
 
 /*
  * At this point, it has not been possible to word align both buffers.
  * The destination buffer (r1) is word aligned, but the source buffer
  * (r0) is not.
  */
 .Lcopyout_bad_align:
 	stmfd	sp!, {r4-r7}
 	mov	r3, #0x01
 	bic	r0, r0, #0x03
 	cmp	ip, #2
 	ldr	ip, [r0], #0x04
 	bgt	.Lcopyout_bad3
 	beq	.Lcopyout_bad2
 	b	.Lcopyout_bad1
 
 .Lcopyout_bad1_loop16:
 #ifdef	__ARMEB__
 	mov	r4, ip, lsl #8
 #else
 	mov	r4, ip, lsr #8
 #endif
 	ldr	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldr	r6, [r0], #0x04
 	ldr	r7, [r0], #0x04
 	ldr	ip, [r0], #0x04
 #ifdef	__ARMEB__
 	orr	r4, r4, r5, lsr #24
 	mov	r5, r5, lsl #8
 	orr	r5, r5, r6, lsr #24
 	mov	r6, r6, lsl #8
 	orr	r6, r6, r7, lsr #24
 	mov	r7, r7, lsl #8
 	orr	r7, r7, ip, lsr #24
 #else
 	orr	r4, r4, r5, lsl #24
 	mov	r5, r5, lsr #8
 	orr	r5, r5, r6, lsl #24
 	mov	r6, r6, lsr #8
 	orr	r6, r6, r7, lsl #24
 	mov	r7, r7, lsr #8
 	orr	r7, r7, ip, lsl #24
 #endif
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	strt	r6, [r1], #0x04
 	strt	r7, [r1], #0x04
 .Lcopyout_bad1:
 	subs	r2, r2, #0x10
 	bge	.Lcopyout_bad1_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x03
 	blt	.Lcopyout_l4
 
 .Lcopyout_bad1_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #8
 #else
 	mov	r4, ip, lsr #8
 #endif
 	ldr	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #24
 #else
 	orr	r4, r4, ip, lsl #24
 #endif
 	strt	r4, [r1], #0x04
 	bge	.Lcopyout_bad1_loop4
 	sub	r0, r0, #0x03
 	b	.Lcopyout_l4
 
 .Lcopyout_bad2_loop16:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #16
 #else
 	mov	r4, ip, lsr #16
 #endif
 	ldr	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldr	r6, [r0], #0x04
 	ldr	r7, [r0], #0x04
 	ldr	ip, [r0], #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, r5, lsr #16
 	mov	r5, r5, lsl #16
 	orr	r5, r5, r6, lsr #16
 	mov	r6, r6, lsl #16
 	orr	r6, r6, r7, lsr #16
 	mov	r7, r7, lsl #16
 	orr	r7, r7, ip, lsr #16
 #else
 	orr	r4, r4, r5, lsl #16
 	mov	r5, r5, lsr #16
 	orr	r5, r5, r6, lsl #16
 	mov	r6, r6, lsr #16
 	orr	r6, r6, r7, lsl #16
 	mov	r7, r7, lsr #16
 	orr	r7, r7, ip, lsl #16
 #endif
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	strt	r6, [r1], #0x04
 	strt	r7, [r1], #0x04
 .Lcopyout_bad2:
 	subs	r2, r2, #0x10
 	bge	.Lcopyout_bad2_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x02
 	blt	.Lcopyout_l4
 
 .Lcopyout_bad2_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #16
 #else
 	mov	r4, ip, lsr #16
 #endif
 	ldr	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #16
 #else
 	orr	r4, r4, ip, lsl #16
 #endif
 	strt	r4, [r1], #0x04
 	bge	.Lcopyout_bad2_loop4
 	sub	r0, r0, #0x02
 	b	.Lcopyout_l4
 
 .Lcopyout_bad3_loop16:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #24
 #else
 	mov	r4, ip, lsr #24
 #endif
 	ldr	r5, [r0], #0x04
 	pld	[r0, #0x018]
 	ldr	r6, [r0], #0x04
 	ldr	r7, [r0], #0x04
 	ldr	ip, [r0], #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, r5, lsr #8
 	mov	r5, r5, lsl #24
 	orr	r5, r5, r6, lsr #8
 	mov	r6, r6, lsl #24
 	orr	r6, r6, r7, lsr #8
 	mov	r7, r7, lsl #24
 	orr	r7, r7, ip, lsr #8
 #else
 	orr	r4, r4, r5, lsl #8
 	mov	r5, r5, lsr #24
 	orr	r5, r5, r6, lsl #8
 	mov	r6, r6, lsr #24
 	orr	r6, r6, r7, lsl #8
 	mov	r7, r7, lsr #24
 	orr	r7, r7, ip, lsl #8
 #endif
 	strt	r4, [r1], #0x04
 	strt	r5, [r1], #0x04
 	strt	r6, [r1], #0x04
 	strt	r7, [r1], #0x04
 .Lcopyout_bad3:
 	subs	r2, r2, #0x10
 	bge	.Lcopyout_bad3_loop16
 
 	adds	r2, r2, #0x10
 	ldmfdeq	sp!, {r4-r7}
 	RETeq				/* Return now if done */
 	subs	r2, r2, #0x04
 	sublt	r0, r0, #0x01
 	blt	.Lcopyout_l4
 
 .Lcopyout_bad3_loop4:
 #ifdef __ARMEB__
 	mov	r4, ip, lsl #24
 #else
 	mov	r4, ip, lsr #24
 #endif
 	ldr	ip, [r0], #0x04
 	subs	r2, r2, #0x04
 #ifdef __ARMEB__
 	orr	r4, r4, ip, lsr #8
 #else
 	orr	r4, r4, ip, lsl #8
 #endif
 	strt	r4, [r1], #0x04
 	bge	.Lcopyout_bad3_loop4
 	sub	r0, r0, #0x01
 
 .Lcopyout_l4:
 	ldmfd	sp!, {r4-r7}
 	mov	r3, #0x00
 	adds	r2, r2, #0x04
 	RETeq
 .Lcopyout_l4_2:
 	rsbs	r2, r2, #0x03
 	addne	pc, pc, r2, lsl #3
 	nop
 	ldrb	ip, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	ldrb	ip, [r0], #0x01
 	strbt	ip, [r1], #0x01
 	ldrb	ip, [r0]
 	strbt	ip, [r1]
 	RET
 END(copyout)
 
Index: head/sys/arm/arm/copystr.S
===================================================================
--- head/sys/arm/arm/copystr.S	(revision 289371)
+++ head/sys/arm/arm/copystr.S	(revision 289372)
@@ -1,215 +1,225 @@
 /*	$NetBSD: copystr.S,v 1.8 2002/10/13 14:54:48 bjh21 Exp $	*/
 
 /*-
  * Copyright (c) 1995 Mark Brinicombe.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *	This product includes software developed by Mark Brinicombe.
  * 4. The name of the company nor the name of the author may be used to
  *    endorse or promote products derived from this software without specific
  *    prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * copystr.S
  *
  * optimised and fault protected copystr functions
  *
  * Created      : 16/05/95
  */
 
 #include "assym.s"
 #include <machine/acle-compat.h>
 #include <machine/asm.h>
 #include <machine/armreg.h>
 __FBSDID("$FreeBSD$");
 
 #include <sys/errno.h>
 
 	.text
 	.align	2
 
 #if __ARM_ARCH >= 6
 #define GET_PCB(tmp) \
 	mrc p15, 0, tmp, c13, c0, 4; \
 	add	tmp, tmp, #(TD_PCB)
 #else
 .Lpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 
 #define GET_PCB(tmp) \
 	ldr	tmp, .Lpcb
 #endif
 
 /*
  * r0 - from
  * r1 - to
  * r2 - maxlens
  * r3 - lencopied
  *
  * Copy string from r0 to r1
  */
 ENTRY(copystr)
 	stmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
 	teq	r2, #0x00000000
 	mov	r5, #0x00000000
 	moveq	r0, #ENAMETOOLONG
 	beq	2f
 
 1:	ldrb	r4, [r0], #0x0001
 	add	r5, r5, #0x00000001
 	teq	r4, #0x00000000
 	strb	r4, [r1], #0x0001
 	teqne	r5, r2
 	bne	1b
 
 	teq	r4, #0x00000000
 	moveq	r0, #0x00000000
 	movne	r0, #ENAMETOOLONG
 
 2:	teq	r3, #0x00000000
 	strne	r5, [r3]
 
 	ldmfd	sp!, {r4-r5}			/* stack is 8 byte aligned */
 	RET
 END(copystr)
 
 #define SAVE_REGS	stmfd	sp!, {r4-r6}
 #define RESTORE_REGS	ldmfd	sp!, {r4-r6}
 
 /*
  * r0 - user space address
  * r1 - kernel space address
  * r2 - maxlens
  * r3 - lencopied
  *
  * Copy string from user space to kernel space
  */
 ENTRY(copyinstr)
 	SAVE_REGS
 
 	teq	r2, #0x00000000
 	mov	r6, #0x00000000
 	moveq	r0, #ENAMETOOLONG
 	beq	2f
 
+	ldr	r12, =VM_MAXUSER_ADDRESS
+
 	GET_PCB(r4)
 	ldr	r4, [r4]
 
 #ifdef DIAGNOSTIC
 	teq	r4, #0x00000000
 	beq	.Lcopystrpcbfault
 #endif
 
 	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
 	teqne	r6, r2
 	bne	1b
 
 	mov	r0, #0x00000000
 	str	r0, [r4, #PCB_ONFAULT]
 
 	teq	r5, #0x00000000
 	moveq	r0, #0x00000000
 	movne	r0, #ENAMETOOLONG
 
 2:	teq	r3, #0x00000000
 	strne	r6, [r3]
 
 	RESTORE_REGS
 	RET
 END(copyinstr)
 
 /*
  * r0 - kernel space address
  * r1 - user space address
  * r2 - maxlens
  * r3 - lencopied
  *
  * Copy string from kernel space to user space
  */
 ENTRY(copyoutstr)
 	SAVE_REGS
 
 	teq	r2, #0x00000000
 	mov	r6, #0x00000000
 	moveq	r0, #ENAMETOOLONG
 	beq	2f
 
+	ldr	r12, =VM_MAXUSER_ADDRESS
+
 	GET_PCB(r4)
 	ldr	r4, [r4]
 
 #ifdef DIAGNOSTIC
 	teq	r4, #0x00000000
 	beq	.Lcopystrpcbfault
 #endif
 
 	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
 	teqne	r6, r2
 	bne	1b
 
 	mov	r0, #0x00000000
 	str	r0, [r4, #PCB_ONFAULT]
 
 	teq	r5, #0x00000000
 	moveq	r0, #0x00000000
 	movne	r0, #ENAMETOOLONG
 
 2:	teq	r3, #0x00000000
 	strne	r6, [r3]
 
 	RESTORE_REGS
 	RET
 END(copyoutstr)
 
 /* A fault occurred during the copy */
 .Lcopystrfault:
-	mov	r0, #EFAULT
 	mov	r1, #0x00000000
 	str	r1, [r4, #PCB_ONFAULT]
+	mov	r0, #EFAULT
 	RESTORE_REGS
 	RET
 
 #ifdef DIAGNOSTIC
 .Lcopystrpcbfault:
 	mov	r2, r1
 	mov	r1, r0
 	adr	r0, Lcopystrpcbfaulttext
 	bic	sp, sp, #7			/* align stack to 8 bytes */
 	b	_C_LABEL(panic)
 
 Lcopystrpcbfaulttext:
 	.asciz	"No valid PCB during copyinoutstr() addr1=%08x addr2=%08x\n"
 	.align	2
 #endif
Index: head/sys/arm/arm/fusu.S
===================================================================
--- head/sys/arm/arm/fusu.S	(revision 289371)
+++ head/sys/arm/arm/fusu.S	(revision 289372)
@@ -1,395 +1,437 @@
 /*	$NetBSD: fusu.S,v 1.10 2003/12/01 13:34:44 rearnsha Exp $	*/
 
 /*-
  * Copyright (c) 1996-1998 Mark Brinicombe.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *	This product includes software developed by Mark Brinicombe
  * 4. The name of the company nor the name of the author may be used to
  *    endorse or promote products derived from this software without specific
  *    prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 
 #include <machine/acle-compat.h>
 #include <machine/asm.h>
 #include <machine/armreg.h>
 #include "assym.s"
 __FBSDID("$FreeBSD$");
 
 	.syntax	unified
 
 #if __ARM_ARCH >= 6
 #define GET_PCB(tmp) \
 	mrc p15, 0, tmp, c13, c0, 4; \
 	add	tmp, tmp, #(TD_PCB)
 #else
 .Lcurpcb:
 	.word	_C_LABEL(__pcpu) + PC_CURPCB
 #define GET_PCB(tmp) \
 	ldr	tmp, .Lcurpcb
 #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, #0
+	bcs	2f
+
+	GET_PCB(r6)
+	ldr	r6, [r6]
+
 #ifdef DIAGNOSTIC
-	teq	r3, #0x00000000
+	teq	r6, #0x00000000
+	ldmfdeq	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
-	bne     2f
-	strex   r5, r2, [r0]
-	cmp     r5, #0
-	bne     1b
+	ldrex	r4, [r0]
+	cmp	r4, r1
+	strexeq	r5, r3, [r0]
+	cmpeq	r5, #1
+	beq	1b
 #else
-	ldrt	r5, [r0]
-	cmp	r5, r1
-	movne	r0, r5
-	strteq	r2, [r0]
+	ldrt	r4, [r0]
+	cmp	r4, r1
+	strteq	r3, [r0]
 #endif
-	moveq	r0, r1
+	str	r4, [r2]
+	mov	r0, #0
+	str	r0, [r6, #PCB_ONFAULT]
 2:
-	ldmfd	sp!, {r4, r5}
-	mov	r1, #0x00000000
-	str	r1, [r3, #PCB_ONFAULT]
+	ldmfd	sp!, {r4, r5, r6}
 	RET
-EEND(casuword32)
-END(casuword)
+EEND(casueword32)
+END(casueword)
 
 /*
  * Handle faults from casuword.  Clean up and return -1.
  */
 
 .Lcasuwordfault:
 	mov	r0, #0x00000000
-	str	r0, [r3, #PCB_ONFAULT]
-	mvn	r0, #0x00000000
-	ldmfd	sp!, {r4, r5}
+	str	r0, [r6, #PCB_ONFAULT]
+	mvn	r0, #0
+	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, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	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)
 
 /*
  * fusword(caddr_t uaddr);
  * Fetch a short from the user's address space.
  */
 
 ENTRY(fusword)
+	ldr	r3, =(VM_MAXUSER_ADDRESS-1)
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r1, .Lfusufault
 	str	r1, [r2, #PCB_ONFAULT]
 
 	ldrbt	r3, [r0], #1
 	ldrbt	ip, [r0]
 #ifdef __ARMEB__
 	orr	r0, ip, r3, asl #8
 #else
 	orr	r0, r3, ip, asl #8
 #endif
 	mov	r1, #0x00000000
 	str	r1, [r2, #PCB_ONFAULT]
 	RET
 END(fusword)
 
 /*
  * fuswintr(caddr_t uaddr);
  * Fetch a short from the user's address space.  Can be called during an
  * interrupt.
  */
 
 ENTRY(fuswintr)
+	ldr	r3, =(VM_MAXUSER_ADDRESS-1)
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	ldr	r2, Lblock_userspace_access
 	ldr	r2, [r2]
 	teq	r2, #0
 	mvnne	r0, #0x00000000
 	RETne
 
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r1, _C_LABEL(fusubailout)
 	str	r1, [r2, #PCB_ONFAULT]
 
 	ldrbt	r3, [r0], #1
 	ldrbt	ip, [r0]
 #ifdef __ARMEB__
 	orr	r0, ip, r3, asl #8
 #else
 	orr	r0, r3, ip, asl #8
 #endif
 
 	mov	r1, #0x00000000
 	str	r1, [r2, #PCB_ONFAULT]
 	RET
 END(fuswintr)
 
 Lblock_userspace_access:
 	.word	_C_LABEL(block_userspace_access)
 
 	.data
 	.align	2
 	.global	_C_LABEL(block_userspace_access)
 _C_LABEL(block_userspace_access):
 	.word	0
 	.text
 
 /*
  * fubyte(caddr_t uaddr);
  * Fetch a byte from the user's address space.
  */
 
 ENTRY(fubyte)
+	ldr	r3, =VM_MAXUSER_ADDRESS
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r1, .Lfusufault
 	str	r1, [r2, #PCB_ONFAULT]
 
 	ldrbt	r3, [r0]
 
 	mov	r1, #0x00000000
 	str	r1, [r2, #PCB_ONFAULT]
 	mov	r0, r3
 	RET
 END(fubyte)
 
 /*
  * Handle faults from [fs]u*().  Clean up and return -1.
  */
 
 .Lfusufault:
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	mvn	r0, #0x00000000
 	RET
 
 /*
  * Handle faults from [fs]u*().  Clean up and return -1.  This differs from
  * fusufault() in that trap() will recognise it and return immediately rather
  * than trying to page fault.
  */
 
 /* label must be global as fault.c references it */
 	.global	_C_LABEL(fusubailout)
 _C_LABEL(fusubailout):
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	mvn	r0, #0x00000000
 	RET
 
 #ifdef DIAGNOSTIC
 /*
  * Handle earlier faults from [fs]u*(), due to no pcb
  */
 
 .Lfusupcbfault:
 	mov	r1, r0
 	adr	r0, fusupcbfaulttext
 	b	_C_LABEL(panic)
 
 fusupcbfaulttext:
 	.asciz	"Yikes - no valid PCB during fusuxxx() addr=%08x\n"
 	.align	2
 #endif
 
 /*
  * suword(caddr_t uaddr, int x);
  * Store an int in the user's address space.
  */
 
 ENTRY(suword)
 EENTRY_NP(suword32)
+	ldr	r3, =(VM_MAXUSER_ADDRESS-3)
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
 	strt	r1, [r0]
 
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	RET
 EEND(suword32)
 END(suword)
 
 /*
  * suswintr(caddr_t uaddr, short x);
  * Store a short in the user's address space.  Can be called during an
  * interrupt.
  */
 
 ENTRY(suswintr)
+	ldr	r3, =(VM_MAXUSER_ADDRESS-1)
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	ldr	r2, Lblock_userspace_access
 	ldr	r2, [r2]
 	teq	r2, #0
 	mvnne	r0, #0x00000000
 	RETne
 
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r3, _C_LABEL(fusubailout)
 	str	r3, [r2, #PCB_ONFAULT]
 
 #ifdef __ARMEB__
 	mov	ip, r1, lsr #8
 	strbt	ip, [r0], #1
 #else
 	strbt	r1, [r0], #1
 	mov	r1, r1, lsr #8
 #endif
 	strbt	r1, [r0]
 
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	RET
 END(suswintr)
 
 /*
  * susword(caddr_t uaddr, short x);
  * Store a short in the user's address space.
  */
 
 ENTRY(susword)
+	ldr	r3, =(VM_MAXUSER_ADDRESS-1)
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
 #ifdef __ARMEB__
 	mov	ip, r1, lsr #8
 	strbt	ip, [r0], #1
 #else
 	strbt	r1, [r0], #1
 	mov	r1, r1, lsr #8
 #endif
 	strbt	r1, [r0]
 
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	RET
 END(susword)
 
 /*
  * subyte(caddr_t uaddr, char x);
  * Store a byte in the user's address space.
  */
 
 ENTRY(subyte)
+	ldr	r3, =VM_MAXUSER_ADDRESS
+	cmp	r0, r3
+	mvncs	r0, #0
+	RETc(cs)
+
 	GET_PCB(r2)
 	ldr	r2, [r2]
 
 
 #ifdef DIAGNOSTIC
 	teq	r2, #0x00000000
 	beq	.Lfusupcbfault
 #endif
 
 	adr	r3, .Lfusufault
 	str	r3, [r2, #PCB_ONFAULT]
 
 	strbt	r1, [r0]
 	mov	r0, #0x00000000
 	str	r0, [r2, #PCB_ONFAULT]
 	RET
 END(subyte)
Index: head/sys/arm/arm/genassym.c
===================================================================
--- head/sys/arm/arm/genassym.c	(revision 289371)
+++ head/sys/arm/arm/genassym.c	(revision 289372)
@@ -1,168 +1,169 @@
 /*-
  * Copyright (c) 2004 Olivier Houchard
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/assym.h>
 #include <sys/proc.h>
 #include <sys/mbuf.h>
 #include <sys/vmmeter.h>
 #include <sys/bus.h>
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
 #include <machine/acle-compat.h>
 #include <machine/vmparam.h>
 #include <machine/armreg.h>
 #include <machine/frame.h>
 #include <machine/pcb.h>
 #include <machine/cpu.h>
 #include <machine/cpu-v6.h>
 #include <machine/proc.h>
 #include <machine/cpufunc.h>
 #include <machine/cpuinfo.h>
 #include <machine/pte.h>
 #include <machine/intr.h>
 #include <machine/sysarch.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
 #include <netinet/ip_var.h>
 
 ASSYM(KERNBASE, KERNBASE);
 ASSYM(PCB_NOALIGNFLT, PCB_NOALIGNFLT);
 #ifdef ARM_NEW_PMAP
 ASSYM(CPU_ASID_KERNEL,CPU_ASID_KERNEL);
 #endif
 ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
 #ifndef ARM_NEW_PMAP
 ASSYM(PCB_DACR, offsetof(struct pcb, pcb_dacr));
 #endif
 ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
 ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
 #ifndef ARM_NEW_PMAP
 ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
 ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
 #endif
 ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4));
 ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5));
 ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6));
 ASSYM(PCB_R7, offsetof(struct pcb, pcb_regs.sf_r7));
 ASSYM(PCB_R8, offsetof(struct pcb, pcb_regs.sf_r8));
 ASSYM(PCB_R9, offsetof(struct pcb, pcb_regs.sf_r9));
 ASSYM(PCB_R10, offsetof(struct pcb, pcb_regs.sf_r10));
 ASSYM(PCB_R11, offsetof(struct pcb, pcb_regs.sf_r11));
 ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12));
 ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
 ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
 ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
 
 ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
 ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
 ASSYM(M_LEN, offsetof(struct mbuf, m_len));
 ASSYM(M_DATA, offsetof(struct mbuf, m_data));
 ASSYM(M_NEXT, offsetof(struct mbuf, m_next));
 ASSYM(IP_SRC, offsetof(struct ip, ip_src));
 ASSYM(IP_DST, offsetof(struct ip, ip_dst));
 ASSYM(CF_SETTTB, offsetof(struct cpu_functions, cf_setttb));
 ASSYM(CF_CONTROL, offsetof(struct cpu_functions, cf_control));
 ASSYM(CF_CONTEXT_SWITCH, offsetof(struct cpu_functions, cf_context_switch));
 ASSYM(CF_DCACHE_WB_RANGE, offsetof(struct cpu_functions, cf_dcache_wb_range));
 ASSYM(CF_L2CACHE_WB_RANGE, offsetof(struct cpu_functions, cf_l2cache_wb_range));
 ASSYM(CF_IDCACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_idcache_wbinv_all));
 ASSYM(CF_L2CACHE_WBINV_ALL, offsetof(struct cpu_functions, cf_l2cache_wbinv_all));
 ASSYM(CF_TLB_FLUSHID_SE, offsetof(struct cpu_functions, cf_tlb_flushID_SE));
 ASSYM(CF_ICACHE_SYNC, offsetof(struct cpu_functions, cf_icache_sync_all));
 
 ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap));
 ASSYM(V_SOFT, offsetof(struct vmmeter, v_soft));
 ASSYM(V_INTR, offsetof(struct vmmeter, v_intr));
 
 ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
 ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
 ASSYM(TD_PROC, offsetof(struct thread, td_proc));
 ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
 ASSYM(TD_MD, offsetof(struct thread, td_md));
 ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
 ASSYM(MD_TP, offsetof(struct mdthread, md_tp));
 ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start));
 ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end));
 
 ASSYM(TF_R0, offsetof(struct trapframe, tf_r0));
 ASSYM(TF_R1, offsetof(struct trapframe, tf_r1));
 ASSYM(TF_PC, offsetof(struct trapframe, tf_pc));
 ASSYM(P_PID, offsetof(struct proc, p_pid));
 ASSYM(P_FLAG, offsetof(struct proc, p_flag));
 
 ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
 
 #if __ARM_ARCH < 6
 ASSYM(ARM_TP_ADDRESS, ARM_TP_ADDRESS);
 ASSYM(ARM_RAS_START, ARM_RAS_START);
 ASSYM(ARM_RAS_END, ARM_RAS_END);
 #endif
 
 #ifdef VFP
 ASSYM(PCB_VFPSTATE, offsetof(struct pcb, pcb_vfpstate));
 #endif
 
 #if __ARM_ARCH >= 6
 ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap));
 #endif
 
 ASSYM(PAGE_SIZE, PAGE_SIZE);
 ASSYM(PMAP_DOMAIN_KERNEL, PMAP_DOMAIN_KERNEL);
 #ifdef PMAP_INCLUDE_PTE_SYNC
 ASSYM(PMAP_INCLUDE_PTE_SYNC, 1);
 #endif
 ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
 ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
 ASSYM(P_TRACED, P_TRACED);
 ASSYM(P_SIGEVENT, P_SIGEVENT);
 ASSYM(P_PROFIL, P_PROFIL);
 ASSYM(TRAPFRAMESIZE, sizeof(struct trapframe));
 
 ASSYM(MAXCOMLEN, MAXCOMLEN);
 ASSYM(MAXCPU, MAXCPU);
 ASSYM(_NCPUWORDS, _NCPUWORDS);
 ASSYM(NIRQ, NIRQ);
 ASSYM(PCPU_SIZE, sizeof(struct pcpu));
 ASSYM(P_VMSPACE, offsetof(struct proc, p_vmspace));
 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));
 ASSYM(ICACHE_LINE_SIZE, offsetof(struct cpuinfo, icache_line_size));
 ASSYM(ICACHE_LINE_MASK, offsetof(struct cpuinfo, icache_line_mask));
Index: head/sys/arm/include/param.h
===================================================================
--- head/sys/arm/include/param.h	(revision 289371)
+++ head/sys/arm/include/param.h	(revision 289372)
@@ -1,156 +1,152 @@
 /*-
  * Copyright (c) 2001 David E. O'Brien
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * William Jolitz.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *	This product includes software developed by the University of
  *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  *	from: @(#)param.h	5.8 (Berkeley) 6/28/91
  * $FreeBSD$
  */
 
 #ifndef _ARM_INCLUDE_PARAM_H_
 #define	_ARM_INCLUDE_PARAM_H_
 
 /*
  * Machine dependent constants for StrongARM
  */
 
 #include <machine/_align.h>
 #include <machine/acle-compat.h>
 
 #define STACKALIGNBYTES	(8 - 1)
 #define STACKALIGN(p)	((u_int)(p) & ~STACKALIGNBYTES)
 
 #define __PCI_REROUTE_INTERRUPT
 
 #if __ARM_ARCH >= 6
 #define	_V6_SUFFIX "v6"
 #else
 #define	_V6_SUFFIX ""
 #endif
 
 #ifdef __ARM_PCS_VFP
 #define	_HF_SUFFIX "hf"
 #else
 #define	_HF_SUFFIX ""
 #endif
 
 #ifdef __ARM_BIG_ENDIAN
 #define	_EB_SUFFIX "eb"
 #else
 #define	_EB_SUFFIX ""
 #endif
 
 #ifndef MACHINE
 #define	MACHINE		"arm"
 #endif
 #ifndef MACHINE_ARCH
 #define	MACHINE_ARCH	"arm" _V6_SUFFIX _HF_SUFFIX _EB_SUFFIX
 #endif
 
 #if defined(SMP) || defined(KLD_MODULE)
 #ifndef MAXCPU
 #define	MAXCPU		4
 #endif
 #else
 #define	MAXCPU		1
 #endif /* SMP || KLD_MODULE */
 
 #ifndef MAXMEMDOM
 #define	MAXMEMDOM	1
 #endif
 
 #define	ALIGNBYTES	_ALIGNBYTES
 #define	ALIGN(p)	_ALIGN(p)
 /*
  * ALIGNED_POINTER is a boolean macro that checks whether an address
  * is valid to fetch data elements of type t from on this architecture.
  * This does not reflect the optimal alignment, just the possibility
  * (within reasonable limits).
  */
 #define	ALIGNED_POINTER(p, t)	((((unsigned)(p)) & (sizeof(t)-1)) == 0)
 
 /*
  * CACHE_LINE_SIZE is the compile-time maximum cache line size for an
  * architecture.  It should be used with appropriate caution.
  */
 #define	CACHE_LINE_SHIFT	6
 #define	CACHE_LINE_SIZE		(1 << CACHE_LINE_SHIFT)
 
 #define	PAGE_SHIFT	12
 #define	PAGE_SIZE	(1 << PAGE_SHIFT)	/* Page size */
 #define	PAGE_MASK	(PAGE_SIZE - 1)
 #define	NPTEPG		(PAGE_SIZE/(sizeof (pt_entry_t)))
 
 #define PDR_SHIFT	20 /* log2(NBPDR) */
 #define NBPDR		(1 << PDR_SHIFT)
 #define PDRMASK		(NBPDR - 1)
 #define NPDEPG          (1 << (32 - PDR_SHIFT))
 
 #define	MAXPAGESIZES	2		/* maximum number of supported page sizes */
 
 #ifndef KSTACK_PAGES
 #define KSTACK_PAGES    2
 #endif /* !KSTACK_PAGES */
 
 #ifndef FPCONTEXTSIZE
 #define FPCONTEXTSIZE	(0x100)
 #endif
 
 #ifndef KSTACK_GUARD_PAGES
 #define KSTACK_GUARD_PAGES	1
 #endif /* !KSTACK_GUARD_PAGES */
 
 #define USPACE_SVC_STACK_TOP		(kstack_pages * PAGE_SIZE)
 
 /*
  * Mach derived conversion macros
  */
 #define	trunc_page(x)		((x) & ~PAGE_MASK)
 #define	round_page(x)		(((x) + PAGE_MASK) & ~PAGE_MASK)
 #define	trunc_1mpage(x)		((unsigned)(x) & ~PDRMASK)
 #define	round_1mpage(x)		((((unsigned)(x)) + PDRMASK) & ~PDRMASK)
 
 #define	atop(x)			((unsigned)(x) >> PAGE_SHIFT)
 #define	ptoa(x)			((unsigned)(x) << PAGE_SHIFT)
 
 #define	arm32_btop(x)		((unsigned)(x) >> PAGE_SHIFT)
 #define	arm32_ptob(x)		((unsigned)(x) << PAGE_SHIFT)
 
 #define	pgtok(x)		((x) * (PAGE_SIZE / 1024))
 
-#ifdef _KERNEL
-#define	NO_FUEWORD	1
-#endif
-
 #endif /* !_ARM_INCLUDE_PARAM_H_ */