Author: kib
Date: Mon Mar 26 16:31:12 2018
New Revision: 331557
URL: https://svnweb.freebsd.org/changeset/base/331557

Log:
  Allow to specify for vm_fault_quick_hold_pages() that nofault mode
  should be honored.
  
  We must not sleep or acquire any MI VM locks if TDP_NOFAULTING is
  specified.  On the other hand, there were some callers in the tree
  which set TDP_NOFAULTING for larger scope than needed, I fixed the
  code which I wrote, but I suspect that linuxkpi and out of tree drm
  drivers might abuse this still.
  
  So only enable the mode for vm_fault_quick_hold_pages() where
  vm_fault_hold() is not called when specifically asked by user.  I
  decided to use vm_prot_t flag to not change KPI.  Since number of
  flags in vm_prot_t is limited, I reused the same flag which was
  already consumed for vm_map_lookup().
  
  Reported and tested by:       pho (as part of the larger patch)
  Reviewed by:  markj
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week
  Differential revision:        https://reviews.freebsd.org/D14825

Modified:
  head/sys/vm/vm.h
  head/sys/vm/vm_fault.c

Modified: head/sys/vm/vm.h
==============================================================================
--- head/sys/vm/vm.h    Mon Mar 26 16:06:04 2018        (r331556)
+++ head/sys/vm/vm.h    Mon Mar 26 16:31:12 2018        (r331557)
@@ -80,7 +80,9 @@ typedef u_char vm_prot_t;     /* protection codes */
 #define        VM_PROT_WRITE           ((vm_prot_t) 0x02)
 #define        VM_PROT_EXECUTE         ((vm_prot_t) 0x04)
 #define        VM_PROT_COPY            ((vm_prot_t) 0x08)      /* copy-on-read 
*/
-#define        VM_PROT_FAULT_LOOKUP    ((vm_prot_t) 0x010)
+#define        VM_PROT_PRIV_FLAG       ((vm_prot_t) 0x10)
+#define        VM_PROT_FAULT_LOOKUP    VM_PROT_PRIV_FLAG
+#define        VM_PROT_QUICK_NOFAULT   VM_PROT_PRIV_FLAG       /* same to save 
bits */
 
 #define        VM_PROT_ALL             
(VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)
 #define VM_PROT_RW             (VM_PROT_READ|VM_PROT_WRITE)

Modified: head/sys/vm/vm_fault.c
==============================================================================
--- head/sys/vm/vm_fault.c      Mon Mar 26 16:06:04 2018        (r331556)
+++ head/sys/vm/vm_fault.c      Mon Mar 26 16:31:12 2018        (r331557)
@@ -1524,7 +1524,18 @@ vm_fault_quick_hold_pages(vm_map_t map, vm_offset_t ad
                 * page was mapped at the specified virtual address or that
                 * mapping had insufficient permissions.  Attempt to fault in
                 * and hold these pages.
+                *
+                * If vm_fault_disable_pagefaults() was called,
+                * i.e., TDP_NOFAULTING is set, we must not sleep nor
+                * acquire MD VM locks, which means we must not call
+                * vm_fault_hold().  Some (out of tree) callers mark
+                * too wide a code area with vm_fault_disable_pagefaults()
+                * already, use the VM_PROT_QUICK_NOFAULT flag to request
+                * the proper behaviour explicitly.
                 */
+               if ((prot & VM_PROT_QUICK_NOFAULT) != 0 &&
+                   (curthread->td_pflags & TDP_NOFAULTING) != 0)
+                       goto error;
                for (mp = ma, va = addr; va < end; mp++, va += PAGE_SIZE)
                        if (*mp == NULL && vm_fault_hold(map, va, prot,
                            VM_FAULT_NORMAL, mp) != KERN_SUCCESS)
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to