diff mbox

[Xen-devel,v4,19/21] xen/arm: grant: Add another entry to map MFN 1:1 in dom0 p2m

Message ID 1398172475-27873-20-git-send-email-julien.grall@linaro.org
State Superseded, archived
Headers show

Commit Message

Julien Grall April 22, 2014, 1:14 p.m. UTC
Grant mapping can be used for DMA request. The dev_bus_addr returned by the
hypercall is the MFN (not the IPA). Currently Linux is using this address (via
swiotlb) to program the DMA.
When the device is protected by IOMMU the request will fail. We have to
add 1:1 mapping in the domain p2m to allow DMA request working.

This is valid because DOM0 has its memory mapped 1:1.

Signed-off-by: Julien Grall <julien.grall@linaro.org>

---
    Changes in v4:
        - Patch added
---
 xen/arch/arm/mm.c |   33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

Comments

Ian Campbell April 28, 2014, 2:11 p.m. UTC | #1
On Tue, 2014-04-22 at 14:14 +0100, Julien Grall wrote:
> Grant mapping can be used for DMA request. The dev_bus_addr returned by the
> hypercall is the MFN (not the IPA). Currently Linux is using this address (via
> swiotlb) to program the DMA.
> When the device is protected by IOMMU the request will fail. We have to
> add 1:1 mapping in the domain p2m to allow DMA request working.
> 
> This is valid because DOM0 has its memory mapped 1:1.
Go on to say:

... and therefore we know that RAM and devices cannot clash (or
something).

> Signed-off-by: Julien Grall <julien.grall@linaro.org>

With that: Acked-by: Ian Campbell <ian.campbell@citrix.com>
Julien Grall April 28, 2014, 2:47 p.m. UTC | #2
On 04/28/2014 03:11 PM, Ian Campbell wrote:
> On Tue, 2014-04-22 at 14:14 +0100, Julien Grall wrote:
>> Grant mapping can be used for DMA request. The dev_bus_addr returned by the
>> hypercall is the MFN (not the IPA). Currently Linux is using this address (via
>> swiotlb) to program the DMA.
>> When the device is protected by IOMMU the request will fail. We have to
>> add 1:1 mapping in the domain p2m to allow DMA request working.
>>
>> This is valid because DOM0 has its memory mapped 1:1.
> Go on to say:
> 
> ... and therefore we know that RAM and devices cannot clash (or
> something).

Your sentence sounds good. I will update the commit message with it.

>> Signed-off-by: Julien Grall <julien.grall@linaro.org>
> 
> With that: Acked-by: Ian Campbell <ian.campbell@citrix.com>

Thanks!
diff mbox

Patch

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 362bc8d..998db1d 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -1199,6 +1199,7 @@  int create_grant_host_mapping(unsigned long addr, unsigned long frame,
 {
     int rc;
     p2m_type_t t = p2m_grant_map_rw;
+    struct domain *d = current->domain;
 
     if ( cache_flags  || (flags & ~GNTMAP_readonly) != GNTMAP_host_map )
         return GNTST_general_error;
@@ -1206,13 +1207,32 @@  int create_grant_host_mapping(unsigned long addr, unsigned long frame,
     if ( flags & GNTMAP_readonly )
         t = p2m_grant_map_ro;
 
-    rc = guest_physmap_add_entry(current->domain, addr >> PAGE_SHIFT,
-                                 frame, 0, t);
+    rc = guest_physmap_add_entry(d, addr >> PAGE_SHIFT, frame, 0, t);
 
     if ( rc )
-        return GNTST_general_error;
-    else
-        return GNTST_okay;
+        goto gerror;
+
+    /* Grant mapping can be used for DMA request. The dev_bus_addr returned by
+     * the hypercall is the MFN (not the IPA). For device protected by
+     * an IOMMU, Xen needs to add a 1:1 mapping in the domain p2m to
+     * allow DMA request working.
+     * This is only valid when the domain is directed mapped
+     */
+    if ( is_domain_direct_mapped(d) && need_iommu(d) )
+    {
+        rc = guest_physmap_add_entry(d, frame, frame, 0, t);
+        if ( rc )
+            goto unmap;
+    }
+
+    return GNTST_okay;
+
+unmap:
+    guest_physmap_remove_page(d, addr >> PAGE_SHIFT, frame, 0);
+
+gerror:
+    return GNTST_general_error;
+
 }
 
 int replace_grant_host_mapping(unsigned long addr, unsigned long mfn,
@@ -1226,6 +1246,9 @@  int replace_grant_host_mapping(unsigned long addr, unsigned long mfn,
 
     guest_physmap_remove_page(d, gfn, mfn, 0);
 
+    if ( is_domain_direct_mapped(d) && need_iommu(d) )
+        guest_physmap_remove_page(d, mfn, mfn, 0);
+
     return GNTST_okay;
 }