All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleksii Moisieiev <Oleksii_Moisieiev@epam.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Oleksii Moisieiev <Oleksii_Moisieiev@epam.com>,
	Wei Liu <wl@xen.org>, Juergen Gross <jgross@suse.com>,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	George Dunlap <george.dunlap@citrix.com>,
	Jan Beulich <jbeulich@suse.com>, Julien Grall <julien@xen.org>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Anthony PERARD <anthony.perard@citrix.com>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>,
	Bertrand Marquis <bertrand.marquis@arm.com>
Subject: [RFC v2 8/8] xen/arm: add SCI mediator support for DomUs
Date: Tue, 8 Feb 2022 18:00:14 +0000	[thread overview]
Message-ID: <8aaab52f54841ebcf31a8f5fc6f1f8fd0b778e49.1644341635.git.oleksii_moisieiev@epam.com> (raw)
In-Reply-To: <cover.1644341635.git.oleksii_moisieiev@epam.com>

Integration of the SCMI mediator with xen libs:
- add hypercalls to aquire SCI channel and set device permissions
for DomUs;
- add SCMI_SMC nodes to DomUs device-tree based on partial device-tree;
- SCI requests redirection from DomUs to Firmware.

Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
---
 tools/include/xenctrl.h               |   3 +
 tools/libs/light/libxl_arm.c          | 214 ++++++++++++++++++++++++--
 tools/libs/light/libxl_create.c       |  44 +++++-
 tools/libs/light/libxl_internal.h     |   3 +
 xen/arch/arm/domctl.c                 |   7 +
 xen/include/public/device_tree_defs.h |   1 +
 6 files changed, 260 insertions(+), 12 deletions(-)

diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 07b96e6671..cdd14f465f 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1238,6 +1238,9 @@ int xc_domain_getvnuma(xc_interface *xch,
 int xc_domain_soft_reset(xc_interface *xch,
                          uint32_t domid);
 
+int xc_domain_add_sci_device(xc_interface *xch,
+                              uint32_t domid, char *path);
+
 #if defined(__i386__) || defined(__x86_64__)
 /*
  * PC BIOS standard E820 types and structure.
diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
index c5090e2b32..106ff33c84 100644
--- a/tools/libs/light/libxl_arm.c
+++ b/tools/libs/light/libxl_arm.c
@@ -7,6 +7,12 @@
 #include <libfdt.h>
 #include <assert.h>
 #include <xen/device_tree_defs.h>
+#include <xenhypfs.h>
+
+#define SCMI_NODE_PATH         "/firmware/scmi"
+#define SCMI_NODE_COMPATIBLE   "arm,scmi-smc"
+#define SCMI_SHMEM_COMPATIBLE  "arm,scmi-shmem"
+#define HYPFS_DEVICETREE_PATH  "/devicetree"
 
 static const char *gicv_to_string(libxl_gic_version gic_version)
 {
@@ -101,6 +107,19 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
         return ERROR_FAIL;
     }
 
+    switch (d_config->b_info.arm_sci) {
+    case LIBXL_ARM_SCI_TYPE_NONE:
+        config->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_NONE;
+        break;
+    case LIBXL_ARM_SCI_TYPE_SCMI_SMC:
+        config->arch.arm_sci_type = XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC;
+        break;
+    default:
+        LOG(ERROR, "Unknown ARM_SCI type %d",
+            d_config->b_info.arm_sci);
+        return ERROR_FAIL;
+    }
+
     if (libxl_defbool_val(d_config->b_info.force_assign_without_iommu))
         config->iommu_opts |= XEN_DOMCTL_IOMMU_force_iommu;
 
@@ -125,6 +144,7 @@ int libxl__arch_domain_save_config(libxl__gc *gc,
     }
 
     state->clock_frequency = config->arch.clock_frequency;
+    state->arm_sci_agent_paddr = config->arch.arm_sci_agent_paddr;
 
     return 0;
 }
@@ -505,9 +525,6 @@ static int make_optee_node(libxl__gc *gc, void *fdt)
     int res;
     LOG(DEBUG, "Creating OP-TEE node in dtb");
 
-    res = fdt_begin_node(fdt, "firmware");
-    if (res) return res;
-
     res = fdt_begin_node(fdt, "optee");
     if (res) return res;
 
@@ -520,9 +537,6 @@ static int make_optee_node(libxl__gc *gc, void *fdt)
     res = fdt_end_node(fdt);
     if (res) return res;
 
-    res = fdt_end_node(fdt);
-    if (res) return res;
-
     return 0;
 }
 
@@ -905,10 +919,9 @@ static int copy_node(libxl__gc *gc, void *fdt, void *pfdt,
     return 0;
 }
 
-static int copy_node_by_path(libxl__gc *gc, const char *path,
-                             void *fdt, void *pfdt)
+static int get_path_nodeoff(const char *path, void *pfdt)
 {
-    int nodeoff, r;
+    int nodeoff;
     const char *name = strrchr(path, '/');
 
     if (!name)
@@ -928,12 +941,189 @@ static int copy_node_by_path(libxl__gc *gc, const char *path,
     if (strcmp(fdt_get_name(pfdt, nodeoff, NULL), name))
         return -FDT_ERR_NOTFOUND;
 
+    return nodeoff;
+}
+
+static int copy_node_by_path(libxl__gc *gc, const char *path,
+                             void *fdt, void *pfdt)
+{
+    int nodeoff, r;
+
+    nodeoff = get_path_nodeoff(path, pfdt);
+    if (nodeoff < 0)
+        return nodeoff;
+
     r = copy_node(gc, fdt, pfdt, nodeoff, 0);
     if (r) return r;
 
     return 0;
 }
 
+static int make_scmi_shmem_node(libxl__gc *gc, void *fdt, void *pfdt)
+{
+    int res;
+    char buf[64];
+
+#ifdef CONFIG_ARM_32
+    snprintf(buf, sizeof(buf), "scp-shmem@%lx",
+             GUEST_SCI_SHMEM_BASE);
+#else
+    snprintf(buf, sizeof(buf), "scp-shmem@%llx",
+             GUEST_SCI_SHMEM_BASE);
+#endif
+
+    res = fdt_begin_node(fdt, buf);
+    if (res) return res;
+
+    res = fdt_property_compat(gc, fdt, 1, SCMI_SHMEM_COMPATIBLE);
+    if (res) return res;
+
+    res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS,
+                    GUEST_ROOT_SIZE_CELLS, 1,
+                    GUEST_SCI_SHMEM_BASE, GUEST_SCI_SHMEM_SIZE);
+    if (res) return res;
+
+    res = fdt_property_cell(fdt, "phandle", GUEST_PHANDLE_SCMI);
+    if (res) return res;
+
+    res = fdt_end_node(fdt);
+    if (res) return res;
+
+    return 0;
+}
+
+static int create_hypfs_property(struct xenhypfs_handle *hdl, void *fdt,
+                                 char *path, char *name)
+{
+    char *p, *result;
+    int ret = 0;
+    struct xenhypfs_dirent *ent;
+
+    if (strcmp(name, "shmem") == 0)
+        return fdt_property_cell(fdt, name, GUEST_PHANDLE_SCMI);
+
+    ret = asprintf(&p, "%s%s", HYPFS_DEVICETREE_PATH, path);
+    result = xenhypfs_read_raw(hdl, p, &ent);
+    free(p);
+    if (!result)
+        return -EINVAL;
+
+    ret = fdt_property(fdt, name, result, ent->size);
+    free(result);
+    free(ent);
+
+    return ret;
+}
+static int create_hypfs_subnode(struct xenhypfs_handle *hdl, void *fdt,
+                                const char *path, const char *name)
+{
+    struct xenhypfs_dirent *ent;
+    unsigned int n, i;
+    char *p, *p_sub;
+    int res = 0;
+
+    res = asprintf(&p, "%s%s", HYPFS_DEVICETREE_PATH, path);
+    if (res < 0)
+        return -ENOMEM;
+
+    ent = xenhypfs_readdir(hdl, p, &n);
+    free(p);
+    if (!ent)
+        return -EINVAL;
+
+    res = fdt_begin_node(fdt, name);
+    if (res) return res;
+
+    for (i = 0; i < n; i++) {
+        res = asprintf(&p_sub,"%s/%s", path, ent[i].name);
+        if (res < 0)
+            break;
+
+        if (ent[i].type == xenhypfs_type_dir)
+             res = create_hypfs_subnode(hdl, fdt, p_sub, ent[i].name);
+        else
+             res = create_hypfs_property(hdl, fdt, p_sub, ent[i].name);
+
+        free(p_sub);
+        if (res)
+            break;
+    }
+
+    res = fdt_end_node(fdt);
+    free(ent);
+    return res;
+}
+
+static int create_scmi_from_hypfs(void *fdt, const char *path)
+{
+    struct xenhypfs_handle *hdl;
+    int res;
+    hdl = xenhypfs_open(NULL, 0);
+    if (!hdl)
+        return -EINVAL;
+
+    res = create_hypfs_subnode(hdl, fdt, path, "scmi");
+    xenhypfs_close(hdl);
+
+    return res;
+}
+
+static int set_shmem_phandle(void *fdt, const char *scmi_node_copmat)
+{
+    uint32_t val;
+    int nodeoff = fdt_node_offset_by_compatible(fdt, 0, scmi_node_copmat);
+    if (nodeoff < 0)
+        return -EINVAL;
+
+    val = cpu_to_fdt32(GUEST_PHANDLE_SCMI);
+    return fdt_setprop_inplace(fdt, nodeoff, "shmem", &val, sizeof(val));
+}
+
+static int make_scmi_node(libxl__gc *gc, void *fdt, void *pfdt)
+{
+    int res = 0;
+    int nodeoff =
+        fdt_node_offset_by_compatible(pfdt, 0, SCMI_NODE_COMPATIBLE);
+    if (nodeoff > 0) {
+        res = copy_node(gc, fdt, pfdt, nodeoff, 0);
+        if (res) return res;
+
+        res = set_shmem_phandle(fdt, SCMI_NODE_COMPATIBLE);
+        if (res) return res;
+    }
+    else
+        res = create_scmi_from_hypfs(fdt, SCMI_NODE_PATH);
+
+    return res;
+}
+
+static int make_firmware_node(libxl__gc *gc, void *fdt, void *pfdt, int tee,
+                              int sci)
+{
+    int res;
+
+    if ((tee == LIBXL_TEE_TYPE_NONE) && (sci == LIBXL_ARM_SCI_TYPE_NONE))
+        return 0;
+
+    res = fdt_begin_node(fdt, "firmware");
+    if (res) return res;
+
+    if (tee == LIBXL_TEE_TYPE_OPTEE) {
+       res = make_optee_node(gc, fdt);
+       if (res) return res;
+    }
+
+    if (sci == LIBXL_ARM_SCI_TYPE_SCMI_SMC) {
+        res = make_scmi_node(gc, fdt, pfdt);
+        if (res) return res;
+    }
+
+    res = fdt_end_node(fdt);
+    if (res) return res;
+
+    return 0;
+}
+
 /*
  * The partial device tree is not copied entirely. Only the relevant bits are
  * copied to the guest device tree:
@@ -1091,8 +1281,10 @@ next_resize:
         if (info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART)
             FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom) );
 
-        if (info->tee == LIBXL_TEE_TYPE_OPTEE)
-            FDT( make_optee_node(gc, fdt) );
+        if (info->arm_sci == LIBXL_ARM_SCI_TYPE_SCMI_SMC)
+            FDT( make_scmi_shmem_node(gc, fdt, pfdt) );
+
+        FDT( make_firmware_node(gc, fdt, pfdt, info->tee, info->arm_sci) );
 
         if (d_config->num_pcidevs)
             FDT( make_vpci_node(gc, fdt, ainfo, dom) );
diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c
index dcd09d32ba..f1f1e66275 100644
--- a/tools/libs/light/libxl_create.c
+++ b/tools/libs/light/libxl_create.c
@@ -596,6 +596,38 @@ out:
     return ret;
 }
 
+static int map_sci_page(libxl__gc *gc, uint32_t domid, uint64_t paddr,
+                         uint64_t guest_addr)
+{
+    int ret;
+    uint64_t _paddr_pfn = paddr >> XC_PAGE_SHIFT;
+    uint64_t _guest_pfn = guest_addr >> XC_PAGE_SHIFT;
+
+    assert(paddr && guest_addr);
+    LOG(DEBUG, "iomem %"PRIx64, _paddr_pfn);
+
+    ret = xc_domain_iomem_permission(CTX->xch, domid, _paddr_pfn, 1, 1);
+    if (ret < 0) {
+        LOG(ERROR,
+              "failed give domain access to iomem page %"PRIx64,
+             _paddr_pfn);
+        return ret;
+    }
+
+    ret = xc_domain_memory_mapping(CTX->xch, domid,
+                                   _guest_pfn, _paddr_pfn,
+                                   1, 1);
+    if (ret < 0) {
+        LOG(ERROR,
+              "failed to map to domain iomem page %"PRIx64
+              " to guest address %"PRIx64,
+              _paddr_pfn, _guest_pfn);
+        return ret;
+    }
+
+    return 0;
+}
+
 int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
                        libxl__domain_build_state *state,
                        uint32_t *domid, bool soft_reset)
@@ -762,6 +794,16 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
         goto out;
     }
 
+    if (d_config->b_info.arm_sci == LIBXL_ARM_SCI_TYPE_SCMI_SMC) {
+        ret = map_sci_page(gc, *domid, state->arm_sci_agent_paddr,
+                            GUEST_SCI_SHMEM_BASE);
+        if (ret < 0) {
+            LOGED(ERROR, *domid, "map scmi fail");
+            rc = ERROR_FAIL;
+            goto out;
+        }
+    }
+
     dom_path = libxl__xs_get_dompath(gc, *domid);
     if (!dom_path) {
         rc = ERROR_FAIL;
@@ -1825,7 +1867,7 @@ static void libxl__add_dtdevs(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
         LOGD(DEBUG, domid, "Assign device \"%s\" to domain", dtdev->path);
         rc = xc_assign_dt_device(CTX->xch, domid, dtdev->path);
         if (rc < 0) {
-            LOGD(ERROR, domid, "xc_assign_dtdevice failed: %d", rc);
+            LOGD(ERROR, domid, "xc_assign_dt_device failed: %d", rc);
             goto out;
         }
     }
diff --git a/tools/libs/light/libxl_internal.h b/tools/libs/light/libxl_internal.h
index 0b4671318c..79f38b60d4 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -1407,6 +1407,9 @@ typedef struct {
     /* Whether this domain is being migrated/restored, or booting fresh.  Only
      * applicable to the primary domain, not support domains (e.g. stub QEMU). */
     bool restore;
+
+    /* arm_sci channel paddr to be set to device-tree node */
+    uint64_t arm_sci_agent_paddr;
 } libxl__domain_build_state;
 
 _hidden void libxl__domain_build_state_init(libxl__domain_build_state *s);
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index 6245af6d0b..23c44f3a13 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2012, Citrix Systems
  */
 
+#include <asm/sci/sci.h>
 #include <xen/errno.h>
 #include <xen/guest_access.h>
 #include <xen/hypercall.h>
@@ -182,7 +183,13 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain *d,
         rc = subarch_do_domctl(domctl, d, u_domctl);
 
         if ( rc == -ENOSYS )
+        {
             rc = iommu_do_domctl(domctl, d, u_domctl);
+            if ( (rc) && (rc != -ENOSYS) )
+                return rc;
+
+            rc = sci_do_domctl(domctl, d, u_domctl);
+        }
 
         return rc;
     }
diff --git a/xen/include/public/device_tree_defs.h b/xen/include/public/device_tree_defs.h
index 209d43de3f..f57684547b 100644
--- a/xen/include/public/device_tree_defs.h
+++ b/xen/include/public/device_tree_defs.h
@@ -7,6 +7,7 @@
  * onwards. Reserve a high value for the GIC phandle.
  */
 #define GUEST_PHANDLE_GIC (65000)
+#define GUEST_PHANDLE_SCMI (67000)
 
 #define GUEST_ROOT_ADDRESS_CELLS 2
 #define GUEST_ROOT_SIZE_CELLS 2
-- 
2.27.0


      parent reply	other threads:[~2022-02-08 18:00 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-08 18:00 [RFC v2 0/8] Introduce SCI-mediator feature Oleksii Moisieiev
2022-02-08 18:00 ` [RFC v2 1/8] xen/hypfs: support fo nested dynamic hypfs nodes Oleksii Moisieiev
2022-02-10  7:34   ` Juergen Gross
2022-02-11  8:16     ` Oleksii Moisieiev
2022-02-11 13:28       ` Juergen Gross
2022-02-11 13:32         ` Oleksii Moisieiev
2022-02-08 18:00 ` [RFC v2 2/8] libs: libxenhypfs - handle blob properties Oleksii Moisieiev
2022-02-09 13:47   ` Oleksandr Andrushchenko
2022-02-09 14:01     ` Jan Beulich
2022-02-09 14:04       ` Oleksandr Andrushchenko
2022-02-09 14:04   ` Juergen Gross
2022-02-08 18:00 ` [RFC v2 3/8] xen/arm: Export host device-tree to hypfs Oleksii Moisieiev
2022-02-08 18:26   ` Julien Grall
2022-02-09 10:20     ` Oleksii Moisieiev
2022-02-09 12:17       ` Julien Grall
2022-02-09 14:17         ` Oleksii Moisieiev
2022-02-09 18:51         ` Oleksii Moisieiev
2022-02-09 19:34           ` Julien Grall
2022-02-10  9:38             ` Oleksii Moisieiev
2022-02-09 14:03     ` Juergen Gross
2022-02-08 18:00 ` [RFC v2 4/8] xen/arm: add generic SCI mediator framework Oleksii Moisieiev
2022-02-08 18:00 ` [RFC v2 5/8] xen/arm: introduce SCMI-SMC mediator driver Oleksii Moisieiev
2022-02-09 15:02   ` Oleksandr Andrushchenko
2022-02-09 15:23     ` Julien Grall
2022-02-11  8:46   ` Bertrand Marquis
2022-02-11 10:44     ` Oleksii Moisieiev
2022-02-11 11:18       ` Bertrand Marquis
2022-02-11 11:55         ` Oleksii Moisieiev
2022-02-11 23:35           ` Stefano Stabellini
2022-02-12 12:43         ` Julien Grall
2022-02-14 11:13           ` Oleksii Moisieiev
2022-02-14 11:27             ` Bertrand Marquis
2022-02-14 11:51               ` Oleksii Moisieiev
2022-02-14 22:05                 ` Stefano Stabellini
2022-02-16 17:41                   ` Oleksii Moisieiev
2022-02-08 18:00 ` [RFC v2 6/8] tools/arm: Introduce force_assign_without_iommu option to xl.cfg Oleksii Moisieiev
2022-02-17 14:52   ` Anthony PERARD
2022-02-18  8:19     ` Oleksii Moisieiev
2022-02-17 15:20   ` Julien Grall
2022-02-18  9:16     ` Oleksii Moisieiev
2022-02-18 10:17       ` Julien Grall
2022-02-21 18:39         ` Oleksii Moisieiev
2022-06-03 13:43   ` Jan Beulich
2022-02-08 18:00 ` [RFC v2 7/8] tools/arm: add "arm_sci" " Oleksii Moisieiev
2022-02-08 18:00 ` Oleksii Moisieiev [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8aaab52f54841ebcf31a8f5fc6f1f8fd0b778e49.1644341635.git.oleksii_moisieiev@epam.com \
    --to=oleksii_moisieiev@epam.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=anthony.perard@citrix.com \
    --cc=bertrand.marquis@arm.com \
    --cc=george.dunlap@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=julien@xen.org \
    --cc=sstabellini@kernel.org \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.