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

[Xen-devel] [RFC PATCH] 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>
---
 tools/libxc/xc_domain.c       |   14 ++++++++++++
 tools/libxc/xenctrl.h         |    2 ++
 tools/libxl/libxl_arm.c       |   50 +++++++++++++++++++++++++++++++++++------
 tools/libxl/libxl_types.idl   |    1 +
 tools/libxl/xl_cmdimpl.c      |    3 +++
 xen/arch/arm/domctl.c         |   21 ++++++++++++++++-
 xen/arch/arm/gic-v3.c         |   13 ++++++++---
 xen/include/public/arch-arm.h |    8 +++++++
 xen/include/public/domctl.h   |   10 +++++++++
 9 files changed, 111 insertions(+), 11 deletions(-)

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 91d856e..69336e6 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -58,6 +58,20 @@ int xc_domain_configure(xc_interface *xch, uint32_t domid,
     domctl.u.configuredomain.nr_spis = nr_spis;
     return do_domctl(xch, &domctl);
 }
+
+int xc_domain_get_gicversion(xc_interface *xch, uint32_t domid,
+                             uint32_t *version)
+{
+    int err;
+    DECLARE_DOMCTL;
+
+    domctl.cmd = XEN_DOMCTL_get_gicversion;
+    domctl.domain = (domid_t)domid;
+    if ( (err =  do_domctl(xch, &domctl)) != 0 )
+       return err;
+    *version = domctl.u.getgicversion.version;
+    return 0;
+}
 #endif
 
 int xc_domain_cacheflush(xc_interface *xch, uint32_t domid,
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 8234962..dfdbd3c 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -485,6 +485,8 @@ 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);
+int xc_domain_get_gicversion(xc_interface *xch, uint32_t domid,
+                             uint32_t *version);
 #endif
 
 /* Functions to produce a dump of a given domain
diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c
index 9605953..901032d 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;
 
     for (dev_index = 0; dev_index < d_config->num_dtdevs; dev_index++)
         nr_spis += state->dtdevs_info[dev_index].num_irqs;
@@ -42,6 +43,16 @@ int libxl__arch_domain_create_pre(libxl__gc *gc, 
libxl_domain_config *d_config,
         return ERROR_FAIL;
     }
 
+    if (d_config->b_info.gic_version == 0) {
+        /* GIC version is not set. Query host */
+        if (xc_domain_get_gicversion(CTX->xch, domid, &gic_version) != 0) {
+            LOG(ERROR, "Couldn't get GIC version from xen");
+            return ERROR_FAIL;        
+        }
+        d_config->b_info.gic_version = gic_version;
+    }
+    LOG(DEBUG, "GIC version %d\n", d_config->b_info.gic_version);
+
     return 0;
 }
 
@@ -384,7 +395,8 @@ static int make_memory_nodes(libxl__gc *gc, void *fdt,
 
 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)
+                          uint64_t gicc_base, uint64_t gicc_size,
+                          int version)
 {
     int res;
     const char *name = GCSPRINTF("interrupt-controller@%"PRIx64, gicd_base);
@@ -392,9 +404,13 @@ static int make_intc_node(libxl__gc *gc, void *fdt,
     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,6 +423,16 @@ static int make_intc_node(libxl__gc *gc, void *fdt,
     res = fdt_property(fdt, "interrupt-controller", NULL, 0);
     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,
                             gicd_base, gicd_size,
@@ -662,9 +688,19 @@ 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) );
+
+        if (info->gic_version == 3) {
+            FDT( make_intc_node(gc, fdt,
+                                GUEST_GICV3_GICD_BASE, GUEST_GICV3_GICD_SIZE,
+                                GUEST_GICV3_GICR_BASE, GUEST_GICV3_GICR_SIZE,
+                                info->gic_version) );
+        }
+        else {
+            FDT( make_intc_node(gc, fdt,
+                                GUEST_GICD_BASE, GUEST_GICD_SIZE,
+                                GUEST_GICC_BASE, GUEST_GICD_SIZE,
+                                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 e93dbfa..fde5361 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -340,6 +340,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 a32e754..ba3fb98 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1472,6 +1472,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..04f84ac 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,
@@ -41,7 +43,24 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain 
*d,
 
         return domain_configure_vgic(d, domctl->u.configuredomain.nr_spis);
     }
-
+    case XEN_DOMCTL_get_gicversion:
+    {
+        switch ( gic_hw_version() )
+        {
+#ifdef CONFIG_ARM_64
+        case GIC_V3:
+            domctl->u.getgicversion.version = 3;
+            break;
+#endif
+        case GIC_V2:
+            domctl->u.getgicversion.version = 2;
+            break;
+        default:
+            return -EINVAL;
+        }
+        return __copy_to_guest(u_domctl, domctl, 1);
+    }
+        
     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 d3db078..b432ca4 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -372,6 +372,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 3d36128..9682ffd 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -76,6 +76,14 @@ struct xen_domctl_configuredomain {
 };
 typedef struct xen_domctl_configuredomain xen_domctl_configuredomain_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_configuredomain_t);
+
+/* XEN_DOMCTL_get_gicversion */
+struct xen_domctl_getgicversion {
+    /* OUT parameters */
+    uint32_t version;
+};
+typedef struct xen_domctl_getgicversion xen_domctl_getgicversion_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_getgicversion_t);
 #endif
 
 /* XEN_DOMCTL_getdomaininfo */
@@ -1096,6 +1104,7 @@ struct xen_domctl {
 #define XEN_DOMCTL_configure_domain              75
 #define XEN_DOMCTL_dtdev_op                      76
 #define XEN_DOMCTL_assign_dt_device              77
+#define XEN_DOMCTL_get_gicversion                78
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -1106,6 +1115,7 @@ struct xen_domctl {
         struct xen_domctl_createdomain      createdomain;
 #if defined(__arm__) || defined(__aarch64__)
         struct xen_domctl_configuredomain   configuredomain;
+        struct xen_domctl_getgicversion     getgicversion;
 #endif
         struct xen_domctl_getdomaininfo     getdomaininfo;
         struct xen_domctl_getmemlist        getmemlist;
-- 
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®.