diff options
author | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-01-05 15:46:31 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2011-03-14 11:17:08 -0400 |
commit | fb38923ead10aa8a28db191548e176e8856614d7 (patch) | |
tree | 320b63258f4a109d91e6836347ce2bb46ad720fd /arch/x86/xen/mmu.c | |
parent | f4cec35b0d4b90d96e3770a3d1e68ea882e7a7c8 (diff) |
xen/mmu: Set _PAGE_IOMAP if PFN is an identity PFN.
If we find that the PFN is within the P2M as an identity
PFN make sure to tack on the _PAGE_IOMAP flag.
Reviewed-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r-- | arch/x86/xen/mmu.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 0180ae88307b..9c9e07615139 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -416,8 +416,12 @@ static pteval_t pte_pfn_to_mfn(pteval_t val) | |||
416 | if (val & _PAGE_PRESENT) { | 416 | if (val & _PAGE_PRESENT) { |
417 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; | 417 | unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT; |
418 | pteval_t flags = val & PTE_FLAGS_MASK; | 418 | pteval_t flags = val & PTE_FLAGS_MASK; |
419 | unsigned long mfn = pfn_to_mfn(pfn); | 419 | unsigned long mfn; |
420 | 420 | ||
421 | if (!xen_feature(XENFEAT_auto_translated_physmap)) | ||
422 | mfn = get_phys_to_machine(pfn); | ||
423 | else | ||
424 | mfn = pfn; | ||
421 | /* | 425 | /* |
422 | * If there's no mfn for the pfn, then just create an | 426 | * If there's no mfn for the pfn, then just create an |
423 | * empty non-present pte. Unfortunately this loses | 427 | * empty non-present pte. Unfortunately this loses |
@@ -427,8 +431,18 @@ static pteval_t pte_pfn_to_mfn(pteval_t val) | |||
427 | if (unlikely(mfn == INVALID_P2M_ENTRY)) { | 431 | if (unlikely(mfn == INVALID_P2M_ENTRY)) { |
428 | mfn = 0; | 432 | mfn = 0; |
429 | flags = 0; | 433 | flags = 0; |
434 | } else { | ||
435 | /* | ||
436 | * Paramount to do this test _after_ the | ||
437 | * INVALID_P2M_ENTRY as INVALID_P2M_ENTRY & | ||
438 | * IDENTITY_FRAME_BIT resolves to true. | ||
439 | */ | ||
440 | mfn &= ~FOREIGN_FRAME_BIT; | ||
441 | if (mfn & IDENTITY_FRAME_BIT) { | ||
442 | mfn &= ~IDENTITY_FRAME_BIT; | ||
443 | flags |= _PAGE_IOMAP; | ||
444 | } | ||
430 | } | 445 | } |
431 | |||
432 | val = ((pteval_t)mfn << PAGE_SHIFT) | flags; | 446 | val = ((pteval_t)mfn << PAGE_SHIFT) | flags; |
433 | } | 447 | } |
434 | 448 | ||