WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] linux/i386-PAE: avoid temporarily inconsistent pte-s

To: <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] linux/i386-PAE: avoid temporarily inconsistent pte-s
From: "Jan Beulich" <jbeulich@xxxxxxxxxx>
Date: Wed, 19 Sep 2007 16:14:21 +0100
Delivery-date: Wed, 19 Sep 2007 08:14:05 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
One more of these issues (which were considered fixed): Other than on
x86-64, i386 allows set_fixmap() to replace already present mappings.
Consequently, on PAE, care must be taken to not update the high half
of a pte while the low half is still holding the old value.

As always, tested on 2.6.22 and made apply on 2.6.18.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>

Index: head-2007-09-03/arch/i386/mm/pgtable-xen.c
===================================================================
--- head-2007-09-03.orig/arch/i386/mm/pgtable-xen.c     2007-06-01 
16:57:12.000000000 +0200
+++ head-2007-09-03/arch/i386/mm/pgtable-xen.c  2007-09-19 11:04:16.000000000 
+0200
@@ -77,87 +77,6 @@ void show_mem(void)
 }
 
 /*
- * Associate a virtual page frame with a given physical page frame 
- * and protection flags for that frame.
- */ 
-static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
-{
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       pgd = swapper_pg_dir + pgd_index(vaddr);
-       if (pgd_none(*pgd)) {
-               BUG();
-               return;
-       }
-       pud = pud_offset(pgd, vaddr);
-       if (pud_none(*pud)) {
-               BUG();
-               return;
-       }
-       pmd = pmd_offset(pud, vaddr);
-       if (pmd_none(*pmd)) {
-               BUG();
-               return;
-       }
-       pte = pte_offset_kernel(pmd, vaddr);
-       if (pgprot_val(flags))
-               /* <pfn,flags> stored as-is, to permit clearing entries */
-               set_pte(pte, pfn_pte(pfn, flags));
-       else
-               pte_clear(&init_mm, vaddr, pte);
-
-       /*
-        * It's enough to flush this one mapping.
-        * (PGE mappings get flushed as well)
-        */
-       __flush_tlb_one(vaddr);
-}
-
-/*
- * Associate a virtual page frame with a given physical page frame 
- * and protection flags for that frame.
- */ 
-static void set_pte_pfn_ma(unsigned long vaddr, unsigned long pfn,
-                          pgprot_t flags)
-{
-       pgd_t *pgd;
-       pud_t *pud;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       pgd = swapper_pg_dir + pgd_index(vaddr);
-       if (pgd_none(*pgd)) {
-               BUG();
-               return;
-       }
-       pud = pud_offset(pgd, vaddr);
-       if (pud_none(*pud)) {
-               BUG();
-               return;
-       }
-       pmd = pmd_offset(pud, vaddr);
-       if (pmd_none(*pmd)) {
-               BUG();
-               return;
-       }
-       pte = pte_offset_kernel(pmd, vaddr);
-       if (pgprot_val(flags))
-               /* <pfn,flags> stored as-is, to permit clearing entries */
-               set_pte(pte, pfn_pte_ma(pfn, flags));
-       else
-               pte_clear(&init_mm, vaddr, pte);
-
-       /*
-        * It's enough to flush this one mapping.
-        * (PGE mappings get flushed as well)
-        */
-       __flush_tlb_one(vaddr);
-}
-
-/*
  * Associate a large virtual page frame with a given physical page frame 
  * and protection flags for that frame. pfn is for the base of the page,
  * vaddr is what the page gets mapped to - both must be properly aligned. 
@@ -200,6 +119,7 @@ EXPORT_SYMBOL(__FIXADDR_TOP);
 void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
 {
        unsigned long address = __fix_to_virt(idx);
+       pte_t pte;
 
        if (idx >= __end_of_fixed_addresses) {
                BUG();
@@ -207,16 +127,16 @@ void __set_fixmap (enum fixed_addresses 
        }
        switch (idx) {
        case FIX_WP_TEST:
-#ifdef CONFIG_X86_F00F_BUG
-       case FIX_F00F_IDT:
-#endif
        case FIX_VDSO:
-               set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
+               pte = pfn_pte(phys >> PAGE_SHIFT, flags);
                break;
        default:
-               set_pte_pfn_ma(address, phys >> PAGE_SHIFT, flags);
+               pte = pfn_pte_ma(phys >> PAGE_SHIFT, flags);
                break;
        }
+       if (HYPERVISOR_update_va_mapping(address, pte,
+                                        UVMF_INVLPG|UVMF_ALL))
+               BUG();
        nr_fixmaps++;
 }
 




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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] linux/i386-PAE: avoid temporarily inconsistent pte-s, Jan Beulich <=