|
[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 20 Apr 2023, at 10:46, Luca Fancellu <Luca.Fancellu@xxxxxxx> wrote:
>
>>>>>>
>>>>>> +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 ?
>>>>
>>>> I don’t understand, I am checking that the value is below or equal to
>>>> SVE_VL_MAX_BITS,
>>>> If you mean if it should be checked also against the maximum supported
>>>> length by the platform,
>>>> I think this is not the right place, the check is already in
>>>> arch_sanitise_domain_config(), introduced
>>>> in patch #2
>>>
>>> If this is not the right place to check it then why checking the rest here ?
>>>
>>> From a user or a developer point of view I would expect the validity of the
>>> input to be checked only
>>> in one place.
>>> If here is not the place for that it is ok but then i would check
>>> everything in arch_sanitise_domain_config
>>> (multiple, min and supported) instead of doing it partly in 2 places.
>>
>> Ok, given the way we encoded the value in xen_domctl_createdomain structure,
>> we have that the value takes
>> very little space, but a small issue is that when we encode it, we are
>> dividing it by 128, which is fine for user params
>> that are multiple of 128, but it’s less fine if the user passes “129”.
>>
>> To overcome this issue we are checking the value when it is not already
>> encoded. Now, thinking about it, the check
>> "&& (val <= SVE_VL_MAX_BITS)” is not really needed, because even if the
>> value is above, then in arch_sanitise_domain_config
>> we will hit the top limit of the platform maximum VL.
>>
>> int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
>> {
>> unsigned int max_vcpus;
>> unsigned int flags_required = (XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap);
>> unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu);
>> unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
>>
>> if ( (config->flags & ~flags_optional) != flags_required )
>> {
>> dprintk(XENLOG_INFO, "Unsupported configuration %#x\n",
>> config->flags);
>> return -EINVAL;
>> }
>>
>> /* Check feature flags */
>> if ( sve_vl_bits > 0 )
>> {
>> unsigned int zcr_max_bits = get_sys_vl_len();
>>
>> if ( !zcr_max_bits )
>> {
>> dprintk(XENLOG_INFO, "SVE is unsupported on this machine.\n");
>> return -EINVAL;
>> }
>>
>> if ( sve_vl_bits > zcr_max_bits )
>> {
>> dprintk(XENLOG_INFO,
>> "Requested SVE vector length (%u) > supported length
>> (%u)\n",
>> sve_vl_bits, zcr_max_bits);
>> return -EINVAL;
>> }
>> }
>> [...]
>>
>> Now, I understand your point, we could check everything in
>> sve_sanitize_vl_param(), but it would leave a problem
>> for domains created by hypercalls if I am not wrong.
>>
>> What do you think?
Sorry i missed that answer.
Yes i agree, maybe we could factorize the checks in one function and use it in
several places ?
>
> I thought about that and another possibility is to store “sve_vl” as uint16_t
> inside struct xen_arch_domainconfig, and
> check it inside arch_sanitise_domain_config() for it to be mod 128 and less
> than the max supported VL, this will
> allow to have all the checks in one place, taking a bit more space, anyway we
> would take the space from the implicit
> padding as this is the current status:
>
> struct arch_domain {
> enum domain_type type; /* 0 4 */
> uint8_t sve_vl; /* 4 1 */
>
> /* XXX 3 bytes hole, try to pack */
>
> struct p2m_domain p2m; /* 8 328 */
> /* --- cacheline 5 boundary (320 bytes) was 16 bytes ago --- */
> struct hvm_domain hvm; /* 336 312 */
> /* --- cacheline 10 boundary (640 bytes) was 8 bytes ago --- */
> struct paging_domain paging; /* 648 32 */
> struct vmmio vmmio; /* 680 32 */
> /* --- cacheline 11 boundary (704 bytes) was 8 bytes ago --- */
> unsigned int rel_priv; /* 712 4 */
>
> /* XXX 4 bytes hole, try to pack */
>
> struct {
> uint64_t offset; /* 720 8 */
> s_time_t nanoseconds; /* 728 8 */
> } virt_timer_base; /* 720 16 */
> struct vgic_dist vgic; /* 736 200 */
>
> /* XXX last struct has 2 bytes of padding */
>
> /* --- cacheline 14 boundary (896 bytes) was 40 bytes ago --- */
> struct vuart vuart; /* 936 32 */
> /* --- cacheline 15 boundary (960 bytes) was 8 bytes ago --- */
> unsigned int evtchn_irq; /* 968 4 */
> struct {
> uint8_t privileged_call_enabled:1; /* 972: 0 1 */
> } monitor; /* 972 1 */
>
> /* XXX 3 bytes hole, try to pack */
>
> struct vpl011 vpl011; /* 976 72 */
>
> /* size: 1152, cachelines: 18, members: 13 */
> /* sum members: 1038, holes: 3, sum holes: 10 */
> /* padding: 104 */
> /* paddings: 1, sum paddings: 2 */
> } __attribute__((__aligned__(128)));
That would work but it is a bit odd to save a 16bit value just so
you could save invalid values and give an error.
Cheers
Bertrand
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |