aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorJulien Grall <julien.grall@citrix.com>2015-08-07 12:34:35 -0400
committerJulien Grall <julien.grall@citrix.com>2015-09-08 12:10:52 -0400
commit32e09870eedfb501a6cb5729d8c23f44f8a7cbdd (patch)
tree9b74574e53b6016f3ba1b2cd51282bd9a929d489 /drivers/xen
parent626d7508664c4bc8e67f496da4387ecd0c410b8c (diff)
xen: Make clear that swiotlb and biomerge are dealing with DMA address
The swiotlb is required when programming a DMA address on ARM when a device is not protected by an IOMMU. In this case, the DMA address should always be equal to the machine address. For DOM0 memory, Xen ensure it by have an identity mapping between the guest address and host address. However, when mapping a foreign grant reference, the 1:1 model doesn't work. For ARM guest, most of the callers of pfn_to_mfn expects to get a GFN (Guest Frame Number), i.e a PFN (Page Frame Number) from the Linux point of view given that all ARM guest are auto-translated. Even though the name pfn_to_mfn is misleading, we need to ensure that those caller get a GFN and not by mistake a MFN. In pratical, I haven't seen error related to this but we should fix it for the sake of correctness. In order to fix the implementation of pfn_to_mfn on ARM in a follow-up patch, we have to introduce new helpers to return the DMA from a PFN and the invert. On x86, the new helpers will be an alias of pfn_to_mfn and mfn_to_pfn. The helpers will be used in swiotlb and xen_biovec_phys_mergeable. This is necessary in the latter because we have to ensure that the biovec code will not try to merge a biovec using foreign page and another using Linux memory. Lastly, the helper mfn_to_local_pfn has been renamed to bfn_to_local_pfn given that the only usage was in swiotlb. Signed-off-by: Julien Grall <julien.grall@citrix.com> Reviewed-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: David Vrabel <david.vrabel@citrix.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/biomerge.c6
-rw-r--r--drivers/xen/swiotlb-xen.c16
2 files changed, 11 insertions, 11 deletions
diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
index 0edb91c0de6b..8ae2fc90e1ea 100644
--- a/drivers/xen/biomerge.c
+++ b/drivers/xen/biomerge.c
@@ -6,10 +6,10 @@
6bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, 6bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
7 const struct bio_vec *vec2) 7 const struct bio_vec *vec2)
8{ 8{
9 unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page)); 9 unsigned long bfn1 = pfn_to_bfn(page_to_pfn(vec1->bv_page));
10 unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page)); 10 unsigned long bfn2 = pfn_to_bfn(page_to_pfn(vec2->bv_page));
11 11
12 return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && 12 return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) &&
13 ((mfn1 == mfn2) || ((mfn1+1) == mfn2)); 13 ((bfn1 == bfn2) || ((bfn1+1) == bfn2));
14} 14}
15EXPORT_SYMBOL(xen_biovec_phys_mergeable); 15EXPORT_SYMBOL(xen_biovec_phys_mergeable);
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 4c549323c605..d757a3e610c6 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -82,8 +82,8 @@ static u64 start_dma_addr;
82 */ 82 */
83static 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)
84{ 84{
85 unsigned long mfn = pfn_to_mfn(PFN_DOWN(paddr)); 85 unsigned long bfn = pfn_to_bfn(PFN_DOWN(paddr));
86 dma_addr_t dma = (dma_addr_t)mfn << PAGE_SHIFT; 86 dma_addr_t dma = (dma_addr_t)bfn << PAGE_SHIFT;
87 87
88 dma |= paddr & ~PAGE_MASK; 88 dma |= paddr & ~PAGE_MASK;
89 89
@@ -92,7 +92,7 @@ static inline dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
92 92
93static 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)
94{ 94{
95 unsigned long pfn = mfn_to_pfn(PFN_DOWN(baddr)); 95 unsigned long pfn = bfn_to_pfn(PFN_DOWN(baddr));
96 dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT; 96 dma_addr_t dma = (dma_addr_t)pfn << PAGE_SHIFT;
97 phys_addr_t paddr = dma; 97 phys_addr_t paddr = dma;
98 98
@@ -110,15 +110,15 @@ static int check_pages_physically_contiguous(unsigned long pfn,
110 unsigned int offset, 110 unsigned int offset,
111 size_t length) 111 size_t length)
112{ 112{
113 unsigned long next_mfn; 113 unsigned long next_bfn;
114 int i; 114 int i;
115 int nr_pages; 115 int nr_pages;
116 116
117 next_mfn = pfn_to_mfn(pfn); 117 next_bfn = pfn_to_bfn(pfn);
118 nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT; 118 nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
119 119
120 for (i = 1; i < nr_pages; i++) { 120 for (i = 1; i < nr_pages; i++) {
121 if (pfn_to_mfn(++pfn) != ++next_mfn) 121 if (pfn_to_bfn(++pfn) != ++next_bfn)
122 return 0; 122 return 0;
123 } 123 }
124 return 1; 124 return 1;
@@ -138,8 +138,8 @@ static inline int range_straddles_page_boundary(phys_addr_t p, size_t size)
138 138
139static int is_xen_swiotlb_buffer(dma_addr_t dma_addr) 139static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
140{ 140{
141 unsigned long mfn = PFN_DOWN(dma_addr); 141 unsigned long bfn = PFN_DOWN(dma_addr);
142 unsigned long pfn = mfn_to_local_pfn(mfn); 142 unsigned long pfn = bfn_to_local_pfn(bfn);
143 phys_addr_t paddr; 143 phys_addr_t paddr;
144 144
145 /* If the address is outside our domain, it CAN 145 /* If the address is outside our domain, it CAN