diff mbox series

[v2] qemu-arm: round down memory to multiple of 2MB for LPAE

Message ID 20240201124054.2094572-1-igor.opaniuk@foundries.io
State Accepted
Commit 1fa38ca9aae45aca58e9394a121bec6baa166f31
Delegated to: Tom Rini
Headers show
Series [v2] qemu-arm: round down memory to multiple of 2MB for LPAE | expand

Commit Message

Igor Opaniuk Feb. 1, 2024, 12:40 p.m. UTC
QEMU's -m option can take fractional megabyte values,
and lowest granularity seems to be 0x2000.
For example, run qemu with amount of memory set to 100005k (0x61A9400):

$ qemu-system-arm -machine virt -cpu cortex-a15 -m 100005k \
-bios denx/u-boot.bin -nographic

=> fdt addr $fdt_addr
=> fdt print /memory@40000000
memory@40000000 {
        reg = <0x00000000 0x40000000 0x00000000 0x061aa000>;
        device_type = "memory";
};

When LPAE is enabled, 1:1 mapping is created using 2 MB blocks.
In case amount of memory provided to QEMU is not multiple
of 2 MB, hang occurs during MMU initialization.

How to reproduce:
qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin - boots
qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin - hangs

DRAM:  1 GiB
initcall: 60011df8
initcall: 60011904
New Stack Pointer is: 80fffe90
initcall: 60011a20
initcall: 60011bcc
initcall: 60011bd4
initcall: 600119b4
Relocation Offset is: 22042000
Relocating to 82042000, new gd at 81001ed0, sp at 80fffe90
initcall: 60011b8c
initcall: 82053ea0
initcall: 82053ea8
initcall: 60012040 (relocated to 82054040)
dram_bank_mmu_setup: bank: 0
- hang here during mmu init -

This patches rounds down to the nearest multiple of 2MB when
CONFIG_ARMV7_LPAE=y.

Fixes: 3fa914af82("arm: qemu: implement enable_caches()")
Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
---

Changes in v2:
- Adjust commit message, add more details

 board/emulation/qemu-arm/qemu-arm.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Oleksandr Suvorov Feb. 2, 2024, 4:16 a.m. UTC | #1
On Thu, Feb 1, 2024, 14:41 Igor Opaniuk <igor.opaniuk@foundries.io> wrote:

> QEMU's -m option can take fractional megabyte values,
> and lowest granularity seems to be 0x2000.
> For example, run qemu with amount of memory set to 100005k (0x61A9400):
>
> $ qemu-system-arm -machine virt -cpu cortex-a15 -m 100005k \
> -bios denx/u-boot.bin -nographic
>
> => fdt addr $fdt_addr
> => fdt print /memory@40000000
> memory@40000000 {
>         reg = <0x00000000 0x40000000 0x00000000 0x061aa000>;
>         device_type = "memory";
> };
>
> When LPAE is enabled, 1:1 mapping is created using 2 MB blocks.
> In case amount of memory provided to QEMU is not multiple
> of 2 MB, hang occurs during MMU initialization.
>
> How to reproduce:
> qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin - boots
> qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin - hangs
>
> DRAM:  1 GiB
> initcall: 60011df8
> initcall: 60011904
> New Stack Pointer is: 80fffe90
> initcall: 60011a20
> initcall: 60011bcc
> initcall: 60011bd4
> initcall: 600119b4
> Relocation Offset is: 22042000
> Relocating to 82042000, new gd at 81001ed0, sp at 80fffe90
> initcall: 60011b8c
> initcall: 82053ea0
> initcall: 82053ea8
> initcall: 60012040 (relocated to 82054040)
> dram_bank_mmu_setup: bank: 0
> - hang here during mmu init -
>
> This patches rounds down to the nearest multiple of 2MB when
> CONFIG_ARMV7_LPAE=y.
>
> Fixes: 3fa914af82("arm: qemu: implement enable_caches()")
> Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
>

Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io
<igor.opaniuk@foundries.io>>

