From: Linus Torvalds Date: Fri, 10 Sep 2021 18:58:20 +0000 (-0700) Subject: Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux X-Git-Tag: microblaze-v5.16~29 X-Git-Url: http://git.monstr.eu/?p=linux-2.6-microblaze.git;a=commitdiff_plain;h=e99f23c5bf59219d0cd9b6e0d7d4c1b641a98704 Merge tag 'arm64-fixes' of git://git./linux/kernel/git/arm64/linux Pull arm64 fixes from Catalin Marinas: - Limit the linear region to 51-bit when KVM is running in nVHE mode. Otherwise, depending on the placement of the ID map, kernel-VA to hyp-VA translations may produce addresses that either conflict with other HYP mappings or generate addresses outside of the 52-bit addressable range. - Instruct kmemleak not to scan the memory reserved for kdump as this range is removed from the kernel linear map and therefore not accessible. * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm64: kdump: Skip kmemleak scan reserved memory for kdump arm64: mm: limit linear region to 51 bits for KVM in nVHE mode --- e99f23c5bf59219d0cd9b6e0d7d4c1b641a98704 diff --cc arch/arm64/mm/init.c index b16be52233c6,5a16f5715716..37a81754d9b6 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@@ -220,10 -254,59 +226,24 @@@ static int __init early_mem(char *p } early_param("mem", early_mem); -static int __init early_init_dt_scan_usablemem(unsigned long node, - const char *uname, int depth, void *data) -{ - struct memblock_region *usablemem = data; - const __be32 *reg; - int len; - - if (depth != 1 || strcmp(uname, "chosen") != 0) - return 0; - - reg = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len); - if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells))) - return 1; - - usablemem->base = dt_mem_next_cell(dt_root_addr_cells, ®); - usablemem->size = dt_mem_next_cell(dt_root_size_cells, ®); - - return 1; -} - -static void __init fdt_enforce_memory_region(void) -{ - struct memblock_region reg = { - .size = 0, - }; - - of_scan_flat_dt(early_init_dt_scan_usablemem, ®); - - if (reg.size) - memblock_cap_memory_range(reg.base, reg.size); -} - void __init arm64_memblock_init(void) { - const s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual); + s64 linear_region_size = PAGE_END - _PAGE_OFFSET(vabits_actual); + + /* + * Corner case: 52-bit VA capable systems running KVM in nVHE mode may + * be limited in their ability to support a linear map that exceeds 51 + * bits of VA space, depending on the placement of the ID map. Given + * that the placement of the ID map may be randomized, let's simply + * limit the kernel's linear map to 51 bits as well if we detect this + * configuration. + */ + if (IS_ENABLED(CONFIG_KVM) && vabits_actual == 52 && + is_hyp_mode_available() && !is_kernel_in_hyp_mode()) { + pr_info("Capping linear region to 51 bits for KVM in nVHE mode on LVA capable hardware.\n"); + linear_region_size = min_t(u64, linear_region_size, BIT(51)); + } - /* Handle linux,usable-memory-range property */ - fdt_enforce_memory_region(); - /* Remove memory above our supported physical address size */ memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX);