VirtualBox

Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#18945 closed defect (fixed)

Linux 5.4: no more arbitrary executable pages and more changes

Reported by: Frank Batschulat (Oracle) Owned by: Frank Batschulat (Oracle)
Component: host support Version: VirtualBox 6.0.12
Keywords: linux54 exec page Cc:
Guest type: other Host type: Linux

Description

It was kindly pointed out that the Linux 5.4 kernel will no longer make interfaces available so that arbitrary kernel modules may modify page attributes to turn the executable bit on/off. Virtualbox currently is one of such kernel modules doing that.

From: "Larry Finger" <Larry.Finger@xxxxxxxx>
To: vbox-dev@virtualbox.org
Subject: [vbox-dev] Problem with kernel 5.4
Date: Wed, 18 Sep 2019 21:16:12 +0200

In kernel 5.4, the wrapper routines set_pages_x() and set_pages_nx() that enable/disable execution of memory are removed. The underlying routines set_memory_x() and set_memory_nx() are not, and will not be exported. See
[http://lkml.iu.edu/hypermail/linux/kernel/1909.2/02763.html]
for a   discussion of the issue.

I have currently disabled the only calls to these routines, which occur in alloc-r0drv-linux.c. My test VMs appear to work OK.

Is there some case where allocated pages really need to be executable? If  so, then the developers at Oracle will need to consult with Linus to develop a method that will be acceptable. In the meantime, I have developed a patch that allows a build with kernel 5.4 that eliminates the offending calls.

Larry

https://www.virtualbox.org/pipermail/vbox-dev/2019-September/015343.html
http://lkml.iu.edu/hypermail/linux/kernel/1909.2/02763.html
http://lkml.iu.edu/hypermail/linux/kernel/1909.2/02837.html

Lets see where and how we get that:

trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

339 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
340 # define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
341 # define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
342 #else
343 # define MY_SET_PAGES_EXEC(pPages, cPages) \
344     do { \
345         if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
346             MY_CHANGE_PAGE_ATTR(pPages, cPages, MY_PAGE_KERNEL_EXEC); \
347     } while (0)
348 # define MY_SET_PAGES_NOEXEC(pPages, cPages) \
349     do { \
350         if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
351             MY_CHANGE_PAGE_ATTR(pPages, cPages, PAGE_KERNEL); \
352     } while (0)
353 #endif

C symbol: MY_SET_PAGES_EXEC

  File                 Function                  Line
0 the-linux-kernel.h   <global>                  340 #define MY_SET_PAGES_EXEC(pPages, cPages) set_pages_x(pPages,
                                                     cPages)
1 the-linux-kernel.h   <global>                  343 #define MY_SET_PAGES_EXEC(pPages, cPages) \
2 alloc-r0drv-linux.c  RTMemContAlloc            447 MY_SET_PAGES_EXEC(&paPages[iPage], 1);
3 memobj-r0drv-linux.c rtR0MemObjLinuxAllocPages 374 MY_SET_PAGES_EXEC(pMemLnx->apPages[iPage], 1);

trunk/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c

385  * Allocates physical contiguous memory (below 4GB).
386  * The allocation is page aligned and the content is undefined.
387  *
388  * @returns Pointer to the memory block. This is page aligned.
389  * @param   pPhys   Where to store the physical address.
390  * @param   cb      The allocation size in bytes. This is always
391  *                  rounded up to PAGE_SIZE.
392  */
393 RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
[...]
428          * Reserve the pages and mark them executable.
429          */            
430         unsigned iPage;                         
431         for (iPage = 0; iPage < cPages; iPage++)
[...]
445             SetPageReserved(&paPages[iPage]);                                                                       446 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introdu    ced. */        
447             MY_SET_PAGES_EXEC(&paPages[iPage], 1);
448 #endif   
449         }  

trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c

 282  * Internal worker that allocates physical pages and creates the memory object for them.
 283  *
 284  * @returns IPRT status code.
 285  * @param   ppMemLnx    Where to store the memory object pointer.
 286  * @param   enmType     The object type.
 287  * @param   cb          The number of bytes to allocate.
 288  * @param   uAlignment  The alignment of the physical memory.
 289  *                      Only valid if fContiguous == true, ignored otherwise.
 290  * @param   fFlagsLnx   The page allocation flags (GPFs).
 291  * @param   fContiguous Whether the allocation must be contiguous.
 292  * @param   rcNoMem     What to return when we're out of pages.
 293  */
 294 static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb,
 295                                      size_t uAlignment, gfp_t fFlagsLnx, bool fContiguous, int rcNoMem)
 296 {
[...]
 323      * Allocate the pages.
 324      * For small allocations we'll try contiguous first and then fall back on page by page.
 325      */
 326 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 22)
 327     if (    fContiguous
 328         ||  cb <= PAGE_SIZE * 2)
 329     {  
[...]
 363 #else /* < 2.4.22 */
 364     /** @todo figure out why we didn't allocate page-by-page on 2.4.21 and older... */
 365     paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages));
 366     if (!paPages)
 367     {
 368         rtR0MemObjDelete(&pMemLnx->Core);
 369         return rcNoMem;
 370     }
 371     for (iPage = 0; iPage < cPages; iPage++)
 372     {
 373         pMemLnx->apPages[iPage] = &paPages[iPage];
 374         MY_SET_PAGES_EXEC(pMemLnx->apPages[iPage], 1);
 375         if (PageHighMem(pMemLnx->apPages[iPage]))
 376             BUG();
 377     }
 378 
 379     fContiguous = true;
 380 #endif /* < 2.4.22 */

I'll investigate why we'd possibly think we need this anyways and seek to remove that code.

Attachments (1)

54-guest-opensuse.txt (5.2 KB ) - added by Frank Batschulat (Oracle) 5 years ago.
inital unit testing log

Download all attachments as: .zip

Change History (21)

comment:1 by Frank Batschulat (Oracle), 5 years ago

Keywords: linux54 exec page added
Owner: set to Frank Batschulat (Oracle)
Status: newaccepted

comment:2 by Frank Batschulat (Oracle), 5 years ago

The compile errors against the 5.4rc1 kernel in detail:

/home/ws/lin54/trunk

$ kmk KERN_VER=linux-5.4-rc1 KERN_DIR=/home/ws/linux-5.4-rc1

In file included from /home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:28:0:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/alloc-r0drv-linux.c: In function ‘VBoxGuest_RTMemContAlloc’:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/the-linux-kernel.h:340:47: error: implicit declaration of function ‘set_pages_x’; did you mean ‘set_pages_rw’? [-Werror=implicit-function-declaration]
 # define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
                                               ^
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/alloc-r0drv-linux.c:447:13: note: in expansion of macro ‘MY_SET_PAGES_EXEC’
             MY_SET_PAGES_EXEC(&paPages[iPage], 1);
             ^~~~~~~~~~~~~~~~~
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/alloc-r0drv-linux.c: In function ‘VBoxGuest_RTMemContFree’:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/the-linux-kernel.h:341:47: error: implicit declaration of function ‘set_pages_nx’; did you mean ‘set_pages_rw’? [-Werror=implicit-function-declaration]
 # define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
                                               ^
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/alloc-r0drv-linux.c:495:13: note: in expansion of macro ‘MY_SET_PAGES_NOEXEC’
             MY_SET_PAGES_NOEXEC(&paPages[iPage], 1);
             ^~~~~~~~~~~~~~~~~~~
kBuild: Generating DTrace Provider for the VBox API (from XIDL)
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/VBoxAPIWrap/VBoxAPI.d.ts -> /home/ws/lin54/trunk/out/linux.amd64/debug/obj/VBoxAPIWrap/VBoxAPI.d
In file included from /home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:44:0:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c: In function ‘rtThreadNativeSetPriority’:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:12: error: variable ‘Param’ has initializer but incomplete type
     struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
            ^~~~~~~~~~~
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:42: error: ‘struct sched_param’ has no member named ‘sched_priority’
     struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
                                          ^~~~~~~~~~~~~~
In file included from ./include/linux/sched.h:27:0,
                 from ./include/linux/ioprio.h:5,
                 from ./include/linux/fs.h:39,
                 from /home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/the-linux-kernel.h:97,
                 from /home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:28:
./include/linux/sched/prio.h:25:19: error: excess elements in struct initializer [-Werror]
 #define MAX_PRIO  (MAX_RT_PRIO + NICE_WIDTH)
                   ^
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:59: note: in expansion of macro ‘MAX_PRIO’
     struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
                                                           ^~~~~~~~
./include/linux/sched/prio.h:25:19: note: (near initialization for ‘Param’)
 #define MAX_PRIO  (MAX_RT_PRIO + NICE_WIDTH)
                   ^
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:59: note: in expansion of macro ‘MAX_PRIO’
     struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
                                                           ^~~~~~~~
In file included from /home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:44:0:
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:25: error: storage size of ‘Param’ isn’t known
     struct sched_param  Param       = { .sched_priority = MAX_PRIO - 1 };
                         ^~~~~
/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/thread2-r0drv-linux.c:58:25: error: unused variable ‘Param’ [-Werror=unused-variable]
cc1: all warnings being treated as errors
make[2]: *** [/home/ws/lin54/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.o] Error 1

1.) struct sched_param VBox/Trunk fbatschu@lserver linux-5.4-rc1 $ grep sched_param ./include/uapi/linux/sched/types.h

struct sched_param {
 * This is needed because the original struct sched_param can not be

VBox/Trunk fbatschu@lserver linux-5.4-rc1 $ head ./include/uapi/linux/sched/types.h

/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI_LINUX_SCHED_TYPES_H
#define _UAPI_LINUX_SCHED_TYPES_H

#include <linux/types.h>

struct sched_param {
	int sched_priority;
};

vrs: /usr$ grep sched_param ./src/linux-headers-4.15.0-20/include/uapi/linux/sched/types.h

struct sched_param {
 * This is needed because the original struct sched_param can not be

/usr$ head ./src/linux-headers-4.15.0-20/include/uapi/linux/sched/types.h

/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _UAPI_LINUX_SCHED_TYPES_H
#define _UAPI_LINUX_SCHED_TYPES_H

#include <linux/types.h>

struct sched_param {
	int sched_priority;
};

=> we should check how far back this really goes, we might not need an #ifdef here at all

This first appears with the release kernel 4.11:

https://elixir.bootlin.com/linux/v4.11/source/include/uapi/linux/sched/types.h

and with the development release canidiate kernel 4.11-rc1:

https://elixir.bootlin.com/linux/v4.11-rc1/source/include/uapi/linux/sched/types.h

=> so here we can actually go way more back to include that header file then the suggested kernel version 5.4.0, let's make this instead:

+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+#include <uapi/linux/sched/types.h>
+#endif

2.) set_pages_x()/ set_pages_nx()

Linux change details already discussed in the inital bug description. Should probably be removed entirely from the code unless we can dig out some information as to why that was needed in:

#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introduced. */

There is no comment left in the code as to why that had been introduced. Maybe we should just disable it for the 5.4.0 kernel only though initially. However looking around in the code, there's is more code involved around the executable pages. In Trunk we find:

trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

339 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
340 # define MY_SET_PAGES_EXEC(pPages, cPages)    set_pages_x(pPages, cPages)
341 # define MY_SET_PAGES_NOEXEC(pPages, cPages)  set_pages_nx(pPages, cPages)
342 #else
343 # define MY_SET_PAGES_EXEC(pPages, cPages) \
344     do { \
345         if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
346             MY_CHANGE_PAGE_ATTR(pPages, cPages, MY_PAGE_KERNEL_EXEC); \
347     } while (0)
348 # define MY_SET_PAGES_NOEXEC(pPages, cPages) \
349     do { \
350         if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
351             MY_CHANGE_PAGE_ATTR(pPages, cPages, PAGE_KERNEL); \
352     } while (0)
353 #endif

C symbol: MY_SET_PAGES_EXEC

  File                 Function                  Line
0 the-linux-kernel.h   <global>                  340 #define MY_SET_PAGES_EXEC(pPages, cPages) set_pages_x(pPages,
                                                     cPages)
1 the-linux-kernel.h   <global>                  343 #define MY_SET_PAGES_EXEC(pPages, cPages) \
2 alloc-r0drv-linux.c  RTMemContAlloc            447 MY_SET_PAGES_EXEC(&paPages[iPage], 1);
3 memobj-r0drv-linux.c rtR0MemObjLinuxAllocPages 374 MY_SET_PAGES_EXEC(pMemLnx->apPages[iPage], 1);

trunk/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c

385  * Allocates physical contiguous memory (below 4GB).
386  * The allocation is page aligned and the content is undefined.
387  *
388  * @returns Pointer to the memory block. This is page aligned.
389  * @param   pPhys   Where to store the physical address.
390  * @param   cb      The allocation size in bytes. This is always
391  *                  rounded up to PAGE_SIZE.
392  */
393 RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
[....]
425     if (paPages)
426     {
427         /*
428          * Reserve the pages and mark them executable.
429          */
430         unsigned iPage;
431         for (iPage = 0; iPage < cPages; iPage++)
[...]
445             SetPageReserved(&paPages[iPage]);
446 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) /** @todo find the exact kernel where change_page_attr was introdu    ced. */        
447             MY_SET_PAGES_EXEC(&paPages[iPage], 1);
448 #endif

trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c

 282  * Internal worker that allocates physical pages and creates the memory object for them.
 283  *
 284  * @returns IPRT status code.
 285  * @param   ppMemLnx    Where to store the memory object pointer.
 286  * @param   enmType     The object type.
 287  * @param   cb          The number of bytes to allocate.
 288  * @param   uAlignment  The alignment of the physical memory.
 289  *                      Only valid if fContiguous == true, ignored otherwise.
 290  * @param   fFlagsLnx   The page allocation flags (GPFs).
 291  * @param   fContiguous Whether the allocation must be contiguous.
 292  * @param   rcNoMem     What to return when we're out of pages.
 293  */
 294 static int rtR0MemObjLinuxAllocPages(PRTR0MEMOBJLNX *ppMemLnx, RTR0MEMOBJTYPE enmType, size_t cb,
 295                                      size_t uAlignment, gfp_t fFlagsLnx, bool fContiguous, int rcNoMem)
