pgalloc.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * include/asm-s390/pgalloc.h
  3. *
  4. * S390 version
  5. * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6. * Author(s): Hartmut Penner (hp@de.ibm.com)
  7. * Martin Schwidefsky (schwidefsky@de.ibm.com)
  8. *
  9. * Derived from "include/asm-i386/pgalloc.h"
  10. * Copyright (C) 1994 Linus Torvalds
  11. */
  12. #ifndef _S390_PGALLOC_H
  13. #define _S390_PGALLOC_H
  14. #include <linux/threads.h>
  15. #include <linux/gfp.h>
  16. #include <linux/mm.h>
  17. #define check_pgt_cache() do {} while (0)
  18. unsigned long *crst_table_alloc(struct mm_struct *, int);
  19. void crst_table_free(unsigned long *);
  20. unsigned long *page_table_alloc(int);
  21. void page_table_free(unsigned long *);
  22. static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
  23. {
  24. *s = val;
  25. n = (n / 256) - 1;
  26. asm volatile(
  27. #ifdef CONFIG_64BIT
  28. " mvc 8(248,%0),0(%0)\n"
  29. #else
  30. " mvc 4(252,%0),0(%0)\n"
  31. #endif
  32. "0: mvc 256(256,%0),0(%0)\n"
  33. " la %0,256(%0)\n"
  34. " brct %1,0b\n"
  35. : "+a" (s), "+d" (n));
  36. }
  37. static inline void crst_table_init(unsigned long *crst, unsigned long entry)
  38. {
  39. clear_table(crst, entry, sizeof(unsigned long)*2048);
  40. crst = get_shadow_table(crst);
  41. if (crst)
  42. clear_table(crst, entry, sizeof(unsigned long)*2048);
  43. }
  44. #ifndef __s390x__
  45. static inline unsigned long pgd_entry_type(struct mm_struct *mm)
  46. {
  47. return _SEGMENT_ENTRY_EMPTY;
  48. }
  49. #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
  50. #define pmd_free(x) do { } while (0)
  51. #define pgd_populate(mm, pmd, pte) BUG()
  52. #define pgd_populate_kernel(mm, pmd, pte) BUG()
  53. #else /* __s390x__ */
  54. static inline unsigned long pgd_entry_type(struct mm_struct *mm)
  55. {
  56. return _REGION3_ENTRY_EMPTY;
  57. }
  58. static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
  59. {
  60. unsigned long *crst = crst_table_alloc(mm, s390_noexec);
  61. if (crst)
  62. crst_table_init(crst, _SEGMENT_ENTRY_EMPTY);
  63. return (pmd_t *) crst;
  64. }
  65. #define pmd_free(pmd) crst_table_free((unsigned long *) pmd)
  66. static inline void pgd_populate_kernel(struct mm_struct *mm,
  67. pgd_t *pgd, pmd_t *pmd)
  68. {
  69. pgd_val(*pgd) = _REGION3_ENTRY | __pa(pmd);
  70. }
  71. static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
  72. {
  73. pgd_t *shadow_pgd = get_shadow_table(pgd);
  74. pmd_t *shadow_pmd = get_shadow_table(pmd);
  75. if (shadow_pgd && shadow_pmd)
  76. pgd_populate_kernel(mm, shadow_pgd, shadow_pmd);
  77. pgd_populate_kernel(mm, pgd, pmd);
  78. }
  79. #endif /* __s390x__ */
  80. static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  81. {
  82. unsigned long *crst = crst_table_alloc(mm, s390_noexec);
  83. if (crst)
  84. crst_table_init(crst, pgd_entry_type(mm));
  85. return (pgd_t *) crst;
  86. }
  87. #define pgd_free(pgd) crst_table_free((unsigned long *) pgd)
  88. static inline void
  89. pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
  90. {
  91. #ifndef __s390x__
  92. pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
  93. pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
  94. pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
  95. pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
  96. #else /* __s390x__ */
  97. pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
  98. pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
  99. #endif /* __s390x__ */
  100. }
  101. static inline void
  102. pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
  103. {
  104. pte_t *pte = (pte_t *)page_to_phys(page);
  105. pmd_t *shadow_pmd = get_shadow_table(pmd);
  106. pte_t *shadow_pte = get_shadow_pte(pte);
  107. pmd_populate_kernel(mm, pmd, pte);
  108. if (shadow_pmd && shadow_pte)
  109. pmd_populate_kernel(mm, shadow_pmd, shadow_pte);
  110. }
  111. /*
  112. * page table entry allocation/free routines.
  113. */
  114. #define pte_alloc_one_kernel(mm, vmaddr) \
  115. ((pte_t *) page_table_alloc(s390_noexec))
  116. #define pte_alloc_one(mm, vmaddr) \
  117. virt_to_page(page_table_alloc(s390_noexec))
  118. #define pte_free_kernel(pte) \
  119. page_table_free((unsigned long *) pte)
  120. #define pte_free(pte) \
  121. page_table_free((unsigned long *) page_to_phys((struct page *) pte))
  122. #endif /* _S390_PGALLOC_H */