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: e66003e7be ("xen/riscv: introduce setup_initial_pages")
Reported-by: Zheng Zhang <zhangzheng@iscas.ac.cn>
Signed-off-by: Baptiste Le Duc <baptiste.le-duc@vates.tech>
Tested-by: Zheng Zhang <zhangzheng@iscas.ac.cn>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
This commit is contained in:
Baptiste Le Duc authored and Jan Beulich committed 2026-09-23 10:01:38 +02:00
1 parent d8ca89f26c
commit 08a898b93d
1 file changed
+1 -1
+1 -1
View File
@@ -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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.