abs_lowcore.c 1.1 KB

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