From 08a898b93d214a38965fbc4cd9b7a36e5c715691 Mon Sep 17 00:00:00 2001 From: Baptiste Le Duc Date: Wed, 23 Sep 2026 09:04:16 +0200 Subject: [PATCH] xen/riscv: fix level_map_mask truncation on load_start check_pgtbl_mode_support() declares level_map_mask as bare `unsigned`, i.e. a 32-bit type while it derives from a paddr_t which is in both RV32/RV64 a 64-bit type. Storing that value into a 32-bit local silently drops any set bits above bit 31. The mask is then used as: aligned_load_start = load_start & level_map_mask; load_start is `unsigned long` (64-bit on riscv64) and if it requires more than 32 bits to represent, because load_start zero-extend to 64 bits, we would drop some load_start's bits during the AND. Widen level_map_mask to `unsigned long`, matching the width of the physical address. Fixes: e66003e7be19 ("xen/riscv: introduce setup_initial_pages") Reported-by: Zheng Zhang Signed-off-by: Baptiste Le Duc Tested-by: Zheng Zhang Reviewed-by: Jan Beulich Reviewed-by: Oleksii Kurochko --- xen/arch/riscv/mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c index 4d3b8c2204..610d111945 100644 --- a/xen/arch/riscv/mm.c +++ b/xen/arch/riscv/mm.c @@ -181,7 +181,7 @@ static bool __init check_pgtbl_mode_support(struct mmu_desc *mmu_desc, bool is_mode_supported = false; unsigned int index; unsigned int page_table_level = (mmu_desc->num_levels - 1); - unsigned level_map_mask = XEN_PT_LEVEL_MAP_MASK(page_table_level); + unsigned long level_map_mask = XEN_PT_LEVEL_MAP_MASK(page_table_level); unsigned long aligned_load_start = load_start & level_map_mask; unsigned long aligned_page_size = XEN_PT_LEVEL_SIZE(page_table_level);