diff options
| -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 0180ae88307..9c9e0761513 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 | ||
