From owner-svn-src-all@FreeBSD.ORG Tue Nov 12 01:15:27 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3F0F64F1; Tue, 12 Nov 2013 01:15:27 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 770192FAB; Mon, 11 Nov 2013 23:37:17 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rABNbHfq067867; Mon, 11 Nov 2013 23:37:17 GMT (envelope-from nwhitehorn@svn.freebsd.org) Received: (from nwhitehorn@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id rABNbHn8067862; Mon, 11 Nov 2013 23:37:17 GMT (envelope-from nwhitehorn@svn.freebsd.org) Message-Id: <201311112337.rABNbHn8067862@svn.freebsd.org> From: Nathan Whitehorn Date: Mon, 11 Nov 2013 23:37:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258024 - in head/sys: conf powerpc/aim powerpc/booke powerpc/powerpc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Nov 2013 01:15:27 -0000 Author: nwhitehorn Date: Mon Nov 11 23:37:16 2013 New Revision: 258024 URL: http://svnweb.freebsd.org/changeset/base/258024 Log: Use the same implementation of copyinout.c for both AIM and Book-E. This fixes some bugs in both implementations related to validity checks on mapping bounds. Added: head/sys/powerpc/powerpc/copyinout.c - copied, changed from r257990, head/sys/powerpc/aim/copyinout.c Deleted: head/sys/powerpc/aim/copyinout.c head/sys/powerpc/booke/copyinout.c Modified: head/sys/conf/files.powerpc Modified: head/sys/conf/files.powerpc ============================================================================== --- head/sys/conf/files.powerpc Mon Nov 11 22:07:56 2013 (r258023) +++ head/sys/conf/files.powerpc Mon Nov 11 23:37:16 2013 (r258024) @@ -86,7 +86,6 @@ libkern/qdivrem.c optional powerpc libkern/ucmpdi2.c optional powerpc libkern/udivdi3.c optional powerpc libkern/umoddi3.c optional powerpc -powerpc/aim/copyinout.c optional aim powerpc/aim/interrupt.c optional aim powerpc/aim/locore.S optional aim no-obj powerpc/aim/machdep.c optional aim @@ -98,7 +97,6 @@ powerpc/aim/mp_cpudep.c optional aim sm powerpc/aim/slb.c optional aim powerpc64 powerpc/aim/trap.c optional aim powerpc/aim/uma_machdep.c optional aim -powerpc/booke/copyinout.c optional booke powerpc/booke/interrupt.c optional booke powerpc/booke/locore.S optional booke no-obj powerpc/booke/machdep.c optional booke @@ -173,6 +171,7 @@ powerpc/powerpc/bcopy.c standard powerpc/powerpc/bus_machdep.c standard powerpc/powerpc/busdma_machdep.c standard powerpc/powerpc/clock.c standard +powerpc/powerpc/copyinout.c standard powerpc/powerpc/copystr.c standard powerpc/powerpc/cpu.c standard powerpc/powerpc/db_disasm.c optional ddb Copied and modified: head/sys/powerpc/powerpc/copyinout.c (from r257990, head/sys/powerpc/aim/copyinout.c) ============================================================================== --- head/sys/powerpc/aim/copyinout.c Mon Nov 11 14:08:25 2013 (r257990, copy source) +++ head/sys/powerpc/powerpc/copyinout.c Mon Nov 11 23:37:16 2013 (r258024) @@ -69,9 +69,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include int setfault(faultbuf); /* defined in locore.S */ +#ifdef AIM /* * Makes sure that the right segment of userspace is mapped in. */ @@ -132,6 +134,43 @@ set_user_sr(pmap_t pm, const void *addr) } #endif +static __inline int +map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen, + size_t *klen) +{ + size_t l; + + *kaddr = (char *)USER_ADDR + ((uintptr_t)uaddr & ~SEGMENT_MASK); + + l = ((char *)USER_ADDR + SEGMENT_LENGTH) - (char *)(*kaddr); + if (l > ulen) + l = ulen; + if (klen) + *klen = l; + else if (l != ulen) + return (EFAULT); + + set_user_sr(pm, uaddr); + + return (0); +} +#else /* Book-E uses a combined kernel/user mapping */ +static __inline int +map_user_ptr(pmap_t pm, const void *uaddr, void **kaddr, size_t ulen, + size_t *klen) +{ + + if ((uintptr_t)uaddr + ulen > VM_MAXUSER_ADDRESS + PAGE_SIZE) + return (EFAULT); + + *kaddr = (void *)(uintptr_t)uaddr; + if (klen) + *klen = ulen; + + return (0); +} +#endif + int copyout(const void *kaddr, void *udaddr, size_t len) { @@ -154,13 +193,10 @@ copyout(const void *kaddr, void *udaddr, up = udaddr; while (len > 0) { - p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK); - - l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p; - if (l > len) - l = len; - - set_user_sr(pm,up); + if (map_user_ptr(pm, udaddr, (void **)&p, len, &l)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } bcopy(kp, p, l); @@ -195,13 +231,10 @@ copyin(const void *udaddr, void *kaddr, up = udaddr; while (len > 0) { - p = (char *)USER_ADDR + ((uintptr_t)up & ~SEGMENT_MASK); - - l = ((char *)USER_ADDR + SEGMENT_LENGTH) - p; - if (l > len) - l = len; - - set_user_sr(pm,up); + if (map_user_ptr(pm, udaddr, (void **)&p, len, &l)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } bcopy(p, kp, l); @@ -269,14 +302,16 @@ subyte(void *addr, int byte) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } *p = (char)byte; @@ -295,14 +330,16 @@ suword32(void *addr, int word) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (int *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } *p = word; @@ -321,14 +358,16 @@ suword(void *addr, long word) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } *p = word; @@ -361,14 +400,16 @@ fubyte(const void *addr) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (u_char *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } val = *p; @@ -387,14 +428,16 @@ fuword32(const void *addr) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (int32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } val = *p; @@ -413,14 +456,16 @@ fuword(const void *addr) td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } - set_user_sr(pm,addr); + if (map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } val = *p; @@ -446,15 +491,18 @@ casuword32(volatile uint32_t *addr, uint td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (uint32_t *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); - - set_user_sr(pm,(const void *)(vm_offset_t)addr); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } + if (map_user_ptr(pm, (void *)(uintptr_t)addr, (void **)&p, sizeof(*p), + NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } + __asm __volatile ( "1:\tlwarx %0, 0, %2\n\t" /* load old value */ "cmplw %3, %0\n\t" /* compare */ @@ -491,15 +539,18 @@ casuword(volatile u_long *addr, u_long o td = curthread; pm = &td->td_proc->p_vmspace->vm_pmap; - p = (u_long *)(USER_ADDR + ((uintptr_t)addr & ~SEGMENT_MASK)); - - set_user_sr(pm,(const void *)(vm_offset_t)addr); if (setfault(env)) { td->td_pcb->pcb_onfault = NULL; return (-1); } + if (map_user_ptr(pm, (void *)(uintptr_t)addr, (void **)&p, sizeof(*p), + NULL)) { + td->td_pcb->pcb_onfault = NULL; + return (-1); + } + __asm __volatile ( "1:\tldarx %0, 0, %2\n\t" /* load old value */ "cmpld %3, %0\n\t" /* compare */