aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r--arch/x86/xen/mmu.c48
1 files changed, 4 insertions, 44 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 16fb0099b7f2..f62af7647ec9 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -399,38 +399,14 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
399 if (unlikely(mfn == INVALID_P2M_ENTRY)) { 399 if (unlikely(mfn == INVALID_P2M_ENTRY)) {
400 mfn = 0; 400 mfn = 0;
401 flags = 0; 401 flags = 0;
402 } else { 402 } else
403 /* 403 mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
404 * Paramount to do this test _after_ the
405 * INVALID_P2M_ENTRY as INVALID_P2M_ENTRY &
406 * IDENTITY_FRAME_BIT resolves to true.
407 */
408 mfn &= ~FOREIGN_FRAME_BIT;
409 if (mfn & IDENTITY_FRAME_BIT) {
410 mfn &= ~IDENTITY_FRAME_BIT;
411 flags |= _PAGE_IOMAP;
412 }
413 }
414 val = ((pteval_t)mfn << PAGE_SHIFT) | flags; 404 val = ((pteval_t)mfn << PAGE_SHIFT) | flags;
415 } 405 }
416 406
417 return val; 407 return val;
418} 408}
419 409
420static pteval_t iomap_pte(pteval_t val)
421{
422 if (val & _PAGE_PRESENT) {
423 unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
424 pteval_t flags = val & PTE_FLAGS_MASK;
425
426 /* We assume the pte frame number is a MFN, so
427 just use it as-is. */
428 val = ((pteval_t)pfn << PAGE_SHIFT) | flags;
429 }
430
431 return val;
432}
433
434__visible pteval_t xen_pte_val(pte_t pte) 410__visible pteval_t xen_pte_val(pte_t pte)
435{ 411{
436 pteval_t pteval = pte.pte; 412 pteval_t pteval = pte.pte;
@@ -441,9 +417,6 @@ __visible pteval_t xen_pte_val(pte_t pte)
441 pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT; 417 pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
442 } 418 }
443#endif 419#endif
444 if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
445 return pteval;
446
447 return pte_mfn_to_pfn(pteval); 420 return pte_mfn_to_pfn(pteval);
448} 421}
449PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val); 422PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
@@ -481,7 +454,6 @@ void xen_set_pat(u64 pat)
481 454
482__visible pte_t xen_make_pte(pteval_t pte) 455__visible pte_t xen_make_pte(pteval_t pte)
483{ 456{
484 phys_addr_t addr = (pte & PTE_PFN_MASK);
485#if 0 457#if 0
486 /* If Linux is trying to set a WC pte, then map to the Xen WC. 458 /* If Linux is trying to set a WC pte, then map to the Xen WC.
487 * If _PAGE_PAT is set, then it probably means it is really 459 * If _PAGE_PAT is set, then it probably means it is really
@@ -496,19 +468,7 @@ __visible pte_t xen_make_pte(pteval_t pte)
496 pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT; 468 pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT;
497 } 469 }
498#endif 470#endif
499 /* 471 pte = pte_pfn_to_mfn(pte);
500 * Unprivileged domains are allowed to do IOMAPpings for
501 * PCI passthrough, but not map ISA space. The ISA
502 * mappings are just dummy local mappings to keep other
503 * parts of the kernel happy.
504 */
505 if (unlikely(pte & _PAGE_IOMAP) &&
506 (xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
507 pte = iomap_pte(pte);
508 } else {
509 pte &= ~_PAGE_IOMAP;
510 pte = pte_pfn_to_mfn(pte);
511 }
512 472
513 return native_make_pte(pte); 473 return native_make_pte(pte);
514} 474}
@@ -2091,7 +2051,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2091 2051
2092 default: 2052 default:
2093 /* By default, set_fixmap is used for hardware mappings */ 2053 /* By default, set_fixmap is used for hardware mappings */
2094 pte = mfn_pte(phys, __pgprot(pgprot_val(prot) | _PAGE_IOMAP)); 2054 pte = mfn_pte(phys, prot);
2095 break; 2055 break;
2096 } 2056 }
2097 2057