From: Linus Torvalds <torvalds@linux-foundation.org>
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: baikal/mips/sdk5.9~10106
X-Git-Url: https://git.baikalelectronics.ru/?a=commitdiff_plain;h=282238a9d9b3cdd4371cf6651e96e4708107f7dc;p=kernel.git

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/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
---

282238a9d9b3cdd4371cf6651e96e4708107f7dc
diff --cc arch/arm64/mm/init.c
index b16be52233c67,5a16f57157161..37a81754d9b61
--- 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, &reg);
 -	usablemem->size = dt_mem_next_cell(dt_root_size_cells, &reg);
 -
 -	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, &reg);
 -
 -	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);