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);
+}

Reply via email to