VirtualBox

Opened 5 years ago

Last modified 5 years ago

#19312 closed defect

Linux: kernel 5.6 - we need changes — at Version 8

Reported by: Frank Batschulat (Oracle) Owned by: Frank Batschulat (Oracle)
Component: other Version: VirtualBox 6.1.2
Keywords: linux 5.6 kernel Cc:
Guest type: Linux Host type: Linux

Description (last modified by Frank Batschulat (Oracle))

So mainline 5.6-rc1 is out and we have already 1 change required:

In file included from /home/ws/vbtrunk/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:33:0:
/home/ws/vbtrunk/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/memobj-r0drv-linux.c: In function ‘rtR0MemObjNativeMapKernel’:
/home/ws/vbtrunk/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/memobj-r0drv-linux.c:1465:32: error: implicit declaration of function ‘ioremap_nocache’; did you mean ‘ioremap_cache’? [-Werror=implicit-function-declaration]
                              ? ioremap_nocache(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub)
                                ^~~~~~~~~~~~~~~
                                ioremap_cache
/home/ws/vbtrunk/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/memobj-r0drv-linux.c:1466:30: error: pointer/integer type mismatch in conditional expression [-Werror]
                              : ioremap(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub);

                              ^

This is due to:

https://github.com/torvalds/linux/commit/4bdc0d676a643140bdf17dbf7eafedee3d496a3c
https://github.com/torvalds/linux/tree/master/drivers/usb/early

ioremap has provided non-cached semantics by default
since the Linux 2.6 days, so remove the additional
ioremap_nocache interface.

Merging generic-ioremap/for-next (4bdc0d676a64 remove ioremap_nocache and devm_ioremap_nocache)

https://www.spinics.net/lists/netdev/msg623588.html
https://lkml.org/lkml/2020/2/4/275

obvious fix:
=> replace use of ioremap_nocache() with ioremap_cache()

Edit:

ioremap_cache() is uncached by default since a long time.

all 5.X kernels down to version 5.0 all 4.X kernels down to version 4.0 all 3.X kernels down to version 3.0

from version 2.6.25 onwards we know for sure that ioremap_cache() has uncached semantics by default.

https://elixir.bootlin.com/linux/v2.6.25/source/include/asm-x86/io_64.h#L161

 * This one maps high address device memory and turns off caching for that area.
 * it's useful if some control registers are in such an area and write combining
 * or read caching is not desirable:
 */
extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);

/*
 * The default ioremap() behavior is non-cached:
 */
static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
{
	return ioremap_nocache(offset, size);
}

That means we can and should replace ioremap_nocache() usage with ioremap_cache() and make kernel version 2.6.25 the tipping point for this.

Change History (10)

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

Guest type: otherLinux
Host type: otherLinux
Owner: set to Frank Batschulat (Oracle)
Status: newassigned

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

C symbol: ioremap_nocache
  File                 Function                  Line
