--- a/vboxdrv/r0drv/linux/memobj-r0drv-linux.c 2017-01-12 10:04:01.000000000 -0500 +++ b/vboxdrv/r0drv/linux/memobj-r0drv-linux.c 2017-05-28 18:04:25.607775983 -0400 @@ -902,6 +902,9 @@ union { pgd_t Global; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + p4d_t Four; +#endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) pud_t Upper; #endif @@ -917,9 +920,24 @@ u.Global = *pgd_offset(current->active_mm, ulAddr); if (RT_UNLIKELY(pgd_none(u.Global))) return NULL; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + u.Four = *p4d_offset(&u.Global, ulAddr); + if (RT_UNLIKELY(p4d_none(u.Four))) + return NULL; + if (p4d_large(u.Four)) + { + pPage = p4d_page(u.Four); + AssertReturn(pPage, NULL); + pfn = page_to_pfn(pPage); /* doing the safe way... */ + AssertCompile(P4D_SHIFT - PAGE_SHIFT < 31); + pfn += (ulAddr >> PAGE_SHIFT) & ((UINT32_C(1) << (P4D_SHIFT - PAGE_SHIFT)) - 1); + return pfn_to_page(pfn); + } + u.Upper = *pud_offset(&u.Four, ulAddr); +# else /* < 4.12 */ u.Upper = *pud_offset(&u.Global, ulAddr); +# endif /* < 4.12 */ if (RT_UNLIKELY(pud_none(u.Upper))) return NULL; # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) @@ -932,7 +950,6 @@ return pfn_to_page(pfn); } # endif - u.Middle = *pmd_offset(&u.Upper, ulAddr); #else /* < 2.6.11 */ u.Middle = *pmd_offset(&u.Global, ulAddr); --- work/vboxdrv/r0drv/linux/the-linux-kernel.h 2017-05-28 18:02:10.644768590 -0400 +++ work/vboxdrv/r0drv/linux/the-linux-kernel.h 2017-05-28 18:04:41.367776846 -0400 @@ -49,7 +49,7 @@ # include #else # ifndef AUTOCONF_INCLUDED -# include +# include # endif #endif @@ -159,6 +159,11 @@ # include #endif +/* for set_pages_x() */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +# include +#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) # include #else