[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] More PAE PGD fixes. Ensure we do not pin PGDs with no kernel



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 0ec1d38f26f76512487717cf2109ada189efc3e4
# Parent  86964d50bcfac60dbbeba3866b32ad862ec70b2e
More PAE PGD fixes. Ensure we do not pin PGDs with no kernel
PMD (Xen will not allow it). This is okay even across
suspend/resume -- such PGDs are completely empty and so
contain no PTEs that become garbage across suspend/resume.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 86964d50bcfa -r 0ec1d38f26f7 
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Nov 24 17:19:51 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Nov 24 18:16:13 2005
@@ -27,8 +27,9 @@
 #include <asm-xen/foreign_page.h>
 #include <asm/hypervisor.h>
 
-static void __pgd_pin(pgd_t *pgd);
-static void __pgd_unpin(pgd_t *pgd);
+static void pgd_test_and_unpin(pgd_t *pgd);
+#define suspend_disable        preempt_disable
+#define suspend_enable preempt_enable
 
 void show_mem(void)
 {
@@ -310,8 +311,7 @@
        pgd_list_del(pgd);
        spin_unlock_irqrestore(&pgd_lock, flags);
 
-       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
-               __pgd_unpin(pgd);
+       pgd_test_and_unpin(pgd);
 }
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -319,8 +319,7 @@
        int i = 0;
        pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
 
-       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
-               __pgd_unpin(pgd);
+       pgd_test_and_unpin(pgd);
 
        if (PTRS_PER_PMD == 1 || !pgd)
                return pgd;
@@ -347,11 +346,11 @@
                pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
                if (!pmd)
                        goto out_oom;
-               preempt_disable();
+               suspend_disable();
                if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
                        make_lowmem_page_readonly(pmd);
                set_pgd(&pgd[i], __pgd(1 + __pa(pmd)));
-               preempt_enable();
+               suspend_enable();
        }
        return pgd;
 
@@ -366,8 +365,8 @@
 {
        int i;
 
-       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
-               __pgd_unpin(pgd);
+       suspend_disable();
+       pgd_test_and_unpin(pgd);
 
        /* in the PAE case user pgd entries are overwritten before usage */
        if (PTRS_PER_PMD > 1) {
@@ -385,6 +384,9 @@
                        kmem_cache_free(pmd_cache, pmd);
                }
        }
+
+       suspend_enable();
+
        /* in the non-PAE case, free_pgtables() clears user pgd entries */
        kmem_cache_free(pgd_cache, pgd);
 }
@@ -509,6 +511,9 @@
 
 static void __pgd_pin(pgd_t *pgd)
 {
+       /* PAE PGDs with no kernel PMD cannot be pinned. Bail right now. */
+       if ((PTRS_PER_PMD > 1) && pgd_none(pgd[USER_PTRS_PER_PGD]))
+               return;
        pgd_walk(pgd, PAGE_KERNEL_RO);
        xen_pgd_pin(__pa(pgd));
        set_bit(PG_pinned, &virt_to_page(pgd)->flags);
@@ -519,6 +524,14 @@
        xen_pgd_unpin(__pa(pgd));
        pgd_walk(pgd, PAGE_KERNEL);
        clear_bit(PG_pinned, &virt_to_page(pgd)->flags);
+}
+
+static void pgd_test_and_unpin(pgd_t *pgd)
+{
+       suspend_disable();
+       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
+               __pgd_unpin(pgd);
+       suspend_enable();
 }
 
 void mm_pin(struct mm_struct *mm)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.