[...]
 363 #else /* < 2.4.22 */                              
 364     /** @todo figure out why we didn't allocate page-by-page on 2.4.21 and older... */
 365     paPages = alloc_pages(fFlagsLnx, rtR0MemObjLinuxOrder(cPages));
 366     if (!paPages)
 367     {                       
 368         rtR0MemObjDelete(&pMemLnx->Core);                                                          
 369         return rcNoMem;
 370     }                                                                                 
 371     for (iPage = 0; iPage < cPages; iPage++)
 372     {               
 373         pMemLnx->apPages[iPage] = &paPages[iPage];
 374         MY_SET_PAGES_EXEC(pMemLnx->apPages[iPage], 1);
 375         if (PageHighMem(pMemLnx->apPages[iPage]))   
 376             BUG();                                        
 377     }    
 378                              
 379     fContiguous = true;
 380 #endif /* < 2.4.22 */  

C symbol: MY_SET_PAGES_NOEXEC

  File                 Function                 Line
0 the-linux-kernel.h   <global>                 341 #define MY_SET_PAGES_NOEXEC(pPages, cPages) set_pages_nx(pPages,
                                                    cPages)
1 the-linux-kernel.h   <global>                 348 #define MY_SET_PAGES_NOEXEC(pPages, cPages) \
2 alloc-r0drv-linux.c  RTMemContFree            495 MY_SET_PAGES_NOEXEC(&paPages[iPage], 1);
3 memobj-r0drv-linux.c rtR0MemObjLinuxFreePages 448 MY_SET_PAGES_NOEXEC(pMemLnx->apPages[iPage], 1);

trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

278 #if   LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(RT_ARCH_AMD64)
279 # define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL_EXEC
280 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8) && defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)
281 # ifdef __PAGE_KERNEL_EXEC
282    /* >= 2.6.27 */
283 #  define MY_PAGE_KERNEL_EXEC   __pgprot(boot_cpu_has(X86_FEATURE_PGE) ? __PAGE_KERNEL_EXEC | _PAGE_GLOBAL : __PAGE_    KERNEL_EXEC)   
284 # else
285 #  define MY_PAGE_KERNEL_EXEC   __pgprot(boot_cpu_has(X86_FEATURE_PGE) ? _PAGE_KERNEL_EXEC | _PAGE_GLOBAL : _PAGE_KE    RNEL_EXEC)     
286 # endif
287 #else
288 # define MY_PAGE_KERNEL_EXEC    PAGE_KERNEL
289 #endif

C symbol: MY_PAGE_KERNEL_EXEC

  File                 Function                   Line
0 the-linux-kernel.h   <global>                   279 #define MY_PAGE_KERNEL_EXEC PAGE_KERNEL_EXEC
1 the-linux-kernel.h   <global>                   283 #define MY_PAGE_KERNEL_EXEC __pgprot(boot_cpu_has(X86_FEATURE_PGE)
                                                      ? __PAGE_KERNEL_EXEC | _PAGE_GLOBAL : __PAGE_KERNEL_EXEC)
2 the-linux-kernel.h   <global>                   285 #define MY_PAGE_KERNEL_EXEC __pgprot(boot_cpu_has(X86_FEATURE_PGE)
                                                      ? _PAGE_KERNEL_EXEC | _PAGE_GLOBAL : _PAGE_KERNEL_EXEC)
3 the-linux-kernel.h   <global>                   288 #define MY_PAGE_KERNEL_EXEC PAGE_KERNEL
4 alloc-r0drv-linux.c  rtR0MemAllocEx             268 pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL |
                                                      __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC);
5 alloc-r0drv-linux.c  rtR0MemAllocEx             272 pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL |
                                                      __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC);
6 memobj-r0drv-linux.c rtR0MemObjLinuxConvertProt 163 pgprot_t fPg = MY_PAGE_KERNEL_EXEC;
7 memobj-r0drv-linux.c rtR0MemObjLinuxConvertProt 169 return fKernel ? MY_PAGE_KERNEL_EXEC : PAGE_READONLY_EXEC;
8 memobj-r0drv-linux.c rtR0MemObjLinuxConvertProt 174 return fKernel ? MY_PAGE_KERNEL_EXEC : PAGE_SHARED_EXEC;
9 the-linux-kernel.h   MY_SET_PAGES_EXEC          345 if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \
a the-linux-kernel.h   MY_SET_PAGES_EXEC          346 MY_CHANGE_PAGE_ATTR(pPages, cPages, MY_PAGE_KERNEL_EXEC); \
b the-linux-kernel.h   MY_SET_PAGES_NOEXEC        350 if (pgprot_val(MY_PAGE_KERNEL_EXEC) != pgprot_val(PAGE_KERNEL)) \

trunk/src/VBox/Runtime/r0drv/linux/alloc-r0drv-linux.c

235  * OS specific allocation function.
236  */
237 DECLHIDDEN(int) rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
[...]
243      * Allocate.
244      */
245     if (fFlags & RTMEMHDR_FLAG_EXEC)
246     {
247         if (fFlags & RTMEMHDR_FLAG_ANY_CTX)
248             return VERR_NOT_SUPPORTED;
249 
250 #if defined(RT_ARCH_AMD64)
251 # ifdef RTMEMALLOC_EXEC_HEAP
252         if (g_HeapExec != NIL_RTHEAPSIMPLE)
253         {
254             RTSpinlockAcquire(g_HeapExecSpinlock);
255             pHdr = (PRTMEMHDR)RTHeapSimpleAlloc(g_HeapExec, cb + sizeof(*pHdr), 0);
256             RTSpinlockRelease(g_HeapExecSpinlock);
257             fFlags |= RTMEMHDR_FLAG_EXEC_HEAP;
258         }
259         else
260             pHdr = NULL;
261 
262 # elif defined(RTMEMALLOC_EXEC_VM_AREA)
263         pHdr = rtR0MemAllocExecVmArea(cb);
264         fFlags |= RTMEMHDR_FLAG_EXEC_VM_AREA;
265 
266 # else  /* !RTMEMALLOC_EXEC_HEAP */
267 # error "you don not want to go here..."
268         pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC)    ;           
269 # endif /* !RTMEMALLOC_EXEC_HEAP */
270 
271 #elif defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)
272         pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC)    ;           
273 #else
274         pHdr = (PRTMEMHDR)vmalloc(cb + sizeof(*pHdr));
275 #endif
276     }

Summary:

1) Only on Linux we apparently have this request for executable kernel pages?

2) r0drv RTMemContAlloc() sets pages executable only for:

LINUX_VERSION_CODE > KERNEL_VERSION(2, 4, 20) 

using: MY_SET_PAGES_EXEC()

3) r0drv rtR0MemObjLinuxAllocPages() sets pages executable only for:

LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22)

using: MY_SET_PAGES_EXEC()

This is not very consistent in its usage. One time, we do it for kernels above KERNEL_VERSION(2, 4, 20) and the other time we do it only for kernels lower then KERNEL_VERSION(2, 4, 22). Ie. the first form does include kernel versions 2.4.21/22 and will exclude kernel versions 2.4.20 and below while the second form does include kernel versions 2.4.21/20 and will exclude kernel versions 2.4.22 and above.

4) r0drv rtR0MemAllocEx) also allocates executable kernel memory for:

if (fFlags & RTMEMHDR_FLAG_EXEC)
#if defined(RT_ARCH_AMD64)
    #elif defined(PAGE_KERNEL_EXEC) && defined(CONFIG_X86_PAE)

