1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <linux/pgtable.h> 4 #include <asm/abs_lowcore.h> 5 #include <asm/sections.h> 6 7 unsigned long __bootdata_preserved(__abs_lowcore); 8 int __bootdata_preserved(relocate_lowcore); 9 10 int abs_lowcore_map(int cpu, struct lowcore *lc, bool alloc) 11 { 12 unsigned long addr = __abs_lowcore + (cpu * sizeof(struct lowcore)); 13 unsigned long phys = __pa(lc); 14 int rc, i; 15 16 for (i = 0; i < LC_PAGES; i++) { 17 rc = __vmem_map_4k_page(addr, phys, PAGE_KERNEL, alloc); 18 if (rc) { 19 /* 20 * Do not unmap allocated page tables in case the 21 * allocation was not requested. In such a case the 22 * request is expected coming from an atomic context, 23 * while the unmap attempt might sleep. 24 */ 25 if (alloc) { 26 for (--i; i >= 0; i--) { 27 addr -= PAGE_SIZE; 28 vmem_unmap_4k_page(addr); 29 } 30 } 31 return rc; 32 } 33 addr += PAGE_SIZE; 34 phys += PAGE_SIZE; 35 } 36 return 0; 37 } 38 39 void abs_lowcore_unmap(int cpu) 40 { 41 unsigned long addr = __abs_lowcore + (cpu * sizeof(struct lowcore)); 42 int i; 43 44 for (i = 0; i < LC_PAGES; i++) { 45 vmem_unmap_4k_page(addr); 46 addr += PAGE_SIZE; 47 } 48 } 49