[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC PATCH v2] xen/arm: Add support for GICv3 for domU



From: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>

With this patch gic version can be specified in cfg file.
If no gic version is specified, xl tool queries host
supported gic version and generate gic dt node accordingly.
Ex: If gic_version is 3, gic dt node for GICv3 is generated.

Specify gic version in cfg as 'gic_version = <version>'

This patch is based on Julien's non-pci passthrough patch
series.

Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@xxxxxxxxxxxxxxxxxx>
---
v2: - Used domainconfigure domctl to fetch gic version
    - domainconfigure return error if gic version is not compatible
    - Remove register data parameters in make_intc_node() and
      add pass gic version as parameter
---
 tools/libxc/include/xenctrl.h |    2 +-
 tools/libxc/xc_domain.c       |   10 +++++--
 tools/libxl/libxl_arm.c       |   60 ++++++++++++++++++++++++++++++-----------
 tools/libxl/libxl_types.idl   |    1 +
 tools/libxl/xl_cmdimpl.c      |    3 +++
 xen/arch/arm/domctl.c         |   33 +++++++++++++++++++++--
 xen/arch/arm/gic-v3.c         |   13 ++++++---
 xen/include/public/arch-arm.h |    8 ++++++
 xen/include/public/domctl.h   |    2 ++
 9 files changed, 108 insertions(+), 24 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 51cba70..56fe74c 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -484,7 +484,7 @@ int xc_domain_create(xc_interface *xch,
 
 #if defined(__arm__) || defined(__aarch64__)
 int xc_domain_configure(xc_interface *xch, uint32_t domid,
-                        uint32_t nr_spis);
+                        uint32_t nr_spis, uint32_t *gic_version);
 #endif
 
 /* Functions to produce a dump of a given domain
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index a55b5a8..b96c178 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -50,13 +50,19 @@ int xc_domain_create(xc_interface *xch,
 
 #if defined(__arm__) || defined(__arch64__)
 int xc_domain_configure(xc_interface *xch, uint32_t domid,
-                        uint32_t nr_spis)
+                        uint32_t nr_spis, uint32_t *version)
 {
+    int err;
     DECLARE_DOMCTL;
+
     domctl.cmd = XEN_DOMCTL_configure_domain;
     domctl.domain = (domid_t)domid;
     domctl.u.configuredomain.nr_spis = nr_spis;
-    return do_domctl(xch, &domctl);
+    domctl.u.configuredomain.gic_version = *version;
+    if ( (err = do_domctl(xch, &domctl)) != 0 )
+        return err;
+    *version = domctl.u.configuredomain.gic_version;
+    return 0;
 }
 #endif
 
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 9605953..8475d1e 100644
--- a/tools/libxl/libxl_arm.c
+++ b/tools/libxl/libxl_arm.c
@@ -29,6 +29,7 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, 
libxl_domain_config *d_config,
 {
     int dev_index;
     uint32_t nr_spis = 0;
+    uint32_t gic_version = d_config->b_info.gic_version;
 
     for (dev_index = 0; dev_index < d_config->num_dtdevs; dev_index++)
         nr_spis += state->dtdevs_info[dev_index].num_irqs;
@@ -37,10 +38,14 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, 
libxl_domain_config *d_config,
 
     LOG(DEBUG, "Allocate %u SPIs\n", nr_spis);
 
-    if (xc_domain_configure(CTX->xch, domid, nr_spis) != 0) {
+    if (xc_domain_configure(CTX->xch, domid, nr_spis, &gic_version) != 0) {
         LOG(ERROR, "Couldn't configure the domain");
         return ERROR_FAIL;
     }
+    LOG(DEBUG, "Specified GIC version %d GIC version supported %d\n",
+               d_config->b_info.gic_version, gic_version);
+
+    d_config->b_info.gic_version = gic_version;
 
     return 0;
 }
@@ -382,19 +387,26 @@ static int make_memory_nodes(libxl__gc *gc, void *fdt,
     return 0;
 }
 
-static int make_intc_node(libxl__gc *gc, void *fdt,
-                          uint64_t gicd_base, uint64_t gicd_size,
-                          uint64_t gicc_base, uint64_t gicc_size)
+static int make_intc_node(libxl__gc *gc, void *fdt, int version)
 {
     int res;
-    const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, gicd_base);
+    const char *name;
+
+    if (version == 3)
+        name = GCSPRINTF("interrupt-controller@%"PRIx64, 
(uint64_t)GUEST_GICV3_GICD_BASE);
+    else
+        name = GCSPRINTF("interrupt-controller@%"PRIx64, 
(uint64_t)GUEST_GICD_BASE);
 
     res = fdt_begin_node(fdt, name);
     if (res) return res;
 
-    res = fdt_property_compat(gc, fdt, 2,
-                              "arm,cortex-a15-gic",
-                              "arm,cortex-a9-gic");
+    if (version == 3)
+        res = fdt_property_compat(gc, fdt, 1,
+                                  "arm,gic-v3");
+    else
+        res = fdt_property_compat(gc, fdt, 2,
+                                  "arm,cortex-a15-gic",
+                                  "arm,cortex-a9-gic");
     if (res) return res;
 
 
@@ -407,11 +419,29 @@ static int make_intc_node(libxl__gc *gc, void *fdt,
     res = fdt_property(fdt, "interrupt-controller", NULL, 0);
     if (res) return res;
 
-    res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
-                            2,
-                            gicd_base, gicd_size,
-                            gicc_base, gicc_size);
-    if (res) return res;
+    if (version == 3) {
+        res = fdt_property_cell(fdt, "redistributor-stride",
+                                GUEST_GICV3_RDIST_STRIDE);
+        if (res) return res;
+
+        res = fdt_property_cell(fdt, "#redistributor-regions",
+                                GUEST_GICV3_RDIST_REGIONS);
+        if (res) return res;
+
+        res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
+                                2,
+                                GUEST_GICV3_GICD_BASE, GUEST_GICV3_GICD_SIZE,
+                                GUEST_GICV3_GICR_BASE, GUEST_GICV3_GICR_SIZE);
+        if (res) return res;
+    }
+    else
+    {
+        res = fdt_property_regs(gc, fdt, ROOT_ADDRESS_CELLS, ROOT_SIZE_CELLS,
+                                2,
+                                GUEST_GICD_BASE, GUEST_GICD_SIZE,
+                                GUEST_GICC_BASE, GUEST_GICD_SIZE);
+        if (res) return res;
+    }
 
     res = fdt_property_cell(fdt, "linux,phandle", PHANDLE_GIC);
     if (res) return res;
@@ -662,10 +692,8 @@ next_resize:
         FDT( make_psci_node(gc, fdt) );
 
         FDT( make_memory_nodes(gc, fdt, dom) );
-        FDT( make_intc_node(gc, fdt,
-                            GUEST_GICD_BASE, GUEST_GICD_SIZE,
-                            GUEST_GICC_BASE, GUEST_GICD_SIZE) );
 
+        FDT( make_intc_node(gc, fdt, info->gic_version) );
         FDT( make_timer_node(gc, fdt, ainfo) );
         FDT( make_hypervisor_node(gc, fdt, vers) );
 
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 7d9eec2..8f3f074 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -349,6 +349,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
     ("disable_migrate", libxl_defbool),
     ("cpuid",           libxl_cpuid_policy_list),
     ("blkdev_start",    string),
+    ("gic_version",     uint32),
     
     ("device_model_version", libxl_device_model_version),
     ("device_model_stubdomain", libxl_defbool),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 2ec17ca..5fcb396 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1523,6 +1523,9 @@ skip_vfb:
     if (!xlu_cfg_get_long (config, "pci_seize", &l, 0))
         pci_seize = l;
 
+    if (!xlu_cfg_get_long (config, "gic_version", &l, 0))
+        b_info->gic_version = l;
+
     /* To be reworked (automatically enabled) once the auto ballooning
      * after guest starts is done (with PCI devices passed in). */
     if (c_info->type == LIBXL_DOMAIN_TYPE_PV) {
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 370dd99..1bea026 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -10,6 +10,8 @@
 #include <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/hypercall.h>
+#include <asm/gic.h>
+#include <xen/guest_access.h>
 #include <public/domctl.h>
 
 long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
@@ -39,9 +41,36 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain 
*d,
         if ( domctl->u.configuredomain.nr_spis > (gic_number_lines() - 32) )
             return -EINVAL;
 
-        return domain_configure_vgic(d, domctl->u.configuredomain.nr_spis);
-    }
+        if ( domain_configure_vgic(d, domctl->u.configuredomain.nr_spis) )
+            return -EINVAL;
 
+        switch ( gic_hw_version() )
+        {
+#ifdef CONFIG_ARM_64
+        case GIC_V3:
+            if ( domctl->u.configuredomain.gic_version == 0 )
+            {
+                domctl->u.configuredomain.gic_version = 3;
+                return __copy_to_guest(u_domctl, domctl, 1);
+            }
+            /* XXX: Support only v3 gic emulation */
+            if ( domctl->u.configuredomain.gic_version != 3 )
+                return -EINVAL;
+            break;
+#endif
+        case GIC_V2:
+            if ( domctl->u.configuredomain.gic_version == 0 )
+            {
+                domctl->u.configuredomain.gic_version = 2;
+                return __copy_to_guest(u_domctl, domctl, 1);
+            }
+            if ( domctl->u.configuredomain.gic_version != 2 )
+                return -EINVAL;
+            break;
+        default:
+            return -EINVAL;
+        }
+    }
     default:
     {
         int rc;
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 9bdda32..059b60e 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -907,9 +907,16 @@ static int gicv_v3_init(struct domain *d)
         d->arch.vgic.rdist_count = gicv3.rdist_count;
     }
     else
-        d->arch.vgic.dbase = GUEST_GICD_BASE;
+    {
+        d->arch.vgic.dbase = GUEST_GICV3_GICD_BASE;
+        d->arch.vgic.dbase_size = GUEST_GICV3_GICD_SIZE;
+
+        /* XXX: Only one Re-distributor region mapped for guest */
+        d->arch.vgic.rdist_count = 1;
+        d->arch.vgic.rbase[0] = GUEST_GICV3_GICR_BASE;
+        d->arch.vgic.rbase_size[0] = GUEST_GICV3_GICR_SIZE;
+        d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE;
+    }
 
     return 0;
 }
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index cebb349..6f80c99 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -363,6 +363,14 @@ typedef uint64_t xen_callback_t;
  * should instead use the FDT.
  */
 
+/* GICv3 address space */
+#define GUEST_GICV3_GICD_BASE      0x03001000ULL
+#define GUEST_GICV3_GICD_SIZE      0x10000ULL
+#define GUEST_GICV3_GICR_BASE      0x03020000ULL
+#define GUEST_GICV3_GICR_SIZE      0x200000ULL
+#define GUEST_GICV3_RDIST_STRIDE   0x20000ULL
+#define GUEST_GICV3_RDIST_REGIONS  0x1ULL
+
 /* Physical Address Space */
 #define GUEST_GICD_BASE   0x03001000ULL
 #define GUEST_GICD_SIZE   0x00001000ULL
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 8adb8e2..502cfb6 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -73,6 +73,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t);
 struct xen_domctl_configuredomain {
     /* IN parameters */
     uint32_t nr_spis;
+    /* IN/OUT parameter */
+    uint32_t gic_version;
 };
 typedef struct xen_domctl_configuredomain xen_domctl_configuredomain_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_configuredomain_t);
-- 
1.7.9.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.