diff options
Diffstat (limited to 'meta-oe/recipes-support/vboxguestdrivers/vboxguestdrivers/0001-Runtime-memobj-r0drv-linux.c-Changes-to-support-the-.patch')
-rw-r--r-- | meta-oe/recipes-support/vboxguestdrivers/vboxguestdrivers/0001-Runtime-memobj-r0drv-linux.c-Changes-to-support-the-.patch | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/vboxguestdrivers/vboxguestdrivers/0001-Runtime-memobj-r0drv-linux.c-Changes-to-support-the-.patch b/meta-oe/recipes-support/vboxguestdrivers/vboxguestdrivers/0001-Runtime-memobj-r0drv-linux.c-Changes-to-support-the-.patch new file mode 100644 index 0000000000..db27cb883b --- /dev/null +++ b/meta-oe/recipes-support/vboxguestdrivers/vboxguestdrivers/0001-Runtime-memobj-r0drv-linux.c-Changes-to-support-the-.patch @@ -0,0 +1,119 @@ +From 2a6e3cf63f58e289802a11faad5fb495e2d04e97 Mon Sep 17 00:00:00 2001 +From: vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> +Date: Wed, 9 Dec 2020 18:59:04 +0000 +Subject: [PATCH] Runtime/memobj-r0drv-linux.c: Changes to support the upcoming + 5.10 kernel, bugref:9879 + +Upstream-Status: Backport + +git-svn-id: http://www.virtualbox.org/svn/vbox@87074 cfe28804-0f27-0410-a406-dd0f0b0b656f + +Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com> +--- + .../Runtime/r0drv/linux/memobj-r0drv-linux.c | 68 ++++++++++++++++++- + 1 file changed, 67 insertions(+), 1 deletion(-) + +--- a/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c ++++ b/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c +@@ -56,9 +56,19 @@ + * Whether we use alloc_vm_area (3.2+) for executable memory. + * This is a must for 5.8+, but we enable it all the way back to 3.2.x for + * better W^R compliance (fExecutable flag). */ +-#if RTLNX_VER_MIN(3,2,0) || defined(DOXYGEN_RUNNING) ++#if RTLNX_VER_RANGE(3,2,0, 5,10,0) || defined(DOXYGEN_RUNNING) + # define IPRT_USE_ALLOC_VM_AREA_FOR_EXEC + #endif ++/** @def IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC ++ * alloc_vm_area was removed with 5.10 so we have to resort to a different way ++ * to allocate executable memory. ++ * It would be possible to remove IPRT_USE_ALLOC_VM_AREA_FOR_EXEC and use ++ * this path execlusively for 3.2+ but no time to test it really works on every ++ * supported kernel, so better play safe for now. ++ */ ++#if RTLNX_VER_MIN(5,10,0) || defined(DOXYGEN_RUNNING) ++# define IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC ++#endif + + /* + * 2.6.29+ kernels don't work with remap_pfn_range() anymore because +@@ -502,6 +512,46 @@ static void rtR0MemObjLinuxFreePages(PRT + } + + ++#ifdef IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC ++/** ++ * User data passed to the apply_to_page_range() callback. ++ */ ++typedef struct LNXAPPLYPGRANGE ++{ ++ /** Pointer to the memory object. */ ++ PRTR0MEMOBJLNX pMemLnx; ++ /** The page protection flags to apply. */ ++ pgprot_t fPg; ++} LNXAPPLYPGRANGE; ++/** Pointer to the user data. */ ++typedef LNXAPPLYPGRANGE *PLNXAPPLYPGRANGE; ++/** Pointer to the const user data. */ ++typedef const LNXAPPLYPGRANGE *PCLNXAPPLYPGRANGE; ++ ++/** ++ * Callback called in apply_to_page_range(). ++ * ++ * @returns Linux status code. ++ * @param pPte Pointer to the page table entry for the given address. ++ * @param uAddr The address to apply the new protection to. ++ * @param pvUser The opaque user data. ++ */ ++#ifdef __i386__ ++static int rtR0MemObjLinuxApplyPageRange(pte_t *pPte, unsigned long uAddr, void *pvUser) ++#else ++static DECLCALLBACK(int) rtR0MemObjLinuxApplyPageRange(pte_t *pPte, unsigned long uAddr, void *pvUser) ++#endif ++{ ++ PCLNXAPPLYPGRANGE pArgs = (PCLNXAPPLYPGRANGE)pvUser; ++ PRTR0MEMOBJLNX pMemLnx = pArgs->pMemLnx; ++ size_t idxPg = (uAddr - (unsigned long)pMemLnx->Core.pv) >> PAGE_SHIFT; ++ ++ set_pte(pPte, mk_pte(pMemLnx->apPages[idxPg], pArgs->fPg)); ++ return 0; ++} ++#endif ++ ++ + /** + * Maps the allocation into ring-0. + * +@@ -584,6 +634,11 @@ static int rtR0MemObjLinuxVMap(PRTR0MEMO + else + # endif + { ++# if defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) ++ if (fExecutable) ++ pgprot_val(fPg) |= _PAGE_NX; /* Uses RTR0MemObjProtect to clear NX when memory ready, W^X fashion. */ ++# endif ++ + # ifdef VM_MAP + pMemLnx->Core.pv = vmap(&pMemLnx->apPages[0], pMemLnx->cPages, VM_MAP, fPg); + # else +@@ -1851,6 +1906,21 @@ DECLHIDDEN(int) rtR0MemObjNativeProtect( + preempt_enable(); + return VINF_SUCCESS; + } ++# elif defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) ++ PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem; ++ if ( pMemLnx->fExecutable ++ && pMemLnx->fMappedToRing0) ++ { ++ LNXAPPLYPGRANGE Args; ++ Args.pMemLnx = pMemLnx; ++ Args.fPg = rtR0MemObjLinuxConvertProt(fProt, true /*fKernel*/); ++ int rcLnx = apply_to_page_range(current->active_mm, (unsigned long)pMemLnx->Core.pv + offSub, cbSub, ++ rtR0MemObjLinuxApplyPageRange, (void *)&Args); ++ if (rcLnx) ++ return VERR_NOT_SUPPORTED; ++ ++ return VINF_SUCCESS; ++ } + # endif + + NOREF(pMem); |