Skip to content

Commit 32f5b69

Browse files
mrutland-armwilldeacon
authored andcommitted
arm64: add FIXADDR_TOT_{START,SIZE}
Currently arm64's FIXADDR_{START,SIZE} definitions only cover the runtime fixmap slots (and not the boot-time fixmap slots), but the code for creating the fixmap assumes that these definitions cover the entire fixmap range. This means that the ptdump boundaries are reported in a misleading way, missing the VA region of the runtime slots. In theory this could also cause the fixmap creation to go wrong if the boot-time fixmap slots end up spilling into a separate PMD entry, though luckily this is not currently the case in any configuration. While it seems like we could extend FIXADDR_{START,SIZE} to cover the entire fixmap area, core code relies upon these *only* covering the runtime slots. For example, fix_to_virt() and virt_to_fix() try to reject manipulation of the boot-time slots based upon FIXADDR_{START,SIZE}, while __fix_to_virt() and __virt_to_fix() can handle any fixmap slot. This patch follows the lead of x86 in commit: 55f49fc ("x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP") ... and add new FIXADDR_TOT_{START,SIZE} definitions which cover the entire fixmap area, using these for the fixmap creation and ptdump code. As the boot-time fixmap slots are now rejected by fix_to_virt(), the early_fixmap_init() code is changed to consistently use __fix_to_virt(), as it already does in a few cases. Signed-off-by: Mark Rutland <[email protected]> Cc: Anshuman Khandual <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Ryan Roberts <[email protected]> Cc: Will Deacon <[email protected]> Reviewed-by: Ryan Roberts <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 7bd6680 commit 32f5b69

File tree

3 files changed

+18
-16
lines changed

3 files changed

+18
-16
lines changed

arch/arm64/include/asm/fixmap.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,10 @@ enum fixed_addresses {
9595
__end_of_fixed_addresses
9696
};
9797

98-
#define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
99-
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
98+
#define FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
99+
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
100+
#define FIXADDR_TOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
101+
#define FIXADDR_TOT_START (FIXADDR_TOP - FIXADDR_TOT_SIZE)
100102

101103
#define FIXMAP_PAGE_IO __pgprot(PROT_DEVICE_nGnRE)
102104

arch/arm64/mm/mmu.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -795,14 +795,14 @@ static void __init map_kernel(pgd_t *pgdp)
795795
&vmlinux_initdata, 0, VM_NO_GUARD);
796796
map_kernel_segment(pgdp, _data, _end, PAGE_KERNEL, &vmlinux_data, 0, 0);
797797

798-
if (!READ_ONCE(pgd_val(*pgd_offset_pgd(pgdp, FIXADDR_START)))) {
798+
if (!READ_ONCE(pgd_val(*pgd_offset_pgd(pgdp, FIXADDR_TOT_START)))) {
799799
/*
800800
* The fixmap falls in a separate pgd to the kernel, and doesn't
801801
* live in the carveout for the swapper_pg_dir. We can simply
802802
* re-use the existing dir for the fixmap.
803803
*/
804-
set_pgd(pgd_offset_pgd(pgdp, FIXADDR_START),
805-
READ_ONCE(*pgd_offset_k(FIXADDR_START)));
804+
set_pgd(pgd_offset_pgd(pgdp, FIXADDR_TOT_START),
805+
READ_ONCE(*pgd_offset_k(FIXADDR_TOT_START)));
806806
} else if (CONFIG_PGTABLE_LEVELS > 3) {
807807
pgd_t *bm_pgdp;
808808
p4d_t *bm_p4dp;
@@ -814,9 +814,9 @@ static void __init map_kernel(pgd_t *pgdp)
814814
* entry instead.
815815
*/
816816
BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
817-
bm_pgdp = pgd_offset_pgd(pgdp, FIXADDR_START);
818-
bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_START);
819-
bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_START);
817+
bm_pgdp = pgd_offset_pgd(pgdp, FIXADDR_TOT_START);
818+
bm_p4dp = p4d_offset(bm_pgdp, FIXADDR_TOT_START);
819+
bm_pudp = pud_set_fixmap_offset(bm_p4dp, FIXADDR_TOT_START);
820820
pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd));
821821
pud_clear_fixmap();
822822
} else {
@@ -1275,7 +1275,7 @@ void __init early_fixmap_init(void)
12751275
p4d_t *p4dp, p4d;
12761276
pud_t *pudp;
12771277
pmd_t *pmdp;
1278-
unsigned long addr = FIXADDR_START;
1278+
unsigned long addr = FIXADDR_TOT_START;
12791279

12801280
pgdp = pgd_offset_k(addr);
12811281
p4dp = p4d_offset(pgdp, addr);
@@ -1306,16 +1306,16 @@ void __init early_fixmap_init(void)
13061306
BUILD_BUG_ON((__fix_to_virt(FIX_BTMAP_BEGIN) >> PMD_SHIFT)
13071307
!= (__fix_to_virt(FIX_BTMAP_END) >> PMD_SHIFT));
13081308

1309-
if ((pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)))
1310-
|| pmdp != fixmap_pmd(fix_to_virt(FIX_BTMAP_END))) {
1309+
if ((pmdp != fixmap_pmd(__fix_to_virt(FIX_BTMAP_BEGIN)))
1310+
|| pmdp != fixmap_pmd(__fix_to_virt(FIX_BTMAP_END))) {
13111311
WARN_ON(1);
13121312
pr_warn("pmdp %p != %p, %p\n",
1313-
pmdp, fixmap_pmd(fix_to_virt(FIX_BTMAP_BEGIN)),
1314-
fixmap_pmd(fix_to_virt(FIX_BTMAP_END)));
1313+
pmdp, fixmap_pmd(__fix_to_virt(FIX_BTMAP_BEGIN)),
1314+
fixmap_pmd(__fix_to_virt(FIX_BTMAP_END)));
13151315
pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
1316-
fix_to_virt(FIX_BTMAP_BEGIN));
1316+
__fix_to_virt(FIX_BTMAP_BEGIN));
13171317
pr_warn("fix_to_virt(FIX_BTMAP_END): %08lx\n",
1318-
fix_to_virt(FIX_BTMAP_END));
1318+
__fix_to_virt(FIX_BTMAP_END));
13191319

13201320
pr_warn("FIX_BTMAP_END: %d\n", FIX_BTMAP_END);
13211321
pr_warn("FIX_BTMAP_BEGIN: %d\n", FIX_BTMAP_BEGIN);

arch/arm64/mm/ptdump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static struct addr_marker address_markers[] = {
4545
{ MODULES_END, "Modules end" },
4646
{ VMALLOC_START, "vmalloc() area" },
4747
{ VMALLOC_END, "vmalloc() end" },
48-
{ FIXADDR_START, "Fixmap start" },
48+
{ FIXADDR_TOT_START, "Fixmap start" },
4949
{ FIXADDR_TOP, "Fixmap end" },
5050
{ PCI_IO_START, "PCI I/O start" },
5151
{ PCI_IO_END, "PCI I/O end" },

0 commit comments

Comments
 (0)