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