12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /*
- * arch/s390/mm/pgtable.c
- *
- * Copyright IBM Corp. 2007
- * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
- */
- #include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/mm.h>
- #include <linux/swap.h>
- #include <linux/smp.h>
- #include <linux/highmem.h>
- #include <linux/slab.h>
- #include <linux/pagemap.h>
- #include <linux/spinlock.h>
- #include <linux/module.h>
- #include <linux/quicklist.h>
- #include <asm/system.h>
- #include <asm/pgtable.h>
- #include <asm/pgalloc.h>
- #include <asm/tlb.h>
- #include <asm/tlbflush.h>
- #ifndef CONFIG_64BIT
- #define ALLOC_ORDER 1
- #else
- #define ALLOC_ORDER 2
- #endif
- unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
- {
- struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
- if (!page)
- return NULL;
- page->index = 0;
- if (noexec) {
- struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
- if (!shadow) {
- __free_pages(page, ALLOC_ORDER);
- return NULL;
- }
- page->index = page_to_phys(shadow);
- }
- return (unsigned long *) page_to_phys(page);
- }
- void crst_table_free(unsigned long *table)
- {
- unsigned long *shadow = get_shadow_table(table);
- if (shadow)
- free_pages((unsigned long) shadow, ALLOC_ORDER);
- free_pages((unsigned long) table, ALLOC_ORDER);
- }
- /*
- * page table entry allocation/free routines.
- */
- unsigned long *page_table_alloc(int noexec)
- {
- struct page *page = alloc_page(GFP_KERNEL);
- unsigned long *table;
- if (!page)
- return NULL;
- page->index = 0;
- if (noexec) {
- struct page *shadow = alloc_page(GFP_KERNEL);
- if (!shadow) {
- __free_page(page);
- return NULL;
- }
- table = (unsigned long *) page_to_phys(shadow);
- clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
- page->index = (addr_t) table;
- }
- table = (unsigned long *) page_to_phys(page);
- clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
- return table;
- }
- void page_table_free(unsigned long *table)
- {
- unsigned long *shadow = get_shadow_pte(table);
- if (shadow)
- free_page((unsigned long) shadow);
- free_page((unsigned long) table);
- }
|