Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fac84939609a683503947f41eb93e1917d026263
Commit:     fac84939609a683503947f41eb93e1917d026263
Parent:     b1d95f4e41d6a5969e3a847ceeae8379f30c84c3
Author:     Thomas Gleixner <[EMAIL PROTECTED]>
AuthorDate: Sat Feb 9 23:24:09 2008 +0100
Committer:  Thomas Gleixner <[EMAIL PROTECTED]>
CommitDate: Sat Feb 9 23:24:09 2008 +0100

    x86: cpa, strict range check in try_preserve_large_page()
    
    Right now, we check only the first 4k page for static required protections.
    This does not take overlapping regions into account. So we might end up
    setting the wrong permissions/protections for other parts of this large 
page.
    
    This can be optimized further, but correctness is the important part.
    
    Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
---
 arch/x86/mm/pageattr.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index e5d29a1..440210a 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -253,10 +253,10 @@ static int
 try_preserve_large_page(pte_t *kpte, unsigned long address,
                        struct cpa_data *cpa)
 {
-       unsigned long nextpage_addr, numpages, pmask, psize, flags;
+       unsigned long nextpage_addr, numpages, pmask, psize, flags, addr;
        pte_t new_pte, old_pte, *tmp;
        pgprot_t old_prot, new_prot;
-       int do_split = 1;
+       int i, do_split = 1;
        unsigned int level;
 
        spin_lock_irqsave(&pgd_lock, flags);
@@ -304,6 +304,19 @@ try_preserve_large_page(pte_t *kpte, unsigned long address,
        new_prot = static_protections(new_prot, address);
 
        /*
+        * We need to check the full range, whether
+        * static_protection() requires a different pgprot for one of
+        * the pages in the range we try to preserve:
+        */
+       addr = address + PAGE_SIZE;
+       for (i = 1; i < cpa->numpages; i++, addr += PAGE_SIZE) {
+               pgprot_t chk_prot = static_protections(new_prot, addr);
+
+               if (pgprot_val(chk_prot) != pgprot_val(new_prot))
+                       goto out_unlock;
+       }
+
+       /*
         * If there are no changes, return. maxpages has been updated
         * above:
         */
-
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