File vbox-upd08-no-vm_area.diff of Package virtualbox52

  This patch addresses the removal of *_vm_area() functions from newer linux 
  kernels. Essentially, to not depend on allocations within modules' address 
  space, vmm ring 0 modules can be compiled with 64-bit fixups instead of 
  32-bit fixups. This is what -mcmodel=large does. After that, any regular
  allocations will do, hence no need for *_vm_area().

  Cherry-picking with some adaptations from:
    https://www.virtualbox.org/changeset/85507/vbox/trunk

  Important note: this patch can not work with dtrace. Please disable dtrace.

--- a/Config.kmk	2023-03-11 19:54:55.000000000 +0300
+++ b/Config.kmk	2023-03-12 01:42:54.211867524 +0300
@@ -4361,8 +4361,8 @@
 TEMPLATE_VBoxR0_TOOL                = $(VBOX_GCC_TOOL)
 TEMPLATE_VBoxR0_CFLAGS              = -fno-pie -nostdinc -g $(VBOX_GCC_pipe) $(VBOX_GCC_WERR) $(VBOX_GCC_PEDANTIC_C)   $(VBOX_GCC_Wno-variadic-macros) $(VBOX_GCC_R0_OPT) $(VBOX_GCC_R0_FP) -fno-strict-aliasing -fno-exceptions $(VBOX_GCC_fno-stack-protector) -fno-common $(VBOX_GCC_fvisibility-hidden) -std=gnu99 $(VBOX_GCC_IPRT_FMT_CHECK)
 TEMPLATE_VBoxR0_CXXFLAGS            = -fno-pie -nostdinc -g $(VBOX_GCC_pipe) $(VBOX_GCC_WERR) $(VBOX_GCC_PEDANTIC_CXX) $(VBOX_GCC_Wno-variadic-macros) $(VBOX_GCC_R0_OPT) $(VBOX_GCC_R0_FP) -fno-strict-aliasing -fno-exceptions $(VBOX_GCC_fno-stack-protector) -fno-common $(VBOX_GCC_fvisibility-inlines-hidden) $(VBOX_GCC_fvisibility-hidden) -fno-rtti $(VBOX_GCC_IPRT_FMT_CHECK)
-TEMPLATE_VBoxR0_CFLAGS.amd64        = -m64 -mno-red-zone -mcmodel=kernel -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-asynchronous-unwind-tables -ffreestanding
-TEMPLATE_VBoxR0_CXXFLAGS.amd64      = -m64 -mno-red-zone -mcmodel=kernel -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-asynchronous-unwind-tables
+TEMPLATE_VBoxR0_CFLAGS.amd64        = -m64 -mno-red-zone -mcmodel=large -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-asynchronous-unwind-tables -ffreestanding
+TEMPLATE_VBoxR0_CXXFLAGS.amd64      = -m64 -mno-red-zone -mcmodel=large -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -fno-asynchronous-unwind-tables
 ifeq ($(KBUILD_TARGET),solaris)
  TEMPLATE_VBoxR0_LDFLAGS            = -r
  TEMPLATE_VBoxR0_LDFLAGS.solaris    = -u _init -u _info
--- a/src/VBox/HostDrivers/Support/SUPDrvInternal.h	2020-07-09 19:56:59.000000000 +0300
+++ b/src/VBox/HostDrivers/Support/SUPDrvInternal.h	2023-02-27 02:20:50.626384466 +0300
@@ -142,6 +142,14 @@
 # define SUPDRV_USE_MUTEX_FOR_GIP
 #endif
 
+#ifdef RT_OS_LINUX
+/** Use the RTR0MemObj API rather than the RTMemExecAlloc for the images.
+ * This is a good idea in general, but a necessity for @bugref{9801}. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+# define SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+#endif
+#endif
+
 
 /**
  * OS debug print macro.
@@ -323,10 +331,15 @@
     struct SUPDRVLDRIMAGE * volatile pNext;
     /** Pointer to the image. */
     void                           *pvImage;
+#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+    /** The memory object for the module allocation. */
+    RTR0MEMOBJ                      hMemObjImage;
+#else
     /** Pointer to the allocated image buffer.
      * pvImage is 32-byte aligned or it may governed by the native loader (this
      * member is NULL then). */
     void                           *pvImageAlloc;
+#endif
     /** Size of the image including the tables. This is mainly for verification
      * of the load request. */
     uint32_t                        cbImageWithTabs;