> ---
>
> Changes in v2:
> - Adjust commit message, add more details
>
>  board/emulation/qemu-arm/qemu-arm.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/board/emulation/qemu-arm/qemu-arm.c
> b/board/emulation/qemu-arm/qemu-arm.c
> index 942f1fff571..ecfd19f1a7e 100644
> --- a/board/emulation/qemu-arm/qemu-arm.c
> +++ b/board/emulation/qemu-arm/qemu-arm.c
> @@ -127,6 +127,18 @@ int dram_init(void)
>         if (fdtdec_setup_mem_size_base() != 0)
>                 return -EINVAL;
>
> +       /*
> +        * When LPAE is enabled (ARMv7),
> +        * 1:1 mapping is created using 2 MB blocks.
> +        *
> +        * In case amount of memory provided to QEMU
> +        * is not multiple of 2 MB, round down the amount
> +        * of available memory to avoid hang during MMU
> +        * initialization.
> +        */
> +       if (CONFIG_IS_ENABLED(ARMV7_LPAE))
> +               gd->ram_size -= (gd->ram_size % 0x200000);
> +
>         return 0;
>  }
>
> --
> 2.34.1
>
>
Tom Rini March 4, 2024, 3:26 p.m. UTC | #2
On Thu, Feb 01, 2024 at 01:40:54PM +0100, Igor Opaniuk wrote:

> QEMU's -m option can take fractional megabyte values,
> and lowest granularity seems to be 0x2000.
> For example, run qemu with amount of memory set to 100005k (0x61A9400):
> 
> $ qemu-system-arm -machine virt -cpu cortex-a15 -m 100005k \
> -bios denx/u-boot.bin -nographic
> 
> => fdt addr $fdt_addr
> => fdt print /memory@40000000
> memory@40000000 {
>         reg = <0x00000000 0x40000000 0x00000000 0x061aa000>;
>         device_type = "memory";
> };
> 
> When LPAE is enabled, 1:1 mapping is created using 2 MB blocks.
> In case amount of memory provided to QEMU is not multiple
> of 2 MB, hang occurs during MMU initialization.
> 
> How to reproduce:
> qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin - boots
> qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin - hangs
> 
> DRAM:  1 GiB
> initcall: 60011df8
> initcall: 60011904
> New Stack Pointer is: 80fffe90
> initcall: 60011a20
> initcall: 60011bcc
> initcall: 60011bd4
> initcall: 600119b4
> Relocation Offset is: 22042000
> Relocating to 82042000, new gd at 81001ed0, sp at 80fffe90
> initcall: 60011b8c
> initcall: 82053ea0
> initcall: 82053ea8
> initcall: 60012040 (relocated to 82054040)
> dram_bank_mmu_setup: bank: 0
> - hang here during mmu init -
> 
> This patches rounds down to the nearest multiple of 2MB when
> CONFIG_ARMV7_LPAE=y.
> 
> Fixes: 3fa914af82("arm: qemu: implement enable_caches()")
> Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
> Reviewed-by: Oleksandr Suvorov <oleksandr.suvorov@foundries.io

Applied to u-boot/next, thanks!
diff mbox series

Patch

diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c
index 942f1fff571..ecfd19f1a7e 100644
--- a/board/emulation/qemu-arm/qemu-arm.c
+++ b/board/emulation/qemu-arm/qemu-arm.c
@@ -127,6 +127,18 @@  int dram_init(void)
 	if (fdtdec_setup_mem_size_base() != 0)
 		return -EINVAL;
 
+	/*
+	 * When LPAE is enabled (ARMv7),
+	 * 1:1 mapping is created using 2 MB blocks.
+	 *
+	 * In case amount of memory provided to QEMU
+	 * is not multiple of 2 MB, round down the amount
+	 * of available memory to avoid hang during MMU
+	 * initialization.
+	 */
+	if (CONFIG_IS_ENABLED(ARMV7_LPAE))
+		gd->ram_size -= (gd->ram_size % 0x200000);
+
 	return 0;
 }