ia64/xen-unstable
changeset 12411:c6efd6c2feaa
[LINUX] Fix clear_fixmap().
On i386-PAE, clear_fixmap() results in ill use of set_pte(). In all
contexts, p2m translations shouldn't occur here. Note that this is not
really an issue on native linux, as there is
(a) no pfn-to-mfn translation and
(b) __set_fixmap() takes an unsigned long physical address rather than
a paddr_t, which makes it so that bits 32 and up of the physical
address are always zero, permitting either order store when
clearing the entry.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
On i386-PAE, clear_fixmap() results in ill use of set_pte(). In all
contexts, p2m translations shouldn't occur here. Note that this is not
really an issue on native linux, as there is
(a) no pfn-to-mfn translation and
(b) __set_fixmap() takes an unsigned long physical address rather than
a paddr_t, which makes it so that bits 32 and up of the physical
address are always zero, permitting either order store when
clearing the entry.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author | kfraser@localhost.localdomain |
---|---|
date | Mon Nov 13 13:37:54 2006 +0000 (2006-11-13) |
parents | 16977bd93dbe |
children | 3dfb2eef0f05 |
files | linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon Nov 13 12:06:21 2006 +0000 1.2 +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon Nov 13 13:37:54 2006 +0000 1.3 @@ -102,8 +102,11 @@ static void set_pte_pfn(unsigned long va 1.4 return; 1.5 } 1.6 pte = pte_offset_kernel(pmd, vaddr); 1.7 - /* <pfn,flags> stored as-is, to permit clearing entries */ 1.8 - set_pte(pte, pfn_pte(pfn, flags)); 1.9 + if (pgprot_val(flags)) 1.10 + /* <pfn,flags> stored as-is, to permit clearing entries */ 1.11 + set_pte(pte, pfn_pte(pfn, flags)); 1.12 + else 1.13 + pte_clear(&init_mm, vaddr, pte); 1.14 1.15 /* 1.16 * It's enough to flush this one mapping. 1.17 @@ -140,8 +143,11 @@ static void set_pte_pfn_ma(unsigned long 1.18 return; 1.19 } 1.20 pte = pte_offset_kernel(pmd, vaddr); 1.21 - /* <pfn,flags> stored as-is, to permit clearing entries */ 1.22 - set_pte(pte, pfn_pte_ma(pfn, flags)); 1.23 + if (pgprot_val(flags)) 1.24 + /* <pfn,flags> stored as-is, to permit clearing entries */ 1.25 + set_pte(pte, pfn_pte_ma(pfn, flags)); 1.26 + else 1.27 + pte_clear(&init_mm, vaddr, pte); 1.28 1.29 /* 1.30 * It's enough to flush this one mapping.
2.1 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Mon Nov 13 12:06:21 2006 +0000 2.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Mon Nov 13 13:37:54 2006 +0000 2.3 @@ -260,7 +260,10 @@ static void set_pte_phys(unsigned long v 2.4 return; 2.5 } 2.6 } 2.7 - new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); 2.8 + if (pgprot_val(prot)) 2.9 + new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); 2.10 + else 2.11 + new_pte = __pte(0); 2.12 2.13 pte = pte_offset_kernel(pmd, vaddr); 2.14 if (!pte_none(*pte) &&