[PATCH v5 0/1] MR2118: ntdll: Explaining with wine requires a 3G/1G split on 32bit
Windows has a 2G/2G split by default, but some addresses are fixed in the win32 API, so we have to ensure that those addresses are still available in the virtual memory space and not taken by Linux. Kudos to stefand for taking the time to explain on IRC. -- v5: ntdll: Explaining why 3G/1G split is needed on 32bit https://gitlab.winehq.org/wine/wine/-/merge_requests/2118
From: Steve Schnepp <steve.schnepp(a)pwkf.org> Windows has a 2G/2G split by default, but some addresses are fixed in the win32 ABI, so we have to ensure that those addresses are still available in the virtual memory space and not taken by Linux. Kudos to stefand for taking the time to explain on IRC. --- dlls/ntdll/unix/loader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 65934acfc36..09171e18d88 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2309,6 +2309,23 @@ static int pre_exec(void) #elif defined(__linux__) && (defined(__i386__) || defined(__arm__)) +/* In the Win32 ABI, KUSER_SHARED_DATA is at a fixed address (0x7ffe0000), so + * it needs to be mapped precisely there in every virtual process space by the + * wine process loader. + * + * It is used to map kernel address space pages to user space, so that it is + * user-space readable without any syscall overhead. It is very comparable + * to Linux's vDSO. + * + * For that, we need to ensure that Linux doesn't map anything internal in that + * area, which it does if configured with a 2G/2G split. Unfortunately, Linux + * does initially map the stack there, along with its own vDSO. + * + * More information: + * + * https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/ns-ntdd... + * https://en.wikipedia.org/wiki/VDSO + */ static void check_vmsplit( void *stack ) { if (stack < (void *)0x80000000) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2118
On Mon Feb 6 21:50:45 2023 +0000, Steve Schnepp wrote:
Oh, but it looked actually very similar to how `gettimeofday()` is implemented in Linux.
The KUSER_SHARED_DATA structure is a single page (4096 bytes) in memory that is mapped at a fixed, hardcoded address in both kernel and user side of VAS. KUSER_SHARED_DATA is mapped into every process and provides a quick mechanism to obtain frequently needed global data (interrupt time, version, debugger state, processor extensions, etc.) from the kernel without involving user-kernel mode switching using system calls or interrupts from https://msrc-blog.microsoft.com/2022/04/05/randomizing-the-kuser_shared_data... On that page, there's even some discussion at _what_ will break and how to move it out. TLDR: you cannot :disappointed: Actually, you are right and I'm wrong.
vDSO is randomized, vsyscall is the static version. Also, in Linux a full function is provided, whereas in win32 only the values are provided, relying on header macros to fetch the correct values. Amending also. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2118#note_23171
participants (2)
-
Steve Schnepp -
Steve Schnepp (@steveschnepp)