[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC v1 5/5] xen/arm: add SCI mediator support for DomUs
Hi Oleksandr, On Thu, Dec 16, 2021 at 02:04:35AM +0200, Oleksandr wrote: > > On 14.12.21 11:34, Oleksii Moisieiev wrote: > > Hi Oleksii > > > 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@xxxxxxxx> > > --- > > tools/include/xenctrl.h | 3 + > > tools/include/xenguest.h | 2 + > > tools/libs/ctrl/xc_domain.c | 23 ++++++ > > tools/libs/guest/xg_dom_arm.c | 5 +- > > tools/libs/light/libxl_arm.c | 122 +++++++++++++++++++++++++++--- > > tools/libs/light/libxl_create.c | 54 ++++++++++++- > > tools/libs/light/libxl_dom.c | 1 + > > tools/libs/light/libxl_internal.h | 4 + > > xen/arch/arm/domctl.c | 15 ++++ > > xen/include/public/domctl.h | 9 +++ > > 10 files changed, 223 insertions(+), 15 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/include/xenguest.h b/tools/include/xenguest.h > > index 61d0a82f48..35c611ac73 100644 > > --- a/tools/include/xenguest.h > > +++ b/tools/include/xenguest.h > > @@ -242,6 +242,8 @@ struct xc_dom_image { > > /* Number of vCPUs */ > > unsigned int max_vcpus; > > + > > + xen_pfn_t sci_shmem_gfn; > > }; > > /* --- arch specific hooks ----------------------------------------- */ > > diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c > > index b155d6afd2..07bb390e17 100644 > > --- a/tools/libs/ctrl/xc_domain.c > > +++ b/tools/libs/ctrl/xc_domain.c > > @@ -2206,6 +2206,29 @@ int xc_domain_soft_reset(xc_interface *xch, > > domctl.domain = domid; > > return do_domctl(xch, &domctl); > > } > > + > > +int xc_domain_add_sci_device(xc_interface *xch, > > + uint32_t domid, char *path) > > +{ > > + size_t size = strlen(path); > > + int rc; > > + DECLARE_DOMCTL; > > + DECLARE_HYPERCALL_BOUNCE(path, size, XC_HYPERCALL_BUFFER_BOUNCE_IN); > > + > > + if ( xc_hypercall_bounce_pre(xch, path) ) > > + return -1; > > + > > + domctl.cmd = XEN_DOMCTL_add_sci_device; > > + domctl.domain = domid; > > + domctl.u.sci_device_op.size = size; > > + set_xen_guest_handle(domctl.u.sci_device_op.path, path); > > + rc = do_domctl(xch, &domctl); > > + > > + xc_hypercall_bounce_post(xch, path); > > + > > + return rc; > > +} > > + > > /* > > * Local variables: > > * mode: C > > diff --git a/tools/libs/guest/xg_dom_arm.c b/tools/libs/guest/xg_dom_arm.c > > index 5e3b76355e..368a670c46 100644 > > --- a/tools/libs/guest/xg_dom_arm.c > > +++ b/tools/libs/guest/xg_dom_arm.c > > @@ -25,11 +25,12 @@ > > #include "xg_private.h" > > -#define NR_MAGIC_PAGES 4 > > +#define NR_MAGIC_PAGES 5 > > #define CONSOLE_PFN_OFFSET 0 > > #define XENSTORE_PFN_OFFSET 1 > > #define MEMACCESS_PFN_OFFSET 2 > > #define VUART_PFN_OFFSET 3 > > +#define SCI_SHMEM_OFFSET 4 > > #define LPAE_SHIFT 9 > > @@ -69,11 +70,13 @@ static int alloc_magic_pages(struct xc_dom_image *dom) > > dom->console_pfn = base + CONSOLE_PFN_OFFSET; > > dom->xenstore_pfn = base + XENSTORE_PFN_OFFSET; > > dom->vuart_gfn = base + VUART_PFN_OFFSET; > > + dom->sci_shmem_gfn = base + SCI_SHMEM_OFFSET; > > xc_clear_domain_page(dom->xch, dom->guest_domid, dom->console_pfn); > > xc_clear_domain_page(dom->xch, dom->guest_domid, dom->xenstore_pfn); > > xc_clear_domain_page(dom->xch, dom->guest_domid, base + > > MEMACCESS_PFN_OFFSET); > > xc_clear_domain_page(dom->xch, dom->guest_domid, dom->vuart_gfn); > > + xc_clear_domain_page(dom->xch, dom->guest_domid, dom->sci_shmem_gfn); > > xc_hvm_param_set(dom->xch, dom->guest_domid, HVM_PARAM_CONSOLE_PFN, > > dom->console_pfn); > > diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c > > index eef1de0939..73ef591822 100644 > > --- a/tools/libs/light/libxl_arm.c > > +++ b/tools/libs/light/libxl_arm.c > > @@ -8,6 +8,8 @@ > > #include <assert.h> > > #include <xen/device_tree_defs.h> > > +#define SCMI_NODE_PATH "/firmware/scmi" > > + > > static const char *gicv_to_string(libxl_gic_version gic_version) > > { > > switch (gic_version) { > > @@ -101,6 +103,19 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, > > return ERROR_FAIL; > > } > > + switch (d_config->b_info.sci) { > > + case LIBXL_SCI_TYPE_NONE: > > + config->arch.sci_type = XEN_DOMCTL_CONFIG_SCI_NONE; > > + break; > > + case LIBXL_SCI_TYPE_SCMI_SMC: > > + config->arch.sci_type = XEN_DOMCTL_CONFIG_SCI_SCMI_SMC; > > + break; > > + default: > > + LOG(ERROR, "Unknown SCI type %d", > > + d_config->b_info.sci); > > + return ERROR_FAIL; > > + } > > + > > return 0; > > } > > @@ -122,6 +137,7 @@ int libxl__arch_domain_save_config(libxl__gc *gc, > > } > > state->clock_frequency = config->arch.clock_frequency; > > + state->sci_agent_paddr = config->arch.sci_agent_paddr; > > return 0; > > } > > @@ -502,9 +518,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; > > @@ -517,9 +530,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; > > } > > @@ -902,10 +912,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) > > @@ -925,12 +934,101 @@ 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 get_node_phandle(const char *path, void *pfdt, uint32_t > > *phandle) > > +{ > > + int nodeoff; > > + const char *name = strrchr(path, '/'); > > + > > + if (!name) > > + return -FDT_ERR_INTERNAL; > > + > > + name++; > > + nodeoff = fdt_path_offset(pfdt, path); > > + if (nodeoff < 0) > > + return nodeoff; > > + > > + *phandle = fdt_get_phandle(pfdt, nodeoff); > > + return 0; > > +} > > + > > +static int make_scmi_shmem_node(libxl__gc *gc, void *fdt, void *pfdt, > > + struct xc_dom_image *dom) > > +{ > > + int res; > > + char buf[64]; > > + uint32_t phandle = 0; > > + > > + res = get_node_phandle("/scp-shmem", pfdt, &phandle); > > + if (res) return res; > > + > > + snprintf(buf, sizeof(buf), "scp-shmem@%lx", > > + dom->sci_shmem_gfn << XC_PAGE_SHIFT); > > + res = fdt_begin_node(fdt, buf); > > + if (res) return res; > > + > > + res = fdt_property_compat(gc, fdt, 1, "arm,scmi-shmem"); > > + if (res) return res; > > + > > + res = fdt_property_regs(gc, fdt, GUEST_ROOT_ADDRESS_CELLS, > > + GUEST_ROOT_SIZE_CELLS, 1, > > + dom->sci_shmem_gfn << XC_PAGE_SHIFT, XC_PAGE_SHIFT); > > + if (res) return res; > > + > > + LOG(DEBUG, "scmi: setting phandle = %u\n", phandle); > > + res = fdt_property_cell(fdt, "phandle", phandle); > > + if (res) return res; > > + > > + res = fdt_end_node(fdt); > > + if (res) return res; > > + > > + return 0; > > +} > > + > > +static int make_firmware_node(libxl__gc *gc, void *fdt, void *pfdt, int > > tee, > > + int sci) > > +{ > > + int res; > > + > > + if ((tee != LIBXL_TEE_TYPE_OPTEE) && (sci != LIBXL_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_SCI_TYPE_SCMI_SMC) { > > + res = copy_node_by_path(gc, SCMI_NODE_PATH, 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: > > @@ -1088,8 +1186,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) ); > > + FDT( make_firmware_node(gc, fdt, pfdt, info->tee, info->sci) ); > > + > > + if (info->sci == LIBXL_SCI_TYPE_SCMI_SMC) > > + FDT( make_scmi_shmem_node(gc, fdt, pfdt, dom) ); > > 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..c7372fd344 100644 > > --- a/tools/libs/light/libxl_create.c > > +++ b/tools/libs/light/libxl_create.c > > @@ -596,6 +596,37 @@ 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; > > + > > + 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 +793,16 @@ int libxl__domain_make(libxl__gc *gc, > > libxl_domain_config *d_config, > > goto out; > > } > > + if (state->sci_agent_paddr != 0) { > > + ret = map_sci_page(gc, *domid, state->sci_agent_paddr, > > + state->sci_shmem_gfn << XC_PAGE_SHIFT); > > + if (ret < 0) { > > + LOGED(ERROR, *domid, "map SCI page fail"); > > + rc = ERROR_FAIL; > > + goto out; > > + } > > + } > > + > > dom_path = libxl__xs_get_dompath(gc, *domid); > > if (!dom_path) { > > rc = ERROR_FAIL; > > @@ -1817,17 +1858,24 @@ static void libxl__add_dtdevs(libxl__egc *egc, > > libxl__ao *ao, uint32_t domid, > > { > > AO_GC; > > libxl__ao_device *aodev = libxl__multidev_prepare(multidev); > > - int i, rc = 0; > > + int i, rc = 0, rc_sci = 0; > > for (i = 0; i < d_config->num_dtdevs; i++) { > > const libxl_device_dtdev *dtdev = &d_config->dtdevs[i]; > > 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); > > + rc_sci = xc_domain_add_sci_device(CTX->xch, domid, dtdev->path); > > + > > + if ((rc < 0) && (rc_sci < 0)) { > > + LOGD(ERROR, domid, "xc_assign_dt_device failed: %d; " > > + "xc_domain_add_sci_device failed: %d", > > + rc, rc_sci); > > goto out; > > } > > + > > + if (rc) > > + rc = rc_sci; > > > If I get this code right, it sounds like the dom.cfg's dtdev property is > reused to describe sci devices as well, but the libxl__add_dtdevs() does not > (and can not) differentiate them. So it has no option but to send two > domctls for each device in dtdevs[] hoping to at least one domctl to > succeeded. Or I really missed something? > > It feels to me that: > - either new dom.cfg's property could be introduced (scidev?) to describe > sci devices together with new parsing logic/management code, so you will end > up having new libxl__add_scidevs() to invoke XEN_DOMCTL_add_sci_device, > so no mixing things. > - or indeed dtdev logic could be *completely* reused including extending > XEN_DOMCTL_assign_device to cover your use-case, although sounds generic, it > is used to describe devices for the passthrough (to configure an IOMMU for > the device), in that case you wouldn't need an extra > XEN_DOMCTL_add_sci_device introduced by current patch. > > Personally I would use the first option as I am not sure that second option > is conceptually correct && possible. I would leave this for the maintainers > to clarify. > Thank you for the point. I agree that reusing XEN_DOMCTL_assign_device seems not to be conceptually correct. Introducing new dom.cfg property seems to be the only way to avoid extra Domctl calls. I will handle this in v2 if there will be no complains from Maintainers. --- Oleksii. > > > > } > > out: > > diff --git a/tools/libs/light/libxl_dom.c b/tools/libs/light/libxl_dom.c > > index fe9f760f71..b1d288a8b9 100644 > > --- a/tools/libs/light/libxl_dom.c > > +++ b/tools/libs/light/libxl_dom.c > > @@ -710,6 +710,7 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid, > > state->console_mfn = dom->console_pfn; > > state->store_mfn = dom->xenstore_pfn; > > state->vuart_gfn = dom->vuart_gfn; > > + state->sci_shmem_gfn = dom->sci_shmem_gfn; > > } else { > > state->console_mfn = xc_dom_p2m(dom, dom->console_pfn); > > state->store_mfn = xc_dom_p2m(dom, dom->xenstore_pfn); > > diff --git a/tools/libs/light/libxl_internal.h > > b/tools/libs/light/libxl_internal.h > > index 0b4671318c..f9f9cc633a 100644 > > --- a/tools/libs/light/libxl_internal.h > > +++ b/tools/libs/light/libxl_internal.h > > @@ -1407,6 +1407,10 @@ 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; > > + > > + /* sci channel paddr to be set to device-tree node */ > > + uint64_t sci_agent_paddr; > > + xen_pfn_t sci_shmem_gfn; > > } 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..ba200407da 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> > > @@ -175,6 +176,20 @@ long arch_do_domctl(struct xen_domctl *domctl, struct > > domain *d, > > return rc; > > } > > + case XEN_DOMCTL_add_sci_device: > > + { > > + int rc; > > + struct dt_device_node *dev; > > + > > + rc = dt_find_node_by_gpath(domctl->u.sci_device_op.path, > > + domctl->u.sci_device_op.size, > > + &dev); > > + if ( rc ) > > + return rc; > > + > > + return sci_add_dt_device(d, dev); > > + } > > + > > default: > > { > > int rc; > > diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h > > index b85e6170b0..671c72c3e8 100644 > > --- a/xen/include/public/domctl.h > > +++ b/xen/include/public/domctl.h > > @@ -1177,6 +1177,13 @@ struct xen_domctl_vmtrace_op { > > #define XEN_DOMCTL_vmtrace_get_option 5 > > #define XEN_DOMCTL_vmtrace_set_option 6 > > }; > > + > > +/* XEN_DOMCTL_add_sci_device: set sci device permissions */ > > +struct xen_domctl_sci_device_op { > > + uint32_t size; /* Length of the path */ > > + XEN_GUEST_HANDLE_64(char) path; /* path to the device tree node */ > > +}; > > + > > typedef struct xen_domctl_vmtrace_op xen_domctl_vmtrace_op_t; > > DEFINE_XEN_GUEST_HANDLE(xen_domctl_vmtrace_op_t); > > @@ -1265,6 +1272,7 @@ struct xen_domctl { > > #define XEN_DOMCTL_get_cpu_policy 82 > > #define XEN_DOMCTL_set_cpu_policy 83 > > #define XEN_DOMCTL_vmtrace_op 84 > > +#define XEN_DOMCTL_add_sci_device 85 > > #define XEN_DOMCTL_gdbsx_guestmemio 1000 > > #define XEN_DOMCTL_gdbsx_pausevcpu 1001 > > #define XEN_DOMCTL_gdbsx_unpausevcpu 1002 > > @@ -1326,6 +1334,7 @@ struct xen_domctl { > > struct xen_domctl_psr_alloc psr_alloc; > > struct xen_domctl_vuart_op vuart_op; > > struct xen_domctl_vmtrace_op vmtrace_op; > > + struct xen_domctl_sci_device_op sci_device_op; > > uint8_t pad[128]; > > } u; > > }; > > I assume the XSM needs updating (adding new hook, etc). > > > -- > Regards, > > Oleksandr Tyshchenko >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |