include/qemu/atomic.h | 16 ---------------- meson.build | 4 ++-- 2 files changed, 2 insertions(+), 18 deletions(-)
From: Helge Deller <deller@gmx.de>
Qemu's tools like qemu-img are often needed on 32-bit platforms,
although the actual qemu emulators have been discontinued on 32-bit.
To allow building the tools on 32-bit this patch implements two small
changes:
a) The check in meson.build is changed to still error out if the user
tries to build qemu-system or qemu-user on a 32-bit platform, but allows
building tools (e.g. by "--enable-tools") alone.
b) Remove the compile time checks in atomic.h because:
- for the qemu-system and qemu-user emulators this check is redundant
since we only allow 64-bit platforms anyway (see a)
- it breaks those 32-bit platforms, which do provide (slower) 64-bit atomics
- 32-bit platforms without 64-bit atomics will fail instead with linker errors
- the runtime speed of the qemu tools aren't actually that important.
I've sucessfully tested building qemu tools on 32-bit hppa.
Signed-off-by: Helge Deller <deller@gmx.de>
---
include/qemu/atomic.h | 16 ----------------
meson.build | 4 ++--
2 files changed, 2 insertions(+), 18 deletions(-)
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index dc9290084b..f05dce36eb 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -56,14 +56,6 @@
*/
#define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
-/*
- * Sanity check that the size of an atomic operation isn't "overly large".
- * Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
- * want to use them because we ought not need them, and this lets us do a
- * bit of sanity checking that other 32-bit hosts might build.
- */
-#define ATOMIC_REG_SIZE sizeof(void *)
-
/* Weak atomic operations prevent the compiler moving other
* loads/stores past the atomic operation load/store. However there is
* no explicit memory barrier for the processor.
@@ -79,7 +71,6 @@
#define qatomic_read(ptr) \
({ \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
qatomic_read__nocheck(ptr); \
})
@@ -87,7 +78,6 @@
__atomic_store_n(ptr, i, __ATOMIC_RELAXED)
#define qatomic_set(ptr, i) do { \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
qatomic_set__nocheck(ptr, i); \
} while(0)
@@ -110,7 +100,6 @@
*/
#define qatomic_rcu_read_internal(ptr, _val) \
({ \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
typeof_strip_qual(*ptr) _val; \
qatomic_rcu_read__nocheck(ptr, &_val); \
_val; \
@@ -119,20 +108,17 @@
qatomic_rcu_read_internal((ptr), MAKE_IDENTIFIER(_val))
#define qatomic_rcu_set(ptr, i) do { \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
__atomic_store_n(ptr, i, __ATOMIC_RELEASE); \
} while(0)
#define qatomic_load_acquire(ptr) \
({ \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
typeof_strip_qual(*ptr) _val; \
__atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \
_val; \
})
#define qatomic_store_release(ptr, i) do { \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
__atomic_store_n(ptr, i, __ATOMIC_RELEASE); \
} while(0)
@@ -144,7 +130,6 @@
})
#define qatomic_xchg(ptr, i) ({ \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
qatomic_xchg__nocheck(ptr, i); \
})
@@ -157,7 +142,6 @@
})
#define qatomic_cmpxchg(ptr, old, new) ({ \
- qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
qatomic_cmpxchg__nocheck(ptr, old, new); \
})
diff --git a/meson.build b/meson.build
index daa58e46a3..98a708372b 100644
--- a/meson.build
+++ b/meson.build
@@ -323,8 +323,8 @@ endif
# Compiler flags #
##################
-if cc.sizeof('void *') < 8
- error('QEMU requires a 64-bit CPU host architecture')
+if (cc.sizeof('void *') < 8) and (have_system or have_user)
+ error('QEMU emulator requires a 64-bit CPU host architecture. Only tools may be built for 32-bit.')
endif
foreach lang : all_languages
--
2.53.0
On 4/2/26 23:28, Helge Deller wrote: > From: Helge Deller <deller@gmx.de> > > Qemu's tools like qemu-img are often needed on 32-bit platforms, > although the actual qemu emulators have been discontinued on 32-bit. > > To allow building the tools on 32-bit this patch implements two small > changes: > > a) The check in meson.build is changed to still error out if the user > tries to build qemu-system or qemu-user on a 32-bit platform, but allows > building tools (e.g. by "--enable-tools") alone. > > b) Remove the compile time checks in atomic.h because: > - for the qemu-system and qemu-user emulators this check is redundant > since we only allow 64-bit platforms anyway (see a) No it isn't. It double-checks that we don't pass e.g. Int128. > - it breaks those 32-bit platforms, which do provide (slower) 64-bit atomics > - 32-bit platforms without 64-bit atomics will fail instead with linker errors > - the runtime speed of the qemu tools aren't actually that important. Only i686 and armv7 have these. I agree that other 32-bit hosts could fall back to libatomic, but we'd need to actually use it. > I've sucessfully tested building qemu tools on 32-bit hppa. Really? So where does the 64-bit atomic come into it? Was it in code that was compiled but not actually linked? r~
On 04.04.2026 02:10, Richard Henderson wrote: > On 4/2/26 23:28, Helge Deller wrote: >> From: Helge Deller <deller@gmx.de> >> >> Qemu's tools like qemu-img are often needed on 32-bit platforms, >> although the actual qemu emulators have been discontinued on 32-bit. >> >> To allow building the tools on 32-bit this patch implements two small >> changes: >> >> a) The check in meson.build is changed to still error out if the user >> tries to build qemu-system or qemu-user on a 32-bit platform, but allows >> building tools (e.g. by "--enable-tools") alone. >> >> b) Remove the compile time checks in atomic.h because: >> - for the qemu-system and qemu-user emulators this check is redundant >> since we only allow 64-bit platforms anyway (see a) > > No it isn't. It double-checks that we don't pass e.g. Int128. Well. In current qemu 11.0-tobe, this compile test passes already, so there's no code *currently* which pass an Int128 to atomic_read. This concern can be adjusted at the start of 11.1 development cycle, - with a check which has been thought about. Right now we're too close to the release, so more invasive changes is not a good idea. With the current check in place, it's completely impossible to build even the qga on 32bit platform, which is quite a drastic change. >> - it breaks those 32-bit platforms, which do provide (slower) 64-bit >> atomics >> - 32-bit platforms without 64-bit atomics will fail instead with >> linker errors >> - the runtime speed of the qemu tools aren't actually that important. > > Only i686 and armv7 have these. I've built it on most 32bit platforms on debian, including tests. It failed in the end on m68k, powerpc and sh4 becausse I forgot to pass -latomic there. > I agree that other 32-bit hosts could fall back to libatomic, but we'd > need to actually use it. It can be added in --extra-ldflags at the very least, - there's no need to rush for that this late in the release cycle. >> I've sucessfully tested building qemu tools on 32-bit hppa. > > Really? So where does the 64-bit atomic come into it? > Was it in code that was compiled but not actually linked? In my case, it builds qemu-img and qemu-nbd fine, - so there, yes, that code isn't used. But it fails to link qga: ld: libqemuutil.a.p/util_qsp.c.o: undefined reference to symbol '__atomic_load_8@@LIBATOMIC_1.0' ld: /usr/lib/m68k-linux-gnu/libatomic.so.1: error adding symbols: DSO missing from command line maybe that one also isn't needed for qga link, - I saw these results just now, will take a closer look later today. Overall, I think this change (plus my adjustment in util/meson.build) is enough to get going for 11.0, with possible further changes after the reelase. Thanks, /mjt
On 4/4/26 07:46, Michael Tokarev wrote: > On 04.04.2026 02:10, Richard Henderson wrote: >> On 4/2/26 23:28, Helge Deller wrote: >>> From: Helge Deller <deller@gmx.de> >>> >>> Qemu's tools like qemu-img are often needed on 32-bit platforms, >>> although the actual qemu emulators have been discontinued on 32-bit. >>> >>> To allow building the tools on 32-bit this patch implements two small >>> changes: >>> >>> a) The check in meson.build is changed to still error out if the user >>> tries to build qemu-system or qemu-user on a 32-bit platform, but allows >>> building tools (e.g. by "--enable-tools") alone. >>> >>> b) Remove the compile time checks in atomic.h because: >>> - for the qemu-system and qemu-user emulators this check is redundant >>> since we only allow 64-bit platforms anyway (see a) >> >> No it isn't. It double-checks that we don't pass e.g. Int128. > > Well. In current qemu 11.0-tobe, this compile test passes already, so > there's no code *currently* which pass an Int128 to atomic_read. This > concern can be adjusted at the start of 11.1 development cycle, - with > a check which has been thought about. Right now we're too close to the > release, so more invasive changes is not a good idea. > > With the current check in place, it's completely impossible to build > even the qga on 32bit platform, which is quite a drastic change. I've just sent a patch which I think addresses Richard's concerns. It actually implements his suggested fix to check against uint64_t instead. >>> - it breaks those 32-bit platforms, which do provide (slower) 64-bit atomics >>> - 32-bit platforms without 64-bit atomics will fail instead with linker errors >>> - the runtime speed of the qemu tools aren't actually that important. >> >> Only i686 and armv7 have these. > > I've built it on most 32bit platforms on debian, including tests. > It failed in the end on m68k, powerpc and sh4 becausse I forgot to pass > -latomic there. This is fixed in my latest patch as well. I actually tested on powerpc... >> I agree that other 32-bit hosts could fall back to libatomic, but we'd need to actually use it. > > It can be added in --extra-ldflags at the very least, - there's no need > to rush for that this late in the release cycle. > >>> I've sucessfully tested building qemu tools on 32-bit hppa. >> >> Really? So where does the 64-bit atomic come into it? >> Was it in code that was compiled but not actually linked? > > In my case, it builds qemu-img and qemu-nbd fine, - so there, yes, that > code isn't used. > > But it fails to link qga: > > ld: libqemuutil.a.p/util_qsp.c.o: undefined reference to symbol '__atomic_load_8@@LIBATOMIC_1.0' > ld: /usr/lib/m68k-linux-gnu/libatomic.so.1: error adding symbols: DSO missing from command line > > maybe that one also isn't needed for qga link, - I saw these results > just now, will take a closer look later today. Try the patch (v2) I sent... Helge
On 02.04.2026 16:28, Helge Deller wrote:
> From: Helge Deller <deller@gmx.de>
>
> Qemu's tools like qemu-img are often needed on 32-bit platforms,
> although the actual qemu emulators have been discontinued on 32-bit.
>
> To allow building the tools on 32-bit this patch implements two small
> changes:
>
> a) The check in meson.build is changed to still error out if the user
> tries to build qemu-system or qemu-user on a 32-bit platform, but allows
> building tools (e.g. by "--enable-tools") alone.
>
> b) Remove the compile time checks in atomic.h because:
> - for the qemu-system and qemu-user emulators this check is redundant
> since we only allow 64-bit platforms anyway (see a)
> - it breaks those 32-bit platforms, which do provide (slower) 64-bit atomics
> - 32-bit platforms without 64-bit atomics will fail instead with linker errors
> - the runtime speed of the qemu tools aren't actually that important.
>
> I've sucessfully tested building qemu tools on 32-bit hppa.
There's a bit more of this. When building on i386, I'm getting this:
util/cpuinfo-i386.c:15:39: warning: no previous prototype for
‘cpuinfo_init’ [-Wmissing-prototypes]
15 | unsigned __attribute__((constructor)) cpuinfo_init(void)
| ^~~~~~~~~~~~
util/cpuinfo-i386.c: In function ‘cpuinfo_init’:
util/cpuinfo-i386.c:30:33: error: ‘CPUINFO_BMI1’ undeclared (first use
in this function)
30 | info |= (b7 & bit_BMI ? CPUINFO_BMI1 : 0);
| ^~~~~~~~~~~~
util/cpuinfo-i386.c:30:33: note: each undeclared identifier is reported
only once for each function it appears in
util/cpuinfo-i386.c:31:34: error: ‘CPUINFO_BMI2’ undeclared (first use
in this function)
31 | info |= (b7 & bit_BMI2 ? CPUINFO_BMI2 : 0);
...
(this is mentioned in my initial email about this issue).
It's fixed by
https://lore.kernel.org/qemu-devel/20260325134932.765163-1-mjt@tls.msk.ru/
Thanks,
/mjt
On 02.04.2026 16:28, Helge Deller wrote:
> From: Helge Deller <deller@gmx.de>
>
> Qemu's tools like qemu-img are often needed on 32-bit platforms,
> although the actual qemu emulators have been discontinued on 32-bit.
>
> To allow building the tools on 32-bit this patch implements two small
> changes:
>
> a) The check in meson.build is changed to still error out if the user
> tries to build qemu-system or qemu-user on a 32-bit platform, but allows
> building tools (e.g. by "--enable-tools") alone.
>
> b) Remove the compile time checks in atomic.h because:
> - for the qemu-system and qemu-user emulators this check is redundant
> since we only allow 64-bit platforms anyway (see a)
> - it breaks those 32-bit platforms, which do provide (slower) 64-bit atomics
> - 32-bit platforms without 64-bit atomics will fail instead with linker errors
> - the runtime speed of the qemu tools aren't actually that important.
>
> I've sucessfully tested building qemu tools on 32-bit hppa.
I think this makes very good sense indeed, and is an excellent idea.
Atomics don't really mean much outside of qemu/tcg proper, all other
their usages aren't performance critical.
Also, atomics aren't actually used (much) in tools or the guest agent
(which is another problematic part of qemu), but are linked in indirectly
because of other interdependencies in source files.
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
And it looks like this one can go to 11.0 just fine.
Thank you very much!
/mjt
> Signed-off-by: Helge Deller <deller@gmx.de>
> ---
> include/qemu/atomic.h | 16 ----------------
> meson.build | 4 ++--
> 2 files changed, 2 insertions(+), 18 deletions(-)
>
> diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
> index dc9290084b..f05dce36eb 100644
> --- a/include/qemu/atomic.h
> +++ b/include/qemu/atomic.h
> @@ -56,14 +56,6 @@
> */
> #define signal_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
>
> -/*
> - * Sanity check that the size of an atomic operation isn't "overly large".
> - * Despite the fact that e.g. i686 has 64-bit atomic operations, we do not
> - * want to use them because we ought not need them, and this lets us do a
> - * bit of sanity checking that other 32-bit hosts might build.
> - */
> -#define ATOMIC_REG_SIZE sizeof(void *)
> -
> /* Weak atomic operations prevent the compiler moving other
> * loads/stores past the atomic operation load/store. However there is
> * no explicit memory barrier for the processor.
> @@ -79,7 +71,6 @@
>
> #define qatomic_read(ptr) \
> ({ \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> qatomic_read__nocheck(ptr); \
> })
>
> @@ -87,7 +78,6 @@
> __atomic_store_n(ptr, i, __ATOMIC_RELAXED)
>
> #define qatomic_set(ptr, i) do { \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> qatomic_set__nocheck(ptr, i); \
> } while(0)
>
> @@ -110,7 +100,6 @@
> */
> #define qatomic_rcu_read_internal(ptr, _val) \
> ({ \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> typeof_strip_qual(*ptr) _val; \
> qatomic_rcu_read__nocheck(ptr, &_val); \
> _val; \
> @@ -119,20 +108,17 @@
> qatomic_rcu_read_internal((ptr), MAKE_IDENTIFIER(_val))
>
> #define qatomic_rcu_set(ptr, i) do { \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \
> } while(0)
>
> #define qatomic_load_acquire(ptr) \
> ({ \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> typeof_strip_qual(*ptr) _val; \
> __atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \
> _val; \
> })
>
> #define qatomic_store_release(ptr, i) do { \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \
> } while(0)
>
> @@ -144,7 +130,6 @@
> })
>
> #define qatomic_xchg(ptr, i) ({ \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> qatomic_xchg__nocheck(ptr, i); \
> })
>
> @@ -157,7 +142,6 @@
> })
>
> #define qatomic_cmpxchg(ptr, old, new) ({ \
> - qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
> qatomic_cmpxchg__nocheck(ptr, old, new); \
> })
>
> diff --git a/meson.build b/meson.build
> index daa58e46a3..98a708372b 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -323,8 +323,8 @@ endif
> # Compiler flags #
> ##################
>
> -if cc.sizeof('void *') < 8
> - error('QEMU requires a 64-bit CPU host architecture')
> +if (cc.sizeof('void *') < 8) and (have_system or have_user)
> + error('QEMU emulator requires a 64-bit CPU host architecture. Only tools may be built for 32-bit.')
> endif
>
> foreach lang : all_languages
© 2016 - 2026 Red Hat, Inc.