|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v1 25/26] libxl/arm: add and validate Realm guest support
Add realm=true for Arm guests, reject unsupported combinations, and call the CCA finalization domctl after the guest is built. Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx> --- docs/man/xl.cfg.5.pod.in | 46 +++++++++- tools/include/libxl.h | 5 ++ tools/libs/light/libxl_arm.c | 140 ++++++++++++++++++++++++++----- tools/libs/light/libxl_create.c | 2 + tools/libs/light/libxl_types.idl | 1 + tools/xl/xl_parse.c | 2 + 6 files changed, 173 insertions(+), 23 deletions(-) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 2f77016ecfae..7ca7dba4d29d 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -1704,6 +1704,47 @@ i.e. enable grants if backend-domid != 0. =back +=item B<realm=BOOLEAN> + +B<Arm only.> Create the guest as an Arm CCA Realm guest. + +Realm guests use the Arm PVH guest model and currently support only a +minimal configuration: + +=over 4 + +=item * + +type=E<quot>pvhE<quot> + +=item * + +guest RAM fully contained within the first guest RAM bank + +=item * + +GICv3 only + +=item * + +Xen-generated device tree only + +=item * + +no passthrough, no virtio, no Xen grant or IOMMU exposure to the guest, +and no ACPI + +=back + +When B<realm=true>, Realm DTBs set the PSCI method to B<"smc">. They do +not expose the Xen hypervisor node because this series does not provide +Xen PV interfaces for Realm guests. + +Realm guests may use B<vuart="sbsa_uart"> only when Xen was built with +B<CONFIG_ARM_CCA_REALM_DEBUG_VUART=y>. This is a host-visible clear-text +debug console for Realm debug access, not a confidentiality-oriented guest +access path. + =item B<tee="STRING"> B<Arm only.> Set TEE type for the guest. TEE is a Trusted Execution @@ -3096,6 +3137,10 @@ vuart = "sbsa_uart" Currently, only the "sbsa_uart" model is supported for ARM. +For Realm guests, B<vuart="sbsa_uart"> is supported with the same device +model only when B<CONFIG_ARM_CCA_REALM_DEBUG_VUART=y>. The guest kernel should +use C<ttyAMA0>. + =back =over 4 @@ -3249,4 +3294,3 @@ documentation. Patches to improve incomplete items (or any other item) are gratefully received on the xen-devel@xxxxxxxxxxxxxxxxxxxx mailing list. Please see L<https://wiki.xenproject.org/wiki/Submitting_Xen_Project_Patches> for information on how to submit a patch to Xen. - diff --git a/tools/include/libxl.h b/tools/include/libxl.h index 7c098edab663..9b9398401029 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -293,6 +293,11 @@ */ #define LIBXL_HAVE_BUILDINFO_ARM_GIC_VERSION 1 +/* + * libxl_domain_build_info has the realm field. + */ +#define LIBXL_HAVE_BUILDINFO_ARM_REALM 1 + /* * libxl_domain_build_info has the arch_arm.tee field. */ diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c index 7e9f8a1bc366..fa13703bb98b 100644 --- a/tools/libs/light/libxl_arm.c +++ b/tools/libs/light/libxl_arm.c @@ -80,6 +80,70 @@ static const char *gicv_to_string(libxl_gic_version gic_version) } } +static bool arm_guest_is_realm(const libxl_domain_build_info *info) +{ + return libxl_defbool_val(info->realm); +} + +static int arm_realm_reject(libxl__gc *gc, const char *what) +{ + LOG(ERROR, "Realm guests do not support %s", what); + return ERROR_INVAL; +} + +static int arm_realm_check_config(libxl__gc *gc, + const libxl_domain_config *d_config) +{ + const libxl_domain_build_info *const info = &d_config->b_info; + const uint64_t bank0_memkb = GUEST_RAM0_SIZE >> 10; + + if ( !arm_guest_is_realm(info) ) + return 0; + + if ( info->type != LIBXL_DOMAIN_TYPE_PVH ) + return arm_realm_reject(gc, "non-PVH build types"); + + if ( info->target_memkb > bank0_memkb || info->max_memkb > bank0_memkb ) + return arm_realm_reject(gc, "guest RAM beyond the first RAM bank"); + + if ( info->device_tree ) + return arm_realm_reject(gc, "partial device trees"); + + if ( libxl_defbool_val(info->acpi) ) + return arm_realm_reject(gc, "ACPI"); + + if ( info->arch_arm.gic_version != LIBXL_GIC_VERSION_V3 ) + return arm_realm_reject(gc, "non-GICv3 interrupt controllers"); + + if ( info->tee != LIBXL_TEE_TYPE_NONE ) + return arm_realm_reject(gc, "TEE/FF-A plumbing"); + + if ( info->num_irqs || info->num_iomem ) + return arm_realm_reject(gc, "IRQ/IOMEM passthrough"); + + if ( info->num_vnuma_nodes ) + return arm_realm_reject(gc, "vNUMA"); + + if ( d_config->c_info.passthrough != LIBXL_PASSTHROUGH_DISABLED ) + return arm_realm_reject(gc, "passthrough mode"); + + if ( d_config->num_pcidevs || d_config->num_dtdevs ) + return arm_realm_reject(gc, "passthrough devices"); + + if ( d_config->num_disks || d_config->num_nics || + d_config->num_virtios || d_config->num_vkbs || + d_config->num_p9s || d_config->num_pvcallsifs ) + return arm_realm_reject(gc, "frontend/backend devices"); + + if ( d_config->num_vtpms || d_config->num_vfbs || + d_config->num_vdispls || d_config->num_vsnds || + d_config->num_channels || d_config->num_usbctrls || + d_config->num_usbdevs ) + return arm_realm_reject(gc, "auxiliary frontend devices"); + + return 0; +} + int libxl__arch_domain_prepare_config(libxl__gc *gc, libxl_domain_config *d_config, struct xen_domctl_createdomain *config) @@ -92,6 +156,10 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, uint32_t virtio_mmio_irq = GUEST_VIRTIO_MMIO_SPI_FIRST; int rc; + rc = arm_realm_check_config(gc, d_config); + if ( rc ) + return rc; + /* * If pl011 vuart is enabled then increment the nr_spis to allow allocation * of SPI VIRQ for pl011. @@ -617,7 +685,7 @@ static int make_cpus_node(libxl__gc *gc, void *fdt, int nr_cpus, return 0; } -static int make_psci_node(libxl__gc *gc, void *fdt) +static int make_psci_node(libxl__gc *gc, void *fdt, bool realm) { int res; @@ -628,7 +696,7 @@ static int make_psci_node(libxl__gc *gc, void *fdt) "arm,psci-0.2", "arm,psci"); if (res) return res; - res = fdt_property_string(fdt, "method", "hvc"); + res = fdt_property_string(fdt, "method", realm ? "smc" : "hvc"); if (res) return res; res = fdt_property_cell(fdt, "cpu_off", PSCI_cpu_off); @@ -1363,7 +1431,7 @@ next_resize: FDT( make_root_properties(gc, vers, fdt) ); FDT( make_chosen_node(gc, fdt, !!dom->modules[0].blob, state, info) ); FDT( make_cpus_node(gc, fdt, info->max_vcpus, ainfo) ); - FDT( make_psci_node(gc, fdt) ); + FDT( make_psci_node(gc, fdt, arm_guest_is_realm(info)) ); FDT( make_memory_nodes(gc, fdt, dom) ); @@ -1384,7 +1452,13 @@ next_resize: } FDT( make_timer_node(gc, fdt, ainfo, state->clock_frequency) ); - FDT( make_hypervisor_node(gc, fdt, vers) ); + /* + * Common domain creation may still allocate grant-table resources, + * but this is the guest-visible path to them. Realm guests + * deliberately omit Xen PV interfaces, including grant-table space. + */ + if (!arm_guest_is_realm(info)) + FDT( make_hypervisor_node(gc, fdt, vers) ); if (info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom) ); @@ -1427,7 +1501,7 @@ next_resize: * The iommu node should be created only once for all virtio-mmio * devices. */ - if (iommu_needed) + if (iommu_needed && !arm_guest_is_realm(info)) FDT( make_xen_iommu_node(gc, fdt) ); if (pfdt) @@ -1559,6 +1633,9 @@ static int finalize_hypervisor_node(libxl__gc *gc, libxl_dominfo info; int offset, rc; + if ( arm_guest_is_realm(b_info) ) + return 0; + offset = fdt_path_offset(fdt, "/hypervisor"); if (offset < 0) return offset; @@ -1732,31 +1809,50 @@ int libxl__arch_domain_finalise_hw_description(libxl__gc *gc, return 0; } +static int arm_realm_finalize_guest(libxl__gc *gc, struct xc_dom_image *dom) +{ + int rc; + + if (dom->rambank_size[1] != 0) { + LOG(ERROR, "Realm guests must fit entirely within the first RAM bank"); + return ERROR_INVAL; + } + + rc = xc_arm_cca_init_realm(CTX->xch, dom->guest_domid, + GUEST_RAM_BASE >> XC_PAGE_SHIFT, + dom->rambank_size[0]); + if (rc < 0) { + LOGE(ERROR, "xc_arm_cca_init_realm failed"); + return ERROR_FAIL; + } + + return 0; +} + int libxl__arch_build_dom_finish(libxl__gc *gc, libxl_domain_build_info *info, struct xc_dom_image *dom, libxl__domain_build_state *state) { - int rc = 0, ret; - - if (info->arch_arm.vuart != LIBXL_VUART_TYPE_SBSA_UART) { - rc = 0; - goto out; + int ret; + + if (info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) { + ret = xc_dom_vuart_init(CTX->xch, + XEN_DOMCTL_VUART_TYPE_VPL011, + dom->guest_domid, + dom->console_domid, + dom->vuart_gfn, + &state->vuart_port); + if (ret < 0) { + LOG(ERROR, "xc_dom_vuart_init failed\n"); + return ERROR_FAIL; + } } - ret = xc_dom_vuart_init(CTX->xch, - XEN_DOMCTL_VUART_TYPE_VPL011, - dom->guest_domid, - dom->console_domid, - dom->vuart_gfn, - &state->vuart_port); - if (ret < 0) { - rc = ERROR_FAIL; - LOG(ERROR, "xc_dom_vuart_init failed\n"); - } + if (arm_guest_is_realm(info)) + return arm_realm_finalize_guest(gc, dom); -out: - return rc; + return 0; } int libxl__arch_vnuma_build_vmemrange(libxl__gc *gc, diff --git a/tools/libs/light/libxl_create.c b/tools/libs/light/libxl_create.c index bfc9149096a3..1401697ab1d4 100644 --- a/tools/libs/light/libxl_create.c +++ b/tools/libs/light/libxl_create.c @@ -407,6 +407,8 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, libxl_defbool_setdefault(&b_info->nested_hvm, false); } + libxl_defbool_setdefault(&b_info->realm, false); + if (b_info->max_grant_version == LIBXL_MAX_GRANT_DEFAULT) { if (info.cap_gnttab_v2) b_info->max_grant_version = 2; diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_types.idl index a7893460f013..d2fa3535ab18 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -657,6 +657,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("apic", libxl_defbool), ("dm_restrict", libxl_defbool), ("tee", libxl_tee_type), + ("realm", libxl_defbool), ("u", KeyedUnion(None, libxl_domain_type, "type", [("hvm", Struct(None, [("firmware", string), ("bios", libxl_bios_type), diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 48c72dce9c6d..742c203a0326 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -3058,6 +3058,8 @@ skip_usbdev: } } + xlu_cfg_get_defbool(config, "realm", &b_info->realm, 0); + if (!xlu_cfg_get_string (config, "sve", &buf, 1)) { e = libxl_sve_type_from_string(buf, &b_info->arch_arm.sve_vl); if (e) { -- 2.51.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |