* [PULL 0/9] tcg/linux-user/fpu patch queue
@ 2025-07-11 17:22 Richard Henderson
2025-07-11 17:22 ` [PULL 1/9] fpu: Process float_muladd_negate_result after rounding Richard Henderson
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel
The following changes since commit df6fe2abf2e990f767ce755d426bc439c7bba336:
Merge tag 'pull-target-arm-20250704' of https://gitlab.com/pm215/qemu into staging (2025-07-07 09:22:41 -0400)
are available in the Git repository at:
https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20250711
for you to fetch changes up to d6390204c61e148488f034d1f79be35cd3318d93:
linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC (2025-07-11 10:45:14 -0600)
----------------------------------------------------------------
fpu: Process float_muladd_negate_result after rounding
tcg: Use uintptr_t in tcg_malloc implementation
linux-user: Hold the fd-trans lock across fork
linux-user: Implement fchmodat2 syscall
linux-user: Check for EFAULT failure in nanosleep
linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC
linux-user/gen-vdso: Handle fseek() failure
linux-user/gen-vdso: Don't read off the end of buf[]
----------------------------------------------------------------
Geoffrey Thomas (1):
linux-user: Hold the fd-trans lock across fork
Peter Maydell (5):
linux-user: Implement fchmodat2 syscall
linux-user: Check for EFAULT failure in nanosleep
linux-user/gen-vdso: Handle fseek() failure
linux-user/gen-vdso: Don't read off the end of buf[]
linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC
Richard Henderson (2):
fpu: Process float_muladd_negate_result after rounding
tcg: Use uintptr_t in tcg_malloc implementation
Thomas Weißschuh (1):
linux-user/mips/o32: Drop sa_restorer functionality
include/tcg/tcg.h | 6 ++---
linux-user/fd-trans.h | 10 +++++++
linux-user/mips/target_signal.h | 1 -
linux-user/syscall_defs.h | 4 ---
fpu/softfloat.c | 54 ++++++++++++++++++++++++++++++-------
linux-user/gen-vdso.c | 16 +++++++++--
linux-user/main.c | 2 ++
linux-user/syscall.c | 26 ++++++++++++++----
tcg/tcg.c | 9 ++++---
tests/tcg/multiarch/fnmsub.c | 37 +++++++++++++++++++++++++
fpu/softfloat-parts.c.inc | 4 ---
tests/tcg/multiarch/Makefile.target | 1 +
12 files changed, 137 insertions(+), 33 deletions(-)
create mode 100644 tests/tcg/multiarch/fnmsub.c
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PULL 1/9] fpu: Process float_muladd_negate_result after rounding
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 2/9] linux-user: Implement fchmodat2 syscall Richard Henderson
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: WANG Rui, Philippe Mathieu-Daudé
Changing the sign before rounding affects the correctness of
the asymmetric rouding modes: float_round_up and float_round_down.
Reported-by: WANG Rui <wangrui@loongson.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
fpu/softfloat.c | 54 +++++++++++++++++++++++------
tests/tcg/multiarch/fnmsub.c | 37 ++++++++++++++++++++
fpu/softfloat-parts.c.inc | 4 ---
tests/tcg/multiarch/Makefile.target | 1 +
4 files changed, 82 insertions(+), 14 deletions(-)
create mode 100644 tests/tcg/multiarch/fnmsub.c
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 34c962d6bd..8094358c2e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1731,11 +1731,8 @@ static float64 float64_round_pack_canonical(FloatParts64 *p,
return float64_pack_raw(p);
}
-static float64 float64r32_round_pack_canonical(FloatParts64 *p,
- float_status *s)
+static float64 float64r32_pack_raw(FloatParts64 *p)
{
- parts_uncanon(p, s, &float32_params);
-
/*
* In parts_uncanon, we placed the fraction for float32 at the lsb.
* We need to adjust the fraction higher so that the least N bits are
@@ -1776,6 +1773,13 @@ static float64 float64r32_round_pack_canonical(FloatParts64 *p,
return float64_pack_raw(p);
}
+static float64 float64r32_round_pack_canonical(FloatParts64 *p,
+ float_status *s)
+{
+ parts_uncanon(p, s, &float32_params);
+ return float64r32_pack_raw(p);
+}
+
static void float128_unpack_canonical(FloatParts128 *p, float128 f,
float_status *s)
{
@@ -2240,7 +2244,12 @@ float16_muladd_scalbn(float16 a, float16 b, float16 c,
float16_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
- return float16_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &float16_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return float16_pack_raw(pr);
}
float16 float16_muladd(float16 a, float16 b, float16 c,
@@ -2260,7 +2269,12 @@ float32_muladd_scalbn(float32 a, float32 b, float32 c,
float32_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
- return float32_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &float32_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return float32_pack_raw(pr);
}
float64 QEMU_SOFTFLOAT_ATTR
@@ -2274,7 +2288,12 @@ float64_muladd_scalbn(float64 a, float64 b, float64 c,
float64_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, scale, flags, status);
- return float64_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &float64_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return float64_pack_raw(pr);
}
static bool force_soft_fma;
@@ -2428,7 +2447,12 @@ float64 float64r32_muladd(float64 a, float64 b, float64 c,
float64_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
- return float64r32_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &float32_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return float64r32_pack_raw(pr);
}
bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
@@ -2441,7 +2465,12 @@ bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
bfloat16_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
- return bfloat16_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &bfloat16_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return bfloat16_pack_raw(pr);
}
float128 QEMU_FLATTEN float128_muladd(float128 a, float128 b, float128 c,
@@ -2454,7 +2483,12 @@ float128 QEMU_FLATTEN float128_muladd(float128 a, float128 b, float128 c,
float128_unpack_canonical(&pc, c, status);
pr = parts_muladd_scalbn(&pa, &pb, &pc, 0, flags, status);
- return float128_round_pack_canonical(pr, status);
+ /* Round before applying negate result. */
+ parts_uncanon(pr, status, &float128_params);
+ if ((flags & float_muladd_negate_result) && !is_nan(pr->cls)) {
+ pr->sign ^= 1;
+ }
+ return float128_pack_raw(pr);
}
/*
diff --git a/tests/tcg/multiarch/fnmsub.c b/tests/tcg/multiarch/fnmsub.c
new file mode 100644
index 0000000000..15dd41d3bd
--- /dev/null
+++ b/tests/tcg/multiarch/fnmsub.c
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <stdio.h>
+#include <math.h>
+#include <fenv.h>
+
+union U {
+ double d;
+ unsigned long long l;
+};
+
+union U x = { .l = 0x4ff0000000000000ULL };
+union U y = { .l = 0x2ff0000000000000ULL };
+union U r;
+
+int main()
+{
+#ifdef FE_DOWNWARD
+ fesetround(FE_DOWNWARD);
+
+#if defined(__loongarch__)
+ asm("fnmsub.d %0, %1, %1, %2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__powerpc64__)
+ asm("fnmsub %0,%1,%1,%2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__s390x__) && 0 /* need -march=z14 */
+ asm("vfnms %0,%1,%1,%2,0,3" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#else
+ r.d = -fma(x.d, x.d, -y.d);
+#endif
+
+ if (r.l != 0xdfefffffffffffffULL) {
+ printf("r = %.18a (%016llx)\n", r.d, r.l);
+ return 1;
+ }
+#endif
+ return 0;
+}
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 171bfd06e3..5e0438fc0b 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -708,10 +708,6 @@ static FloatPartsN *partsN(muladd_scalbn)(FloatPartsN *a, FloatPartsN *b,
return_normal:
a->exp += scale;
finish_sign:
- if (flags & float_muladd_negate_result) {
- a->sign ^= 1;
- }
-
/*
* All result types except for "return the default NaN
* because this is an Invalid Operation" go through here;
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 45c9cfe18c..bfdf7197a7 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -29,6 +29,7 @@ run-float_%: float_%
$(call run-test,$<, $(QEMU) $(QEMU_OPTS) $<)
$(call conditional-diff-out,$<,$(SRC_PATH)/tests/tcg/$(TARGET_NAME)/$<.ref)
+fnmsub: LDFLAGS+=-lm
testthread: LDFLAGS+=-lpthread
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 2/9] linux-user: Implement fchmodat2 syscall
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
2025-07-11 17:22 ` [PULL 1/9] fpu: Process float_muladd_negate_result after rounding Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 3/9] linux-user: Check for EFAULT failure in nanosleep Richard Henderson
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Philippe Mathieu-Daudé
From: Peter Maydell <peter.maydell@linaro.org>
The fchmodat2 syscall is new from Linux 6.6; it is like the
existing fchmodat syscall except that it takes a flags parameter.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3019
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250710113123.1109461-1-peter.maydell@linaro.org>
---
linux-user/syscall.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fc37028597..e1b1476936 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -790,6 +790,10 @@ safe_syscall6(ssize_t, copy_file_range, int, infd, loff_t *, pinoff,
int, outfd, loff_t *, poutoff, size_t, length,
unsigned int, flags)
#endif
+#if defined(TARGET_NR_fchmodat2) && defined(__NR_fchmodat2)
+safe_syscall4(int, fchmodat2, int, dfd, const char *, filename,
+ unsigned short, mode, unsigned int, flags)
+#endif
/* We do ioctl like this rather than via safe_syscall3 to preserve the
* "third argument might be integer or pointer or not present" behaviour of
@@ -10713,6 +10717,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
ret = get_errno(fchmodat(arg1, p, arg3, 0));
unlock_user(p, arg2, 0);
return ret;
+#endif
+#if defined(TARGET_NR_fchmodat2) && defined(__NR_fchmodat2)
+ case TARGET_NR_fchmodat2:
+ if (!(p = lock_user_string(arg2))) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(safe_fchmodat2(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
+ return ret;
#endif
case TARGET_NR_getpriority:
/* Note that negative values are valid for getpriority, so we must
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 3/9] linux-user: Check for EFAULT failure in nanosleep
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
2025-07-11 17:22 ` [PULL 1/9] fpu: Process float_muladd_negate_result after rounding Richard Henderson
2025-07-11 17:22 ` [PULL 2/9] linux-user: Implement fchmodat2 syscall Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 4/9] linux-user/gen-vdso: Handle fseek() failure Richard Henderson
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
target_to_host_timespec() returns an error if the memory the guest
passed us isn't actually readable. We check for this everywhere
except the callsite in the TARGET_NR_nanosleep case, so this mistake
was caught by a Coverity heuristic.
Add the missing error checks to the calls that convert between the
host and target timespec structs.
Coverity: CID 1507104
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250710164355.1296648-1-peter.maydell@linaro.org>
---
linux-user/syscall.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index e1b1476936..38dd563166 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -11643,10 +11643,14 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
case TARGET_NR_nanosleep:
{
struct timespec req, rem;
- target_to_host_timespec(&req, arg1);
+ if (target_to_host_timespec(&req, arg1)) {
+ return -TARGET_EFAULT;
+ }
ret = get_errno(safe_nanosleep(&req, &rem));
if (is_error(ret) && arg2) {
- host_to_target_timespec(arg2, &rem);
+ if (host_to_target_timespec(arg2, &rem)) {
+ return -TARGET_EFAULT;
+ }
}
}
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 4/9] linux-user/gen-vdso: Handle fseek() failure
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (2 preceding siblings ...)
2025-07-11 17:22 ` [PULL 3/9] linux-user: Check for EFAULT failure in nanosleep Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 5/9] linux-user/gen-vdso: Don't read off the end of buf[] Richard Henderson
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
Coverity points out that we don't check for fseek() failure in gen-vdso.c,
and so we might pass -1 to malloc(). Add the error checking.
(This is a standalone executable that doesn't link against glib, so
we can't do the easy thing and use g_file_get_contents().)
Coverity: CID 1523742
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250710170707.1299926-2-peter.maydell@linaro.org>
---
linux-user/gen-vdso.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/linux-user/gen-vdso.c b/linux-user/gen-vdso.c
index fce9d5cbc3..1c406d1b10 100644
--- a/linux-user/gen-vdso.c
+++ b/linux-user/gen-vdso.c
@@ -113,9 +113,16 @@ int main(int argc, char **argv)
* We expect the vdso to be small, on the order of one page,
* therefore we do not expect a partial read.
*/
- fseek(inf, 0, SEEK_END);
+ if (fseek(inf, 0, SEEK_END) < 0) {
+ goto perror_inf;
+ }
total_len = ftell(inf);
- fseek(inf, 0, SEEK_SET);
+ if (total_len < 0) {
+ goto perror_inf;
+ }
+ if (fseek(inf, 0, SEEK_SET) < 0) {
+ goto perror_inf;
+ }
buf = malloc(total_len);
if (buf == NULL) {
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 5/9] linux-user/gen-vdso: Don't read off the end of buf[]
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (3 preceding siblings ...)
2025-07-11 17:22 ` [PULL 4/9] linux-user/gen-vdso: Handle fseek() failure Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 6/9] linux-user/mips/o32: Drop sa_restorer functionality Richard Henderson
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
From: Peter Maydell <peter.maydell@linaro.org>
In gen-vdso we load in a file and assume it's a valid ELF file. In
particular we assume it's big enough to be able to read the ELF
information in e_ident in the ELF header.
Add a check that the total file length is at least big enough for all
the e_ident bytes, which is good enough for the code in gen-vdso.c.
This will catch the most obvious possible bad input file (truncated)
and allow us to run the sanity checks like "not actually an ELF file"
without potentially crashing.
The code in elf32_process() and elf64_process() still makes
assumptions about the file being well-formed, but this is OK because
we only run it on the vdso binaries that we create ourselves in the
build process by running the compiler.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250710170707.1299926-3-peter.maydell@linaro.org>
---
linux-user/gen-vdso.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/linux-user/gen-vdso.c b/linux-user/gen-vdso.c
index 1c406d1b10..aeaa927db8 100644
--- a/linux-user/gen-vdso.c
+++ b/linux-user/gen-vdso.c
@@ -124,6 +124,11 @@ int main(int argc, char **argv)
goto perror_inf;
}
+ if (total_len < EI_NIDENT) {
+ fprintf(stderr, "%s: file too small (truncated?)\n", inf_name);
+ return EXIT_FAILURE;
+ }
+
buf = malloc(total_len);
if (buf == NULL) {
goto perror_inf;
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 6/9] linux-user/mips/o32: Drop sa_restorer functionality
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (4 preceding siblings ...)
2025-07-11 17:22 ` [PULL 5/9] linux-user/gen-vdso: Don't read off the end of buf[] Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 7/9] linux-user: Hold the fd-trans lock across fork Richard Henderson
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Weißschuh, Philippe Mathieu-Daudé
From: Thomas Weißschuh <thomas@t-8ch.de>
The Linux kernel dropped support for sa_restorer on O32 MIPS in the
release 2.5.48 because it was unused. See the comment in
arch/mips/include/uapi/asm/signal.h.
Applications using the kernels UAPI headers will not reserve enough
space for qemu-user to copy the sigaction.sa_restorer field to.
Unrelated data may be overwritten.
Align qemu-user with the kernel by also dropping sa_restorer support.
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250709-mips-sa-restorer-v1-1-fc17120e4afe@t-8ch.de>
---
linux-user/mips/target_signal.h | 1 -
linux-user/syscall_defs.h | 4 ----
2 files changed, 5 deletions(-)
diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
index fa542c1f4e..4481426b99 100644
--- a/linux-user/mips/target_signal.h
+++ b/linux-user/mips/target_signal.h
@@ -64,7 +64,6 @@ typedef struct target_sigaltstack {
#define TARGET_SA_NODEFER 0x40000000
#define TARGET_SA_RESTART 0x10000000
#define TARGET_SA_RESETHAND 0x80000000
-#define TARGET_SA_RESTORER 0x04000000 /* Only for O32 */
#define TARGET_MINSIGSTKSZ 2048
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 5d22759992..df26a2d28f 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -515,10 +515,6 @@ struct target_sigaction {
abi_ulong _sa_handler;
#endif
target_sigset_t sa_mask;
-#ifdef TARGET_ARCH_HAS_SA_RESTORER
- /* ??? This is always present, but ignored unless O32. */
- abi_ulong sa_restorer;
-#endif
};
#else
struct target_old_sigaction {
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 7/9] linux-user: Hold the fd-trans lock across fork
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (5 preceding siblings ...)
2025-07-11 17:22 ` [PULL 6/9] linux-user/mips/o32: Drop sa_restorer functionality Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 8/9] tcg: Use uintptr_t in tcg_malloc implementation Richard Henderson
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Geoffrey Thomas, qemu-stable
From: Geoffrey Thomas <geofft@ldpreload.com>
If another thread is holding target_fd_trans_lock during a fork,
then the lock becomes permanently locked in the child and the
emulator deadlocks at the next interaction with the fd-trans table.
As with other locks, acquire the lock in fork_start() and release
it in fork_end().
Cc: qemu-stable@nongnu.org
Signed-off-by: Geoffrey Thomas <geofft@ldpreload.com>
Fixes: c093364f4d91 "fd-trans: Fix race condition on reallocation of the translation table."
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2846
Buglink: https://github.com/astral-sh/uv/issues/6105
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250314124742.4965-1-geofft@ldpreload.com>
---
linux-user/fd-trans.h | 10 ++++++++++
linux-user/main.c | 2 ++
2 files changed, 12 insertions(+)
diff --git a/linux-user/fd-trans.h b/linux-user/fd-trans.h
index 910faaf237..e14f96059c 100644
--- a/linux-user/fd-trans.h
+++ b/linux-user/fd-trans.h
@@ -36,6 +36,16 @@ static inline void fd_trans_init(void)
qemu_mutex_init(&target_fd_trans_lock);
}
+static inline void fd_trans_prefork(void)
+{
+ qemu_mutex_lock(&target_fd_trans_lock);
+}
+
+static inline void fd_trans_postfork(void)
+{
+ qemu_mutex_unlock(&target_fd_trans_lock);
+}
+
static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd)
{
if (fd < 0) {
diff --git a/linux-user/main.c b/linux-user/main.c
index a9142ee726..f4f2007439 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,12 +149,14 @@ void fork_start(void)
cpu_list_lock();
qemu_plugin_user_prefork_lock();
gdbserver_fork_start();
+ fd_trans_prefork();
}
void fork_end(pid_t pid)
{
bool child = pid == 0;
+ fd_trans_postfork();
qemu_plugin_user_postfork(child);
mmap_fork_end(child);
if (child) {
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 8/9] tcg: Use uintptr_t in tcg_malloc implementation
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (6 preceding siblings ...)
2025-07-11 17:22 ` [PULL 7/9] linux-user: Hold the fd-trans lock across fork Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-11 17:22 ` [PULL 9/9] linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC Richard Henderson
2025-07-13 7:06 ` [PULL 0/9] tcg/linux-user/fpu patch queue Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Ilya Leoshkevich, Philippe Mathieu-Daudé
Avoid ubsan failure with clang-20,
tcg.h:715:19: runtime error: applying non-zero offset 64 to null pointer
by not using pointers.
Acked-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg.h | 6 +++---
tcg/tcg.c | 9 +++++----
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 125323f153..0c2a319c11 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -357,7 +357,7 @@ static inline TCGRegSet output_pref(const TCGOp *op, unsigned i)
}
struct TCGContext {
- uint8_t *pool_cur, *pool_end;
+ uintptr_t pool_cur, pool_end;
TCGPool *pool_first, *pool_current, *pool_first_large;
int nb_labels;
int nb_globals;
@@ -706,7 +706,7 @@ size_t tcg_nb_tbs(void);
static inline void *tcg_malloc(int size)
{
TCGContext *s = tcg_ctx;
- uint8_t *ptr, *ptr_end;
+ uintptr_t ptr, ptr_end;
/* ??? This is a weak placeholder for minimum malloc alignment. */
size = QEMU_ALIGN_UP(size, 8);
@@ -717,7 +717,7 @@ static inline void *tcg_malloc(int size)
return tcg_malloc_internal(tcg_ctx, size);
} else {
s->pool_cur = ptr_end;
- return ptr;
+ return (void *)ptr;
}
}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 50d40b9cbe..afac55a203 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1331,8 +1331,9 @@ void *tcg_malloc_internal(TCGContext *s, int size)
p = s->pool_current;
if (!p) {
p = s->pool_first;
- if (!p)
+ if (!p) {
goto new_pool;
+ }
} else {
if (!p->next) {
new_pool:
@@ -1351,8 +1352,8 @@ void *tcg_malloc_internal(TCGContext *s, int size)
}
}
s->pool_current = p;
- s->pool_cur = p->data + size;
- s->pool_end = p->data + p->size;
+ s->pool_cur = (uintptr_t)p->data + size;
+ s->pool_end = (uintptr_t)p->data + p->size;
return p->data;
}
@@ -1364,7 +1365,7 @@ void tcg_pool_reset(TCGContext *s)
g_free(p);
}
s->pool_first_large = NULL;
- s->pool_cur = s->pool_end = NULL;
+ s->pool_cur = s->pool_end = 0;
s->pool_current = NULL;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PULL 9/9] linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (7 preceding siblings ...)
2025-07-11 17:22 ` [PULL 8/9] tcg: Use uintptr_t in tcg_malloc implementation Richard Henderson
@ 2025-07-11 17:22 ` Richard Henderson
2025-07-13 7:06 ` [PULL 0/9] tcg/linux-user/fpu patch queue Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2025-07-11 17:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell, Daniel P . Berrangé
From: Peter Maydell <peter.maydell@linaro.org>
In the linux-user do_fork() function we try to set the FD_CLOEXEC
flag on a pidfd like this:
fcntl(pid_fd, F_SETFD, fcntl(pid_fd, F_GETFL) | FD_CLOEXEC);
This has two problems:
(1) it doesn't check errors, which Coverity complains about
(2) we use F_GETFL when we mean F_GETFD
Deal with both of these problems by using qemu_set_cloexec() instead.
That function will assert() if the fcntls fail, which is fine (we are
inside fork_start()/fork_end() so we know nothing can mess around
with our file descriptors here, and we just got this one from
pidfd_open()).
(As we are touching the if() statement here, we correct the
indentation.)
Coverity: CID 1508111
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250711141217.1429412-1-peter.maydell@linaro.org>
---
linux-user/syscall.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 38dd563166..91360a072c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6747,10 +6747,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
int pid_child = ret;
pid_fd = pidfd_open(pid_child, 0);
if (pid_fd >= 0) {
- fcntl(pid_fd, F_SETFD, fcntl(pid_fd, F_GETFL)
- | FD_CLOEXEC);
+ qemu_set_cloexec(pid_fd);
} else {
- pid_fd = 0;
+ pid_fd = 0;
}
#endif
put_user_u32(pid_fd, parent_tidptr);
--
2.43.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PULL 0/9] tcg/linux-user/fpu patch queue
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
` (8 preceding siblings ...)
2025-07-11 17:22 ` [PULL 9/9] linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC Richard Henderson
@ 2025-07-13 7:06 ` Stefan Hajnoczi
9 siblings, 0 replies; 11+ messages in thread
From: Stefan Hajnoczi @ 2025-07-13 7:06 UTC (permalink / raw)
To: Richard Henderson; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/10.1 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2025-07-13 7:11 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 17:22 [PULL 0/9] tcg/linux-user/fpu patch queue Richard Henderson
2025-07-11 17:22 ` [PULL 1/9] fpu: Process float_muladd_negate_result after rounding Richard Henderson
2025-07-11 17:22 ` [PULL 2/9] linux-user: Implement fchmodat2 syscall Richard Henderson
2025-07-11 17:22 ` [PULL 3/9] linux-user: Check for EFAULT failure in nanosleep Richard Henderson
2025-07-11 17:22 ` [PULL 4/9] linux-user/gen-vdso: Handle fseek() failure Richard Henderson
2025-07-11 17:22 ` [PULL 5/9] linux-user/gen-vdso: Don't read off the end of buf[] Richard Henderson
2025-07-11 17:22 ` [PULL 6/9] linux-user/mips/o32: Drop sa_restorer functionality Richard Henderson
2025-07-11 17:22 ` [PULL 7/9] linux-user: Hold the fd-trans lock across fork Richard Henderson
2025-07-11 17:22 ` [PULL 8/9] tcg: Use uintptr_t in tcg_malloc implementation Richard Henderson
2025-07-11 17:22 ` [PULL 9/9] linux-user: Use qemu_set_cloexec() to mark pidfd as FD_CLOEXEC Richard Henderson
2025-07-13 7:06 ` [PULL 0/9] tcg/linux-user/fpu patch queue Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).