[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] linux/i386-PAE: avoid temporarily inconsistent pte's.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1190215609 -3600 # Node ID 08e2785d344f66abe3e84b875c3cb7b26497459f # Parent 4d713626f5b5eecfbd71ebd9f8c85c20b822fed7 linux/i386-PAE: avoid temporarily inconsistent pte's. 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. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- arch/i386/mm/pgtable-xen.c | 92 ++------------------------------------------- 1 files changed, 6 insertions(+), 86 deletions(-) diff -r 4d713626f5b5 -r 08e2785d344f arch/i386/mm/pgtable-xen.c --- a/arch/i386/mm/pgtable-xen.c Wed Sep 19 12:06:01 2007 +0100 +++ b/arch/i386/mm/pgtable-xen.c Wed Sep 19 16:26:49 2007 +0100 @@ -74,87 +74,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. @@ -204,6 +123,7 @@ void __set_fixmap (enum fixed_addresses 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(); @@ -211,16 +131,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-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |