aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--drivers/xen/swiotlb-xen.c22
2 files changed, 21 insertions, 2 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c1f1a7eee953..24307dc85d08 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1885,6 +1885,7 @@ config XEN
1885 depends on !GENERIC_ATOMIC64 1885 depends on !GENERIC_ATOMIC64
1886 select ARM_PSCI 1886 select ARM_PSCI
1887 select SWIOTLB_XEN 1887 select SWIOTLB_XEN
1888 select ARCH_DMA_ADDR_T_64BIT
1888 help 1889 help
1889 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. 1890 Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
1890 1891
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 1eac0731c349..ebd8f218a788 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -75,14 +75,32 @@ static unsigned long xen_io_tlb_nslabs;
75 75
76static u64 start_dma_addr; 76static u64 start_dma_addr;
77 77
78/*
79 * Both of these functions should avoid PFN_PHYS because phys_addr_t
80 * can be 32bit when dma_addr_t is 64bit leading to a loss in
81 * information if the shift is done before casting to 64bit.
82 */
78static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr) 83static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
79{ 84{
80 return phys_to_machine(XPADDR(paddr)).maddr; 85 unsigned long mfn = pfn_to_mfn(PFN_DOWN(paddr));
86 dma_addr_t dma = (dma_addr_t)mfn << PAGE_SHIFT;
87
88 dma |= paddr & ~PAGE_MASK;
89
90 return dma;
81} 91}
82 92
83static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr) 93static inline phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
84{ 94{
85 return machine_to_phys(XMADDR(baddr)).paddr; 95 unsigned long pfn = mfn_to_pfn(PFN_DOWN(baddr));
96 dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
97 phys_addr_t paddr = dma;
98
99 BUG_ON(paddr != dma); /* truncation has occurred, should never happen */
100
101 paddr |= baddr & ~PAGE_MASK;
102
103 return paddr;
86} 104}
87 105
88static inline dma_addr_t xen_virt_to_bus(void *address) 106static inline dma_addr_t xen_virt_to_bus(void *address)