* [PULL 1/8] linux-user/sh4: use the kernel's sigreturn trampoline sequence in the vdso
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 2/8] linux-user/sh4: fix vdso CFA for rt_sigreturn frames Helge Deller
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Matt Turner <mattst88@gmail.com>
With the vdso, default_sigreturn and default_rt_sigreturn point at
__kernel_sigreturn and __kernel_rt_sigreturn and setup_sigtramp() is no
longer used. The vdso trampolines load the syscall number with mov.l
instead of the kernel's mov.w/trapa/or r0,r0 sequence, which undoes
commit 9ac5aa7227 ("linux-user/sh4: Fix setup_sigtramp to match Linux
kernel trampoline pattern"): libunwind's unw_is_signal_frame() no longer
recognizes the signal frame, so unwinding through a signal handler stops
there.
Use the sequence from the kernel's own vdso,
arch/sh/kernel/vsyscall/vsyscall-sigreturn.S.
Fixes: 975bd51a88 ("linux-user/sh4: add VDSO support for sh4 and sh4eb")
Cc: qemu-stable@nongnu.org
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sh4/vdso-be.so | Bin 2704 -> 2720 bytes
linux-user/sh4/vdso-le.so | Bin 2704 -> 2720 bytes
linux-user/sh4/vdso.S | 26 ++++++++++++++++++--------
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/linux-user/sh4/vdso-be.so b/linux-user/sh4/vdso-be.so
index 4f50143f8284ab63693c1117e68f3efa886155e3..bc1fb37e1089b7aa5612da0039e24193b156b3d8 100755
GIT binary patch
delta 194
zcmbOrx<GV-GNZyo6=&8T3=AwkCgxO#v^^7IdSMZuBqF1%9rYmk#g%V{*C+nCEhr$w
zz`(=6z>vYf!19cNfk9yN6UOaK%t{QNljpHmC{1QPETF&*gAC<p{Iv|6lM@-mC;w-8
z!1!(Q1J-<2uo;s>*zEZrCMPE+g;si2C2d~Fmd4B&GMR%*neoSD9WHgo6_Z1_)J119
NFfg<*AOItX2>?A$F(&{3
delta 178
zcmZ1=Ize=TGNZsm6=&8L3=AwUCgxO#6if>*aPh9(e`{gllH+YV4J~=!giQQ#TaZhL
zfq{pCfgyu|f#m@M0|UqACyd*fm_-=eCeLHB5W38GSb%|(fq|j?GQ(j31_p+;lM@-m
zC-bvDV0<z818Y7jSkL4XHhVsZNy*7YQI?S@>6<sQr7<(QOqSqMW_&T(hD)7s#^e+(
Qb<s`+28I>}1YiU)0VjPgU;qFB
diff --git a/linux-user/sh4/vdso-le.so b/linux-user/sh4/vdso-le.so
index c41cb5831b9e5883a64564da8b2149a33e199f4f..c1ff560cc165413d7b07aa873225bd92afb8569e 100755
GIT binary patch
delta 202
zcmbOrx<GV-0;9r2MQ7F@EDQ`kCT3QP?EQGW?V6EbjpN0Ka-A|h8NXg^nl$mp4M710
z1_mJp9)=7C28L%W3=9IBA2M!dVpC#ZU|{f^Jdedfk#(}bVQvK&EN4LFuVvtzoX99T
z`47tj#&47FvgWgbO_?0XW)C-;AvxK|)6&>Db@M{DWM;;Y$*f$;j6Wu8a;Y<}m>kHZ
RE-{mxfuRLtBNQ+~834g&GJ*gA
delta 184
zcmZ1=Ize=T0;9l0MQ7F*EDQ`UCT3QPl&)2g-L`IF)#Kt%zJj4I-B(^c;xzHc4M8pj
z1_mJp9)=7C28IVL3=ABbA2M!dViRFtU|?{YJdeeKpYgK5VNQl}kicbu!)qreGKx>;
zVST{(V)9$od{(fY$%$<CaFZC4lPkSUBf_#aZ)8hmW^|b>%B9TsVzMQdI^&GViCpRu
Qo$L$@Eg<8dfDy_70CGt$_W%F@
diff --git a/linux-user/sh4/vdso.S b/linux-user/sh4/vdso.S
index 4fb5ee9d31..1faa665774 100644
--- a/linux-user/sh4/vdso.S
+++ b/linux-user/sh4/vdso.S
@@ -43,6 +43,22 @@ vdso_syscall __vdso_clock_gettime64, __NR_clock_gettime64
vdso_syscall __vdso_clock_getres, __NR_clock_getres
vdso_syscall __vdso_gettimeofday, __NR_gettimeofday
+/*
+ * Same instruction sequence as the kernel's
+ * arch/sh/kernel/vsyscall/vsyscall-sigreturn.S. libunwind matches these
+ * bytes to recognize a signal frame.
+ */
+.macro sigreturn_tramp nr
+ mov.w 1f, r3
+ trapa #0x10
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+1: .word \nr
+.endm
+
/*
* Signal return trampolines.
*
@@ -122,20 +138,14 @@ vdso_syscall __vdso_gettimeofday, __NR_gettimeofday
sigreturn_region_start:
__kernel_sigreturn:
- mov.l 1f, r3
- trapa #0x10
- .align 2
-1: .long __NR_sigreturn
+ sigreturn_tramp __NR_sigreturn
endf __kernel_sigreturn
/* Update CFA base for the rt_sigreturn frame layout. */
.cfi_def_cfa_offset RT_SIGFRAME_SC_OFFSET
__kernel_rt_sigreturn:
- mov.l 2f, r3
- trapa #0x10
- .align 2
-2: .long __NR_rt_sigreturn
+ sigreturn_tramp __NR_rt_sigreturn
endf __kernel_rt_sigreturn
sigreturn_region_end:
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 2/8] linux-user/sh4: fix vdso CFA for rt_sigreturn frames
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
2026-09-25 9:38 ` [PULL 1/8] linux-user/sh4: use the kernel's sigreturn trampoline sequence in the vdso Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 3/8] linux-user/sh4: align the vdso sigreturn trampolines Helge Deller
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Matt Turner <mattst88@gmail.com>
The unwinder looks up a return address as IP - 1 (hence the nop before
sigreturn_region_start). For a frame returning to __kernel_rt_sigreturn
that is the last byte of __kernel_sigreturn, which still has the
sigreturn CFA, so the rt_sigreturn frame is unwound with the wrong
sigcontext offset. _Unwind_Backtrace() from an SA_SIGINFO handler stops
after three frames.
Add a nop after .cfi_def_cfa_offset, as linux-user/i386/vdso.S does.
Fixes: 975bd51a88 ("linux-user/sh4: add VDSO support for sh4 and sh4eb")
Cc: qemu-stable@nongnu.org
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sh4/vdso-be.so | Bin 2720 -> 2720 bytes
linux-user/sh4/vdso-le.so | Bin 2720 -> 2720 bytes
linux-user/sh4/vdso.S | 3 ++-
3 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/linux-user/sh4/vdso-be.so b/linux-user/sh4/vdso-be.so
index bc1fb37e1089b7aa5612da0039e24193b156b3d8..df9fa22efab46bffbb9957af078199639998ea43 100755
GIT binary patch
delta 94
zcmZ1=x<GWo6OqVuQt#KSJ9B!^(@jmb3bB#wuObyE{&>##V)FyW-As%sljpE_2{CX^
vW<4yRzzu^8YbPf%icjWeeZcr*@(0#@#ut+l*u2^Nd@N1<oHuV|d(R92IA0@3
delta 94
zcmZ1=x<GWo6Op!OLQF3#0+d8#l(nNCM8CN5&G7ofAI}+|ZGOPGn~70r@*EZ~p~<X=
u1r)epkYOzY=j232@yYzG4;a5q{=k~g_-t|ln>SlhXr*UW(&mk9@0kI)8X|`P
diff --git a/linux-user/sh4/vdso-le.so b/linux-user/sh4/vdso-le.so
index c1ff560cc165413d7b07aa873225bd92afb8569e..decd674202260f045b646b318ebb0b6daf416651 100755
GIT binary patch
delta 93
zcmZ1=x<GWo6Olh5saKn)T)*7)W8rK!`{(^j`F=Z0{PBeG#pb(=yO|hOCeLK?735@K
uoh)#eTLA{wPEKSLoy^1ffbqxVx2*Y$FDA#b`LUHn_<IEVZ{EoEo*4j_?<GY5
delta 93
zcmZ1=x<GWo6Op|ikGEYj60C8&_)xA>#wX*~i%pXz{&>RpZ1Y{l-As&1lV`H{3bIZX
uILxg8gKHT$CnqwBPUc~K!1!(QTh@HWXOm;u{Md{<Esc#+H*aKn&kO)kh$G_w
diff --git a/linux-user/sh4/vdso.S b/linux-user/sh4/vdso.S
index 1faa665774..290eb498ae 100644
--- a/linux-user/sh4/vdso.S
+++ b/linux-user/sh4/vdso.S
@@ -141,8 +141,9 @@ __kernel_sigreturn:
sigreturn_tramp __NR_sigreturn
endf __kernel_sigreturn
- /* Update CFA base for the rt_sigreturn frame layout. */
+ /* rt_sigreturn frame layout; nop for the same reason as above. */
.cfi_def_cfa_offset RT_SIGFRAME_SC_OFFSET
+ nop
__kernel_rt_sigreturn:
sigreturn_tramp __NR_rt_sigreturn
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 3/8] linux-user/sh4: align the vdso sigreturn trampolines
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
2026-09-25 9:38 ` [PULL 1/8] linux-user/sh4: use the kernel's sigreturn trampoline sequence in the vdso Helge Deller
2026-09-25 9:38 ` [PULL 2/8] linux-user/sh4: fix vdso CFA for rt_sigreturn frames Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 4/8] linux-user: report EBADF for setsockopt()/getsockopt() on a bad fd Helge Deller
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Matt Turner <mattst88@gmail.com>
libunwind's unw_is_signal_frame() reads the trampoline as 32-bit words,
but __kernel_sigreturn is only 2-byte aligned. Align both trampolines
to 4 bytes, as the kernel's vsyscall-sigreturn.S does (with .balign 32).
Signed-off-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/sh4/vdso-be.so | Bin 2720 -> 2724 bytes
linux-user/sh4/vdso-le.so | Bin 2720 -> 2724 bytes
linux-user/sh4/vdso.S | 2 ++
3 files changed, 2 insertions(+)
diff --git a/linux-user/sh4/vdso-be.so b/linux-user/sh4/vdso-be.so
index df9fa22efab46bffbb9957af078199639998ea43..d74a2d78e869d7bc6c531c36d82d6c2b1315287b 100755
GIT binary patch
delta 192
zcmZ1=x<qt>GNZ~w6=&8z3=AxPCgxO#9C@_r)US}NFAa~om)?|aoD?HG|JB4F*9C7d
zFfa%RF);8jFfe2=FtEJY{D5&c6SD?`*W`ID79tFslUWZ7C~(6dLpcNI<Yz2D!TLY|
zq)!=S$>a~L`HXKSC$QNIA<RrpPBe)yOw8N7ku8mxF=Da=monp@$u?Z-jB6&RaH)&V
PWnf@v0h<E>j35dCBc3ya
delta 172
zcmZ1?x<GV-GNZyo6=&8T3=AwkCgxO#M6Q#1zh>Q;(|ew7YO+;`jbwinsW|b+b-`;4
z3=9H73=BLB3=A0z3@k4;KVaO=#H_;LIe8w7g}`Li!vYH2Fvw6o`4!7gupSTq=}`t*
zF!>8>KI4nYDQxya2=kJY{d_D<{hT*%WlLjb44Ev$rOfzavICbo<BG`{T<VN7Cr{uK
F0RTQaF{c0k
diff --git a/linux-user/sh4/vdso-le.so b/linux-user/sh4/vdso-le.so
index decd674202260f045b646b318ebb0b6daf416651..a59c9e5244dbebd709f187028831f0a51a8b0706 100755
GIT binary patch
delta 200
zcmZ1=x<qt>0;9@AMQ7GOEDQ{PCT3QPWaXVH&gBv-40~8xYBG;6g<=1u`xAd$5xl{|
zz#zcDz#zoH!;rzi!0=}CUB=x^Y#Iy<3=CeA=doA_b26|_7C6kU0E6WWoRgojd<W}<
z03HTq1_p*dli#xDGrpM|%VsZ%Y$`)?a%6;mVNk~Ajcm!xj1iMXxs)0IOt$1wXIwKm
TkxN}-E;|E53)CnOV1%*(2DmUT
delta 193
zcmZ1?x<GV-0;9r2MQ7F@EDQ`kCT3QP{0T|D+C1g@<*pwKXS>-y?_bLI+hO95D}vWp
z7#IW?7#M^Yco;Gm7#Ln`zRS3qiA{xpfq}tu@;nv`e%8qXhq)DCuzd1MmhWI)5WvHr
z%)r3#WAaDVe8v}(6WQ!VkxgVsPA-e^_Xzgiyp=7PnK5K?B8Tu~9WDXJACqml)LB=s
YF))0b9LOm=xrR%CbtXFlLkoxp030MX^8f$<
diff --git a/linux-user/sh4/vdso.S b/linux-user/sh4/vdso.S
index 290eb498ae..a66cac7439 100644
--- a/linux-user/sh4/vdso.S
+++ b/linux-user/sh4/vdso.S
@@ -135,6 +135,7 @@ vdso_syscall __vdso_gettimeofday, __NR_gettimeofday
.cfi_offset 24, SC_FPSCR
nop
+ .balign 4
sigreturn_region_start:
__kernel_sigreturn:
@@ -144,6 +145,7 @@ endf __kernel_sigreturn
/* rt_sigreturn frame layout; nop for the same reason as above. */
.cfi_def_cfa_offset RT_SIGFRAME_SC_OFFSET
nop
+ .balign 4
__kernel_rt_sigreturn:
sigreturn_tramp __NR_rt_sigreturn
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 4/8] linux-user: report EBADF for setsockopt()/getsockopt() on a bad fd
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (2 preceding siblings ...)
2026-09-25 9:38 ` [PULL 3/8] linux-user/sh4: align the vdso sigreturn trampolines Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 5/8] linux-user: report EINVAL for a misaligned mincore() start Helge Deller
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Igor Shevlyakov <igor@tachyum.com>
The kernel looks the fd up before validating the rest of the call, so a
negative fd is EBADF whatever else is wrong with the arguments. Several
arms of do_setsockopt()/do_getsockopt() reject optlen or optname and
return without ever reaching the host syscall, so the host never gets to
supply that EBADF and the guest sees the argument error instead:
setsockopt(-1, SOL_TCP, TCP_NODELAY, ptr, 0) EINVAL, want EBADF
setsockopt(-1, 0x4321, 1, ptr, sizeof(int)) ENOPROTOOPT
getsockopt(-1, 0x4321, 1, ptr, &len) EOPNOTSUPP
Caught by glibc's posix/test-errno.
Signed-off-by: Igor Shevlyakov <igor@tachyum.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/syscall.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9f454502cb..e7c9fb33a3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2119,6 +2119,15 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
abi_long ret;
int val;
+ /*
+ * The kernel looks the fd up before it validates anything else, so a bad
+ * fd is EBADF even when the rest of the call is also wrong. Several arms
+ * below reject optlen or optname without ever reaching the host syscall,
+ * and would report that instead.
+ */
+ if (sockfd < 0) {
+ return -TARGET_EBADF;
+ }
switch(level) {
case SOL_TCP:
case SOL_UDP:
@@ -2623,6 +2632,10 @@ static abi_long do_getsockopt(int sockfd, int level, int optname,
int len, val;
socklen_t lv;
+ /* EBADF wins over the argument checks below; see do_setsockopt(). */
+ if (sockfd < 0) {
+ return -TARGET_EBADF;
+ }
switch(level) {
case TARGET_SOL_SOCKET:
level = SOL_SOCKET;
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 5/8] linux-user: report EINVAL for a misaligned mincore() start
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (3 preceding siblings ...)
2026-09-25 9:38 ` [PULL 4/8] linux-user: report EBADF for setsockopt()/getsockopt() on a bad fd Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 6/8] accel/tcg: Set CF_NOIRQ during cpu_exec_step_atomic Helge Deller
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Igor Shevlyakov <igor@tachyum.com>
mincore(2) rejects a misaligned start address before it looks the range
up, so a start that is both misaligned and unmapped is EINVAL. Here
lock_user() runs first and fails, and the call reports ENOMEM instead.
When the range is mapped this changes nothing -- the host syscall
receives the misaligned pointer and answers EINVAL by itself -- which is
why only the unmapped case is visibly wrong.
Caught by glibc's misc/test-errno-linux.
Signed-off-by: Igor Shevlyakov <igor@tachyum.com>
Reviewed-by: Helge Deller <deller@gmx.de>
Signed-off-by: Helge Deller <deller@gmx.de>
---
linux-user/syscall.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e7c9fb33a3..0380691a8b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -13064,7 +13064,17 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_mincore
case TARGET_NR_mincore:
{
- void *a = lock_user(VERIFY_NONE, arg1, arg2, 0);
+ void *a;
+
+ /*
+ * The kernel rejects a misaligned start before it looks the range
+ * up, so a start that is both misaligned and unmapped is EINVAL,
+ * not the ENOMEM that a failing lock_user() would report.
+ */
+ if (arg1 & ~TARGET_PAGE_MASK) {
+ return -TARGET_EINVAL;
+ }
+ a = lock_user(VERIFY_NONE, arg1, arg2, 0);
if (!a) {
return -TARGET_ENOMEM;
}
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 6/8] accel/tcg: Set CF_NOIRQ during cpu_exec_step_atomic
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (4 preceding siblings ...)
2026-09-25 9:38 ` [PULL 5/8] linux-user: report EINVAL for a misaligned mincore() start Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 7/8] target/sh4: Replace TB_FLAG_GUSA_EXCLUSIVE with CF_STEP_ATOMIC Helge Deller
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Richard Henderson <richard.henderson@linaro.org>
Do not go through the effort of grabbing the exclusive lock
only to check for interrupts and exit without making progress.
Cc: qemu-stable@nongnu.org
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
accel/tcg/cpu-exec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 5226cfb765..f4428e9f7b 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -566,7 +566,8 @@ void cpu_exec_step_atomic(CPUState *cpu)
/* Execute in a serial context. */
s.cflags &= ~CF_PARALLEL;
/* After 1 insn, return and release the exclusive lock. */
- s.cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | 1;
+ s.cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_NOIRQ | 1;
+
/*
* No need to check_for_breakpoints here.
* We only arrive in cpu_exec_step_atomic after beginning execution
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 7/8] target/sh4: Replace TB_FLAG_GUSA_EXCLUSIVE with CF_STEP_ATOMIC
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (5 preceding siblings ...)
2026-09-25 9:38 ` [PULL 6/8] accel/tcg: Set CF_NOIRQ during cpu_exec_step_atomic Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 9:38 ` [PULL 8/8] target/sh4: Drop use_exit_tb Helge Deller
2026-09-25 18:52 ` [PULL 0/8] Linux user next patches Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Richard Henderson <richard.henderson@linaro.org>
There was a complex bug with gUSA wherein:
* decode_gusa calls gen_restart_exclusive
* gen_restart_exclusive generates code that sets TB_FLAG_GUSA_EXCLUSIVE
and generates a call to helper_exclusive
* when the code is executed, TB_FLAG_GUSA_EXCLUSIVE is set
* helper_exclusive calls cpu_loop_exit_atomic, this makes cpu_exec exit
with EXCP_ATOMIC
* we go to cpu_loop, we execute cpu_exec_step_atomic
* suppose that exit request is set, cpu_exec_step_atomic does nothing, it
leaves the CPU in the same state as it was before
* we go back to cpu_loop
* suppose that no signal is delivered, so the gUSA is not rewound
* cpu_loop goes to cpu_exec
* there is one difference - now, TB_FLAG_GUSA_EXCLUSIVE is set and it was
clear before - so cpu_exec will not use the TB that calls
helper_exclusive, it will instead use the TB that performs the atomic
operation (both of these TBs have the same PC, they only differ in flags)
* the TB that performs the atomic operation is executed inside cpu_exec
=> race condition
Fix the bug by managing the "are we in cpu_exec_step_atomic" flag
from cpu_exec_step_atomic itself, rather from the translator.
Cc: qemu-stable@nongnu.org
Fixes: 4bfa602bc22 ("target/sh4: Handle user-space atomics")
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
accel/tcg/cpu-exec.c | 3 ++-
include/exec/translation-block.h | 1 +
target/sh4/cpu.h | 6 ++----
target/sh4/translate.c | 34 +++++++++++++++++++++++---------
4 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index f4428e9f7b..5b4bca5084 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -566,7 +566,8 @@ void cpu_exec_step_atomic(CPUState *cpu)
/* Execute in a serial context. */
s.cflags &= ~CF_PARALLEL;
/* After 1 insn, return and release the exclusive lock. */
- s.cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR | CF_NOIRQ | 1;
+ s.cflags |= CF_NO_GOTO_TB | CF_NO_GOTO_PTR |
+ CF_NOIRQ | CF_STEP_ATOMIC | 1;
/*
* No need to check_for_breakpoints here.
diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h
index 40cc699031..7c42c57cca 100644
--- a/include/exec/translation-block.h
+++ b/include/exec/translation-block.h
@@ -84,6 +84,7 @@ struct TranslationBlock {
#define CF_NOIRQ 0x00010000 /* Generate an uninterruptible TB */
#define CF_PCREL 0x00020000 /* Opcodes in TB are PC-relative */
#define CF_BP_PAGE 0x00040000 /* Breakpoint present in code page */
+#define CF_STEP_ATOMIC 0x00080000 /* Running in cpu_exec_step_atomic */
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
#define CF_CLUSTER_SHIFT 24
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 3302702376..6984bb462f 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -84,8 +84,7 @@
#define TB_FLAG_DELAY_SLOT_RTE (1 << 2)
#define TB_FLAG_PENDING_MOVCA (1 << 3)
#define TB_FLAG_GUSA_SHIFT 4 /* [11:4] */
-#define TB_FLAG_GUSA_EXCLUSIVE (1 << 12)
-#define TB_FLAG_UNALIGN (1 << 13)
+#define TB_FLAG_UNALIGN (1 << 12)
#define TB_FLAG_SR_FD (1 << SR_FD) /* 15 */
#define TB_FLAG_FPSCR_PR FPSCR_PR /* 19 */
#define TB_FLAG_FPSCR_SZ FPSCR_SZ /* 20 */
@@ -96,8 +95,7 @@
#define TB_FLAG_DELAY_SLOT_MASK (TB_FLAG_DELAY_SLOT | \
TB_FLAG_DELAY_SLOT_COND | \
TB_FLAG_DELAY_SLOT_RTE)
-#define TB_FLAG_GUSA_MASK ((0xff << TB_FLAG_GUSA_SHIFT) | \
- TB_FLAG_GUSA_EXCLUSIVE)
+#define TB_FLAG_GUSA_MASK (0xff << TB_FLAG_GUSA_SHIFT)
#define TB_FLAG_FPSCR_MASK (TB_FLAG_FPSCR_PR | \
TB_FLAG_FPSCR_SZ | \
TB_FLAG_FPSCR_FR)
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 373950fd66..c15c0802f7 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -47,6 +47,9 @@ typedef struct DisasContext {
uint16_t opcode;
bool has_movcal;
+#ifdef CONFIG_USER_ONLY
+ bool in_gusa_exclusive;
+#endif
} DisasContext;
#if defined(CONFIG_USER_ONLY)
@@ -220,7 +223,11 @@ static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
static inline bool use_exit_tb(DisasContext *ctx)
{
- return (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) != 0;
+#ifdef CONFIG_USER_ONLY
+ return ctx->in_gusa_exclusive;
+#else
+ return false;
+#endif
}
static bool use_goto_tb(DisasContext *ctx, vaddr dest)
@@ -273,7 +280,8 @@ static void gen_conditional_jump(DisasContext *ctx, vaddr dest,
TCGLabel *l1 = gen_new_label();
TCGCond cond_not_taken = jump_if_true ? TCG_COND_EQ : TCG_COND_NE;
- if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
+#ifdef CONFIG_USER_ONLY
+ if (ctx->in_gusa_exclusive) {
/* When in an exclusive region, we must continue to the end.
Therefore, exit the region on a taken branch, but otherwise
fall through to the next instruction. */
@@ -286,6 +294,7 @@ static void gen_conditional_jump(DisasContext *ctx, vaddr dest,
ctx->base.is_jmp = DISAS_NEXT;
return;
}
+#endif
gen_save_cpu_state(ctx, false);
tcg_gen_brcondi_i32(cond_not_taken, cpu_sr_t, 0, l1);
@@ -304,7 +313,8 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
tcg_gen_mov_i32(ds, cpu_delayed_cond);
tcg_gen_discard_i32(cpu_delayed_cond);
- if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
+#ifdef CONFIG_USER_ONLY
+ if (ctx->in_gusa_exclusive) {
/* When in an exclusive region, we must continue to the end.
Therefore, exit the region on a taken branch, but otherwise
fall through to the next instruction. */
@@ -318,6 +328,7 @@ static void gen_delayed_conditional_jump(DisasContext * ctx)
ctx->base.is_jmp = DISAS_NEXT;
return;
}
+#endif
tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);
gen_goto_tb(ctx, 1, ctx->base.pc_next + 2);
@@ -1793,16 +1804,18 @@ static void decode_opc(DisasContext * ctx)
/* go out of the delay slot */
ctx->envflags &= ~TB_FLAG_DELAY_SLOT_MASK;
+#ifdef CONFIG_USER_ONLY
/* When in an exclusive region, we must continue to the end
for conditional branches. */
- if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE
- && old_flags & TB_FLAG_DELAY_SLOT_COND) {
+ if (ctx->in_gusa_exclusive && old_flags & TB_FLAG_DELAY_SLOT_COND) {
gen_delayed_conditional_jump(ctx);
return;
}
+
/* Otherwise this is probably an invalid gUSA region.
Drop the GUSA bits so the next TB doesn't see them. */
ctx->envflags &= ~TB_FLAG_GUSA_MASK;
+#endif
tcg_gen_movi_i32(cpu_flags, ctx->envflags);
if (old_flags & TB_FLAG_DELAY_SLOT_COND) {
@@ -1820,7 +1833,6 @@ static void decode_opc(DisasContext * ctx)
*/
static void gen_restart_exclusive(DisasContext *ctx)
{
- ctx->envflags |= TB_FLAG_GUSA_EXCLUSIVE;
gen_save_cpu_state(ctx, false);
gen_helper_exclusive(tcg_env);
ctx->base.is_jmp = DISAS_NORETURN;
@@ -2208,11 +2220,13 @@ static void sh4_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
int backup = sextract32(ctx->tbflags, TB_FLAG_GUSA_SHIFT, 8);
int max_insns = (pc_end - pc) / 2;
+ ctx->in_gusa_exclusive = ctx->base.tb->cflags & CF_STEP_ATOMIC;
+
if (pc != pc_end + backup || max_insns < 2) {
/* This is a malformed gUSA region. Don't do anything special,
since the interpreter is likely to get confused. */
ctx->envflags &= ~TB_FLAG_GUSA_MASK;
- } else if (tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
+ } else if (ctx->in_gusa_exclusive) {
/* Regardless of single-stepping or the end of the page,
we must complete execution of the gUSA region while
holding the exclusive lock. */
@@ -2246,7 +2260,7 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
#ifdef CONFIG_USER_ONLY
if (unlikely(ctx->envflags & TB_FLAG_GUSA_MASK)
- && !(ctx->envflags & TB_FLAG_GUSA_EXCLUSIVE)) {
+ && !ctx->in_gusa_exclusive) {
/*
* We're in an gUSA region, and we have not already fallen
* back on using an exclusive region. Attempt to parse the
@@ -2276,10 +2290,12 @@ static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *ctx = container_of(dcbase, DisasContext, base);
- if (ctx->tbflags & TB_FLAG_GUSA_EXCLUSIVE) {
+#ifdef CONFIG_USER_ONLY
+ if (ctx->in_gusa_exclusive) {
/* Ending the region of exclusivity. Clear the bits. */
ctx->envflags &= ~TB_FLAG_GUSA_MASK;
}
+#endif
switch (ctx->base.is_jmp) {
case DISAS_STOP:
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PULL 8/8] target/sh4: Drop use_exit_tb
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (6 preceding siblings ...)
2026-09-25 9:38 ` [PULL 7/8] target/sh4: Replace TB_FLAG_GUSA_EXCLUSIVE with CF_STEP_ATOMIC Helge Deller
@ 2026-09-25 9:38 ` Helge Deller
2026-09-25 18:52 ` [PULL 0/8] Linux user next patches Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Helge Deller @ 2026-09-25 9:38 UTC (permalink / raw)
To: qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato,
Richard Henderson, Helge Deller, Laurent Vivier
From: Richard Henderson <richard.henderson@linaro.org>
Rely on cpu_exec_step_atomic setting CF_NO_GOTO_TB and
CF_NO_GOTO_PTR, which will cause exit_tb to be used.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
---
target/sh4/translate.c | 24 ++----------------------
1 file changed, 2 insertions(+), 22 deletions(-)
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index c15c0802f7..5729a757f1 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -221,20 +221,8 @@ static inline void gen_save_cpu_state(DisasContext *ctx, bool save_pc)
}
}
-static inline bool use_exit_tb(DisasContext *ctx)
-{
-#ifdef CONFIG_USER_ONLY
- return ctx->in_gusa_exclusive;
-#else
- return false;
-#endif
-}
-
static bool use_goto_tb(DisasContext *ctx, vaddr dest)
{
- if (use_exit_tb(ctx)) {
- return false;
- }
return translator_use_goto_tb(&ctx->base, dest);
}
@@ -246,11 +234,7 @@ static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx, vaddr dest)
tcg_gen_exit_tb(ctx->base.tb, tb_slot_idx);
} else {
tcg_gen_movi_i32(cpu_pc, dest);
- if (use_exit_tb(ctx)) {
- tcg_gen_exit_tb(NULL, 0);
- } else {
- tcg_gen_lookup_and_goto_ptr();
- }
+ tcg_gen_lookup_and_goto_ptr();
}
ctx->base.is_jmp = DISAS_NORETURN;
}
@@ -262,11 +246,7 @@ static void gen_jump(DisasContext * ctx)
delayed jump as immediate jump are conditinal jumps */
tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
tcg_gen_discard_i32(cpu_delayed_pc);
- if (use_exit_tb(ctx)) {
- tcg_gen_exit_tb(NULL, 0);
- } else {
- tcg_gen_lookup_and_goto_ptr();
- }
+ tcg_gen_lookup_and_goto_ptr();
ctx->base.is_jmp = DISAS_NORETURN;
} else {
gen_goto_tb(ctx, 0, ctx->delayed_pc);
--
2.54.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PULL 0/8] Linux user next patches
2026-09-25 9:38 [PULL 0/8] Linux user next patches Helge Deller
` (7 preceding siblings ...)
2026-09-25 9:38 ` [PULL 8/8] target/sh4: Drop use_exit_tb Helge Deller
@ 2026-09-25 18:52 ` Richard Henderson
8 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2026-09-25 18:52 UTC (permalink / raw)
To: Helge Deller, qemu-devel
Cc: Pierrick Bouvier, Paolo Bonzini, Yoshinori Sato, Helge Deller,
Laurent Vivier
On 9/25/26 02:38, Helge Deller wrote:
> From: Helge Deller<deller@gmx.de>
>
> The following changes since commit a97f90fcf8029af253a2ba274b9bda9acabc5b23:
>
> Merge tag 'pull-tcg-20260924' ofhttps://gitlab.com/rth7680/qemu into staging (2026-09-24 08:24:59 -0700)
>
> are available in the Git repository at:
>
> https://github.com/hdeller/qemu-hppa.git tags/linux-user-next-pull-request
>
> for you to fetch changes up to 926d6cf4036102e3e0bc9e7f92291ee2277c3215:
>
> target/sh4: Drop use_exit_tb (2026-09-25 11:23:44 +0200)
>
> ----------------------------------------------------------------
> linux user patches
>
> A series of patches, which
> - fix a race in atomic variables on sh4 guest
> - fix unwinding through vdso signal trampolines on sh4 guests
> - improve the parameter checks for setsockopt()/getsockopt() syscalls
> - improves the parameter checks for the mincore() syscall
Applied, thanks.
r~
^ permalink raw reply [flat|nested] 10+ messages in thread