summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2018-10-31 08:50:26 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2018-10-31 08:50:26 +0000
commit11cd045a6b01fc57b8f558340ee12a6b0d9277a4 (patch)
treebeb321a7a892ba850aff8e24a218d810317ac868 /sys
parent54d5cb46157164d31a59414e58eab9a960756897 (diff)
Add support to uvm to establish write-combining mappings. Use this in the
inteldrm driver to add support for the I915_MMAP_WC flag. ok deraadt@, jsg@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/drm/drm_linux.h6
-rw-r--r--sys/dev/pci/drm/i915/i915_dma.c2
-rw-r--r--sys/dev/pci/drm/i915/i915_gem.c3
-rw-r--r--sys/uvm/uvm.h20
-rw-r--r--sys/uvm/uvm_extern.h3
-rw-r--r--sys/uvm/uvm_fault.c21
-rw-r--r--sys/uvm/uvm_map.c4
-rw-r--r--sys/uvm/uvm_pmap.h6
8 files changed, 37 insertions, 28 deletions
diff --git a/sys/dev/pci/drm/drm_linux.h b/sys/dev/pci/drm/drm_linux.h
index ba24e5faa83..a1a35d1f66a 100644
--- a/sys/dev/pci/drm/drm_linux.h
+++ b/sys/dev/pci/drm/drm_linux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.h,v 1.91 2018/08/20 19:33:31 kettenis Exp $ */
+/* $OpenBSD: drm_linux.h,v 1.92 2018/10/31 08:50:25 kettenis Exp $ */
/*
* Copyright (c) 2013, 2014, 2015 Mark Kettenis
* Copyright (c) 2017 Martin Pieuchot
@@ -2123,7 +2123,7 @@ typedef int pgprot_t;
static inline pgprot_t
pgprot_writecombine(pgprot_t prot)
{
-#ifdef PMAP_WC
+#if PMAP_WC != 0
return prot | PMAP_WC;
#else
return prot | PMAP_NOCACHE;
@@ -2133,7 +2133,7 @@ pgprot_writecombine(pgprot_t prot)
static inline pgprot_t
pgprot_noncached(pgprot_t prot)
{
-#ifdef PMAP_DEVICE
+#if PMAP_DEVICE != 0
return prot | PMAP_DEVICE;
#else
return prot | PMAP_NOCACHE;
diff --git a/sys/dev/pci/drm/i915/i915_dma.c b/sys/dev/pci/drm/i915/i915_dma.c
index 51e673480b8..54225532eea 100644
--- a/sys/dev/pci/drm/i915/i915_dma.c
+++ b/sys/dev/pci/drm/i915/i915_dma.c
@@ -156,11 +156,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_HAS_COHERENT_PHYS_GTT:
value = 1;
break;
-#ifdef notyet
case I915_PARAM_MMAP_VERSION:
value = 1;
break;
-#endif
case I915_PARAM_SUBSLICE_TOTAL:
value = INTEL_INFO(dev)->subslice_total;
if (!value)
diff --git a/sys/dev/pci/drm/i915/i915_gem.c b/sys/dev/pci/drm/i915/i915_gem.c
index 017d4ea943c..f018a6adadc 100644
--- a/sys/dev/pci/drm/i915/i915_gem.c
+++ b/sys/dev/pci/drm/i915/i915_gem.c
@@ -1987,7 +1987,8 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
addr = 0;
ret = -uvm_map(&curproc->p_vmspace->vm_map, &addr, size,
obj->uao, args->offset, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE,
- PROT_READ | PROT_WRITE, MAP_INHERIT_SHARE, MADV_RANDOM, 0));
+ PROT_READ | PROT_WRITE, MAP_INHERIT_SHARE, MADV_RANDOM,
+ (args->flags & I915_MMAP_WC) ? UVM_FLAG_WC : 0));
if (ret == 0)
uao_reference(obj->uao);
drm_gem_object_unreference_unlocked(obj);
diff --git a/sys/uvm/uvm.h b/sys/uvm/uvm.h
index 3e765a66226..7a93862dd97 100644
--- a/sys/uvm/uvm.h
+++ b/sys/uvm/uvm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm.h,v 1.62 2018/04/12 17:13:44 deraadt Exp $ */
+/* $OpenBSD: uvm.h,v 1.63 2018/10/31 08:50:25 kettenis Exp $ */
/* $NetBSD: uvm.h,v 1.24 2000/11/27 08:40:02 chs Exp $ */
/*
@@ -82,14 +82,15 @@ struct uvm {
* vm_map_entry etype bits:
*/
-#define UVM_ET_OBJ 0x01 /* it is a uvm_object */
-#define UVM_ET_SUBMAP 0x02 /* it is a vm_map submap */
-#define UVM_ET_COPYONWRITE 0x04 /* copy_on_write */
-#define UVM_ET_NEEDSCOPY 0x08 /* needs_copy */
-#define UVM_ET_HOLE 0x10 /* no backend */
-#define UVM_ET_NOFAULT 0x20 /* don't fault */
-#define UVM_ET_STACK 0x40 /* this is a stack */
-#define UVM_ET_FREEMAPPED 0x80 /* map entry is on free list (DEBUG) */
+#define UVM_ET_OBJ 0x0001 /* it is a uvm_object */
+#define UVM_ET_SUBMAP 0x0002 /* it is a vm_map submap */
+#define UVM_ET_COPYONWRITE 0x0004 /* copy_on_write */
+#define UVM_ET_NEEDSCOPY 0x0008 /* needs_copy */
+#define UVM_ET_HOLE 0x0010 /* no backend */
+#define UVM_ET_NOFAULT 0x0020 /* don't fault */
+#define UVM_ET_STACK 0x0040 /* this is a stack */
+#define UVM_ET_WC 0x0080 /* write combining */
+#define UVM_ET_FREEMAPPED 0x8000 /* map entry is on free list (DEBUG) */
#define UVM_ET_ISOBJ(E) (((E)->etype & UVM_ET_OBJ) != 0)
#define UVM_ET_ISSUBMAP(E) (((E)->etype & UVM_ET_SUBMAP) != 0)
@@ -98,6 +99,7 @@ struct uvm {
#define UVM_ET_ISHOLE(E) (((E)->etype & UVM_ET_HOLE) != 0)
#define UVM_ET_ISNOFAULT(E) (((E)->etype & UVM_ET_NOFAULT) != 0)
#define UVM_ET_ISSTACK(E) (((E)->etype & UVM_ET_STACK) != 0)
+#define UVM_ET_ISWC(E) (((E)->etype & UVM_ET_WC) != 0)
#ifdef _KERNEL
diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h
index 3005a61fcd0..a473f251229 100644
--- a/sys/uvm/uvm_extern.h
+++ b/sys/uvm/uvm_extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_extern.h,v 1.143 2018/04/12 17:13:44 deraadt Exp $ */
+/* $OpenBSD: uvm_extern.h,v 1.144 2018/10/31 08:50:25 kettenis Exp $ */
/* $NetBSD: uvm_extern.h,v 1.57 2001/03/09 01:02:12 chs Exp $ */
/*
@@ -112,6 +112,7 @@ typedef int vm_prot_t;
#define UVM_FLAG_NOFAULT 0x0800000 /* don't fault */
#define UVM_FLAG_UNMAP 0x1000000 /* unmap to make space */
#define UVM_FLAG_STACK 0x2000000 /* page may contain a stack */
+#define UVM_FLAG_WC 0x4000000 /* write combining */
/* macros to extract info */
#define UVM_PROTECTION(X) ((X) & PROT_MASK)
diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c
index 635283fac7b..e94e28c1987 100644
--- a/sys/uvm/uvm_fault.c
+++ b/sys/uvm/uvm_fault.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_fault.c,v 1.93 2018/04/12 17:13:44 deraadt Exp $ */
+/* $OpenBSD: uvm_fault.c,v 1.94 2018/10/31 08:50:25 kettenis Exp $ */
/* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */
/*
@@ -497,7 +497,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vaddr, vm_fault_t fault_type,
int npages, nback, nforw, centeridx, result, lcv, gotpages, ret;
vaddr_t startva, currva;
voff_t uoff;
- paddr_t pa;
+ paddr_t pa, pa_flags;
struct vm_amap *amap;
struct uvm_object *uobj;
struct vm_anon *anons_store[UVM_MAXRANGE], **anons, *anon, *oanon;
@@ -545,6 +545,7 @@ ReFault:
*/
enter_prot = ufi.entry->protection;
+ pa_flags = UVM_ET_ISWC(ufi.entry) ? PMAP_WC : 0;
wired = VM_MAPENT_ISWIRED(ufi.entry) || (fault_type == VM_FAULT_WIRE);
if (wired)
access_type = enter_prot; /* full access for wired */
@@ -688,7 +689,7 @@ ReFault:
* that we enter these right now.
*/
(void) pmap_enter(ufi.orig_map->pmap, currva,
- VM_PAGE_TO_PHYS(anon->an_page),
+ VM_PAGE_TO_PHYS(anon->an_page) | pa_flags,
(anon->an_ref > 1) ? (enter_prot & ~PROT_WRITE) :
enter_prot,
PMAP_CANFAIL |
@@ -789,7 +790,7 @@ ReFault:
* enter these right now.
*/
(void) pmap_enter(ufi.orig_map->pmap, currva,
- VM_PAGE_TO_PHYS(pages[lcv]),
+ VM_PAGE_TO_PHYS(pages[lcv]) | pa_flags,
enter_prot & MASK(ufi.entry),
PMAP_CANFAIL |
(wired ? PMAP_WIRED : 0));
@@ -935,9 +936,9 @@ ReFault:
* suspect since some other thread could blast the page out from
* under us between the unlock and the pmap_enter.
*/
- if (pmap_enter(ufi.orig_map->pmap, ufi.orig_rvaddr, VM_PAGE_TO_PHYS(pg),
- enter_prot, access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0))
- != 0) {
+ if (pmap_enter(ufi.orig_map->pmap, ufi.orig_rvaddr,
+ VM_PAGE_TO_PHYS(pg) | pa_flags, enter_prot,
+ access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0)) != 0) {
/*
* No need to undo what we did; we can simply think of
* this as the pmap throwing away the mapping information.
@@ -1211,9 +1212,9 @@ Case2:
* all resources are present. we can now map it in and free our
* resources.
*/
- if (pmap_enter(ufi.orig_map->pmap, ufi.orig_rvaddr, VM_PAGE_TO_PHYS(pg),
- enter_prot, access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0))
- != 0) {
+ if (pmap_enter(ufi.orig_map->pmap, ufi.orig_rvaddr,
+ VM_PAGE_TO_PHYS(pg) | pa_flags, enter_prot,
+ access_type | PMAP_CANFAIL | (wired ? PMAP_WIRED : 0)) != 0) {
/*
* No need to undo what we did; we can simply think of
* this as the pmap throwing away the mapping information.
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index c8a814d8e3c..d97f60fdf09 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.238 2018/07/22 14:33:44 kettenis Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.239 2018/10/31 08:50:25 kettenis Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1343,6 +1343,8 @@ uvm_map(struct vm_map *map, vaddr_t *addr, vsize_t sz,
entry->etype |= UVM_ET_HOLE;
if (flags & UVM_FLAG_NOFAULT)
entry->etype |= UVM_ET_NOFAULT;
+ if (flags & UVM_FLAG_WC)
+ entry->etype |= UVM_ET_WC;
if (flags & UVM_FLAG_COPYONW) {
entry->etype |= UVM_ET_COPYONWRITE;
if ((flags & UVM_FLAG_OVERLAY) == 0)
diff --git a/sys/uvm/uvm_pmap.h b/sys/uvm/uvm_pmap.h
index a8f5eafbc2b..dd071ddbfac 100644
--- a/sys/uvm/uvm_pmap.h
+++ b/sys/uvm/uvm_pmap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_pmap.h,v 1.27 2016/10/19 08:28:19 guenther Exp $ */
+/* $OpenBSD: uvm_pmap.h,v 1.28 2018/10/31 08:50:25 kettenis Exp $ */
/* $NetBSD: uvm_pmap.h,v 1.1 2000/06/27 09:00:14 mrg Exp $ */
/*
@@ -97,6 +97,10 @@ typedef struct pmap_statistics *pmap_statistics_t;
#define PMAP_MD2 0x00000100 /* Machine dependant */
#define PMAP_MD3 0x00000200 /* Machine dependant */
+#ifndef PMAP_WC
+#define PMAP_WC 0
+#endif
+
#ifndef PMAP_EXCLUDE_DECLS /* Used in Sparc port to virtualize pmap mod */
#ifdef _KERNEL
__BEGIN_DECLS