Skip to content

Commit 6a0f139

Browse files
keesgregkh
authored andcommitted
arm64: mm: Fix CFI failure due to kpti_ng_pgd_alloc function signature
commit ceca927 upstream. Seen during KPTI initialization: CFI failure at create_kpti_ng_temp_pgd+0x124/0xce8 (target: kpti_ng_pgd_alloc+0x0/0x14; expected type: 0xd61b88b6) The call site is alloc_init_pud() at arch/arm64/mm/mmu.c: pud_phys = pgtable_alloc(TABLE_PUD); alloc_init_pud() has the prototype: static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, phys_addr_t phys, pgprot_t prot, phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags) where the pgtable_alloc() prototype is declared. The target (kpti_ng_pgd_alloc) is used in arch/arm64/kernel/cpufeature.c: create_kpti_ng_temp_pgd(kpti_ng_temp_pgd, __pa(alloc), KPTI_NG_TEMP_VA, PAGE_SIZE, PAGE_KERNEL, kpti_ng_pgd_alloc, 0); which is an alias for __create_pgd_mapping_locked() with prototype: extern __alias(__create_pgd_mapping_locked) void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot, phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags); __create_pgd_mapping_locked() passes the function pointer down: __create_pgd_mapping_locked() -> alloc_init_p4d() -> alloc_init_pud() But the target function (kpti_ng_pgd_alloc) has the wrong signature: static phys_addr_t __init kpti_ng_pgd_alloc(int shift); The "int" should be "enum pgtable_type". To make "enum pgtable_type" available to cpufeature.c, move enum pgtable_type definition from arch/arm64/mm/mmu.c to arch/arm64/include/asm/mmu.h. Adjust kpti_ng_pgd_alloc to use "enum pgtable_type" instead of "int". The function behavior remains identical (parameter is unused). Fixes: c64f46e ("arm64: mm: use enum to identify pgtable level instead of *_SHIFT") Cc: <stable@vger.kernel.org> # 6.16.x Signed-off-by: Kees Cook <kees@kernel.org> Acked-by: Ard Biesheuvel <ardb@kernel.org> Link: https://lore.kernel.org/r/20250829190721.it.373-kees@kernel.org Reviewed-by: Ryan Roberts <ryan.roberts@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 7f5fffc commit 6a0f139

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

arch/arm64/include/asm/mmu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
#include <linux/refcount.h>
1818
#include <asm/cpufeature.h>
1919

20+
enum pgtable_type {
21+
TABLE_PTE,
22+
TABLE_PMD,
23+
TABLE_PUD,
24+
TABLE_P4D,
25+
};
26+
2027
typedef struct {
2128
atomic64_t id;
2229
#ifdef CONFIG_COMPAT

arch/arm64/kernel/cpufeature.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#include <asm/hwcap.h>
8585
#include <asm/insn.h>
8686
#include <asm/kvm_host.h>
87+
#include <asm/mmu.h>
8788
#include <asm/mmu_context.h>
8889
#include <asm/mte.h>
8990
#include <asm/hypervisor.h>
@@ -1941,11 +1942,11 @@ static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
19411942
extern
19421943
void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
19431944
phys_addr_t size, pgprot_t prot,
1944-
phys_addr_t (*pgtable_alloc)(int), int flags);
1945+
phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags);
19451946

19461947
static phys_addr_t __initdata kpti_ng_temp_alloc;
19471948

1948-
static phys_addr_t __init kpti_ng_pgd_alloc(int shift)
1949+
static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_type type)
19491950
{
19501951
kpti_ng_temp_alloc -= PAGE_SIZE;
19511952
return kpti_ng_temp_alloc;

arch/arm64/mm/mmu.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,6 @@
4646
#define NO_CONT_MAPPINGS BIT(1)
4747
#define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */
4848

49-
enum pgtable_type {
50-
TABLE_PTE,
51-
TABLE_PMD,
52-
TABLE_PUD,
53-
TABLE_P4D,
54-
};
55-
5649
u64 kimage_voffset __ro_after_init;
5750
EXPORT_SYMBOL(kimage_voffset);
5851

0 commit comments

Comments
 (0)