[PATCH] linux-user/sh4: allow full 32-bit address space

Laurent Vivier posted 1 patch 2 months ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260727114848.1041856-1-laurent@vivier.eu
Maintainers: Laurent Vivier <laurent@vivier.eu>, Helge Deller <deller@gmx.de>, Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>, Yoshinori Sato <yoshinori.sato@nifty.com>
linux-user/sh4/target_mman.h | 2 +-
target/sh4/cpu-param.h       | 6 +-----
2 files changed, 2 insertions(+), 6 deletions(-)
[PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Laurent Vivier 2 months ago
On real SH4 hardware, the address space is split between user mode
(U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.

However, qemu-user does not emulate the MMU, so this limit is not needed.
The only effect is to restrict reserved_va to 2 GB, causing OOM failures
for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).

Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
of 1u to avoid undefined behavior when shifting by 32.

Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
 linux-user/sh4/target_mman.h | 2 +-
 target/sh4/cpu-param.h       | 6 +-----
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
index dd9016081e9f..2d05837c2f36 100644
--- a/linux-user/sh4/target_mman.h
+++ b/linux-user/sh4/target_mman.h
@@ -1,6 +1,6 @@
 /* arch/sh/include/asm/processor_32.h */
 #define TASK_UNMAPPED_BASE \
-    TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
+    TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
 
 /* arch/sh/include/asm/elf.h */
 #define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
diff --git a/target/sh4/cpu-param.h b/target/sh4/cpu-param.h
index c3b8114e538b..d95827078260 100644
--- a/target/sh4/cpu-param.h
+++ b/target/sh4/cpu-param.h
@@ -9,10 +9,6 @@
 #define SH4_CPU_PARAM_H
 
 #define TARGET_PAGE_BITS 12  /* 4k */
-#ifdef CONFIG_USER_ONLY
-# define TARGET_VIRT_ADDR_SPACE_BITS 31
-#else
-# define TARGET_VIRT_ADDR_SPACE_BITS 32
-#endif
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
 
 #endif
-- 
2.54.0
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Michael Tokarev 1 month, 4 weeks ago
On 7/27/26 14:48, Laurent Vivier wrote:
> On real SH4 hardware, the address space is split between user mode
> (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
> so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
> 
> However, qemu-user does not emulate the MMU, so this limit is not needed.
> The only effect is to restrict reserved_va to 2 GB, causing OOM failures
> for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
> 
> Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
> 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
> of 1u to avoid undefined behavior when shifting by 32.

Should I pick this one for the stable series too?  So it will find its
way to debian too, for example, so sh4 buildd(s) will feel a bit better? :)

Thanks,

/mjt
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by John Paul Adrian Glaubitz 1 month, 4 weeks ago
Hi Michael,

On Thu, 2026-07-30 at 09:45 +0300, Michael Tokarev wrote:
> On 7/27/26 14:48, Laurent Vivier wrote:
> > On real SH4 hardware, the address space is split between user mode
> > (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
> > so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
> > 
> > However, qemu-user does not emulate the MMU, so this limit is not needed.
> > The only effect is to restrict reserved_va to 2 GB, causing OOM failures
> > for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
> > 
> > Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
> > 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
> > of 1u to avoid undefined behavior when shifting by 32.
> 
> Should I pick this one for the stable series too?  So it will find its
> way to debian too, for example, so sh4 buildd(s) will feel a bit better? :)

Yes, please. I have already built local packages with the patch that I am going
to deploy on the buildds once they have finished building the current queue.

If the patch is part of the official package, I don't risk accidentally removing
the patched package again with a future update.

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Richard Henderson 2 months ago
On 7/27/26 04:48, Laurent Vivier wrote:
> On real SH4 hardware, the address space is split between user mode
> (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
> so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
> 
> However, qemu-user does not emulate the MMU, so this limit is not needed.
> The only effect is to restrict reserved_va to 2 GB, causing OOM failures
> for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
> 
> Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
> 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
> of 1u to avoid undefined behavior when shifting by 32.
> 
> Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   linux-user/sh4/target_mman.h | 2 +-
>   target/sh4/cpu-param.h       | 6 +-----
>   2 files changed, 2 insertions(+), 6 deletions(-)

So, the goal is to run things under qemu-linux-user that can't run on hardware?

I'm not necessarily opposed, though there have been software systems that know that the 
upper bit is unused and reuse it for tagged pointers.  Emacs did so, sometime last 
century.  I'm sure there were others.  Anyway that's the reason we currently limit 
qemu-linux-user like the hardware does.

If you're going to drop that, you might do this for all targets:

mips/cpu-param.h:#  define TARGET_VIRT_ADDR_SPACE_BITS 31
sh4/cpu-param.h:# define TARGET_VIRT_ADDR_SPACE_BITS 31
xtensa/cpu-param.h:#define TARGET_VIRT_ADDR_SPACE_BITS 30



r~
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Philippe Mathieu-Daudé 2 months ago
Hi Laurent,

On 27/7/26 18:51, Richard Henderson wrote:
> On 7/27/26 04:48, Laurent Vivier wrote:
>> On real SH4 hardware, the address space is split between user mode
>> (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 
>> 0x80000000-0xffffffff),
>> so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
>>
>> However, qemu-user does not emulate the MMU, so this limit is not needed.

             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [*]

>> The only effect is to restrict reserved_va to 2 GB, causing OOM failures
>> for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
>>
>> Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
>> 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
>> of 1u to avoid undefined behavior when shifting by 32.
>>
>> Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
>> ---
>>   linux-user/sh4/target_mman.h | 2 +-
>>   target/sh4/cpu-param.h       | 6 +-----
>>   2 files changed, 2 insertions(+), 6 deletions(-)
> 
> So, the goal is to run things under qemu-linux-user that can't run on 
> hardware?
> 
> I'm not necessarily opposed, though there have been software systems 
> that know that the upper bit is unused and reuse it for tagged 
> pointers.  Emacs did so, sometime last century.  I'm sure there were 
> others.  Anyway that's the reason we currently limit qemu-linux-user 
> like the hardware does.
> 
> If you're going to drop that, you might do this for all targets:
> 
> mips/cpu-param.h:#  define TARGET_VIRT_ADDR_SPACE_BITS 31
> sh4/cpu-param.h:# define TARGET_VIRT_ADDR_SPACE_BITS 31

If so please add a comment ([*]) around these definitions.

Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Max Filippov 2 months ago
On Mon, Jul 27, 2026 at 9:52 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/27/26 04:48, Laurent Vivier wrote:
> > On real SH4 hardware, the address space is split between user mode
> > (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
> > so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
> >
> > However, qemu-user does not emulate the MMU, so this limit is not needed.
> > The only effect is to restrict reserved_va to 2 GB, causing OOM failures
> > for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
> >
> > Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
> > 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
> > of 1u to avoid undefined behavior when shifting by 32.
> >
> > Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> > Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> > ---
> >   linux-user/sh4/target_mman.h | 2 +-
> >   target/sh4/cpu-param.h       | 6 +-----
> >   2 files changed, 2 insertions(+), 6 deletions(-)
>
> So, the goal is to run things under qemu-linux-user that can't run on hardware?
>
> I'm not necessarily opposed, though there have been software systems that know that the
> upper bit is unused and reuse it for tagged pointers.  Emacs did so, sometime last
> century.  I'm sure there were others.  Anyway that's the reason we currently limit
> qemu-linux-user like the hardware does.
>
> If you're going to drop that, you might do this for all targets:
>
> mips/cpu-param.h:#  define TARGET_VIRT_ADDR_SPACE_BITS 31
> sh4/cpu-param.h:# define TARGET_VIRT_ADDR_SPACE_BITS 31
> xtensa/cpu-param.h:#define TARGET_VIRT_ADDR_SPACE_BITS 30

Xtensa has it for the different reason: with the windowed call ABI it cannot
have calls between regions that have addresses with different two topmost
bits. call0 ABI doesn't have this limitation.

-- 
Thanks.
-- Max
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Laurent Vivier 2 months ago
Le 27/07/2026 à 13:48, Laurent Vivier a écrit :
> On real SH4 hardware, the address space is split between user mode
> (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
> so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
> 
> However, qemu-user does not emulate the MMU, so this limit is not needed.
> The only effect is to restrict reserved_va to 2 GB, causing OOM failures
> for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
> 
> Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
> 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
> of 1u to avoid undefined behavior when shifting by 32.
> 

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4093

> Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
> ---
>   linux-user/sh4/target_mman.h | 2 +-
>   target/sh4/cpu-param.h       | 6 +-----
>   2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
> index dd9016081e9f..2d05837c2f36 100644
> --- a/linux-user/sh4/target_mman.h
> +++ b/linux-user/sh4/target_mman.h
> @@ -1,6 +1,6 @@
>   /* arch/sh/include/asm/processor_32.h */
>   #define TASK_UNMAPPED_BASE \
> -    TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
> +    TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>   
>   /* arch/sh/include/asm/elf.h */
>   #define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
> diff --git a/target/sh4/cpu-param.h b/target/sh4/cpu-param.h
> index c3b8114e538b..d95827078260 100644
> --- a/target/sh4/cpu-param.h
> +++ b/target/sh4/cpu-param.h
> @@ -9,10 +9,6 @@
>   #define SH4_CPU_PARAM_H
>   
>   #define TARGET_PAGE_BITS 12  /* 4k */
> -#ifdef CONFIG_USER_ONLY
> -# define TARGET_VIRT_ADDR_SPACE_BITS 31
> -#else
> -# define TARGET_VIRT_ADDR_SPACE_BITS 32
> -#endif
> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
>   
>   #endif
Re: [PATCH] linux-user/sh4: allow full 32-bit address space
Posted by Helge Deller 2 months ago
On 7/27/26 13:56, Laurent Vivier wrote:
> Le 27/07/2026 à 13:48, Laurent Vivier a écrit :
>> On real SH4 hardware, the address space is split between user mode
>> (U0, 0x00000000-0x7fffffff) and kernel mode (P1-P4, 0x80000000-0xffffffff),
>> so TARGET_VIRT_ADDR_SPACE_BITS was set to 31 for CONFIG_USER_ONLY.
>>
>> However, qemu-user does not emulate the MMU, so this limit is not needed.
>> The only effect is to restrict reserved_va to 2 GB, causing OOM failures
>> for memory-intensive builds (e.g. webkit2gtk on Debian sh4 buildds).
>>
>> Set TARGET_VIRT_ADDR_SPACE_BITS to 32 unconditionally, like most other
>> 32-bit targets. Also fix the TASK_UNMAPPED_BASE macro to use 1ull instead
>> of 1u to avoid undefined behavior when shifting by 32.
>>
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4093
> 
>> Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
>> Signed-off-by: Laurent Vivier <laurent@vivier.eu>

Reviewed-by: Helge Deller <deller@gmx.de>

>> ---
>>   linux-user/sh4/target_mman.h | 2 +-
>>   target/sh4/cpu-param.h       | 6 +-----
>>   2 files changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/linux-user/sh4/target_mman.h b/linux-user/sh4/target_mman.h
>> index dd9016081e9f..2d05837c2f36 100644
>> --- a/linux-user/sh4/target_mman.h
>> +++ b/linux-user/sh4/target_mman.h
>> @@ -1,6 +1,6 @@
>>   /* arch/sh/include/asm/processor_32.h */
>>   #define TASK_UNMAPPED_BASE \
>> -    TARGET_PAGE_ALIGN((1u << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>> +    TARGET_PAGE_ALIGN((1ull << TARGET_VIRT_ADDR_SPACE_BITS) / 3)
>>   /* arch/sh/include/asm/elf.h */
>>   #define ELF_ET_DYN_BASE       (TASK_UNMAPPED_BASE * 2)
>> diff --git a/target/sh4/cpu-param.h b/target/sh4/cpu-param.h
>> index c3b8114e538b..d95827078260 100644
>> --- a/target/sh4/cpu-param.h
>> +++ b/target/sh4/cpu-param.h
>> @@ -9,10 +9,6 @@
>>   #define SH4_CPU_PARAM_H
>>   #define TARGET_PAGE_BITS 12  /* 4k */
>> -#ifdef CONFIG_USER_ONLY
>> -# define TARGET_VIRT_ADDR_SPACE_BITS 31
>> -#else
>> -# define TARGET_VIRT_ADDR_SPACE_BITS 32
>> -#endif
>> +#define TARGET_VIRT_ADDR_SPACE_BITS 32
>>   #endif
> 
>