Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=72e458dfa63b3db7a46f66b0eb19e9ff4e17fc0e
Commit:     72e458dfa63b3db7a46f66b0eb19e9ff4e17fc0e
Parent:     6bb8383bebc02dae08a17f561401f58005f75c03
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 4 16:48:07 2008 +0100
Committer:  Ingo Molnar <[EMAIL PROTECTED]>
CommitDate: Mon Feb 4 16:48:07 2008 +0100

    x86: introduce struct cpa_data
    
    The number of arguments which need to be transported is increasing
    and we want to add flush optimizations and large page preserving.
    
    Create struct cpa data and pass a pointer instead of increasing the
    number of arguments further.
    
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
---
 arch/x86/mm/pageattr.c |   75 ++++++++++++++++++++++++-----------------------
 1 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 456ad0a..d1c0830 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -16,6 +16,13 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 
+struct cpa_data {
+       unsigned long   vaddr;
+       int             numpages;
+       pgprot_t        mask_set;
+       pgprot_t        mask_clr;
+};
+
 static inline int
 within(unsigned long addr, unsigned long start, unsigned long end)
 {
@@ -284,8 +291,7 @@ out_unlock:
        return 0;
 }
 
-static int
-__change_page_attr(unsigned long address, pgprot_t mask_set, pgprot_t mask_clr)
+static int __change_page_attr(unsigned long address, struct cpa_data *cpa)
 {
        struct page *kpte_page;
        int level, err = 0;
@@ -305,12 +311,15 @@ repeat:
                pgprot_t new_prot = pte_pgprot(old_pte);
 
                if(!pte_val(old_pte)) {
-                       WARN_ON_ONCE(1);
+                       printk(KERN_WARNING "CPA: called for zero pte. "
+                              "vaddr = %lx cpa->vaddr = %lx\n", address,
+                               cpa->vaddr);
+                       WARN_ON(1);
                        return -EINVAL;
                }
 
-               pgprot_val(new_prot) &= ~pgprot_val(mask_clr);
-               pgprot_val(new_prot) |= pgprot_val(mask_set);
+               pgprot_val(new_prot) &= ~pgprot_val(cpa->mask_clr);
+               pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
 
                new_prot = static_protections(new_prot, address);
 
@@ -343,12 +352,10 @@ repeat:
  * Modules and drivers should use the set_memory_* APIs instead.
  */
 
-
-static int
-change_page_attr_addr(unsigned long address, pgprot_t mask_set,
-                     pgprot_t mask_clr)
+static int change_page_attr_addr(struct cpa_data *cpa)
 {
        int err;
+       unsigned long address = cpa->vaddr;
 
 #ifdef CONFIG_X86_64
        unsigned long phys_addr = __pa(address);
@@ -362,7 +369,7 @@ change_page_attr_addr(unsigned long address, pgprot_t 
mask_set,
                address = (unsigned long) __va(phys_addr);
 #endif
 
-       err = __change_page_attr(address, mask_set, mask_clr);
+       err = __change_page_attr(address, cpa);
        if (err)
                return err;
 
@@ -386,20 +393,19 @@ change_page_attr_addr(unsigned long address, pgprot_t 
mask_set,
                 * everything between 0 and KERNEL_TEXT_SIZE, so do
                 * not propagate lookup failures back to users:
                 */
-               __change_page_attr(address, mask_set, mask_clr);
+               __change_page_attr(address, cpa);
        }
 #endif
        return err;
 }
 
-static int __change_page_attr_set_clr(unsigned long addr, int numpages,
-                                     pgprot_t mask_set, pgprot_t mask_clr)
+static int __change_page_attr_set_clr(struct cpa_data *cpa)
 {
        unsigned int i;
        int ret;
 
-       for (i = 0; i < numpages ; i++, addr += PAGE_SIZE) {
-               ret = change_page_attr_addr(addr, mask_set, mask_clr);
+       for (i = 0; i < cpa->numpages ; i++, cpa->vaddr += PAGE_SIZE) {
+               ret = change_page_attr_addr(cpa);
                if (ret)
                        return ret;
        }
@@ -416,6 +422,7 @@ static inline int cache_attr(pgprot_t attr)
 static int change_page_attr_set_clr(unsigned long addr, int numpages,
                                    pgprot_t mask_set, pgprot_t mask_clr)
 {
+       struct cpa_data cpa;
        int ret, cache;
 
        /*
@@ -427,7 +434,12 @@ static int change_page_attr_set_clr(unsigned long addr, 
int numpages,
        if (!pgprot_val(mask_set) && !pgprot_val(mask_clr))
                return 0;
 
-       ret = __change_page_attr_set_clr(addr, numpages, mask_set, mask_clr);
+       cpa.vaddr = addr;
+       cpa.numpages = numpages;
+       cpa.mask_set = mask_set;
+       cpa.mask_clr = mask_clr;
+
+       ret = __change_page_attr_set_clr(&cpa);
 
        /*
         * No need to flush, when we did not set any of the caching
@@ -548,37 +560,26 @@ int set_pages_rw(struct page *page, int numpages)
        return set_memory_rw(addr, numpages);
 }
 
-
-#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_CPA_DEBUG)
-static inline int __change_page_attr_set(unsigned long addr, int numpages,
-                                        pgprot_t mask)
-{
-       return __change_page_attr_set_clr(addr, numpages, mask, __pgprot(0));
-}
-
-static inline int __change_page_attr_clear(unsigned long addr, int numpages,
-                                          pgprot_t mask)
-{
-       return __change_page_attr_set_clr(addr, numpages, __pgprot(0), mask);
-}
-#endif
-
 #ifdef CONFIG_DEBUG_PAGEALLOC
 
 static int __set_pages_p(struct page *page, int numpages)
 {
-       unsigned long addr = (unsigned long)page_address(page);
+       struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
+                               .numpages = numpages,
+                               .mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
+                               .mask_clr = __pgprot(0)};
 
-       return __change_page_attr_set(addr, numpages,
-                                     __pgprot(_PAGE_PRESENT | _PAGE_RW));
+       return __change_page_attr_set_clr(&cpa);
 }
 
 static int __set_pages_np(struct page *page, int numpages)
 {
-       unsigned long addr = (unsigned long)page_address(page);
+       struct cpa_data cpa = { .vaddr = (unsigned long) page_address(page),
+                               .numpages = numpages,
+                               .mask_set = __pgprot(0),
+                               .mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW)};
 
-       return __change_page_attr_clear(addr, numpages,
-                                       __pgprot(_PAGE_PRESENT));
+       return __change_page_attr_set_clr(&cpa);
 }
 
 void kernel_map_pages(struct page *page, int numpages, int enable)
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to