|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 07/12] xen: enable Dom0 to use SVE feature
Hi Luca,
> On 12 Apr 2023, at 11:49, Luca Fancellu <Luca.Fancellu@xxxxxxx> wrote:
>
> Add a command line parameter to allow Dom0 the use of SVE resources,
> the command line parameter sve=<integer>, sub argument of dom0=,
> controls the feature on this domain and sets the maximum SVE vector
> length for Dom0.
>
> Add a new function, parse_signed_integer(), to parse an integer
> command line argument.
>
> Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
> ---
> Changes from v4:
> - Negative values as user param means max supported HW VL (Jan)
> - update documentation, make use of no_config_param(), rename
> parse_integer into parse_signed_integer and take long long *,
> also put a comment on the -2 return condition, update
> declaration comment to reflect the modifications (Jan)
> Changes from v3:
> - Don't use fixed len types when not needed (Jan)
> - renamed domainconfig_encode_vl to sve_encode_vl
> - Use a sub argument of dom0= to enable the feature (Jan)
> - Add parse_integer() function
> Changes from v2:
> - xen_domctl_createdomain field has changed into sve_vl and its
> value now is the VL / 128, create an helper function for that.
> Changes from v1:
> - No changes
> Changes from RFC:
> - Changed docs to explain that the domain won't be created if the
> requested vector length is above the supported one from the
> platform.
> ---
> docs/misc/xen-command-line.pandoc | 18 ++++++++++++++++--
> xen/arch/arm/arm64/sve.c | 21 +++++++++++++++++++++
> xen/arch/arm/domain_build.c | 27 +++++++++++++++++++++++++++
> xen/arch/arm/include/asm/arm64/sve.h | 15 +++++++++++++++
> xen/common/kernel.c | 25 +++++++++++++++++++++++++
> xen/include/xen/lib.h | 10 ++++++++++
> 6 files changed, 114 insertions(+), 2 deletions(-)
>
> diff --git a/docs/misc/xen-command-line.pandoc
> b/docs/misc/xen-command-line.pandoc
> index e0b89b7d3319..9c0790ce6c7c 100644
> --- a/docs/misc/xen-command-line.pandoc
> +++ b/docs/misc/xen-command-line.pandoc
> @@ -777,9 +777,9 @@ Specify the bit width of the DMA heap.
>
> ### dom0
> = List of [ pv | pvh, shadow=<bool>, verbose=<bool>,
> - cpuid-faulting=<bool>, msr-relaxed=<bool> ]
> + cpuid-faulting=<bool>, msr-relaxed=<bool> ] (x86)
>
> - Applicability: x86
> + = List of [ sve=<integer> ] (Arm)
>
> Controls for how dom0 is constructed on x86 systems.
>
> @@ -838,6 +838,20 @@ Controls for how dom0 is constructed on x86 systems.
>
> If using this option is necessary to fix an issue, please report a bug.
>
> +Enables features on dom0 on Arm systems.
> +
> +* The `sve` integer parameter enables Arm SVE usage for Dom0 domain and
> sets
> + the maximum SVE vector length.
> + A value equal to 0 disables the feature, this is the default value.
> + Values below 0 means the feature uses the maximum SVE vector length
> + supported by hardware, please be aware that if the hardware doesn't
> supports
> + SVE, the feature remains disabled.
> + Values above 0 explicitly set the maximum SVE vector length for Dom0,
> + allowed values are from 128 to maximum 2048, being multiple of 128.
> + Please note that when the user explicitly specify the value, if that
> value
> + is above the hardware supported maximum SVE vector length, the domain
> + creation will fail and the system will stop.
> +
> ### dom0-cpuid
> = List of comma separated booleans
>
> diff --git a/xen/arch/arm/arm64/sve.c b/xen/arch/arm/arm64/sve.c
> index 5485648850a0..ad5db62e1805 100644
> --- a/xen/arch/arm/arm64/sve.c
> +++ b/xen/arch/arm/arm64/sve.c
> @@ -9,6 +9,9 @@
> #include <xen/sizes.h>
> #include <asm/arm64/sve.h>
>
> +/* opt_dom0_sve: allow Dom0 to use SVE and set maximum vector length. */
> +int __initdata opt_dom0_sve;
> +
> extern unsigned int sve_get_hw_vl(void);
> extern void sve_save_ctx(uint64_t *sve_ctx, uint64_t *pregs, int save_ffr);
> extern void sve_load_ctx(uint64_t const *sve_ctx, uint64_t const *pregs,
> @@ -118,3 +121,21 @@ void sve_restore_state(struct vcpu *v)
>
> sve_load_ctx(sve_ctx_zreg_end, v->arch.vfp.fpregs, 1);
> }
> +
> +int __init sve_sanitize_vl_param(int val, unsigned int *out)
> +{
> + /*
> + * Negative SVE parameter value means to use the maximum supported
> + * vector length, otherwise if a positive value is provided, check if the
> + * vector length is a multiple of 128 and not bigger than the maximum
> value
> + * 2048
> + */
> + if ( val < 0 )
> + *out = get_sys_vl_len();
> + else if ( ((val % SVE_VL_MULTIPLE_VAL) == 0) && (val <= SVE_VL_MAX_BITS)
> )
> + *out = val;
Shouldn't you also check if it is not greater than the maximum vector length ?
> + else
> + return -1;
> +
> + return 0;
> +}
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index eeb4662f0eee..3f30ef5c37b6 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -26,6 +26,7 @@
> #include <asm/platform.h>
> #include <asm/psci.h>
> #include <asm/setup.h>
> +#include <asm/arm64/sve.h>
> #include <asm/cpufeature.h>
> #include <asm/domain_build.h>
> #include <xen/event.h>
> @@ -61,6 +62,21 @@ custom_param("dom0_mem", parse_dom0_mem);
>
> int __init parse_arch_dom0_param(const char *s, const char *e)
> {
> + long long val;
> +
> + if ( !parse_signed_integer("sve", s, e, &val) )
> + {
> +#ifdef CONFIG_ARM64_SVE
> + if ( (val >= INT_MIN) && (val <= INT_MAX) )
> + opt_dom0_sve = val;
> + else
> + printk(XENLOG_INFO "'sve=%lld' value out of range!\n", val);
> +#else
> + no_config_param("ARM64_SVE", "sve", s, e);
> +#endif
Correct me if my understanding is wrong but here you just ignore the sve
parameter if SVE is not supported by Xen ?
I am a bit wondering if we should not just refuse it here as the user might
wrongly think that his parameter had some effect.
Or is it a usual way to handle this case ?
> + return 0;
> + }
> +
> return -EINVAL;
> }
>
> @@ -4109,6 +4125,17 @@ void __init create_dom0(void)
> if ( iommu_enabled )
> dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
>
> + if ( opt_dom0_sve )
> + {
> + unsigned int vl;
> +
> + if ( !sve_sanitize_vl_param(opt_dom0_sve, &vl) )
> + dom0_cfg.arch.sve_vl = sve_encode_vl(vl);
> + else
> + printk(XENLOG_WARNING
> + "SVE vector length error, disable feature for Dom0\n");
> + }
> +
> dom0 = domain_create(0, &dom0_cfg, CDF_privileged | CDF_directmap);
> if ( IS_ERR(dom0) )
> panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
> diff --git a/xen/arch/arm/include/asm/arm64/sve.h
> b/xen/arch/arm/include/asm/arm64/sve.h
> index fc162c9d2cf7..f1801876b5de 100644
> --- a/xen/arch/arm/include/asm/arm64/sve.h
> +++ b/xen/arch/arm/include/asm/arm64/sve.h
> @@ -19,8 +19,15 @@ static inline unsigned int sve_decode_vl(unsigned int
> sve_vl)
> return sve_vl * SVE_VL_MULTIPLE_VAL;
> }
>
> +static inline unsigned int sve_encode_vl(unsigned int sve_vl_bits)
> +{
> + return sve_vl_bits / SVE_VL_MULTIPLE_VAL;
> +}
> +
> #ifdef CONFIG_ARM64_SVE
>
> +extern int opt_dom0_sve;
> +
> register_t compute_max_zcr(void);
> register_t vl_to_zcr(unsigned int vl);
> unsigned int get_sys_vl_len(void);
> @@ -28,9 +35,12 @@ int sve_context_init(struct vcpu *v);
> void sve_context_free(struct vcpu *v);
> void sve_save_state(struct vcpu *v);
> void sve_restore_state(struct vcpu *v);
> +int sve_sanitize_vl_param(int val, unsigned int *out);
>
> #else /* !CONFIG_ARM64_SVE */
>
> +#define opt_dom0_sve (0)
> +
> static inline register_t compute_max_zcr(void)
> {
> return 0;
> @@ -55,6 +65,11 @@ static inline void sve_context_free(struct vcpu *v) {}
> static inline void sve_save_state(struct vcpu *v) {}
> static inline void sve_restore_state(struct vcpu *v) {}
>
> +static inline int sve_sanitize_vl_param(int val, unsigned int *out)
> +{
> + return -1;
> +}
> +
> #endif /* CONFIG_ARM64_SVE */
>
> #endif /* _ARM_ARM64_SVE_H */
> diff --git a/xen/common/kernel.c b/xen/common/kernel.c
> index f7b1f65f373c..29d05282c8bb 100644
> --- a/xen/common/kernel.c
> +++ b/xen/common/kernel.c
> @@ -314,6 +314,31 @@ int parse_boolean(const char *name, const char *s, const
> char *e)
> return -1;
> }
>
> +int __init parse_signed_integer(const char *name, const char *s, const char
> *e,
> + long long *val)
> +{
> + size_t slen, nlen;
> + const char *str;
> + long long pval;
> +
> + slen = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
> + nlen = strlen(name);
> +
> + /* Does s start with name or contains only the name? */
> + if ( (slen <= nlen) || strncmp(s, name, nlen) || (s[nlen] != '=') )
> + return -1;
> +
> + pval = simple_strtoll(&s[nlen + 1], &str, 0);
> +
> + /* Number not recognised */
> + if ( str != e )
> + return -2;
> +
> + *val = pval;
> +
> + return 0;
> +}
> +
> int cmdline_strcmp(const char *frag, const char *name)
> {
> for ( ; ; frag++, name++ )
> diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
> index e914ccade095..5343ee7a944a 100644
> --- a/xen/include/xen/lib.h
> +++ b/xen/include/xen/lib.h
> @@ -94,6 +94,16 @@ int parse_bool(const char *s, const char *e);
> */
> int parse_boolean(const char *name, const char *s, const char *e);
>
> +/**
> + * Given a specific name, parses a string of the form:
> + * $NAME=<integer number>
> + * returning 0 and a value in val, for a recognised integer.
> + * Returns -1 for name not found, general errors, or -2 if name is found but
> + * not recognised number.
> + */
> +int parse_signed_integer(const char *name, const char *s, const char *e,
> + long long *val);
> +
> /**
> * Very similar to strcmp(), but will declare a match if the NUL in 'name'
> * lines up with comma, colon, semicolon or equals in 'frag'. Designed for
> --
> 2.34.1
>
Cheers
Bertrand
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |