Diff below adds support to uvm to create wtite-combining mappings and
uses this to implement support for the I915_MMAP_WC flag in
inteldrm(4).  With this diff I can re-enable support for the
I915_PARAM_MMAP_VERSION.

Please test.


Index: dev/pci/drm/i915/i915_dma.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_dma.c,v
retrieving revision 1.27
diff -u -p -r1.27 i915_dma.c
--- dev/pci/drm/i915/i915_dma.c 25 Oct 2018 20:29:38 -0000      1.27
+++ dev/pci/drm/i915/i915_dma.c 26 Oct 2018 19:22:17 -0000
@@ -156,11 +156,9 @@ static int i915_getparam(struct drm_devi
        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)
Index: dev/pci/drm/i915/i915_gem.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_gem.c,v
retrieving revision 1.113
diff -u -p -r1.113 i915_gem.c
--- dev/pci/drm/i915/i915_gem.c 13 Sep 2018 03:38:15 -0000      1.113
+++ dev/pci/drm/i915/i915_gem.c 26 Oct 2018 19:22:17 -0000
@@ -1987,7 +1987,8 @@ i915_gem_mmap_ioctl(struct drm_device *d
        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);
Index: uvm/uvm.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvm.h,v
retrieving revision 1.62
diff -u -p -r1.62 uvm.h
--- uvm/uvm.h   12 Apr 2018 17:13:44 -0000      1.62
+++ uvm/uvm.h   26 Oct 2018 19:22:18 -0000
@@ -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
 
Index: uvm/uvm_extern.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_extern.h,v
retrieving revision 1.143
diff -u -p -r1.143 uvm_extern.h
--- uvm/uvm_extern.h    12 Apr 2018 17:13:44 -0000      1.143
+++ uvm/uvm_extern.h    26 Oct 2018 19:22:18 -0000
@@ -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)
Index: uvm/uvm_fault.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_fault.c,v
retrieving revision 1.93
diff -u -p -r1.93 uvm_fault.c
--- uvm/uvm_fault.c     12 Apr 2018 17:13:44 -0000      1.93
+++ uvm/uvm_fault.c     26 Oct 2018 19:22:18 -0000
@@ -497,7 +497,7 @@ uvm_fault(vm_map_t orig_map, vaddr_t vad
        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.
Index: uvm/uvm_map.c
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_map.c,v
retrieving revision 1.238
diff -u -p -r1.238 uvm_map.c
--- uvm/uvm_map.c       22 Jul 2018 14:33:44 -0000      1.238
+++ uvm/uvm_map.c       26 Oct 2018 19:22:18 -0000
@@ -1343,6 +1343,8 @@ uvm_map(struct vm_map *map, vaddr_t *add
                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)
Index: uvm/uvm_pmap.h
===================================================================
RCS file: /cvs/src/sys/uvm/uvm_pmap.h,v
retrieving revision 1.27
diff -u -p -r1.27 uvm_pmap.h
--- uvm/uvm_pmap.h      19 Oct 2016 08:28:19 -0000      1.27
+++ uvm/uvm_pmap.h      26 Oct 2018 19:22:18 -0000
@@ -97,6 +97,10 @@ typedef struct pmap_statistics       *pmap_sta
 #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

Reply via email to