Index: VirtualBox-5.1.22/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
===================================================================
--- VirtualBox-5.1.22.orig/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
+++ VirtualBox-5.1.22/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
@@ -1397,7 +1397,7 @@ RTDECL(int) SUPR0Printf(const char *pszF
 SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void)
 {
     uint32_t fFlags = 0;
-#ifdef CONFIG_PAX_KERNEXEC
+#if defined(CONFIG_PAX_KERNEXEC) || LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
     fFlags |= SUPKERNELFEATURES_GDT_READ_ONLY;
 #endif
 #if defined(VBOX_STRICT) || defined(VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV)
Index: VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
===================================================================
--- VirtualBox-5.1.22.orig/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
+++ VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c
@@ -36,6 +36,9 @@
 #include <iprt/err.h>
 #include "r0drv/alloc-r0drv.h"
 #include <linux/kmemleak.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+#include <asm/set_memory.h>
+#endif
 
 #if (defined(RT_ARCH_AMD64) || defined(DOXYGEN_RUNNING)) && !defined(RTMEMALLOC_EXEC_HEAP)
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
Index: VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
===================================================================
--- VirtualBox-5.1.22.orig/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
+++ VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
@@ -899,6 +899,9 @@ static struct page *rtR0MemObjLinuxVirtT
     unsigned long   pfn;
     struct page    *pPage;
     pte_t          *pEntry;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+    p4d_t	    p4d;
+#endif
     union
     {
         pgd_t       Global;
@@ -917,9 +920,18 @@ static struct page *rtR0MemObjLinuxVirtT
     u.Global = *pgd_offset(current->active_mm, ulAddr);
     if (RT_UNLIKELY(pgd_none(u.Global)))
         return NULL;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+    p4d = *p4d_offset(&u.Global, ulAddr);
+    if (RT_UNLIKELY(p4d_none(p4d) || p4d_large(p4d) || !p4d_present(p4d)))
+        return NULL;
+#endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+    u.Upper = *pud_offset(&p4d, ulAddr);
+#else
     u.Upper = *pud_offset(&u.Global, ulAddr);
+#endif
     if (RT_UNLIKELY(pud_none(u.Upper)))
         return NULL;
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
@@ -1463,13 +1475,23 @@ static int rtR0MemObjLinuxFixPte(struct
 {
     int rc = -ENOMEM;
     pgd_t *pgd;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+    p4d_t *p4d;
+#endif
 
     spin_lock(&mm->page_table_lock);
 
     pgd = pgd_offset(mm, ulAddr);
     if (!pgd_none(*pgd) && !pgd_bad(*pgd))
     {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+	p4d = p4d_offset(*pgd, ulAddr);
+	if (p4d_none(*p4d))
+	    goto exit;
+	pmd_t *pmd = pmd_offset(p4d, ulAddr);
+#else
         pmd_t *pmd = pmd_offset(pgd, ulAddr);
+#endif
         if (!pmd_none(*pmd))
         {
             pte_t *ptep = pte_offset_map(pmd, ulAddr);
@@ -1487,6 +1509,9 @@ static int rtR0MemObjLinuxFixPte(struct
         }
     }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+exit:
+#endif
     spin_unlock(&mm->page_table_lock);
     return rc;
 }
Index: VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
===================================================================
--- VirtualBox-5.1.22.orig/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
+++ VirtualBox-5.1.22/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
@@ -320,6 +320,9 @@ DECLINLINE(unsigned long) msecs_to_jiffi
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
+#include <asm/cacheflush.h>
+#endif
 # define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
 # define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
 #else