--- a/src/VBox/HostDrivers/Support/SUPDrv.cpp	2020-07-09 19:56:59.000000000 +0300
+++ b/src/VBox/HostDrivers/Support/SUPDrv.cpp	2023-03-03 19:58:43.513324588 +0300
@@ -3618,7 +3618,7 @@
      * Let IPRT do the work.
      */
     if (ppvR0)
-        rc = RTR0MemObjAllocPage(&Mem.MemObj, (size_t)cPages * PAGE_SIZE, true /* fExecutable */);
+        rc = RTR0MemObjAllocPage(&Mem.MemObj, (size_t)cPages * PAGE_SIZE, false /*fExecutable*/);
     else
         rc = RTR0MemObjAllocPhysNC(&Mem.MemObj, (size_t)cPages * PAGE_SIZE, NIL_RTHCPHYS);
     if (RT_SUCCESS(rc))
@@ -4927,7 +4927,11 @@
      */
     pImage = (PSUPDRVLDRIMAGE)pv;
     pImage->pvImage         = NULL;
+#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+    pImage->hMemObjImage    = NIL_RTR0MEMOBJ;
+#else
     pImage->pvImageAlloc    = NULL;
+#endif
     pImage->cbImageWithTabs = pReq->u.In.cbImageWithTabs;
     pImage->cbImageBits     = pReq->u.In.cbImageBits;
     pImage->cSymbols        = 0;
@@ -4950,10 +4954,19 @@
     rc = supdrvOSLdrOpen(pDevExt, pImage, pReq->u.In.szFilename);
     if (rc == VERR_NOT_SUPPORTED)
     {
+#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+        rc = RTR0MemObjAllocPage(&pImage->hMemObjImage, pImage->cbImageBits, true /*fExecutable*/);
+        if (RT_SUCCESS(rc))
+        {
+            pImage->pvImage = RTR0MemObjAddress(pImage->hMemObjImage);
+            pImage->fNative = false;
+        }
+#else
         pImage->pvImageAlloc = RTMemExecAlloc(pImage->cbImageBits + 31);
         pImage->pvImage     = RT_ALIGN_P(pImage->pvImageAlloc, 32);
         pImage->fNative     = false;
         rc = pImage->pvImageAlloc ? VINF_SUCCESS : VERR_NO_EXEC_MEMORY;
+#endif
         SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
     }
     if (RT_FAILURE(rc))
@@ -5200,7 +5213,20 @@
             rc = supdrvOSLdrLoad(pDevExt, pImage, pReq->u.In.abImage, pReq);
         else
         {
+#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+            uint32_t fProt_all = RTMEM_PROT_WRITE | RTMEM_PROT_EXEC | RTMEM_PROT_READ;
+            size_t aligned_cb = RT_ALIGN_32(pImage->cbImageBits, PAGE_SIZE); /* Align size to avoid upsetting RTR0MemObjProtect. */
+
             memcpy(pImage->pvImage, &pReq->u.In.abImage[0], pImage->cbImageBits);
+
+            rc = RTR0MemObjProtect(pImage->hMemObjImage, 0 /* offset */, aligned_cb /* length */, fProt_all);
+            if (RT_SUCCESS(rc))
+                /* Good! */ ;
+            else
+                rc = supdrvLdrLoadError(rc, pReq, "RTR0MemObjProtect failed fProt=%#x", fProt_all);
+#else
+            memcpy(pImage->pvImage, &pReq->u.In.abImage[0], pImage->cbImageBits);
+#endif
             Log(("vboxdrv: Loaded '%s' at %p\n", pImage->szName, pImage->pvImage));
         }
         SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
@@ -5784,8 +5810,14 @@
     pImage->pDevExt = NULL;
     pImage->pNext   = NULL;
     pImage->uState  = SUP_IOCTL_LDR_FREE;
+#ifdef SUPDRV_USE_MEMOBJ_FOR_LDR_IMAGE
+    RTR0MemObjFree(pImage->hMemObjImage, true /*fMappings*/);
+    pImage->hMemObjImage = NIL_RTR0MEMOBJ;
+#else
     RTMemExecFree(pImage->pvImageAlloc, pImage->cbImageBits + 31);
     pImage->pvImageAlloc = NULL;
+#endif
+    pImage->pvImage = NULL;
     RTMemFree(pImage->pachStrTab);
     pImage->pachStrTab = NULL;
     RTMemFree(pImage->paSymbols);
openSUSE Build Service is sponsored by