using: vmalloc(MY_PAGE_KERNEL_EXEC)

pHdr = (PRTMEMHDR)__vmalloc(cb + sizeof(*pHdr), GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, MY_PAGE_KERNEL_EXEC)    ;           

trunk/src/VBox/Runtime/r0drv/alloc-r0drv.h

 60 /** Executable flag. */
 61 #define RTMEMHDR_FLAG_EXEC          RT_BIT(1)
[...]
 71 /** Linux: Allocated using vm_area hacks. */
 72 # define RTMEMHDR_FLAG_EXEC_VM_AREA RT_BIT(29)
 73 /** Linux: Allocated from the special heap for executable memory. */
 74 # define RTMEMHDR_FLAG_EXEC_HEAP    RT_BIT(30)

RTMEMHDR_FLAG_EXEC is only set in 1 place:

trunk/src/VBox/Runtime/r0drv/alloc-r0drv.cpp

338 RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW    _DEF        
[...]
362     if (fFlags & RTMEMALLOCEX_FLAGS_EXEC)
363         fHdrFlags |= RTMEMHDR_FLAG_EXEC;

trunk/include/iprt/mem.h

 306 /** @name RTR0MemAllocEx and RTR0MemAllocExTag flags.
[...]
 310 /** It must be load code into the returned memory block and execute it. */
 311 #define RTMEMALLOCEX_FLAGS_EXEC             RT_BIT(1)

which finally brings us to one place where we load code and execute it:

trunk/src/VBox/Devices/testcase/tstDevice.cpp

  3  * tstDevice - Test framework for PDM devices/drivers
[...]
647 static int tstDevPdmLoadR0RcMod(PTSTDEVPDMMOD pMod)
[...]
656          * R0 modules need special treatment as these are relocatable images
657          * which are supposed to run in ring 0.
658          */
659         rc = RTLdrOpen(pMod->pszFilename, 0, RTLDRARCH_HOST, &pMod->hLdrMod);
660         if (RT_SUCCESS(rc))
661         {
662             size_t cb = RTLdrSize(pMod->hLdrMod) + 1024 * sizeof(TSTDEVPDMMODTRAMPOLINE);
663 
664             /* Allocate bits. */
665             uint32_t fFlags = RTMEMALLOCEX_FLAGS_EXEC;
666 #ifdef RT_OS_LINUX
667             /*
668              * amd64 ELF binaries support only a 2GB code segment everything must be in
669              * (X86_64_PC32 relocation) so we have to use a trampoline to the final destination
670              * which is kept close to the imported module.
671              */
672             fFlags |= RTMEMALLOCEX_FLAGS_32BIT_REACH;
673 #endif
674             rc = RTMemAllocEx(cb, 0, fFlags, (void **)&pMod->R0Rc.pbTrampoline);

Also callers of RTMemExecAllocTag() will request executable memory:

trunk/src/VBox/Runtime/r0drv/alloc-r0drv.cpp

282 RTDECL(void *)    RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_DEF
[...]
293     pHdr = rtR0MemAlloc(cb + RTR0MEM_FENCE_EXTRA, RTMEMHDR_FLAG_EXEC);

which brings us back to the before mentioned r0drv: rtR0MemAllocEx()

Functions calling this function: RTMemExecAllocTag

  File  Function       Line
0 mem.h RTMemExecAlloc 388 #define RTMemExecAlloc(cb) RTMemExecAllocTag((cb), RTMEM_TAG)

trunk/include/iprt/mem.h

 382  * Allocates memory which may contain code (default tag).
 383  *
 384  * @returns Pointer to the allocated memory.
 385  * @returns NULL on failure.
 386  * @param   cb      Size in bytes of the memory block to allocate.
 387  */
 388 #define RTMemExecAlloc(cb)              RTMemExecAllocTag((cb), RTMEM_TAG)
 389 
 390 /**
 391  * Allocates memory which may contain code (custom tag).
 392  *
 393  * @returns Pointer to the allocated memory.
 394  * @returns NULL on failure.
 395  * @param   cb      Size in bytes of the memory block to allocate.
 396  * @param   pszTag  Allocation tag used for statistics and such.
 397  */
 398 RTDECL(void *)  RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW_PROTO;

Functions calling this function: RTMemExecAlloc

  File               Function            Line
0 SUPDrv.cpp         supdrvIOCtl_LdrOpen 5116 pImage->pvImageAlloc = RTMemExecAlloc(pImage->cbImageBits + 31);
1 log.cpp            RTDECL               866 pu8Code = (uint8_t *)RTMemExecAlloc(64);
2 log.cpp            RTLogCreateExV       866 pu8Code = (uint8_t *)RTMemExecAlloc(64);
3 allocex.cpp        RTDECL                84 pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
4 allocex.cpp        RTMemAllocExTag       84 pv = RTMemExecAlloc(cbAligned + sizeof(RTMEMHDRR3));
5 tstLdr-4.cpp       testLdrOne           175 aLoads[i].pvBits = RTMemExecAlloc(cb);
6 tstX86-1.cpp       main                 198 g_pbEfExecPage = (uint8_t *)RTMemExecAlloc(PAGE_SIZE*2);
7 VBoxREMWrapper.cpp DECLASM             1449 pCur = (PREMEXECMEM)RTMemExecAlloc(_64K);
8 VBoxREMWrapper.cpp remAllocGlue        1449 pCur = (PREMEXECMEM)RTMemExecAlloc(_64K);
9 VBoxREMWrapper.cpp remLoadLinuxObj     2029 g_pvREM2 = RTMemExecAlloc(g_cbREM2);
a VBoxRecompiler.c   REMR3DECL            323 code_gen_prologue = RTMemExecAlloc(_1K);
b VBoxRecompiler.c   REMR3Init            323 code_gen_prologue = RTMemExecAlloc(_1K);
c VBoxRecompiler.c   REMR3DECL            346 pVM->rem.s.Env.pvCodeBuffer = RTMemExecAlloc(pVM->rem.s.Env.cbCodeBuffer);
d VBoxRecompiler.c   REMR3Init            346 pVM->rem.s.Env.pvCodeBuffer = RTMemExecAlloc(pVM->rem.s.Env.cbCodeBuffer);
e exec.c             code_gen_alloc       560 code_gen_buffer = RTMemExecAlloc(code_gen_buffer_size);

A lot of this is obviously related to the recompiler but also to the runtime itself.

Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:3 by Frank Batschulat (Oracle), 5 years ago

3) DRIVER_PRIME

/home/ws/vb54/trunk/out/linux.amd64/debug/obj/tstvboxvideo-src_mod/vbox_drv.c:308:6: error: ‘DRIVER_PRIME’ undeclared here (not in a function); did you mean ‘DRIVER_NAME’?
  308 |      DRIVER_PRIME,
      |      ^~~~~~~~~~~~
      |      DRIVER_NAME

Format of Module.symvers has changed adding extra tab and namespace the symbol is in if any. [1] Per file build flags now must include the path to the file instead of just the filename. [2] DRIVER_PRIME flag is dropped as redundant. [3]

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cb9b55d21fe06ca5e4ba244bb5aac0afeb745c8e
[2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=54b8ae66ae1a3454a7645d159a482c31cd89ab33
[3] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ee8375d5dc5bbb50b03bedfb0020d3e1c27ceacb

Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:4 by Frank Batschulat (Oracle), 5 years ago

4) struct ttm_buffer_object, member vma_node moved:

