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