[PATCH v1] qemu-arm: round down memory to multiple of 2MB

From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
---
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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; }

On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
Best regards
Heinrich
- return 0;
}

On Thu, 11 Feb 2021 at 15:18, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
The above value means 512 GiB - 4 MiB, so that shouldn't be a problem. I don't think QEMU's -m option takes fractional megabyte values.

On 11.02.21 15:56, Ard Biesheuvel wrote:
On Thu, 11 Feb 2021 at 15:18, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
The above value means 512 GiB - 4 MiB, so that shouldn't be a problem. I don't think QEMU's -m option takes fractional megabyte values.
$ 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"; };
Granularity seems to be 0x2000 = 8 KiB.
Best regards
Heinrich

On Thu, 11 Feb 2021 at 16:34, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 15:56, Ard Biesheuvel wrote:
On Thu, 11 Feb 2021 at 15:18, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
The above value means 512 GiB - 4 MiB, so that shouldn't be a problem. I don't think QEMU's -m option takes fractional megabyte values.
$ 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"; };
Granularity seems to be 0x2000 = 8 KiB.
In that case, it seems easiest to me to always round down to the nearest multiple of 2MB

Hi Heinrich,
On Thu, Feb 11, 2021 at 5:34 PM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 15:56, Ard Biesheuvel wrote:
On Thu, 11 Feb 2021 at 15:18, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
The above value means 512 GiB - 4 MiB, so that shouldn't be a problem. I don't think QEMU's -m option takes fractional megabyte values.
$ 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"; };
Granularity seems to be 0x2000 = 8 KiB.
I've just run some tests (including the mem=100005k ) with LPAE disabled and haven't faced any issues:
$ cat .config | grep LPAE # CONFIG_ARMV7_LPAE is not set
$ qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200)
DRAM: 1 GiB Flash: 128 MiB ... =>
$ qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin
U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200)
DRAM: 1 GiB Flash: 128 MiB ... =>
$ qemu-system-arm -machine virt -m 100005k -nographic -bios u-boot.bin
U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200) DRAM: 97.7 MiB Flash: 128 MiB ... =>
Best regards
Heinrich
Regards, Igor

Hello Ard,
Just a quick follow-up for this old thread,
I've again stumbled upon the same issue recently and it turned out that I've already sent a fix for that here :)
Considering Heinrich's comment about memory granularity, does it still make sense to land this patch? If not, what objections/suggestions do you have in mind?
Thanks!
Regards, Igor
On Thu, Feb 11, 2021 at 4:39 PM Igor Opaniuk igor.opaniuk@foundries.io wrote:
Hi Heinrich,
On Thu, Feb 11, 2021 at 5:34 PM Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 15:56, Ard Biesheuvel wrote:
On Thu, 11 Feb 2021 at 15:18, Heinrich Schuchardt xypron.glpk@gmx.de wrote:
On 11.02.21 13:04, Igor Opaniuk wrote:
From: Igor Opaniuk igor.opaniuk@foundries.io
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, round down the amount of available memory to avoid hang 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 ---
Fixes: 3fa914af82("arm: qemu: implement enable_caches()") Signed-off-by: Igor Opaniuk igor.opaniuk@foundries.io
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 aa68bef469..841dd7af0e 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -84,6 +84,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);
Is the problem LPAE specific? Couldn't you provoke same problem using an odd memory size without LPAE, e.g qemu-system-arm -m 536870908 (512 MiB - 4)?
The above value means 512 GiB - 4 MiB, so that shouldn't be a problem. I don't think QEMU's -m option takes fractional megabyte values.
$ 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"; };
Granularity seems to be 0x2000 = 8 KiB.
I've just run some tests (including the mem=100005k ) with LPAE disabled and haven't faced any issues:
$ cat .config | grep LPAE # CONFIG_ARMV7_LPAE is not set
$ qemu-system-arm -machine virt -m 1057 -nographic -bios u-boot.bin U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200)
DRAM: 1 GiB Flash: 128 MiB ... =>
$ qemu-system-arm -machine virt -m 1058 -nographic -bios u-boot.bin
U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200)
DRAM: 1 GiB Flash: 128 MiB ... =>
$ qemu-system-arm -machine virt -m 100005k -nographic -bios u-boot.bin
U-Boot 2021.04-rc1-01218-g85e959f09c-dirty (Feb 11 2021 - 17:31:31 +0200) DRAM: 97.7 MiB Flash: 128 MiB ... =>
Best regards
Heinrich
Regards, Igor
-- Best regards - Freundliche Grüsse - Meilleures salutations
Igor Opaniuk Embedded Software Engineer T: +380 938364067 E: igor.opaniuk@foundries.io W: www.foundries.io
participants (3)
-
Ard Biesheuvel
-
Heinrich Schuchardt
-
Igor Opaniuk