[PATCH 5/6] drm/ttm: use gem vma_node https://lists.gt.net/linux/kernel/3353093

/home/ws/vb54/trunk/out/linux.amd64/debug/obj/tstvboxvideo-src_mod/vbox_main.c: In function ‘vbox_bo_mmap_offset’:
/home/ws/vb54/trunk/out/linux.amd64/debug/obj/tstvboxvideo-src_mod/vbox_main.c:622:41: error: ‘struct ttm_buffer_object’ has no member named ‘vma_node’
  622 |  return drm_vma_node_offset_addr(&bo->bo.vma_node);
      |                                         ^
/home/ws/vb54/trunk/out/linux.amd64/debug/obj/tstvboxvideo-src_mod/vbox_main.c:624:1: error: control reaches end of non-void function [-Werror=return-type]
  624 | }
      | ^

In kernel 5.4.rc1 the structure member vma_node formerly in truct ttm_buffer_object:

https://elixir.bootlin.com/linux/v5.3.5/source/include/drm/ttm/ttm_bo_api.h

moved to a new structure:

https://elixir.bootlin.com/linux/v5.4-rc1/source/include/drm/ttm/ttm_bo_api.h

struct ttm_buffer_object {
	struct drm_gem_object base;

in:

https://elixir.bootlin.com/linux/v5.4-rc1/source/include/drm/drm_gem.h#L171

struct drm_gem_object {
[...]
	struct drm_vma_offset_node vma_node;

so we need to change the line to be instead:

trunk/src/VBox/Additions/linux/drm/vbox_main.c

--- return drm_vma_node_offset_addr(&bo->bo.vma_node);
+++ return drm_vma_node_offset_addr(&bo->bo.base.vma_node);

comment:5 by Frank Batschulat (Oracle), 5 years ago

These are the current changes I have UNIT tested right now against: https://git.kernel.org/torvalds/t/linux-5.4-rc2.tar.gz

VBox/Trunk fbatschu@lserver trunk $ svn status
M       src/VBox/Additions/linux/drm/vbox_drv.c
M       src/VBox/Additions/linux/drm/vbox_main.c
M       src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
M       src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
M       src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
VBox/Trunk fbatschu@lserver trunk $ svn diff
Index: src/VBox/Additions/linux/drm/vbox_drv.c
===================================================================
--- src/VBox/Additions/linux/drm/vbox_drv.c	(revision 133811)
+++ src/VBox/Additions/linux/drm/vbox_drv.c	(working copy)
@@ -305,12 +305,16 @@
 }
 
 static struct drm_driver driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)    
 	.driver_features =
 	    DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) && !defined(RHEL_81)
+# if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) && !defined(RHEL_81)
 	    DRIVER_IRQ_SHARED |
-#endif
+# endif
 	    DRIVER_PRIME,
+#else /* >= KERNEL_VERSION(5, 4, 0) */    
+        .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ,    
+#endif /* < KERNEL_VERSION(5, 4, 0) */    
 	.dev_priv_size = 0,
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
Index: src/VBox/Additions/linux/drm/vbox_main.c
===================================================================
--- src/VBox/Additions/linux/drm/vbox_main.c	(revision 133811)
+++ src/VBox/Additions/linux/drm/vbox_main.c	(working copy)
@@ -621,7 +621,9 @@
 
 static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) && !defined(RHEL_70)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+	return drm_vma_node_offset_addr(&bo->bo.base.vma_node);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) && !defined(RHEL_70)
 	return bo->bo.addr_space_offset;
 #else
 	return drm_vma_node_offset_addr(&bo->bo.vma_node);
Index: src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
===================================================================
--- src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c	(revision 133811)
+++ src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c	(working copy)
@@ -924,8 +924,13 @@
     for (i = 0; i < skb_shinfo(pBuf)->nr_frags; i++)
     {
         skb_frag_t *pFrag = &skb_shinfo(pBuf)->frags[i];
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+        pSG->aSegs[iSeg].cb = pFrag->bv_len;
+        pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->bv_offset;
+# else /* < KERNEL_VERSION(5, 4, 0) */
         pSG->aSegs[iSeg].cb = pFrag->size;
         pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->page_offset;
+# endif /* >= KERNEL_VERSION(5, 4, 0) */
         Log6((" %p", pSG->aSegs[iSeg].pv));
         pSG->aSegs[iSeg++].Phys = NIL_RTHCPHYS;
         Assert(iSeg <= pSG->cSegsAlloc);
@@ -940,8 +945,13 @@
         for (i = 0; i < skb_shinfo(pFragBuf)->nr_frags; i++)
         {
             skb_frag_t *pFrag = &skb_shinfo(pFragBuf)->frags[i];
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+            pSG->aSegs[iSeg].cb = pFrag->bv_len;
+            pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->bv_offset;
+# else /* < KERNEL_VERSION(5, 4, 0) */
             pSG->aSegs[iSeg].cb = pFrag->size;
             pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->page_offset;
+# endif /* >= KERNEL_VERSION(5, 4, 0) */
             Log6((" %p", pSG->aSegs[iSeg].pv));
             pSG->aSegs[iSeg++].Phys = NIL_RTHCPHYS;
             Assert(iSeg <= pSG->cSegsAlloc);
Index: src/VBox/Runtime/r0drv/linux/the-linux-kernel.h
===================================================================
--- src/VBox/Runtime/r0drv/linux/the-linux-kernel.h	(revision 133811)
+++ src/VBox/Runtime/r0drv/linux/the-linux-kernel.h	(working copy)
@@ -336,7 +336,11 @@
 # endif
 #endif
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+/* XXX The 5.4 kernel has no interface anymore to make kernel pages execcutable */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)                                 
+# define MY_SET_PAGES_EXEC(pPages, cPages)   do {} while (0) 
+# define MY_SET_PAGES_NOEXEC(pPages, cPages) do {} while (0)     
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
 # 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
Index: src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
===================================================================
--- src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(revision 133811)
+++ src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(working copy)
@@ -36,6 +36,9 @@
 #include <iprt/errcore.h>
 #include "internal/thread.h"
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+    #include <uapi/linux/sched/types.h>
+#endif
 
 RTDECL(RTTHREAD) RTThreadSelf(void)
 {

The following config has been UNIT tested with these changes:

### Guest: OpenSuse 15.1
Linux linux-hzpw 4.12.14-lp151.28.16-default #1 SMP Wed Sep 18 05:32:19 UTC 2019 (3e458e0) x86_64 x86_64 x86_64 GNU/Linux

### Guest Winows 10_1903_V1

### Host: Fedora Rawhide/32
Linux lserver 5.4.0-0.rc2.git1.1.fc32.x86_64 #1 SMP Tue Oct 8 17:04:36 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

VirtualBox VM 6.1.0_BETA1 r133811 linux.amd64 (Oct 10 2019 09:49:04) release log
Oracle VM VirtualBox Extension Pack (Version: 6.1.0_BETA1 r133811; VRDE Module: VBoxVRDP)
Oracle VBoxDTrace Extension Pack (Version: 6.1.0_BETA1 r133811; VRDE Module: )

the above cited changes applied to this trunk state.

by Frank Batschulat (Oracle), 5 years ago

Attachment: 54-guest-opensuse.txt added

inital unit testing log

comment:6 by Frank Batschulat (Oracle), 5 years ago

Summary: Linux 5.4: no more arbitrary executable pagesLinux 5.4: no more arbitrary executable pages and more changes

comment:7 by Frank Batschulat (Oracle), 5 years ago

On Fri, 18 Oct 2019 18:12:32 +0200, Larry Finger <> wrote:

Kernel 5.4.0-rc3 introduced a new incompatibility in that a new statement "fallthrough" was created. This change broke the fall through definitions used in VB. The following single line change fixes the problem:

 Index: VirtualBox-6.0.12/include/iprt/cdefs.h
 ===================================================================
 --- VirtualBox-6.0.12.orig/include/iprt/cdefs.h
 +++ VirtualBox-6.0.12/include/iprt/cdefs.h
 @@ -1166,7 +1166,7 @@
    * Tell the compiler that we're falling through to the next case in a  
 switch.
    * @sa RT_FALL_THRU  */
   #if RT_GNUC_PREREQ(7, 0)
 -# define RT_FALL_THROUGH()      __attribute__((fallthrough))
 +# define RT_FALL_THROUGH()      __attribute__((__fallthrough__))
   #else
   # define RT_FALL_THROUGH()      (void)0
   #endif

Larry

Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:8 by Frank Batschulat (Oracle), 5 years ago

5) fallthrough statement change in kernel version 5.4-rc3

This has been introduced with:

Linux 5.4-rc3 https://lkml.org/lkml/2019/10/13/174

Joe Perches (3):
      net: sctp: Rename fallthrough label to unhandled
      compiler_attributes.h: Add 'fallthrough' pseudo keyword for
switch/case use
      Documentation/process: Add fallthrough pseudo-keyword

https://github.com/torvalds/linux/commit/b9918bdcac1ff7bf11f1ab64708267c73f9b2552
https://lkml.org/lkml/2019/10/5/178
https://lkml.org/lkml/2019/10/5/181
https://lore.kernel.org/patchwork/patch/1135570/
https://lwn.net/Articles/794944/

### past baackround from kernel 5.2 days:
https://www.phoronix.com/scan.php?page=news_item&px=Kernel-Wimplicit-fallthrough
### this pull request for Linux 5.2-rc1 that is marking more switch-fallthroughs as expected.
http://lkml.iu.edu/hypermail/linux/kernel/1905.0/04622.html
### Compiler Attributes: add support for fallthrough (gcc >= 7.1)
https://github.com/ojeda/linux/commit/668f011a2706ea555987e263f609a5deba9c7fc4
https://lkml.org/lkml/2018/10/21/150
"In C mode, GCC supports the
fallthrough attribute since 7.1,"
https://developers.redhat.com/blog/2017/03/10/wimplicit-fallthrough-in-gcc-7/error=login_required&state=8ab39b36-33d7-4552-9d4a-40d0c2143376
https://gcc.gnu.org/gcc-7/changes.html
https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html
https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html#Attribute-Syntax
"You may optionally specify attribute names with "__" preceding and following the name. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use the attribute name
noreturn instead of noreturn."

Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:9 by Frank Batschulat (Oracle), 5 years ago

the actual compiler errors against 5.4-rc3 related to the fallthrough change look like this:

kBuild: Linking VBoxOGLTest
kBuild: Generating /home/ws/vb/trunk/out/linux.amd64/debug/obj/webservice/vboxwebsrv.nsmap
In file included from ././include/linux/compiler_types.h:59:0,
                 from <command-line>:0:
/home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/VBoxGuestR0LibHGCMInternal.c: In function ‘vbglR0HGCMInternalPreprocessCall’:
./include/linux/compiler_attributes.h:200:41: error: expected ‘)’ before ‘__attribute__’
 # define fallthrough                    __attribute__((__fallthrough__))
                                         ^
/home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/cdefs.h:1173:48: note: in expansion of macro ‘fallthrough’
 # define RT_FALL_THROUGH()      __attribute__((fallthrough))
                                                ^~~~~~~~~~~
/home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/cdefs.h:1180:33: note: in expansion of macro ‘RT_FALL_THROUGH’
 #define RT_FALL_THRU()          RT_FALL_THROUGH()
                                 ^~~~~~~~~~~~~~~
...and so on and so on...

In file included from /home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/internal/iprt.h:33:0,
                 from /home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-agnostic.c:28:
/home/ws/vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/cdefs.h:1173:60: error: expected identifier or ‘(’ before ‘)’ token
 # define RT_FALL_THROUGH()      __attribute__((fallthrough))
...
                                                           ^

comment:10 by Frank Batschulat (Oracle), 5 years ago

diffs for the fallthrough issue:

Index: include/iprt/cdefs.h
===================================================================
--- include/iprt/cdefs.h	(revision 134159)
+++ include/iprt/cdefs.h	(working copy)
@@ -1170,7 +1170,7 @@
  * Tell the compiler that we're falling through to the next case in a switch.
  * @sa RT_FALL_THRU  */
 #if RT_GNUC_PREREQ(7, 0)
-# define RT_FALL_THROUGH()      __attribute__((fallthrough))
+# define RT_FALL_THROUGH()      __attribute__((__fallthrough__))
 #else
 # define RT_FALL_THROUGH()      (void)0
 #endif
Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:11 by Frank Batschulat (Oracle), 5 years ago

all the changes have been successfully run against the 5.4-rc4 kernel release:

https://git.kernel.org/torvalds/t/linux-5.4-rc4.tar.gz

comment:12 by Frank Batschulat (Oracle), 5 years ago

The falltrhough changes uncovered another minor nit we're going to fix along with this chanegset:

kBuild: Compiling VBoxRT - /home/ws/vbtrunk/trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
In file included from /home/ws/vbtrunk/trunk/include/iprt/fsvfs.h:32,
                 from /home/ws/vbtrunk/trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp:32:
/home/ws/vbtrunk/trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp: In function ‘int rtFsNtfsAttr_ParseExtents(PRTFSNTFSATTR, PRTFSNTFSEXTENTS, uint8_t, int64_t, uint64_t, PRTERRINFO, uint64_t, uint32_t)’:
/home/ws/vbtrunk/trunk/include/iprt/cdefs.h:1161:33: warning: attribute ‘fallthrough’ not preceding a case label or default label
 1161 | # define RT_FALL_THROUGH()      __attribute__((__fallthrough__))
      |                                 ^~~~~~~~~~~~~
/home/ws/vbtrunk/trunk/include/iprt/cdefs.h:1168:33: note: in expansion of macro ‘RT_FALL_THROUGH’
 1168 | #define RT_FALL_THRU()          RT_FALL_THROUGH()
      |                                 ^~~~~~~~~~~~~~~
/home/ws/vbtrunk/trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp:1055:86: note: in expansion of macro ‘RT_FALL_THRU’
 1055 |                     case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0; RT_FALL_THRU();
      |                                                                                      ^~~~~~~~~~~~

trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp

1046                 switch (cbRunField)
1047                 {
1048                     case 8: cClustersInRun |= (uint64_t)pbPairs[offPairs + 7] << 56; RT_FALL_THRU();
1049                     case 7: cClustersInRun |= (uint64_t)pbPairs[offPairs + 6] << 48; RT_FALL_THRU();
1050                     case 6: cClustersInRun |= (uint64_t)pbPairs[offPairs + 5] << 40; RT_FALL_THRU();
1051                     case 5: cClustersInRun |= (uint64_t)pbPairs[offPairs + 4] << 32; RT_FALL_THRU();
1052                     case 4: cClustersInRun |= (uint32_t)pbPairs[offPairs + 3] << 24; RT_FALL_THRU();
1053                     case 3: cClustersInRun |= (uint32_t)pbPairs[offPairs + 2] << 16; RT_FALL_THRU();
1054                     case 2: cClustersInRun |= (uint16_t)pbPairs[offPairs + 1] <<  8; RT_FALL_THRU();
1055                     case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0; RT_FALL_THRU();
1056                 }

with the diffs:

Index: trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp	(revision 134297)
+++ trunk/src/VBox/Runtime/common/fs/ntfsvfs.cpp	(working copy)
@@ -1052,7 +1052,7 @@
                     case 4: cClustersInRun |= (uint32_t)pbPairs[offPairs + 3] << 24; RT_FALL_THRU();
                     case 3: cClustersInRun |= (uint32_t)pbPairs[offPairs + 2] << 16; RT_FALL_THRU();
                     case 2: cClustersInRun |= (uint16_t)pbPairs[offPairs + 1] <<  8; RT_FALL_THRU();
-                    case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0; RT_FALL_THRU();
+                    case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0;
                 }
                 offPairs += cbRunField;
                 AssertBreakStmt(cClustersInRun <= cMaxClustersInRun,

comment:13 by Frank Batschulat (Oracle), 5 years ago

The part concerning the executable page setting has been fixed and taken care of by the following changes:

https://www.virtualbox.org/changeset/81587/vbox
https://www.virtualbox.org/changeset/81586/vbox

in trunk, r134333 and r134334 ,

The remaining 5.4 kernel and glibc fixes have been integrated into trunk with the changeset revision r134407 .

remaining diffs for this bug report:

trunk $ svn status
M       include/iprt/cdefs.h
X       kBuild
M       src/VBox/Additions/linux/drm/vbox_drv.c
M       src/VBox/Additions/linux/drm/vbox_main.c
M       src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
M       src/VBox/Runtime/common/fs/ntfsvfs.cpp
M       src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
 
trunk $ svn diff
Index: include/iprt/cdefs.h
===================================================================
--- include/iprt/cdefs.h	(revision 134405)
+++ include/iprt/cdefs.h	(working copy)
@@ -1158,7 +1158,7 @@
  * Tell the compiler that we're falling through to the next case in a switch.
  * @sa RT_FALL_THRU  */
 #if RT_GNUC_PREREQ(7, 0)
-# define RT_FALL_THROUGH()      __attribute__((fallthrough))
+# define RT_FALL_THROUGH()      __attribute__((__fallthrough__))
 #else
 # define RT_FALL_THROUGH()      (void)0
 #endif
Index: src/VBox/Additions/linux/drm/vbox_drv.c
===================================================================
--- src/VBox/Additions/linux/drm/vbox_drv.c	(revision 134405)
+++ src/VBox/Additions/linux/drm/vbox_drv.c	(working copy)
@@ -305,12 +305,16 @@
 }
 
 static struct drm_driver driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0)
 	.driver_features =
 	    DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ |
-#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) && !defined(RHEL_81)
+# if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0) && !defined(RHEL_81)
 	    DRIVER_IRQ_SHARED |
-#endif
+# endif /* < KERNEL_VERSION(5, 1, 0) && !defined(RHEL_81) */
 	    DRIVER_PRIME,
+#else /* >= KERNEL_VERSION(5, 4, 0) */
+        .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_HAVE_IRQ,
+#endif /* < KERNEL_VERSION(5, 4, 0) */
 	.dev_priv_size = 0,
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
Index: src/VBox/Additions/linux/drm/vbox_main.c
===================================================================
--- src/VBox/Additions/linux/drm/vbox_main.c	(revision 134405)
+++ src/VBox/Additions/linux/drm/vbox_main.c	(working copy)
@@ -621,11 +621,13 @@
 
 static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) && !defined(RHEL_70)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+        return drm_vma_node_offset_addr(&bo->bo.base.vma_node);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) && !defined(RHEL_70)
 	return bo->bo.addr_space_offset;
 #else
 	return drm_vma_node_offset_addr(&bo->bo.vma_node);
-#endif
+#endif /* >= KERNEL_VERSION(5, 4, 0) */
 }
 
 int
Index: src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c
===================================================================
--- src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c	(revision 134405)
+++ src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux.c	(working copy)
@@ -924,8 +924,13 @@
     for (i = 0; i < skb_shinfo(pBuf)->nr_frags; i++)
     {
         skb_frag_t *pFrag = &skb_shinfo(pBuf)->frags[i];
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+        pSG->aSegs[iSeg].cb = pFrag->bv_len;
+        pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->bv_offset;
+# else /* < KERNEL_VERSION(5, 4, 0) */
         pSG->aSegs[iSeg].cb = pFrag->size;
         pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->page_offset;
+# endif /* >= KERNEL_VERSION(5, 4, 0) */
         Log6((" %p", pSG->aSegs[iSeg].pv));
         pSG->aSegs[iSeg++].Phys = NIL_RTHCPHYS;
         Assert(iSeg <= pSG->cSegsAlloc);
@@ -940,8 +945,13 @@
         for (i = 0; i < skb_shinfo(pFragBuf)->nr_frags; i++)
         {
             skb_frag_t *pFrag = &skb_shinfo(pFragBuf)->frags[i];
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+            pSG->aSegs[iSeg].cb = pFrag->bv_len;
+            pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->bv_offset;
+# else /* < KERNEL_VERSION(5, 4, 0) */
             pSG->aSegs[iSeg].cb = pFrag->size;
             pSG->aSegs[iSeg].pv = VBOX_SKB_KMAP_FRAG(pFrag) + pFrag->page_offset;
+# endif /* >= KERNEL_VERSION(5, 4, 0) */
             Log6((" %p", pSG->aSegs[iSeg].pv));
             pSG->aSegs[iSeg++].Phys = NIL_RTHCPHYS;
             Assert(iSeg <= pSG->cSegsAlloc);
Index: src/VBox/Runtime/common/fs/ntfsvfs.cpp
===================================================================
--- src/VBox/Runtime/common/fs/ntfsvfs.cpp	(revision 134405)
+++ src/VBox/Runtime/common/fs/ntfsvfs.cpp	(working copy)
@@ -1052,7 +1052,7 @@
                     case 4: cClustersInRun |= (uint32_t)pbPairs[offPairs + 3] << 24; RT_FALL_THRU();
                     case 3: cClustersInRun |= (uint32_t)pbPairs[offPairs + 2] << 16; RT_FALL_THRU();
                     case 2: cClustersInRun |= (uint16_t)pbPairs[offPairs + 1] <<  8; RT_FALL_THRU();
-                    case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0; RT_FALL_THRU();
+                    case 1: cClustersInRun |= (uint16_t)pbPairs[offPairs + 0] <<  0;
                 }
                 offPairs += cbRunField;
                 AssertBreakStmt(cClustersInRun <= cMaxClustersInRun,
Index: src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c
===================================================================
--- src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(revision 134405)
+++ src/VBox/Runtime/r0drv/linux/thread2-r0drv-linux.c	(working copy)
@@ -36,6 +36,9 @@
 #include <iprt/errcore.h>
 #include "internal/thread.h"
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+    #include <uapi/linux/sched/types.h>
+#endif /* >= KERNEL_VERSION(4, 11, 0) */
 
 RTDECL(RTTHREAD) RTThreadSelf(void)
 {

All 3 changeset have been verified against:
https://git.kernel.org/torvalds/t/linux-5.4-rc5.tar.gz

comment:14 by Frank Batschulat (Oracle), 5 years ago

Resolution: fixed
Status: acceptedclosed

comment:15 by Frank Batschulat (Oracle), 5 years ago

a new set of trunk (aka development release) builds have been produced an uploaded that contain the 5.4 changes mentioned above, section "Development snapshots"

https://www.virtualbox.org/wiki/Testbuilds

do not forgett the host and the guest both needs updating to the version.

comment:16 by Frank Batschulat (Oracle), 5 years ago

All the mentioned 5.4 kernel changes above have been backported to the 6.X branch as: r134337, r134335 and r134477.
and to the 5.2 branch as: r134341, r134336 and r134482.

Also they have been verified against:
https://git.kernel.org/torvalds/t/linux-5.4-rc6.tar.gz

Version 0, edited 5 years ago by Frank Batschulat (Oracle) (next)

comment:17 by Frank Batschulat (Oracle), 5 years ago

I forgot to mention, that the changes for:
src/VBox/HostDrivers/VBoxNetFlt/linux/VBoxNetFlt-linux
are required by 5.4-rc1 kernel revision, so a 5.4-rc0 kernel will fall over this changeset and needs upgrading to at least 5.4-rc1.

That chnage in Linux was:
[PATCH v3 0/7] Convert skb_frag_t to bio_vec
https://www.spinics.net/lists/netdev/msg585545.html

Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

comment:18 by Frank Batschulat (Oracle), 5 years ago

VirtualBox 6.1 Release Candidate 1 released

contains these fixes, refer to:

Linux host and guest: Support Linux 5.4 (bug #18945)
http://download.virtualbox.org/virtualbox/6.1.0_RC1

https://forums.virtualbox.org/viewtopic.php?f=15&t=95711&sid=c2076288e2e8b73544150a5687336462

comment:19 by Tigran Aivazian, 5 years ago

I tried to install this on Ubuntu 18.04.3 running Linux 5.4.0 kernel and this is what I get:

$ sudo dpkg -i virtualbox-6.1_6.1.0_rc1-134891_Ubuntu_bionic_amd64.deb 
Selecting previously unselected package virtualbox-6.1.
(Reading database ... 235409 files and directories currently installed.)
Preparing to unpack virtualbox-6.1_6.1.0_rc1-134891_Ubuntu_bionic_amd64.deb ...
Unpacking virtualbox-6.1 (6.1.0~rc1-134891~Ubuntu~bionic) ...
Setting up virtualbox-6.1 (6.1.0~rc1-134891~Ubuntu~bionic) ...
addgroup: The group `vboxusers' already exists as a system group. Exiting.
vboxdrv.sh: failed: Look at /var/log/vbox-setup.log to find out what went wrong.

There were problems setting up VirtualBox.  To re-start the set-up process, run
  /sbin/vboxconfig
as root.  If your system is using EFI Secure Boot you may need to sign the
kernel modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) before you can load
them. Please see your Linux system's documentation for more information.
Processing triggers for systemd (237-3ubuntu10.33) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for desktop-file-utils (0.23-1ubuntu3.18.04.2) ...
Processing triggers for gnome-menus (3.13.3-11ubuntu1.1) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Processing triggers for hicolor-icon-theme (0.17-2) ...
Processing triggers for shared-mime-info (1.9-2) ...
$ sudo /sbin/vboxconfig 
vboxdrv.sh: Stopping VirtualBox services.
vboxdrv.sh: Starting VirtualBox services.
vboxdrv.sh: Building VirtualBox kernel modules.
vboxdrv.sh: failed: Look at /var/log/vbox-setup.log to find out what went wrong.

There were problems setting up VirtualBox.  To re-start the set-up process, run
  /sbin/vboxconfig
as root.  If your system is using EFI Secure Boot you may need to sign the
kernel modules (vboxdrv, vboxnetflt, vboxnetadp, vboxpci) before you can load
them. Please see your Linux system's documentation for more information.

Looking in /var/log/vbox-setup.log I see lots of errors:

ERROR: "__cpuhp_remove_state" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "native_write_cr4" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "del_timer" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "gdt_page" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "autoremove_wake_function" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__x86_indirect_thunk_r12" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "hrtimer_cancel" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__x86_indirect_thunk_r9" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__platform_driver_register" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "smp_call_function_many" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "map_vm_area" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "hrtimer_start_range_ns" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__cpu_online_mask" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "vmap" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__x86_indirect_thunk_r13" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "destroy_workqueue" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "down" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "platform_device_unregister" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__cpuhp_setup_state" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "flush_workqueue" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "vm_insert_page" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__sw_hweight64" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "find_vma" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "smp_call_function" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "platform_device_register" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "ioremap_nocache" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "cpu_tlbstate" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "get_user_pages" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "high_memory" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "get_user_pages_remote" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "sched_setscheduler" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__get_vm_area" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "ex_handler_default" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "schedule_hrtimeout_range" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "vm_mmap" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "vunmap" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "remap_pfn_range" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "prepare_to_wait" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "hrtimer_init" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__cpu_present_mask" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "up" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "scnprintf" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "vm_munmap" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "hrtimer_try_to_cancel" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "platform_driver_unregister" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "ktime_get_ts64" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "__msecs_to_jiffies" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "alloc_workqueue" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "smp_call_function_single" [/tmp/vbox.0/vboxdrv.ko] undefined!
ERROR: "yield" [/tmp/vbox.0/vboxdrv.ko] undefined!
scripts/Makefile.modpost:93: recipe for target '__modpost' failed
make[2]: *** [__modpost] Error 1
Makefile:1609: recipe for target 'modules' failed
make[1]: *** [modules] Error 2
/tmp/vbox.0/Makefile-footer.gmk:114: recipe for target 'vboxdrv' failed
make: *** [vboxdrv] Error 2

Last edited 5 years ago by Tigran Aivazian (previous) (diff)

comment:20 by Tigran Aivazian, 5 years ago

Ah, I just noticed that I set CONFIG_TRIM_UNUSED_KSYMS option during kernel configuration and that is probably what is causing it. Recompiling the kernel to check... (will update this comment once everything is sorted out).

UPDATE: Yes, that was the reason, so VirtualBox 6.1-RC1 works fine on 5.4.0 kernel.

However, there is still a small bug in vboxdrv.sh because it tries to unload the module vboxpci (but I always compile the kernel with CONFIG_MODULE_UNLOAD not set, because that is much safer --- at least that was the case 20 years ago and I hope nothing much changes in computers in a decade or two :)

Last edited 5 years ago by Tigran Aivazian (previous) (diff)
Note: See TracTickets for help on using tickets.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette