[PATCH v5 23/26] KVM: arm64/sve: Allow userspace to enable SVE for vcpus

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux