|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 04/17] xen: Introduce XEN_DOMCTL_CDF_not_hypercall_target
On Wed, 16 Jul 2025, Jason Andryuk wrote:
> Add a new create domain flag to indicate if a domain can be the target
> of hypercalls. By default all domains can be targetted - subject to any
> other permission checks.
>
> This property is useful in a safety environment to isolate domains for
> freedom from interference.
>
> Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
> ---
> DOMAIN_CAPS_NOT_HYPERCALL_TARGET duplicates the hypercall-untargetable
> DT property, so it could be removed. Leaving it here for now to at
> least illustrate the alternate approach.
> ---
> docs/misc/arm/device-tree/booting.txt | 6 ++++++
> tools/ocaml/libs/xc/xenctrl.ml | 1 +
> tools/ocaml/libs/xc/xenctrl.mli | 1 +
> xen/arch/arm/domain.c | 3 ++-
> xen/common/device-tree/dom0less-build.c | 6 ++++++
> xen/common/domain.c | 2 +-
> xen/include/public/bootfdt.h | 10 ++++++++--
> xen/include/public/domctl.h | 4 +++-
> xen/include/xen/sched.h | 12 ++++++++++++
> xen/include/xsm/dummy.h | 4 ++++
> 10 files changed, 44 insertions(+), 5 deletions(-)
>
> diff --git a/docs/misc/arm/device-tree/booting.txt
> b/docs/misc/arm/device-tree/booting.txt
> index 07acc7ba64..963dd81912 100644
> --- a/docs/misc/arm/device-tree/booting.txt
> +++ b/docs/misc/arm/device-tree/booting.txt
> @@ -307,6 +307,12 @@ with the following properties:
> passed through. This option is the default if this property is missing
> and the user does not provide the device partial device tree for the
> domain.
>
> +- hypercall-untargetable
> +
> + Optional. An empty property to specify the domain cannot be the target
> + of hypercalls. This protects a domain for freedom of interference from
> + other domains.
This protects a domain from interference
or
This protects a domain ensuring freedom of interference from other
domains
> Under the "xen,domain" compatible node, one or more sub-nodes are present
> for the DomU kernel and ramdisk.
>
> diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
> index f5835e7d95..00c29199dc 100644
> --- a/tools/ocaml/libs/xc/xenctrl.ml
> +++ b/tools/ocaml/libs/xc/xenctrl.ml
> @@ -72,6 +72,7 @@ type domain_create_flag =
> | CDF_VPMU
> | CDF_TRAP_UNMAPPED_ACCESSES
> | CDF_DEVICE_MODEL
> + | CDF_NOT_HYPERCALL_TARGET
>
> type domain_create_iommu_opts =
> | IOMMU_NO_SHAREPT
> diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
> index b9471a56a8..daf6686f4d 100644
> --- a/tools/ocaml/libs/xc/xenctrl.mli
> +++ b/tools/ocaml/libs/xc/xenctrl.mli
> @@ -65,6 +65,7 @@ type domain_create_flag =
> | CDF_VPMU
> | CDF_TRAP_UNMAPPED_ACCESSES
> | CDF_DEVICE_MODEL
> + | CDF_NOT_HYPERCALL_TARGET
>
> type domain_create_iommu_opts =
> | IOMMU_NO_SHAREPT
> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
> index 57eecbd250..5f6358096f 100644
> --- a/xen/arch/arm/domain.c
> +++ b/xen/arch/arm/domain.c
> @@ -614,7 +614,8 @@ int arch_sanitise_domain_config(struct
> xen_domctl_createdomain *config)
> unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu |
> XEN_DOMCTL_CDF_vpmu |
> XEN_DOMCTL_CDF_xs_domain |
> XEN_DOMCTL_CDF_trap_unmapped_accesses |
> - XEN_DOMCTL_CDF_device_model);
> + XEN_DOMCTL_CDF_device_model |
> + XEN_DOMCTL_CDF_not_hypercall_target);
> unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
>
> if ( (config->flags & ~flags_optional) != flags_required )
> diff --git a/xen/common/device-tree/dom0less-build.c
> b/xen/common/device-tree/dom0less-build.c
> index bb52291dfb..22af043aa5 100644
> --- a/xen/common/device-tree/dom0less-build.c
> +++ b/xen/common/device-tree/dom0less-build.c
> @@ -886,6 +886,9 @@ void __init create_domUs(void)
>
> if ( val & DOMAIN_CAPS_DEVICE_MODEL )
> d_cfg.flags |= XEN_DOMCTL_CDF_device_model;
> +
> + if ( val & DOMAIN_CAPS_NOT_HYPERCALL_TARGET )
> + d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target;
> }
>
> if ( dt_find_property(node, "xen,static-mem", NULL) )
> @@ -896,6 +899,9 @@ void __init create_domUs(void)
> flags |= CDF_staticmem;
> }
>
> + if ( dt_property_read_bool(node, "hypercall-untargetable") )
> + d_cfg.flags |= XEN_DOMCTL_CDF_not_hypercall_target;
> +
> if ( dt_property_read_bool(node, "direct-map") )
> {
> if ( !(flags & CDF_staticmem) )
> diff --git a/xen/common/domain.c b/xen/common/domain.c
> index 42c590b8d7..c347de4335 100644
> --- a/xen/common/domain.c
> +++ b/xen/common/domain.c
> @@ -723,7 +723,7 @@ static int sanitise_domain_config(struct
> xen_domctl_createdomain *config)
> XEN_DOMCTL_CDF_xs_domain | XEN_DOMCTL_CDF_iommu |
> XEN_DOMCTL_CDF_nested_virt | XEN_DOMCTL_CDF_vpmu |
> XEN_DOMCTL_CDF_trap_unmapped_accesses |
> - XEN_DOMCTL_CDF_device_model) )
> + XEN_DOMCTL_CDF_device_model |
> XEN_DOMCTL_CDF_not_hypercall_target) )
> {
> dprintk(XENLOG_INFO, "Unknown CDF flags %#x\n", config->flags);
> return -EINVAL;
> diff --git a/xen/include/public/bootfdt.h b/xen/include/public/bootfdt.h
> index c6b5afc76a..1eba1cc487 100644
> --- a/xen/include/public/bootfdt.h
> +++ b/xen/include/public/bootfdt.h
> @@ -32,8 +32,14 @@
> * Hardware domain for running QEMU.
> */
> #define DOMAIN_CAPS_DEVICE_MODEL (1U << 3)
> +/*
> + * Domain cannot be the target of hypercalls. This provides the domain
> + * freedom from interference from other domains.
> + */
> +#define DOMAIN_CAPS_NOT_HYPERCALL_TARGET (1U << 4)
>
> -#define DOMAIN_CAPS_MASK (DOMAIN_CAPS_CONTROL | DOMAIN_CAPS_HARDWARE | \
> - DOMAIN_CAPS_XENSTORE |
> DOMAIN_CAPS_DEVICE_MODEL )
> +#define DOMAIN_CAPS_MASK (DOMAIN_CAPS_CONTROL | DOMAIN_CAPS_HARDWARE | \
> + DOMAIN_CAPS_XENSTORE | DOMAIN_CAPS_DEVICE_MODEL
> | \
> + DOMAIN_CAPS_NOT_HYPERCALL_TARGET)
>
> #endif /* __XEN_PUBLIC_BOOTFDT_H__ */
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
> index 88a294c5be..f1f6f96bc2 100644
> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -70,9 +70,11 @@ struct xen_domctl_createdomain {
> #define XEN_DOMCTL_CDF_trap_unmapped_accesses (1U << 8)
> /* Allow domain to provide device model for multiple other domains */
> #define XEN_DOMCTL_CDF_device_model (1U << 9)
> +/* Domain cannot be the target of hypercalls */
> +#define XEN_DOMCTL_CDF_not_hypercall_target (1U << 10)
>
> /* Max XEN_DOMCTL_CDF_* constant. Used for ABI checking. */
> -#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_device_model
> +#define XEN_DOMCTL_CDF_MAX XEN_DOMCTL_CDF_not_hypercall_target
>
> uint32_t flags;
>
> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
> index 9863603d93..8a32f9a1b6 100644
> --- a/xen/include/xen/sched.h
> +++ b/xen/include/xen/sched.h
> @@ -1157,6 +1157,18 @@ static always_inline bool is_dm_domain(const struct
> domain *d)
> return evaluate_nospec(d->options & XEN_DOMCTL_CDF_device_model);
> }
>
> +/*
> + * Return whether this domain can be the target of hypercalls from other
> + * domains.
> + */
> +static always_inline bool is_hypercall_target(const struct domain *d)
> +{
> + if ( IS_ENABLED(CONFIG_PV_SHIM_EXCLUSIVE) )
> + return true;
> +
> + return evaluate_nospec(!(d->options &
> XEN_DOMCTL_CDF_not_hypercall_target));
> +}
> +
> #define VM_ASSIST(d, t) (test_bit(VMASST_TYPE_ ## t, &(d)->vm_assist))
>
> static always_inline bool is_pv_domain(const struct domain *d)
> diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
> index 0b341efd18..f2205575ed 100644
> --- a/xen/include/xsm/dummy.h
> +++ b/xen/include/xsm/dummy.h
> @@ -91,12 +91,16 @@ static always_inline int xsm_default_action(
> return 0;
> fallthrough;
> case XSM_DM_PRIV:
> + if ( target && !is_hypercall_target(target) )
> + return -EPERM;
> if ( is_dm_domain(src) )
> return 0;
> if ( target && evaluate_nospec(src->target == target) )
> return 0;
> fallthrough;
> case XSM_PRIV:
> + if ( target && !is_hypercall_target(target) )
> + return -EPERM;
> if ( is_control_domain(src) )
> return 0;
> return -EPERM;
> --
> 2.50.0
>
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |