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

[Xen-changelog] Fix pgd allocation for PAE. We must handle the fact that



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 86964d50bcfac60dbbeba3866b32ad862ec70b2e
# Parent  a9fef115e8ecefc769072aaee4a32ba41792d195
Fix pgd allocation for PAE. We must handle the fact that
a PGD may get pinned under our feet by suspend/resume.

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

diff -r a9fef115e8ec -r 86964d50bcfa 
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 16:13:46 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c   Thu Nov 24 17:19:51 2005
@@ -303,14 +303,15 @@
 {
        unsigned long flags; /* can be called from interrupt context */
 
-       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
-
        if (HAVE_SHARED_KERNEL_PMD)
                return;
 
        spin_lock_irqsave(&pgd_lock, flags);
        pgd_list_del(pgd);
        spin_unlock_irqrestore(&pgd_lock, flags);
+
+       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
+               __pgd_unpin(pgd);
 }
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
@@ -318,7 +319,8 @@
        int i = 0;
        pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
 
-       BUG_ON(test_bit(PG_pinned, &virt_to_page(pgd)->flags));
+       if (test_bit(PG_pinned, &virt_to_page(pgd)->flags))
+               __pgd_unpin(pgd);
 
        if (PTRS_PER_PMD == 1 || !pgd)
                return pgd;
@@ -345,7 +347,11 @@
                pmd_t *pmd = kmem_cache_alloc(pmd_cache, GFP_KERNEL);
                if (!pmd)
                        goto out_oom;
+               preempt_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();
        }
        return pgd;
 
@@ -367,11 +373,13 @@
        if (PTRS_PER_PMD > 1) {
                for (i = 0; i < USER_PTRS_PER_PGD; ++i) {
                        pmd_t *pmd = (void *)__va(pgd_val(pgd[i])-1);
+                       set_pgd(&pgd[i], __pgd(0));
                        make_lowmem_page_writable(pmd);
                        kmem_cache_free(pmd_cache, pmd);
                }
                if (!HAVE_SHARED_KERNEL_PMD) {
                        pmd_t *pmd = (void 
*)__va(pgd_val(pgd[USER_PTRS_PER_PGD])-1);
+                       set_pgd(&pgd[USER_PTRS_PER_PGD], __pgd(0));
                        make_lowmem_page_writable(pmd);
                        memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t));
                        kmem_cache_free(pmd_cache, pmd);

_______________________________________________
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®.