aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/mm/fault_32.c3
-rw-r--r--arch/x86/mm/init_32.c3
-rw-r--r--arch/x86/mm/pageattr_32.c7
-rw-r--r--arch/x86/mm/pageattr_64.c7
-rw-r--r--arch/x86/xen/mmu.c9
-rw-r--r--include/asm-x86/pgtable_32.h2
-rw-r--r--include/asm-x86/pgtable_64.h2
7 files changed, 22 insertions, 11 deletions
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index f7972ae7da07..f4f8c324715f 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -613,7 +613,8 @@ no_context:
613 613
614#ifdef CONFIG_X86_PAE 614#ifdef CONFIG_X86_PAE
615 if (error_code & PF_INSTR) { 615 if (error_code & PF_INSTR) {
616 pte_t *pte = lookup_address(address); 616 int level;
617 pte_t *pte = lookup_address(address, &level);
617 618
618 if (pte && pte_present(*pte) && !pte_exec(*pte)) 619 if (pte && pte_present(*pte) && !pte_exec(*pte))
619 printk(KERN_CRIT "kernel tried to execute " 620 printk(KERN_CRIT "kernel tried to execute "
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 5080646da771..206e3f6800b9 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -535,11 +535,12 @@ int __init set_kernel_exec(unsigned long vaddr, int enable)
535{ 535{
536 pte_t *pte; 536 pte_t *pte;
537 int ret = 1; 537 int ret = 1;
538 int level;
538 539
539 if (!nx_enabled) 540 if (!nx_enabled)
540 goto out; 541 goto out;
541 542
542 pte = lookup_address(vaddr); 543 pte = lookup_address(vaddr, &level);
543 BUG_ON(!pte); 544 BUG_ON(!pte);
544 545
545 if (!pte_exec(*pte)) 546 if (!pte_exec(*pte))
diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c
index be4656403d77..523fd5b37df9 100644
--- a/arch/x86/mm/pageattr_32.c
+++ b/arch/x86/mm/pageattr_32.c
@@ -18,7 +18,7 @@
18static DEFINE_SPINLOCK(cpa_lock); 18static DEFINE_SPINLOCK(cpa_lock);
19static struct list_head df_list = LIST_HEAD_INIT(df_list); 19static struct list_head df_list = LIST_HEAD_INIT(df_list);
20 20
21pte_t *lookup_address(unsigned long address) 21pte_t *lookup_address(unsigned long address, int *level)
22{ 22{
23 pgd_t *pgd = pgd_offset_k(address); 23 pgd_t *pgd = pgd_offset_k(address);
24 pud_t *pud; 24 pud_t *pud;
@@ -32,8 +32,10 @@ pte_t *lookup_address(unsigned long address)
32 pmd = pmd_offset(pud, address); 32 pmd = pmd_offset(pud, address);
33 if (pmd_none(*pmd)) 33 if (pmd_none(*pmd))
34 return NULL; 34 return NULL;
35 *level = 2;
35 if (pmd_large(*pmd)) 36 if (pmd_large(*pmd))
36 return (pte_t *)pmd; 37 return (pte_t *)pmd;
38 *level = 3;
37 39
38 return pte_offset_kernel(pmd, address); 40 return pte_offset_kernel(pmd, address);
39} 41}
@@ -156,11 +158,12 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
156 struct page *kpte_page; 158 struct page *kpte_page;
157 unsigned long address; 159 unsigned long address;
158 pte_t *kpte; 160 pte_t *kpte;
161 int level;
159 162
160 BUG_ON(PageHighMem(page)); 163 BUG_ON(PageHighMem(page));
161 address = (unsigned long)page_address(page); 164 address = (unsigned long)page_address(page);
162 165
163 kpte = lookup_address(address); 166 kpte = lookup_address(address, &level);
164 if (!kpte) 167 if (!kpte)
165 return -EINVAL; 168 return -EINVAL;
166 169
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
index 14ab327cde0c..59cd066f6741 100644
--- a/arch/x86/mm/pageattr_64.c
+++ b/arch/x86/mm/pageattr_64.c
@@ -14,7 +14,7 @@
14#include <asm/uaccess.h> 14#include <asm/uaccess.h>
15#include <asm/io.h> 15#include <asm/io.h>
16 16
17pte_t *lookup_address(unsigned long address) 17pte_t *lookup_address(unsigned long address, int *level)
18{ 18{
19 pgd_t *pgd = pgd_offset_k(address); 19 pgd_t *pgd = pgd_offset_k(address);
20 pud_t *pud; 20 pud_t *pud;
@@ -29,8 +29,10 @@ pte_t *lookup_address(unsigned long address)
29 pmd = pmd_offset(pud, address); 29 pmd = pmd_offset(pud, address);
30 if (!pmd_present(*pmd)) 30 if (!pmd_present(*pmd))
31 return NULL; 31 return NULL;
32 *level = 3;
32 if (pmd_large(*pmd)) 33 if (pmd_large(*pmd))
33 return (pte_t *)pmd; 34 return (pte_t *)pmd;
35 *level = 4;
34 36
35 pte = pte_offset_kernel(pmd, address); 37 pte = pte_offset_kernel(pmd, address);
36 if (pte && !pte_present(*pte)) 38 if (pte && !pte_present(*pte))
@@ -140,8 +142,9 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
140 struct page *kpte_page; 142 struct page *kpte_page;
141 pgprot_t ref_prot2; 143 pgprot_t ref_prot2;
142 pte_t *kpte; 144 pte_t *kpte;
145 int level;
143 146
144 kpte = lookup_address(address); 147 kpte = lookup_address(address, &level);
145 if (!kpte) 148 if (!kpte)
146 return 0; 149 return 0;
147 150
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index e6184735545f..45aa771e73a9 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -58,7 +58,8 @@
58 58
59xmaddr_t arbitrary_virt_to_machine(unsigned long address) 59xmaddr_t arbitrary_virt_to_machine(unsigned long address)
60{ 60{
61 pte_t *pte = lookup_address(address); 61 int level;
62 pte_t *pte = lookup_address(address, &level);
62 unsigned offset = address & PAGE_MASK; 63 unsigned offset = address & PAGE_MASK;
63 64
64 BUG_ON(pte == NULL); 65 BUG_ON(pte == NULL);
@@ -70,8 +71,9 @@ void make_lowmem_page_readonly(void *vaddr)
70{ 71{
71 pte_t *pte, ptev; 72 pte_t *pte, ptev;
72 unsigned long address = (unsigned long)vaddr; 73 unsigned long address = (unsigned long)vaddr;
74 int level;
73 75
74 pte = lookup_address(address); 76 pte = lookup_address(address, &level);
75 BUG_ON(pte == NULL); 77 BUG_ON(pte == NULL);
76 78
77 ptev = pte_wrprotect(*pte); 79 ptev = pte_wrprotect(*pte);
@@ -84,8 +86,9 @@ void make_lowmem_page_readwrite(void *vaddr)
84{ 86{
85 pte_t *pte, ptev; 87 pte_t *pte, ptev;
86 unsigned long address = (unsigned long)vaddr; 88 unsigned long address = (unsigned long)vaddr;
89 int level;
87 90
88 pte = lookup_address(address); 91 pte = lookup_address(address, &level);
89 BUG_ON(pte == NULL); 92 BUG_ON(pte == NULL);
90 93
91 ptev = pte_mkwrite(*pte); 94 ptev = pte_mkwrite(*pte);
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index eb8cccfa6a49..9381bd37b9b1 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -182,7 +182,7 @@ static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
182 * NOTE: the return type is pte_t but if the pmd is PSE then we return it 182 * NOTE: the return type is pte_t but if the pmd is PSE then we return it
183 * as a pte too. 183 * as a pte too.
184 */ 184 */
185extern pte_t *lookup_address(unsigned long address); 185extern pte_t *lookup_address(unsigned long address, int *level);
186 186
187/* 187/*
188 * Make a given kernel text page executable/non-executable. 188 * Make a given kernel text page executable/non-executable.
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index 29fdeb8111bb..139da50cd510 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -240,7 +240,7 @@ extern struct list_head pgd_list;
240 240
241extern int kern_addr_valid(unsigned long addr); 241extern int kern_addr_valid(unsigned long addr);
242 242
243pte_t *lookup_address(unsigned long addr); 243pte_t *lookup_address(unsigned long addr, int *level);
244 244
245#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 245#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
246 remap_pfn_range(vma, vaddr, pfn, size, prot) 246 remap_pfn_range(vma, vaddr, pfn, size, prot)