From owner-svn-src-all@FreeBSD.ORG Wed Jul 2 23:12:56 2014 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 E86A2A79; Wed, 2 Jul 2014 23:12:56 +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)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C93922D42; Wed, 2 Jul 2014 23:12:56 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s62NCusY056508; Wed, 2 Jul 2014 23:12:56 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s62NCun6056507; Wed, 2 Jul 2014 23:12:56 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201407022312.s62NCun6056507@svn.freebsd.org> From: Marcel Moolenaar Date: Wed, 2 Jul 2014 23:12:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r268194 - stable/10/sys/ia64/ia64 X-SVN-Group: stable-10 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.18 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: Wed, 02 Jul 2014 23:12:57 -0000 Author: marcel Date: Wed Jul 2 23:12:56 2014 New Revision: 268194 URL: http://svnweb.freebsd.org/changeset/base/268194 Log: MFC r262726: When reading physical memory, make sure to access it using the right memory attributes. Modified: stable/10/sys/ia64/ia64/mem.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/ia64/ia64/mem.c ============================================================================== --- stable/10/sys/ia64/ia64/mem.c Wed Jul 2 23:07:01 2014 (r268193) +++ stable/10/sys/ia64/ia64/mem.c Wed Jul 2 23:12:56 2014 (r268194) @@ -47,19 +47,11 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include -#include -#include -#include -#include -#include #include #include - -#include -#include +#include #include #include @@ -69,10 +61,25 @@ __FBSDID("$FreeBSD$"); struct mem_range_softc mem_range_softc; -static __inline int -ia64_pa_access(vm_offset_t pa) +static int +mem_phys2virt(vm_offset_t offset, int prot, void **ptr, u_long *limit) { - return (VM_PROT_READ|VM_PROT_WRITE); + struct efi_md *md; + + if (prot & ~(VM_PROT_READ | VM_PROT_WRITE)) + return (EPERM); + + md = efi_md_find(offset); + if (md == NULL) + return (EFAULT); + + if (md->md_type == EFI_MD_TYPE_BAD) + return (EIO); + + *ptr = (void *)((md->md_attr & EFI_MD_ATTR_WB) + ? IA64_PHYS_TO_RR7(offset) : IA64_PHYS_TO_RR6(offset)); + *limit = (md->md_pages * EFI_PAGE_SIZE) - (offset - md->md_phys); + return (0); } /* ARGSUSED */ @@ -80,10 +87,15 @@ int memrw(struct cdev *dev, struct uio *uio, int flags) { struct iovec *iov; - vm_offset_t addr, eaddr, o, v; - int c, error, rw; + off_t ofs; + vm_offset_t addr; + void *ptr; + u_long limit; + int count, error, phys, rw; error = 0; + rw = (uio->uio_rw == UIO_READ) ? VM_PROT_READ : VM_PROT_WRITE; + while (uio->uio_resid > 0 && !error) { iov = uio->uio_iov; if (iov->iov_len == 0) { @@ -94,51 +106,41 @@ memrw(struct cdev *dev, struct uio *uio, continue; } - if (dev2unit(dev) == CDEV_MINOR_MEM) { - v = uio->uio_offset; -kmemphys: - /* Allow reads only in RAM. */ - rw = (uio->uio_rw == UIO_READ) - ? VM_PROT_READ : VM_PROT_WRITE; - if ((ia64_pa_access(v) & rw) != rw) { - error = EFAULT; - c = 0; - break; - } + ofs = uio->uio_offset; - o = uio->uio_offset & PAGE_MASK; - c = min(uio->uio_resid, (int)(PAGE_SIZE - o)); - error = uiomove((caddr_t)IA64_PHYS_TO_RR7(v), c, uio); - continue; + phys = (dev2unit(dev) == CDEV_MINOR_MEM) ? 1 : 0; + if (phys == 0 && ofs >= IA64_RR_BASE(6)) { + ofs = IA64_RR_MASK(ofs); + phys++; } - else if (dev2unit(dev) == CDEV_MINOR_KMEM) { - v = uio->uio_offset; - - if (v >= IA64_RR_BASE(6)) { - v = IA64_RR_MASK(v); - goto kmemphys; - } - c = min(iov->iov_len, MAXPHYS); + if (phys) { + error = mem_phys2virt(ofs, rw, &ptr, &limit); + if (error) + return (error); + + count = min(uio->uio_resid, limit); + error = uiomove(ptr, count, uio); + } else { + ptr = (void *)ofs; + count = iov->iov_len; /* * Make sure that all of the pages are currently * resident so that we don't create any zero-fill * pages. */ - addr = trunc_page(v); - eaddr = round_page(v + c); + limit = round_page(ofs + count); + addr = trunc_page(ofs); if (addr < VM_MAXUSER_ADDRESS) - return (EFAULT); - for (; addr < eaddr; addr += PAGE_SIZE) { + return (EINVAL); + for (; addr < limit; addr += PAGE_SIZE) { if (pmap_kextract(addr) == 0) return (EFAULT); } - if (!kernacc((caddr_t)v, c, (uio->uio_rw == UIO_READ) - ? VM_PROT_READ : VM_PROT_WRITE)) + if (!kernacc(ptr, count, rw)) return (EFAULT); - error = uiomove((caddr_t)v, c, uio); - continue; + error = uiomove(ptr, count, uio); } /* else panic! */ } @@ -153,6 +155,10 @@ int memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) { + void *ptr; + u_long limit; + int error; + /* * /dev/mem is the only one that makes sense through this * interface. For /dev/kmem any physaddr we return here @@ -160,13 +166,14 @@ memmmap(struct cdev *dev, vm_ooffset_t o * a later time. */ if (dev2unit(dev) != CDEV_MINOR_MEM) - return (-1); + return (ENXIO); - /* - * Allow access only in RAM. - */ - if ((prot & ia64_pa_access(atop((vm_offset_t)offset))) != prot) - return (-1); - *paddr = IA64_PHYS_TO_RR7(offset); + error = mem_phys2virt(offset, prot, &ptr, &limit); + if (error) + return (error); + + *paddr = offset; + *memattr = ((uintptr_t)ptr >= IA64_RR_BASE(7)) ? + VM_MEMATTR_WRITE_BACK : VM_MEMATTR_UNCACHEABLE; return (0); }