XSAVE-related segfaults observed under wine

Pip Cet pipcet@protonmail.com
Fri Jun 27 14:41:39 GMT 2025


This is about a bug which was observed when running msys2 binaries in
Wine under recent Linux kernels on new Intel/AMD CPUs that support the
PKU/PKRU feature, but it appears to be a bug in Cygwin; specifically,
in:
 c607889824395f0eac7e85d5b81c906bf8025321
 Author: Takashi Yano <takashi.yano@nifty.ne.jp>
 AuthorDate: Sun Oct 13 07:41:40 2024 +0900
 Commit: Takashi Yano <takashi.yano@nifty.ne.jp>
 CommitDate: Fri Nov 1 04:56:27 2024 +0900
 Cygwin: sigfe: Fix a bug that signal handler destroys fpu states
In this commit, we added these lines of code:
	movl	\0ドルx0d,%eax
	xorl	%ecx,%ecx
	cpuid	# get necessary space for xsave
	movq	%rbx,%rcx
	addq	\0ドルx48,%rbx # 0x18 for alignment, 0x30 for additional space
	subq	%rbx,%rsp
	movl	%ebx,0x24(%rsp)
	xorq	%rax,%rax
	shrq	\3,ドル%rcx
	leaq	0x30(%rsp),%rdi
	rep	stosq
	xgetbv	# get XCR0 (ecx is 0 after rep)
	movl	%eax,0x28(%rsp)
	movl	%edx,0x2c(%rsp)
	notl	%ecx # set ecx non-zero
	movl	%ecx,0x20(%rsp)
	xsave64	0x30(%rsp)
The problem is that those new Intel/AMD CPUs (I have one of each here)
report the PKU/PKRU feature with an additional XSAVE area of 8 bytes
(only 4 bytes are used). This means that the cpuid instruction will
return in %rbx a value which is not aligned to 64 bytes, so our
subtraction will make %rsp+0x30 (the target of the xsave64 instruction)
misaligned (by 8 bytes) when we execute the xsave64 instruction, which
assumes its argument to be 64-byte aligned. This causes a segfault and
abnormal program termination.
Disabling the PKU feature ("nopku" on the Linux kernel command line;
reboot) makes the problem go away, as does working around it in
winedbg --gdb:
 b *0x18019c647
 Breakpoint 1 at 0x18019c647
 Wine-gdb> command 1
 command 1
 Type commands for breakpoint(s) 1, one per line.
 End with a line saying just "end".
 >p $rbx += 56
 >c
 >end
 Wine-gdb> c
(Here, 0x18019c647 is the address of the movq %rbx, %rcx instruction in
the segment above).
My suggested fix is to align the value in %rbx to the next 64-byte
multiple after the "cpuid" instruction is executed, by performing the
assembler equivalent of $rbx += 63; $rbx &= -64; I tried this:
diff --git a/winsup/cygwin/scripts/gendef b/winsup/cygwin/scripts/gendef
index 861a2405b..d681fde3f 100755
--- a/winsup/cygwin/scripts/gendef
+++ b/winsup/cygwin/scripts/gendef
@@ -232,6 +232,8 @@ sigdelayed:
 	movl	\0ドルx0d,%eax
 	xorl	%ecx,%ecx
 	cpuid	# get necessary space for xsave
+	addq	\63,ドル %rbx
+	andq	\$-64, %rbx # align to next 64-byte multiple
 	movq	%rbx,%rcx
 	addq	\0ドルx48,%rbx # 0x18 for alignment, 0x30 for additional space
 	subq	%rbx,%rsp
And it worked in a very simple test, on the msys2-runtime source
(copying the DLL from a partially-successful build to the msys2 image).
I hope it's small enough to be exempt from copyright requirements!
I don't know whether (or when) Windows systems will support the PKU/PKRU
feature (which is extremely useful!), but I suspect the bug would occur
there, too, or with other small additional XSAVE areas.
Links to GitHub issues for the related msys2 problem:
 https://github.com/msys2/msys2-runtime/issues/295
 https://github.com/msys2/msys2-docker/issues/18
Sorry this got a bit long, and thanks!
Pip


More information about the Cygwin mailing list

AltStyle によって変換されたページ (->オリジナル) /