aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2017-05-10 00:08:44 -0400
committerJuergen Gross <jgross@suse.com>2017-05-11 09:55:20 -0400
commit69861e0a52f8733355ce246f0db15e1b240ad667 (patch)
treeda511147606697a15f627492178a46c7d3643323
parentdef9331a12977770cc6132d79f8e6565871e8e38 (diff)
xen: adjust early dom0 p2m handling to xen hypervisor behavior
When booted as pv-guest the p2m list presented by the Xen is already mapped to virtual addresses. In dom0 case the hypervisor might make use of 2M- or 1G-pages for this mapping. Unfortunately while being properly aligned in virtual and machine address space, those pages might not be aligned properly in guest physical address space. So when trying to obtain the guest physical address of such a page pud_pfn() and pmd_pfn() must be avoided as those will mask away guest physical address bits not being zero in this special case. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Juergen Gross <jgross@suse.com>
-rw-r--r--arch/x86/xen/mmu_pv.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 9d9ae6650aa1..7397d8b8459d 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2025,7 +2025,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr)
2025 2025
2026/* 2026/*
2027 * Translate a virtual address to a physical one without relying on mapped 2027 * Translate a virtual address to a physical one without relying on mapped
2028 * page tables. 2028 * page tables. Don't rely on big pages being aligned in (guest) physical
2029 * space!
2029 */ 2030 */
2030static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr) 2031static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
2031{ 2032{
@@ -2046,7 +2047,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
2046 sizeof(pud))); 2047 sizeof(pud)));
2047 if (!pud_present(pud)) 2048 if (!pud_present(pud))
2048 return 0; 2049 return 0;
2049 pa = pud_pfn(pud) << PAGE_SHIFT; 2050 pa = pud_val(pud) & PTE_PFN_MASK;
2050 if (pud_large(pud)) 2051 if (pud_large(pud))
2051 return pa + (vaddr & ~PUD_MASK); 2052 return pa + (vaddr & ~PUD_MASK);
2052 2053
@@ -2054,7 +2055,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
2054 sizeof(pmd))); 2055 sizeof(pmd)));
2055 if (!pmd_present(pmd)) 2056 if (!pmd_present(pmd))
2056 return 0; 2057 return 0;
2057 pa = pmd_pfn(pmd) << PAGE_SHIFT; 2058 pa = pmd_val(pmd) & PTE_PFN_MASK;
2058 if (pmd_large(pmd)) 2059 if (pmd_large(pmd))
2059 return pa + (vaddr & ~PMD_MASK); 2060 return pa + (vaddr & ~PMD_MASK);
2060 2061