From 094f75162f05efc56652cc30f539323fbb5d1d26 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 17 Apr 2025 15:32:53 +0200 Subject: [PATCH] cpu/x86/64bit/pt: Fix integer arithmethic in assembly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GNU assembler allows to use arithmetics on constant expression, except for division using the '/' character. By default the '/' introduces a line comment, see [1]. This behaviour can be changed when the command line argument --divide is being used. However that's not the case for coreboot. Since the divide doesn't work as expected the assembler generates 512 times as much instructions on the .rept evaluation than it should. This didn't cause any problem since it only filled PML4E, but the additional entries pointed to non existing PDPTs. As long as the memory above 512GB wasn't accessed it worked just fine. Use shifts to fix the arithmetic and thus generate only the expected number of page table entries. Required for the following patch, which walks page tables and expects to find sane directories. 1: https://sourceware.org/binutils/docs-2.26/as/i386_002dChars.html#i386_002dChars TEST=GAS generates 512 times less entries on .rept evaluation Change-Id: I480142df010bf4e7d6fb84c9891e93b6ee21e908 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/87356 Reviewed-by: Matt DeVillier Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/cpu/x86/64bit/pt.S | 4 ++-- src/cpu/x86/64bit/pt1G.S | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/x86/64bit/pt.S b/src/cpu/x86/64bit/pt.S index 5b10b10118..85d425e29a 100644 --- a/src/cpu/x86/64bit/pt.S +++ b/src/cpu/x86/64bit/pt.S @@ -21,14 +21,14 @@ .align 4096 PML4E: /* For every 512GiB generate a pointer to the corresponding PDPT */ -.rept (CONFIG_CPU_PT_ROM_MAP_GB + 511) / 512 +.rept ((CONFIG_CPU_PT_ROM_MAP_GB + 511) >> 9) .quad _GEN_DIR(PDPT + 4096 * ((. - PML4E) >> 3)) /* Point to PDPT */ .endr .align 4096 PDT: /* For every 2MiB generate a page entry. In one GiB there are 512 pages. */ -.rept 512 * CONFIG_CPU_PT_ROM_MAP_GB +.rept (CONFIG_CPU_PT_ROM_MAP_GB << 9) .quad _GEN_PAGE(0x200000 * ((. - PDT) >> 3)) /* identity map 2MiB page */ .endr diff --git a/src/cpu/x86/64bit/pt1G.S b/src/cpu/x86/64bit/pt1G.S index b1f443301d..30dd0cb239 100644 --- a/src/cpu/x86/64bit/pt1G.S +++ b/src/cpu/x86/64bit/pt1G.S @@ -21,7 +21,7 @@ .align 4096 PML4E: /* For every 512GiB generate a pointer to the corresponding PDPT */ -.rept (CONFIG_CPU_PT_ROM_MAP_GB + 511) / 512 +.rept ((CONFIG_CPU_PT_ROM_MAP_GB + 511) >> 9) .quad _GEN_DIR(PDPT + 4096 * ((. - PML4E) >> 3)) /* Point to PDPT */ .endr