xref: /linux/arch/s390/kernel/abs_lowcore.c (revision ab52c59103002b49f2455371e4b9c56ba3ef1781)
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