0 VBoxPci-linux.c      vboxPciOsDevMapRegion      846 RTR0PTR R0PtrMapping = ioremap_nocache(pci_resource_start(pPciDev, iRegion),
1 memobj-r0drv-linux.c rtR0MemObjNativeMapKernel 1465 ? ioremap_nocache(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub)

Could not find the C symbol: devm_ioremap_nocache

Edit: the diffs for that particular issue are:

$ svn diff
Index: src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c
===================================================================
--- src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c	(revision 136356)
+++ src/VBox/HostDrivers/VBoxPci/linux/VBoxPci-linux.c	(working copy)
@@ -842,8 +842,11 @@
         rcLnx = pci_request_region(pPciDev, iRegion, "vboxpci");
         if (!rcLnx)
         {
-            /* For now no caching, try to optimize later. */
-            RTR0PTR R0PtrMapping = ioremap_nocache(pci_resource_start(pPciDev, iRegion),
+            /*
+             * ioremap() defaults to no caching since 2.6 kernels.
+             * We try to optimize later.
+             */
+            RTR0PTR R0PtrMapping = ioremap(pci_resource_start(pPciDev, iRegion),
                                                    pci_resource_len(pPciDev, iRegion));
 
             if (R0PtrMapping != NIL_RTR0PTR)
@@ -850,7 +853,7 @@
                 pIns->aRegionR0Mapping[iRegion] = R0PtrMapping;
             else
             {
-                vbpci_printk(KERN_DEBUG, pPciDev, "ioremap_nocache() failed\n");
+                vbpci_printk(KERN_DEBUG, pPciDev, "ioremap_cache() failed\n");
                 pci_release_region(pPciDev, iRegion);
                 rc = VERR_MAP_FAILED;
             }
Index: src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
===================================================================
--- src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(revision 136356)
+++ src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(working copy)
@@ -1461,9 +1461,19 @@
              * MMIO / physical memory.
              */
             Assert(pMemLnxToMap->Core.enmType == RTR0MEMOBJTYPE_PHYS && !pMemLnxToMap->Core.u.Phys.fAllocated);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
+            /*
+             * ioremap() defaults to no caching since the 2.6 kernels.
+             * ioremap_nocache() has been removed finally in 5.6-rc1.
+             */
             pMemLnx->Core.pv = pMemLnxToMap->Core.u.Phys.uCachePolicy == RTMEM_CACHE_POLICY_MMIO
+                             ? ioremap(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub)
+                             : ioremap_cache(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub);
+#else /* KERNEL_VERSION < 2.6.25 */
+            pMemLnx->Core.pv = pMemLnxToMap->Core.u.Phys.uCachePolicy == RTMEM_CACHE_POLICY_MMIO
                              ? ioremap_nocache(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub)
                              : ioremap(pMemLnxToMap->Core.u.Phys.PhysBase + offSub, cbSub);
+#endif /* KERNEL_VERSION < 2.6.25 */
             if (pMemLnx->Core.pv)
             {
                 /** @todo fix protection. */
Last edited 5 years ago by Frank Batschulat (Oracle) (previous) (diff)

by Larry998, 5 years ago

Attachment: fixes_for_5.6.patch added

This patch file will fix that problem.

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

With 5.6-rc3 we get additional compilation errors:

In file included from /home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/waitqueue-r0drv-linux.h:38:0,
                 from /home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/semevent-r0drv-linux.c:42,
                 from /home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:38:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h: In function ‘RTTimeSpecGetTimeval’:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h:379:13: error: dereferencing pointer to incomplete type ‘struct timeval’
     pTimeval->tv_sec = (time_t)i64;
             ^~
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h:379:25: error: ‘time_t’ undeclared (first use in this function); did you mean ‘ktime_t’?
     pTimeval->tv_sec = (time_t)i64;
                         ^~~~~~
                         ktime_t
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h:379:25: note: each undeclared identifier is reported only once for each function it appears in
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h:379:32: error: expected ‘;’ before ‘i64’
     pTimeval->tv_sec = (time_t)i64;
                                ^~~
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h: In function ‘RTTimeSpecSetTimeval’:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/include/iprt/time.h:393:67: error: dereferencing pointer to incomplete type ‘const struct timeval’
     return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
                                                                   ^~
In file included from /home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/combined-os-specific.c:46:0:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c: In function ‘rtTimeGetSystemNanoTS’:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c:46:21: error: storage size of ‘Ts’ isn’t known
     struct timespec Ts;
                     ^~
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c:47:5: error: implicit declaration of function ‘ktime_get_ts’; did you mean ‘ktime_get_ns’? [-Werror=implicit-function-declaration]
     ktime_get_ts(&Ts);
     ^~~~~~~~~~~~
     ktime_get_ns
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c:46:21: error: unused variable ‘Ts’ [-Werror=unused-variable]
     struct timespec Ts;
                     ^~
kBuild: Generating /home/ws/56vb/trunk/out/linux.amd64/debug/obj/webservice/vboxweb.wsdl
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c: In function ‘VBoxGuest_RTTimeNow’:
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c:184:12: error: implicit declaration of function ‘RTTimeSpecSetTimespec64’; did you mean ‘RTTimeSpecSetTimeval’? [-Werror=implicit-function-declaration]
     return RTTimeSpecSetTimespec64(pTime, &Ts);
            ^~~~~~~~~~~~~~~~~~~~~~~
            RTTimeSpecSetTimeval
/home/ws/56vb/trunk/out/linux.amd64/debug/obj/tstvboxguest-src_mod/r0drv/linux/time-r0drv-linux.c:184:12: error: return makes pointer from integer without a cast [-Werror=int-conversion]
     return RTTimeSpecSetTimespec64(pTime, &Ts);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

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

We have been finally hit by the Linux-32-bit-Past-Y2038 work/changes that has been going on since at least kernel version 5.5 but is getting close to an end in 5.6.

https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.6-32-bit-Past-Y2038

the individual errors from above:

1) struct timeval:

https://lkml.org/lkml/2020/1/29/355?anz=web
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=y2038-endgame

in Linux 5.6-rc3:
https://lwn.net/Articles/813158/
y2038: hide timeval/timespec/itimerval/itimerspec types
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/commit/?h=y2038-endgame&id=82c3bb87758c4128530f3cbb7ae045ef423ee718

2) ktime_get_ts():

This is used in the Linux runtime:

trunk/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c:rtTimeGetSystemNanoTS()

https://www.kernel.org/doc/html/latest/core-api/timekeeping.html
https://www.kernel.org/doc/html/latest/core-api/timekeeping.html#deprecated-time-interfaces

Deprecated time interfaces
Older kernels used some other interfaces that are now being phased
out but may appear in third-party drivers being ported here. In
particular, all interfaces returning a ‘struct timeval’ or ‘struct
timespec’ have been replaced because the tv_sec member overflows in
year 2038 on 32-bit architectures. These are the recommended
replacements:

void ktime_get_ts(struct timespec *)

    Use ktime_get() or ktime_get_ts64() instead.

present till 5.6-rc2:
https://elixir.bootlin.com/linux/v5.6-rc2/source/include/linux/timekeeping32.h

and it's gone with 5.6-rc3:
https://github.com/torvalds/linux/commit/412c53a680a97cb1ae2c0ab60230e193bee86387#diff-29d5ddd06ea73839af565f438a7c186c
https://elixir.bootlin.com/linux/v5.6-rc3/source/include/linux/timekeeping32.h
https://github.com/torvalds/linux/blob/master/include/linux/timekeeping32.h

it already said in the past: include/linux/timekeeping32.h:

#ifndef _LINUX_TIMEKEEPING32_H
#define _LINUX_TIMEKEEPING32_H
/*
 * These interfaces are all based on the old timespec type
 * and should get replaced with the timespec64 based versions
 * over time so we can remove the file here.
 */

=> use ktime_get_ts64()
https://elixir.bootlin.com/linux/v5.6-rc3/source/include/linux/timekeeping.h#L42

3) struct timespec:

https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/commit/?h=y2038-endgame&id=2d5d83981d9ac5c256a30818c9d8cb1443cbb0ce

4) overall 64-bit kernel time interface merge:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=22b17db4ea05

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

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

Description: modified (diff)

comment:6 by s.zharkoff, 5 years ago

Things seems a bit easier here - need to replace one usage of ktime_get_ts and replaca timespec with timespec64 there.

and time.h file is the biggest issue RTTimeSpecSetTimespec64 is getting compiled only if TIMESPEC interface is set , but it is not starting from 5.6-rc3.

RTTimeSpecGetTimeval, RTTimeSpecSetTimeval - this functions are there only for usage with 2.6 kernels,but they are getting comiled in header time.h unconditionally.

The rest of module seems to be compatible with y2038

by Jags, 5 years ago

Attachment: vbox-setup.log added

vbox-setup.log | Building module fails for kernel 5.6 RC4; VirtualBox-6.1.97-136310-Linux_amd64.run on Ubuntu MATE 20.04 64bit

comment:7 by Jags, 5 years ago

Attached vbox-setup.log for errors while building module for kernel 5.6 RC4 in Ubuntu MATE 20.04 64bit; VirtualBox-6.1.97-136310-Linux_amd64.run. Thanks.

Last edited 5 years ago by Jags (previous) (diff)

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

Description: modified (diff)
Note: See TracTickets for help on using tickets.

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