From a56a748c834077665efcdc1379073d6738dbe8c5 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 May 2007 19:27:10 +0200 Subject: [PATCH] --- yaml --- r: 53809 b: refs/heads/master c: d01ad8dd56527be72947b4b9997bb2c05783c3ed h: refs/heads/master i: 53807: 34b39274a56041baffbbc7ac202fea639f35b4a2 v: v3 --- [refs] | 2 +- trunk/arch/i386/mm/pageattr.c | 4 ++-- trunk/arch/x86_64/mm/pageattr.c | 16 ++++++++++++---- trunk/include/asm-i386/pgtable.h | 2 ++ 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index b543c5f0d27b..7844666876cb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 90a0a06aa81692028864c21f981905fda46b1208 +refs/heads/master: d01ad8dd56527be72947b4b9997bb2c05783c3ed diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index 412ebbd8adb0..ea6b6d4a0a2a 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -142,7 +142,7 @@ __change_page_attr(struct page *page, pgprot_t prot) return -EINVAL; kpte_page = virt_to_page(kpte); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { - if ((pte_val(*kpte) & _PAGE_PSE) == 0) { + if (!pte_huge(*kpte)) { set_pte_atomic(kpte, mk_pte(page, prot)); } else { pgprot_t ref_prot; @@ -158,7 +158,7 @@ __change_page_attr(struct page *page, pgprot_t prot) kpte_page = split; } page_private(kpte_page)++; - } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { + } else if (!pte_huge(*kpte)) { set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); BUG_ON(page_private(kpte_page) == 0); page_private(kpte_page)--; diff --git a/trunk/arch/x86_64/mm/pageattr.c b/trunk/arch/x86_64/mm/pageattr.c index 76ee90a5abe0..bf4aa8dd4254 100644 --- a/trunk/arch/x86_64/mm/pageattr.c +++ b/trunk/arch/x86_64/mm/pageattr.c @@ -179,16 +179,24 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) { unsigned long phys_base_pfn = __pa_symbol(__START_KERNEL_map) >> PAGE_SHIFT; - int err = 0; + int err = 0, kernel_map = 0; int i; + if (address >= __START_KERNEL_map + && address < __START_KERNEL_map + KERNEL_TEXT_SIZE) { + address = (unsigned long)__va(__pa(address)); + kernel_map = 1; + } + down_write(&init_mm.mmap_sem); for (i = 0; i < numpages; i++, address += PAGE_SIZE) { unsigned long pfn = __pa(address) >> PAGE_SHIFT; - err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); - if (err) - break; + if (!kernel_map || pte_present(pfn_pte(0, prot))) { + err = __change_page_attr(address, pfn, prot, PAGE_KERNEL); + if (err) + break; + } /* Handle kernel mapping too which aliases part of the * lowmem */ if ((pfn >= phys_base_pfn) && diff --git a/trunk/include/asm-i386/pgtable.h b/trunk/include/asm-i386/pgtable.h index c3b58d473a55..143ddc42b86f 100644 --- a/trunk/include/asm-i386/pgtable.h +++ b/trunk/include/asm-i386/pgtable.h @@ -159,6 +159,7 @@ void paging_init(void); extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define __PAGE_KERNEL_RO (__PAGE_KERNEL & ~_PAGE_RW) +#define __PAGE_KERNEL_RX (__PAGE_KERNEL_EXEC & ~_PAGE_RW) #define __PAGE_KERNEL_NOCACHE (__PAGE_KERNEL | _PAGE_PCD) #define __PAGE_KERNEL_LARGE (__PAGE_KERNEL | _PAGE_PSE) #define __PAGE_KERNEL_LARGE_EXEC (__PAGE_KERNEL_EXEC | _PAGE_PSE) @@ -166,6 +167,7 @@ extern unsigned long long __PAGE_KERNEL, __PAGE_KERNEL_EXEC; #define PAGE_KERNEL __pgprot(__PAGE_KERNEL) #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO) #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) +#define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX) #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE) #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE) #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC)