1// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/pgtable.h>
4#include <asm/abs_lowcore.h>
5
6unsigned long __bootdata_preserved(__abs_lowcore);
7
8int 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
37void 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