Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/64s/hash: Restrict stress_hpt_struct memblock region to within RMA limit

When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real
Addressing Mode during early boot. During this, we should ensure that
memory region allocations for stress_hpt_struct should happen from
within RMA region as otherwise the boot might get stuck while doing
memset of this region.

History behind why do we have RMA region limitation is better explained
in these 2 patches [1] & [2]. This patch ensures that memset to
stress_hpt_struct during early boot does not cross ppc64_rma_size
boundary.

[1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/
[2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/

Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults")
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com

authored by

Ritesh Harjani (IBM) and committed by
Madhavan Srinivasan
17b45ccf 00312419

+6 -4
+6 -4
arch/powerpc/mm/book3s64/hash_utils.c
··· 1302 1302 unsigned long table; 1303 1303 unsigned long pteg_count; 1304 1304 unsigned long prot; 1305 - phys_addr_t base = 0, size = 0, end; 1305 + phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; 1306 1306 u64 i; 1307 1307 1308 1308 DBG(" -> htab_initialize()\n"); 1309 + 1310 + if (firmware_has_feature(FW_FEATURE_LPAR)) 1311 + limit = ppc64_rma_size; 1309 1312 1310 1313 if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { 1311 1314 mmu_kernel_ssize = MMU_SEGSIZE_1T; ··· 1325 1322 // Too early to use nr_cpu_ids, so use NR_CPUS 1326 1323 tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, 1327 1324 __alignof__(struct stress_hpt_struct), 1328 - 0, MEMBLOCK_ALLOC_ANYWHERE); 1325 + MEMBLOCK_LOW_LIMIT, limit); 1329 1326 memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); 1330 1327 stress_hpt_struct = __va(tmp); 1331 1328 ··· 1359 1356 mmu_hash_ops.hpte_clear_all(); 1360 1357 #endif 1361 1358 } else { 1362 - unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; 1363 1359 1364 1360 table = memblock_phys_alloc_range(htab_size_bytes, 1365 1361 htab_size_bytes, 1366 - 0, limit); 1362 + MEMBLOCK_LOW_LIMIT, limit); 1367 1363 if (!table) 1368 1364 panic("ERROR: Failed to allocate %pa bytes below %pa\n", 1369 1365 &htab_size_bytes, &limit);