Module Name: src Committed By: riastradh Date: Wed Jul 24 03:46:22 UTC 2013
Modified Files: src/sys/external/bsd/drm2/include/linux [riastradh-drm2]: highmem.h src/sys/external/bsd/drm2/linux [riastradh-drm2]: linux_kmap.c Log Message: Implement non-`atomic' kmap/kunmap in drm2 Linux shims. Uses uvm_km_alloc and pmap_kenter_pa. Does not use direct mappings on architectures that support this (e.g., amd64). To generate a diff of this commit: cvs rdiff -u -r1.1.2.2 -r1.1.2.3 \ src/sys/external/bsd/drm2/include/linux/highmem.h cvs rdiff -u -r1.1.2.1 -r1.1.2.2 src/sys/external/bsd/drm2/linux/linux_kmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/include/linux/highmem.h diff -u src/sys/external/bsd/drm2/include/linux/highmem.h:1.1.2.2 src/sys/external/bsd/drm2/include/linux/highmem.h:1.1.2.3 --- src/sys/external/bsd/drm2/include/linux/highmem.h:1.1.2.2 Wed Jul 24 03:31:12 2013 +++ src/sys/external/bsd/drm2/include/linux/highmem.h Wed Jul 24 03:46:22 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: highmem.h,v 1.1.2.2 2013/07/24 03:31:12 riastradh Exp $ */ +/* $NetBSD: highmem.h,v 1.1.2.3 2013/07/24 03:46:22 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -50,4 +50,7 @@ void linux_kmap_fini(void); void * kmap_atomic(struct page *); void kunmap_atomic(void *); +void * kmap(struct page *); +void kunmap(void *); + #endif /* _LINUX_HIGHMEM_H_ */ Index: src/sys/external/bsd/drm2/linux/linux_kmap.c diff -u src/sys/external/bsd/drm2/linux/linux_kmap.c:1.1.2.1 src/sys/external/bsd/drm2/linux/linux_kmap.c:1.1.2.2 --- src/sys/external/bsd/drm2/linux/linux_kmap.c:1.1.2.1 Wed Jul 24 03:31:12 2013 +++ src/sys/external/bsd/drm2/linux/linux_kmap.c Wed Jul 24 03:46:22 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: linux_kmap.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $ */ +/* $NetBSD: linux_kmap.c,v 1.1.2.2 2013/07/24 03:46:22 riastradh Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_kmap.c,v 1.1.2.1 2013/07/24 03:31:12 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_kmap.c,v 1.1.2.2 2013/07/24 03:46:22 riastradh Exp $"); #include <sys/types.h> #include <sys/mutex.h> @@ -46,6 +46,12 @@ __KERNEL_RCSID(0, "$NetBSD: linux_kmap.c * use at a time. */ +/* + * XXX Use direct-mapped physical pages where available, e.g. amd64. + * + * XXX ...or add an abstraction to uvm for this. (uvm_emap?) + */ + static kmutex_t linux_kmap_atomic_lock; static vaddr_t linux_kmap_atomic_vaddr; @@ -102,6 +108,7 @@ kunmap_atomic(void *addr) { const vaddr_t vaddr = (vaddr_t)addr; + KASSERT(mutex_owned(&linux_kmap_atomic_lock)); KASSERT(linux_kmap_atomic_vaddr == vaddr); KASSERT(pmap_extract(pmap_kernel(), vaddr, NULL)); @@ -110,3 +117,42 @@ kunmap_atomic(void *addr) mutex_spin_exit(&linux_kmap_atomic_lock); } + +void * +kmap(struct page *page) +{ + int s; + + const vaddr_t vaddr = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, + (UVM_KMF_VAONLY | UVM_KMF_WAITVA)); + KASSERT(vaddr != 0); + + s = splvm(); + + KASSERT(!pmap_extract(pmap_kernel(), vaddr, NULL)); + const paddr_t paddr = uvm_vm_page_to_phys(&page->p_vmp); + const int prot = (VM_PROT_READ | VM_PROT_WRITE); + const int flags = 0; + pmap_kenter_pa(vaddr, paddr, prot, flags); + pmap_update(pmap_kernel()); + + splx(s); + + return (void *)vaddr; +} + +void +kunmap(void *addr) +{ + const vaddr_t vaddr = (vaddr_t)addr; + int s; + + s = splvm(); + + KASSERT(pmap_extract(pmap_kernel(), vaddr, NULL)); + + pmap_kremove(vaddr, PAGE_SIZE); + pmap_update(pmap_kernel()); + + splx(s); +}