|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 05/12] arm/sve: save/restore SVE context switch
Hi Luca,
> On 19 Apr 2023, at 09:09, Luca Fancellu <Luca.Fancellu@xxxxxxx> wrote:
>
> Hi Bertrand,
>
>> On 18 Apr 2023, at 13:40, Bertrand Marquis <Bertrand.Marquis@xxxxxxx> wrote:
>>
>> Hi Luca,
>>
>>>
>>> diff --git a/xen/arch/arm/arm64/sve.c b/xen/arch/arm/arm64/sve.c
>>> index 78f7482619da..5485648850a0 100644
>>> --- a/xen/arch/arm/arm64/sve.c
>>> +++ b/xen/arch/arm/arm64/sve.c
>>> @@ -5,14 +5,29 @@
>>> * Copyright (C) 2022 ARM Ltd.
>>> */
>>>
>>> -#include <xen/types.h>
>>> -#include <asm/cpufeature.h>
>>> +#include <xen/sched.h>
>>> +#include <xen/sizes.h>
>>> #include <asm/arm64/sve.h>
>>> -#include <asm/arm64/sysregs.h>
>>> -#include <asm/processor.h>
>>> -#include <asm/system.h>
>>>
>>> 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,
>>> + int restore_ffr);
>>> +
>>> +static inline unsigned int sve_zreg_ctx_size(unsigned int vl)
>>> +{
>>> + /*
>>> + * Z0-31 registers size in bytes is computed from VL that is in bits,
>>> so VL
>>> + * in bytes is VL/8.
>>> + */
>>> + return (vl / 8U) * 32U;
>>> +}
>>> +
>>> +static inline unsigned int sve_ffrreg_ctx_size(unsigned int vl)
>>> +{
>>> + /* FFR register size is VL/8, which is in bytes (VL/8)/8 */
>>> + return (vl / 64U);
>>> +}
>>>
>>> register_t compute_max_zcr(void)
>>> {
>>> @@ -60,3 +75,46 @@ unsigned int get_sys_vl_len(void)
>>> return ((system_cpuinfo.zcr64.bits[0] & ZCR_ELx_LEN_MASK) + 1U) *
>>> SVE_VL_MULTIPLE_VAL;
>>> }
>>> +
>>> +int sve_context_init(struct vcpu *v)
>>> +{
>>> + unsigned int sve_vl_bits = sve_decode_vl(v->domain->arch.sve_vl);
>>> + uint64_t *ctx = _xzalloc(sve_zreg_ctx_size(sve_vl_bits) +
>>> + sve_ffrreg_ctx_size(sve_vl_bits),
>>> + L1_CACHE_BYTES);
>>> +
>>> + if ( !ctx )
>>> + return -ENOMEM;
>>> +
>>> + v->arch.vfp.sve_context = ctx;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +void sve_context_free(struct vcpu *v)
>>> +{
>>> + xfree(v->arch.vfp.sve_context);
>>> +}
>>> +
>>> +void sve_save_state(struct vcpu *v)
>>> +{
>>> + unsigned int sve_vl_bits = sve_decode_vl(v->domain->arch.sve_vl);
>>> + uint64_t *sve_ctx_zreg_end = v->arch.vfp.sve_context +
>>> + (sve_zreg_ctx_size(sve_vl_bits) / sizeof(uint64_t));
>>
>> You do quite some computation here for something which does not change
>> during the life of the VM.
>> Could we save the context_end in the vcpu instead and just do this
>> computation on init and free only ?
>
> Yes sure, would you be ok to have it in struct vfp_state?
Yes definitely i would store it instead of the current sve_context.
>
>>
>>>
>>> #endif /* _ARM_ARM64_SVE_H */
>>> diff --git a/xen/arch/arm/include/asm/arm64/sysregs.h
>>> b/xen/arch/arm/include/asm/arm64/sysregs.h
>>> index 4cabb9eb4d5e..3fdeb9d8cdef 100644
>>> --- a/xen/arch/arm/include/asm/arm64/sysregs.h
>>> +++ b/xen/arch/arm/include/asm/arm64/sysregs.h
>>> @@ -88,6 +88,9 @@
>>> #ifndef ID_AA64ISAR2_EL1
>>> #define ID_AA64ISAR2_EL1 S3_0_C0_C6_2
>>> #endif
>>> +#ifndef ZCR_EL1
>>> +#define ZCR_EL1 S3_0_C1_C2_0
>>> +#endif
>>>
>>
>> What about ZCR_EL2 ?
>
> It was introduced in patch #1 because we use it in register_t
> compute_max_zcr(void)
>
Sorry i missed that.
Cheers
Bertrand
>
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |