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.
-- v2: ntdll: Explaining with wine requires a 3G/1G split on 32bit
From: Steve Schnepp steve.schnepp@pwkf.org
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. --- dlls/ntdll/unix/loader.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 65934acfc36..d27a9930b3c 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -2309,6 +2309,27 @@ static int pre_exec(void)
#elif defined(__linux__) && (defined(__i386__) || defined(__arm__))
+/* In Win32, the KSM (Kernel Shared Page) has a fixed address between + * 2GiB (0x7FFFFFFF) and 3GiB (0x17FFFFFF) so it needs to be mapped there. + * + * 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. + * + * A potentially nice thing to have is to move the shared data if the hardcoded + * address does not work. + * + * Yet there is no official way to communicate the address from ntdll to + * kernel32, as is should be at a fixed address in the first place. The only + * alternative might be wine-specific private calls from kernel32 to ntdll, + * which is bad. + * + * Moreover, it would probably make 99% of applications out there happy, this + * would still break the ABI, which is also bad. + */ static void check_vmsplit( void *stack ) { if (stack < (void *)0x80000000)
That doesn't sound right. The page (which I've only ever heard called "user shared data" or "shared user data", never "KSM" or "Kernel Shared Page") is mapped at 0x7ffe0000 for 32-bit programs.
On Mon Feb 6 18:10:57 2023 +0000, Zebediah Figura wrote:
That doesn't sound right. The page (which I've only ever heard called "user shared data" or "shared user data", never "KSM" or "Kernel Shared Page") is mapped at 0x7ffe0000 for 32-bit programs.
oh, you are right... @stefan said :
<@stefand> hmm, 0x7ffe0000. Not that high <@stefand> it must be some other data structure
I can remove the wrong info, but then, what's needed ? ;-)
As far as I can see the problem is that Linux maps things to the top of address space, blocking 0x7ffe0000. So even though it is below 2GB, we can't grab this address with 2/2 memsplit.
In my quick'n'dirty testing vDSO (which, incidentally, is a Linux feature that has similar purpose to KUSER_SHARED_DATA) and the initial stack are in the way.
I am not an authoritative expert on this in any way :-/ .