X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fmm%2Fpageattr.c;h=00ced1d84bb52159214d02bd8d8faaf3dd08dbb4;hb=fbe873afbb149c2d419a726afd27fa7be91cec58;hp=5507708153db06c9d501c63d93ff6cc4001f289f;hpb=62f00ab52b8aa6fe7d1db81d6477c635f3fa652a;p=linux-2.6.git diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 550770815..00ced1d84 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -32,8 +32,7 @@ static inline pte_t *lookup_address(unsigned long address) return pte; } -static struct page *split_large_page(unsigned long address, pgprot_t prot, - pgprot_t ref_prot) +static struct page *split_large_page(unsigned long address, pgprot_t prot) { int i; unsigned long addr; @@ -46,7 +45,7 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, pbase = (pte_t *)page_address(base); for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) { pbase[i] = pfn_pte(addr >> PAGE_SHIFT, - addr == address ? prot : ref_prot); + addr == address ? prot : PAGE_KERNEL); } return base; } @@ -96,7 +95,7 @@ static inline void save_page(unsigned long address, struct page *fpage) * No more special protections in this 2/4MB area - revert to a * large page again. */ -static void revert_page(unsigned long address, pgprot_t ref_prot) +static void revert_page(struct page *kpte_page, unsigned long address) { pgd_t *pgd; pmd_t *pmd; @@ -105,14 +104,12 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) pgd = pgd_offset_k(address); pmd = pmd_offset(pgd, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); - pgprot_val(ref_prot) |= _PAGE_PSE; - large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); + large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, PAGE_KERNEL_LARGE); set_pte((pte_t *)pmd, large_pte); } static int -__change_page_attr(unsigned long address, struct page *page, pgprot_t prot, - pgprot_t ref_prot) +__change_page_attr(unsigned long address, struct page *page, pgprot_t prot) { pte_t *kpte; struct page *kpte_page; @@ -122,29 +119,29 @@ __change_page_attr(unsigned long address, struct page *page, pgprot_t prot, if (!kpte) return 0; kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); kpte_flags = pte_val(*kpte); - if (pgprot_val(prot) != pgprot_val(ref_prot)) { + if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((kpte_flags & _PAGE_PSE) == 0) { pte_t old = *kpte; - pte_t standard = mk_pte(page, ref_prot); + pte_t standard = mk_pte(page, PAGE_KERNEL); set_pte(kpte, mk_pte(page, prot)); if (pte_same(old,standard)) get_page(kpte_page); } else { - struct page *split = split_large_page(address, prot, ref_prot); + struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; get_page(kpte_page); - set_pte(kpte,mk_pte(split, ref_prot)); + set_pte(kpte,mk_pte(split, PAGE_KERNEL)); } } else if ((kpte_flags & _PAGE_PSE) == 0) { - set_pte(kpte, mk_pte(page, ref_prot)); + set_pte(kpte, mk_pte(page, PAGE_KERNEL)); __put_page(kpte_page); } if (page_count(kpte_page) == 1) { save_page(address, kpte_page); - revert_page(address, ref_prot); + revert_page(kpte_page, address); } return 0; } @@ -170,17 +167,13 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) down_write(&init_mm.mmap_sem); for (i = 0; i < numpages; !err && i++, page++) { unsigned long address = (unsigned long)page_address(page); - err = __change_page_attr(address, page, prot, PAGE_KERNEL); + err = __change_page_attr(address, page, prot); if (err) break; - /* Handle kernel mapping too which aliases part of the - * lowmem */ - /* Disabled right now. Fixme */ - if (0 && page_to_phys(page) < KERNEL_TEXT_SIZE) { - unsigned long addr2; - addr2 = __START_KERNEL_map + page_to_phys(page); - err = __change_page_attr(addr2, page, prot, - PAGE_KERNEL_EXECUTABLE); + /* Handle kernel mapping too which aliases part of the lowmem */ + if (page_to_phys(page) < KERNEL_TEXT_SIZE) { + unsigned long addr2 = __START_KERNEL_map + page_to_phys(page); + err = __change_page_attr(addr2, page, prot); } } up_write(&init_mm.mmap_sem);