|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 2/2] swiotlb-xen: implement xen_swiotlb_get_sgtable callback
On Mon, 16 Jan 2017, Andrii Anisov wrote:
> From: Andrii Anisov <andrii_anisov@xxxxxxxx>
>
> Signed-off-by: Andrii Anisov <andrii_anisov@xxxxxxxx>
Thanks for the patch!
> arch/arm/xen/mm.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
> index ff812a2..dc83a35 100644
> --- a/arch/arm/xen/mm.c
> +++ b/arch/arm/xen/mm.c
> @@ -176,6 +176,16 @@ static int xen_swiotlb_dma_mmap(struct device *dev,
> struct vm_area_struct *vma,
> return dma_common_mmap(dev, vma, cpu_addr, dma_addr, size);
> }
As for the other patch, I would move xen_swiotlb_get_sgtable to
drivers/xen/swiotlb-xen.c, if Konrad agrees.
> +static int xen_swiotlb_get_sgtable(struct device *dev, struct sg_table *sgt,
> + void *cpu_addr, dma_addr_t handle, size_t size,
> + unsigned long attrs)
> +{
> + if (__generic_dma_ops(dev)->get_sgtable)
> + return __generic_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr,
> handle,
> + size, attrs);
> + return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size);
> +}
> +
__generic_dma_ops(dev)->get_sgtable on ARM is implemented by
arm_dma_get_sgtable, which doesn't work on foreign pages (pages for
which bfn != pfn).
If get_sgtable is guaranteed to be always called passing references to
pages previously allocated with dma_alloc_coherent, then we don't have
any issues, because those can't be foreign pages. I suggest we add an
in-code comment to explain why this is safe, as for the previous patch.
I think this is the case, but I am not 100% sure.
On the other hand, if this function can be called passing as parameters
cpu_addr and handle that could potentially refer to a foreign page, then
we have a problem. On ARM, virt_to_phys doesn't work on some pages, in
fact that is the reason why ARM has its own separate get_sgtable
implementation (arm_dma_get_sgtable). But with Xen foreign pages,
dma_to_pfn doesn't work either, because we have no way of finding out
the pfn address corresponding to the mfn of the foreign page. Both
arm_dma_get_sgtable and dma_common_get_sgtable wouldn't work. I have no
solution to this problem, but maybe we could add a check like the
following (also to the previous patch?). I haven't tested it, but I
think it should work as long as page_is_ram is returns the correct value
for the handle parameter.
Signed-off-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index dc83a35..cd0441c 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -18,6 +18,7 @@
#include <xen/page.h>
#include <xen/swiotlb-xen.h>
+#include <asm/dma-mapping.h>
#include <asm/cacheflush.h>
#include <asm/xen/hypercall.h>
#include <asm/xen/interface.h>
@@ -180,9 +181,18 @@ static int xen_swiotlb_get_sgtable(struct device *dev,
struct sg_table *sgt,
void *cpu_addr, dma_addr_t handle, size_t size,
unsigned long attrs)
{
- if (__generic_dma_ops(dev)->get_sgtable)
+
+ if (__generic_dma_ops(dev)->get_sgtable) {
+ /* We can't handle foreign pages here. */
+#ifdef CONFIG_ARM
+ unsigned long bfn = dma_to_pfn(dev, handle);
+#else
+ unsigned long bfn = handle >> PAGE_SHIFT;
+#endif
+ BUG_ON (!page_is_ram(bfn));
return __generic_dma_ops(dev)->get_sgtable(dev, sgt, cpu_addr,
handle,
size, attrs);
+ }
return dma_common_get_sgtable(dev, sgt, cpu_addr, handle, size);
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |