highmem.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/compiler.h>
  3. #include <linux/init.h>
  4. #include <linux/export.h>
  5. #include <linux/highmem.h>
  6. #include <linux/sched.h>
  7. #include <linux/smp.h>
  8. #include <asm/fixmap.h>
  9. #include <asm/tlbflush.h>
  10. static pte_t *kmap_pte;
  11. unsigned long highstart_pfn, highend_pfn;
  12. void kmap_flush_tlb(unsigned long addr)
  13. {
  14. flush_tlb_one(addr);
  15. }
  16. EXPORT_SYMBOL(kmap_flush_tlb);
  17. void *kmap_atomic_high_prot(struct page *page, pgprot_t prot)
  18. {
  19. unsigned long vaddr;
  20. int idx, type;
  21. type = kmap_atomic_idx_push();
  22. idx = type + KM_TYPE_NR*smp_processor_id();
  23. vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
  24. #ifdef CONFIG_DEBUG_HIGHMEM
  25. BUG_ON(!pte_none(*(kmap_pte - idx)));
  26. #endif
  27. set_pte(kmap_pte-idx, mk_pte(page, prot));
  28. local_flush_tlb_one((unsigned long)vaddr);
  29. return (void*) vaddr;
  30. }
  31. EXPORT_SYMBOL(kmap_atomic_high_prot);
  32. void kunmap_atomic_high(void *kvaddr)
  33. {
  34. unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
  35. int type __maybe_unused;
  36. if (vaddr < FIXADDR_START)
  37. return;
  38. type = kmap_atomic_idx();
  39. #ifdef CONFIG_DEBUG_HIGHMEM
  40. {
  41. int idx = type + KM_TYPE_NR * smp_processor_id();
  42. BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
  43. /*
  44. * force other mappings to Oops if they'll try to access
  45. * this pte without first remap it
  46. */
  47. pte_clear(&init_mm, vaddr, kmap_pte-idx);
  48. local_flush_tlb_one(vaddr);
  49. }
  50. #endif
  51. kmap_atomic_idx_pop();
  52. }
  53. EXPORT_SYMBOL(kunmap_atomic_high);
  54. /*
  55. * This is the same as kmap_atomic() but can map memory that doesn't
  56. * have a struct page associated with it.
  57. */
  58. void *kmap_atomic_pfn(unsigned long pfn)
  59. {
  60. unsigned long vaddr;
  61. int idx, type;
  62. preempt_disable();
  63. pagefault_disable();
  64. type = kmap_atomic_idx_push();
  65. idx = type + KM_TYPE_NR*smp_processor_id();
  66. vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
  67. set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
  68. flush_tlb_one(vaddr);
  69. return (void*) vaddr;
  70. }
  71. void __init kmap_init(void)
  72. {
  73. unsigned long kmap_vstart;
  74. /* cache the first kmap pte */
  75. kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
  76. kmap_pte = virt_to_kpte(kmap_vstart);
  77. }