Skip to content

Commit 5926f87

Browse files
author
David Vrabel
committed
Revert "xen: properly account for _PAGE_NUMA during xen pte translations"
This reverts commit a9c8e4b. PTEs in Xen PV guests must contain machine addresses if _PAGE_PRESENT is set and pseudo-physical addresses is _PAGE_PRESENT is clear. This is because during a domain save/restore (migration) the page table entries are "canonicalised" and uncanonicalised". i.e., MFNs are converted to PFNs during domain save so that on a restore the page table entries may be rewritten with the new MFNs on the destination. This canonicalisation is only done for PTEs that are present. This change resulted in writing PTEs with MFNs if _PAGE_PROTNONE (or _PAGE_NUMA) was set but _PAGE_PRESENT was clear. These PTEs would be migrated as-is which would result in unexpected behaviour in the destination domain. Either a) the MFN would be translated to the wrong PFN/page; b) setting the _PAGE_PRESENT bit would clear the PTE because the MFN is no longer owned by the domain; or c) the present bit would not get set. Symptoms include "Bad page" reports when munmapping after migrating a domain. Signed-off-by: David Vrabel <david.vrabel@citrix.com> Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: <stable@vger.kernel.org> [3.12+]
1 parent 09ed3d5 commit 5926f87

File tree

2 files changed

+4
-14
lines changed

2 files changed

+4
-14
lines changed

arch/x86/include/asm/pgtable.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -445,20 +445,10 @@ static inline int pte_same(pte_t a, pte_t b)
445445
return a.pte == b.pte;
446446
}
447447

448-
static inline int pteval_present(pteval_t pteval)
449-
{
450-
/*
451-
* Yes Linus, _PAGE_PROTNONE == _PAGE_NUMA. Expressing it this
452-
* way clearly states that the intent is that protnone and numa
453-
* hinting ptes are considered present for the purposes of
454-
* pagetable operations like zapping, protection changes, gup etc.
455-
*/
456-
return pteval & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_NUMA);
457-
}
458-
459448
static inline int pte_present(pte_t a)
460449
{
461-
return pteval_present(pte_flags(a));
450+
return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE |
451+
_PAGE_NUMA);
462452
}
463453

464454
#define pte_accessible pte_accessible

arch/x86/xen/mmu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
365365
/* Assume pteval_t is equivalent to all the other *val_t types. */
366366
static pteval_t pte_mfn_to_pfn(pteval_t val)
367367
{
368-
if (pteval_present(val)) {
368+
if (val & _PAGE_PRESENT) {
369369
unsigned long mfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
370370
unsigned long pfn = mfn_to_pfn(mfn);
371371

@@ -381,7 +381,7 @@ static pteval_t pte_mfn_to_pfn(pteval_t val)
381381

382382
static pteval_t pte_pfn_to_mfn(pteval_t val)
383383
{
384-
if (pteval_present(val)) {
384+
if (val & _PAGE_PRESENT) {
385385
unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
386386
pteval_t flags = val & PTE_FLAGS_MASK;
387387
unsigned long mfn;

0 commit comments

Comments
 (0)