Hi Dave, On 18/02/2019 19:52, Dave Martin wrote: > Now that all the pieces are in place, this patch offers a new flag > KVM_ARM_VCPU_SVE that userspace can pass to KVM_ARM_VCPU_INIT to > turn on SVE for the guest, on a per-vcpu basis. > > As part of this, support for initialisation and reset of the SVE > vector length set and registers is added in the appropriate places. > Allocation SVE registers is deferred until kvm_arm_vcpu_finalize(), > by which time the size of the registers is known. > > Setting the vector lengths supported by the vcpu is considered > configuration of the emulated hardware rather than runtime > configuration, so no support is offered for changing the vector > lengths of an existing vcpu across reset. > > Signed-off-by: Dave Martin <Dave.Martin at arm.com> > > --- > > Changes since v4: > > * Pull out vcpu_sve_state_size(), for use earlier in the series. > > * Remove unnecessary vcpu->arch.sve_vqs[], and clamp maximum guest > vector length to 256 bytes for forwards compatibility. > > (See "KVM: arm64/sve: Add pseudo-register for the guest's vector > lengths".) > > * Minor tidyups to make some checks less verbose. > --- > arch/arm64/include/asm/kvm_host.h | 2 +- > arch/arm64/include/uapi/asm/kvm.h | 1 + > arch/arm64/kvm/reset.c | 70 ++++++++++++++++++++++++++++++++++++++- > 3 files changed, 71 insertions(+), 2 deletions(-) > [...] > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h > index 7ff1bd4..6963b7e 100644 > --- a/arch/arm64/include/uapi/asm/kvm.h > +++ b/arch/arm64/include/uapi/asm/kvm.h > @@ -102,6 +102,7 @@ struct kvm_regs { > #define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */ > #define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */ > #define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */ > +#define KVM_ARM_VCPU_SVE 4 /* enable SVE for this CPU */ > > struct kvm_vcpu_init { > __u32 target; > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c > index 1379fb2..e67cd2e 100644 > --- a/arch/arm64/kvm/reset.c > +++ b/arch/arm64/kvm/reset.c [...] > @@ -98,11 +100,69 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext) > return r; > } > > +static int kvm_reset_sve(struct kvm_vcpu *vcpu) > +{ > + if (!system_supports_sve()) > + return -EINVAL; > + > + /* If resetting an already-configured vcpu, just zero the SVE regs: */ > + if (vcpu->arch.sve_state) { > + size_t size = vcpu_sve_state_size(vcpu); > + > + if (!size || WARN_ON(!vcpu_has_sve(vcpu))) > + return -EINVAL; > + > + memset(vcpu->arch.sve_state, 0, size); > + return 0; > + } > + > + if (WARN_ON(!sve_vl_valid(sve_max_vl))) > + return -EINVAL; > + > + /* If the full set of host vector lengths cannot be used, give up: */ > + if (sve_max_virtualisable_vl < sve_max_vl) > + return -EINVAL; > + > + /* Default to the set of vector lengths supported by the host */ > + vcpu->arch.sve_max_vl = sve_max_vl; > + > + /* > + * The get_sve_reg()/set_sve_reg() ioctl interface will need > + * to be extended with multiple register slice support in > + * order to support vector lengths greater than > + * SVE_VL_ARCH_MAX: > + */ > + if (WARN_ONCE(vcpu->arch.sve_max_vl > SVE_VL_ARCH_MAX, > + "KVM: SVE vector length for guests limited to %d bytes\n", > + SVE_VL_ARCH_MAX)) > + vcpu->arch.sve_max_vl = SVE_VL_ARCH_MAX; > + > + /* > + * Userspace can still customize the vector lengths by writing > + * KVM_REG_ARM64_SVE_VLS. Allocation is deferred until > + * kvm_arm_vcpu_finalize(), which freezes the configuration. > + */ > + vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_SVE; > + > + return 0; > +} > + > int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu) > { > if (likely(kvm_arm_vcpu_finalized(vcpu))) > return 0; > > + if (vcpu_has_sve(vcpu)) { > + size_t size = vcpu_sve_state_size(vcpu); > + > + if (!size) > + return -EINVAL; > + > + vcpu->arch.sve_state = kzalloc(size, GFP_KERNEL); We should probably free this in kvm_arch_vcpu_free(). Cheers, -- Julien Thierry