pgtable.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * arch/s390/mm/pgtable.c
  3. *
  4. * Copyright IBM Corp. 2007
  5. * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  6. */
  7. #include <linux/sched.h>
  8. #include <linux/kernel.h>
  9. #include <linux/errno.h>
  10. #include <linux/mm.h>
  11. #include <linux/swap.h>
  12. #include <linux/smp.h>
  13. #include <linux/highmem.h>
  14. #include <linux/slab.h>
  15. #include <linux/pagemap.h>
  16. #include <linux/spinlock.h>
  17. #include <linux/module.h>
  18. #include <linux/quicklist.h>
  19. #include <asm/system.h>
  20. #include <asm/pgtable.h>
  21. #include <asm/pgalloc.h>
  22. #include <asm/tlb.h>
  23. #include <asm/tlbflush.h>
  24. #ifndef CONFIG_64BIT
  25. #define ALLOC_ORDER 1
  26. #else
  27. #define ALLOC_ORDER 2
  28. #endif
  29. unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
  30. {
  31. struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
  32. if (!page)
  33. return NULL;
  34. page->index = 0;
  35. if (noexec) {
  36. struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
  37. if (!shadow) {
  38. __free_pages(page, ALLOC_ORDER);
  39. return NULL;
  40. }
  41. page->index = page_to_phys(shadow);
  42. }
  43. return (unsigned long *) page_to_phys(page);
  44. }
  45. void crst_table_free(unsigned long *table)
  46. {
  47. unsigned long *shadow = get_shadow_table(table);
  48. if (shadow)
  49. free_pages((unsigned long) shadow, ALLOC_ORDER);
  50. free_pages((unsigned long) table, ALLOC_ORDER);
  51. }
  52. /*
  53. * page table entry allocation/free routines.
  54. */
  55. unsigned long *page_table_alloc(int noexec)
  56. {
  57. struct page *page = alloc_page(GFP_KERNEL);
  58. unsigned long *table;
  59. if (!page)
  60. return NULL;
  61. page->index = 0;
  62. if (noexec) {
  63. struct page *shadow = alloc_page(GFP_KERNEL);
  64. if (!shadow) {
  65. __free_page(page);
  66. return NULL;
  67. }
  68. table = (unsigned long *) page_to_phys(shadow);
  69. clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
  70. page->index = (addr_t) table;
  71. }
  72. table = (unsigned long *) page_to_phys(page);
  73. clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
  74. return table;
  75. }
  76. void page_table_free(unsigned long *table)
  77. {
  78. unsigned long *shadow = get_shadow_pte(table);
  79. if (shadow)
  80. free_page((unsigned long) shadow);
  81. free_page((unsigned long) table);
  82. }