diff mbox

[v9,08/28] ARM: introduce vgic_access_guest_memory()

Message ID 20170511175340.8448-9-andre.przywara@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andre Przywara May 11, 2017, 5:53 p.m. UTC
From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>

This function allows to copy a chunk of data from and to guest physical
memory. It looks up the associated page from the guest's p2m tree
and maps this page temporarily for the time of the access.
This function was originally written by Vijaya as part of an earlier series:
https://patchwork.kernel.org/patch/8177251

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 xen/arch/arm/vgic.c        | 50 ++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/vgic.h |  3 +++
 2 files changed, 53 insertions(+)

Comments

Julien Grall May 12, 2017, 3:30 p.m. UTC | #1
Hi Andre,

On 11/05/17 18:53, Andre Przywara wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
>
> This function allows to copy a chunk of data from and to guest physical
> memory. It looks up the associated page from the guest's p2m tree
> and maps this page temporarily for the time of the access.
> This function was originally written by Vijaya as part of an earlier series:
> https://patchwork.kernel.org/patch/8177251
>
> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  xen/arch/arm/vgic.c        | 50 ++++++++++++++++++++++++++++++++++++++++++++++
>  xen/include/asm-arm/vgic.h |  3 +++
>  2 files changed, 53 insertions(+)
>
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index c29ad5e..66adeb4 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -20,6 +20,7 @@
>  #include <xen/bitops.h>
>  #include <xen/lib.h>
>  #include <xen/init.h>
> +#include <xen/domain_page.h>
>  #include <xen/softirq.h>
>  #include <xen/irq.h>
>  #include <xen/sched.h>
> @@ -620,6 +621,55 @@ void vgic_free_virq(struct domain *d, unsigned int virq)
>  }
>
>  /*
> + * Temporarily map one physical guest page and copy data to or from it.
> + * The data to be copied cannot cross a page boundary.
> + */
> +int vgic_access_guest_memory(struct domain *d, paddr_t gpa, void *buf,
> +                             uint32_t size, bool_t is_write)

s/bool_t/bool/

With that:

Reviewed-by: Julien Grall <julien.grall@arm.com>

Cheers,
diff mbox

Patch

diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index c29ad5e..66adeb4 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -20,6 +20,7 @@ 
 #include <xen/bitops.h>
 #include <xen/lib.h>
 #include <xen/init.h>
+#include <xen/domain_page.h>
 #include <xen/softirq.h>
 #include <xen/irq.h>
 #include <xen/sched.h>
@@ -620,6 +621,55 @@  void vgic_free_virq(struct domain *d, unsigned int virq)
 }
 
 /*
+ * Temporarily map one physical guest page and copy data to or from it.
+ * The data to be copied cannot cross a page boundary.
+ */
+int vgic_access_guest_memory(struct domain *d, paddr_t gpa, void *buf,
+                             uint32_t size, bool_t is_write)
+{
+    struct page_info *page;
+    uint64_t offset = gpa & ~PAGE_MASK;  /* Offset within the mapped page */
+    p2m_type_t p2mt;
+    void *p;
+
+    /* Do not cross a page boundary. */
+    if ( size > (PAGE_SIZE - offset) )
+    {
+        printk(XENLOG_G_ERR "d%d: vITS: memory access would cross page boundary\n",
+               d->domain_id);
+        return -EINVAL;
+    }
+
+    page = get_page_from_gfn(d, paddr_to_pfn(gpa), &p2mt, P2M_ALLOC);
+    if ( !page )
+    {
+        printk(XENLOG_G_ERR "d%d: vITS: Failed to get table entry\n",
+               d->domain_id);
+        return -EINVAL;
+    }
+
+    if ( !p2m_is_ram(p2mt) )
+    {
+        put_page(page);
+        printk(XENLOG_G_ERR "d%d: vITS: memory used by the ITS should be RAM.",
+               d->domain_id);
+        return -EINVAL;
+    }
+
+    p = __map_domain_page(page);
+
+    if ( is_write )
+        memcpy(p + offset, buf, size);
+    else
+        memcpy(buf, p + offset, size);
+
+    unmap_domain_page(p);
+    put_page(page);
+
+    return 0;
+}
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index 7efa164..6b17802 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -313,6 +313,9 @@  extern void register_vgic_ops(struct domain *d, const struct vgic_ops *ops);
 int vgic_v2_init(struct domain *d, int *mmio_count);
 int vgic_v3_init(struct domain *d, int *mmio_count);
 
+int vgic_access_guest_memory(struct domain *d, paddr_t gpa, void *buf,
+                             uint32_t size, bool_t is_write);
+
 extern int domain_vgic_register(struct domain *d, int *mmio_count);
 extern int vcpu_vgic_free(struct vcpu *v);
 extern bool vgic_to_sgi(struct vcpu *v, register_t sgir,