From: Dave Martin <Dave.Martin@arm.com> To: kvmarm@lists.cs.columbia.edu Cc: Okamoto Takayuki <tokamoto@jp.fujitsu.com>, Christoffer Dall <cdall@kernel.org>, Ard Biesheuvel <ard.biesheuvel@linaro.org>, Marc Zyngier <marc.zyngier@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will.deacon@arm.com>, linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 22/25] KVM: arm64/sve: Allow userspace to enable SVE for vcpus Date: Thu, 17 Jan 2019 20:33:36 +0000 [thread overview] Message-ID: <1547757219-19439-23-git-send-email-Dave.Martin@arm.com> (raw) In-Reply-To: <1547757219-19439-1-git-send-email-Dave.Martin@arm.com> 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@arm.com> --- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/reset.c | 78 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 82a99f6..f77b780 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -45,7 +45,7 @@ #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS -#define KVM_VCPU_MAX_FEATURES 4 +#define KVM_VCPU_MAX_FEATURES 5 #define KVM_REQ_SLEEP \ KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 6dfbfa3..fc613af 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..5ff2360 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -23,11 +23,13 @@ #include <linux/kvm_host.h> #include <linux/kvm.h> #include <linux/hw_breakpoint.h> +#include <linux/slab.h> #include <kvm/arm_arch_timer.h> #include <asm/cpufeature.h> #include <asm/cputype.h> +#include <asm/fpsimd.h> #include <asm/ptrace.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> @@ -98,11 +100,77 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext) return r; } +static size_t vcpu_sve_state_size(struct kvm_vcpu *vcpu) +{ + if (WARN_ON(!sve_vl_valid(vcpu->arch.sve_max_vl))) + return 0; + + return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vcpu->arch.sve_max_vl)); +} + +static int kvm_reset_sve(struct kvm_vcpu *vcpu) +{ + unsigned int vq; + + 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) + return -EINVAL; + + if (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; + for (vq = SVE_VQ_MIN; vq <= sve_vq_from_vl(sve_max_vl); ++vq) { + unsigned int i = vq - SVE_VQ_MIN; + + if (sve_vq_available(vq)) + vcpu->arch.sve_vqs[i / 64] |= (u64)1 << (i % 64); + } + + /* + * 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); + if (!vcpu->arch.sve_state) + return -ENOMEM; + } + vcpu->arch.flags |= KVM_ARM64_VCPU_FINALIZED; return 0; } @@ -113,12 +181,20 @@ int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu) * * This function finds the right table above and sets the registers on * the virtual CPU struct to their architecturally defined reset - * values. + * values, except for registers whose reset is deferred until + * kvm_arm_vcpu_finalize(). */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { + int ret; const struct kvm_regs *cpu_reset; + if (test_bit(KVM_ARM_VCPU_SVE, vcpu->arch.features)) { + ret = kvm_reset_sve(vcpu); + if (ret) + return ret; + } + switch (vcpu->arch.target) { default: if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { -- 2.1.4
WARNING: multiple messages have this Message-ID (diff)
From: Dave Martin <Dave.Martin@arm.com> To: kvmarm@lists.cs.columbia.edu Cc: "Peter Maydell" <peter.maydell@linaro.org>, "Okamoto Takayuki" <tokamoto@jp.fujitsu.com>, "Christoffer Dall" <cdall@kernel.org>, "Ard Biesheuvel" <ard.biesheuvel@linaro.org>, "Marc Zyngier" <marc.zyngier@arm.com>, "Catalin Marinas" <catalin.marinas@arm.com>, "Will Deacon" <will.deacon@arm.com>, "Julien Grall" <Julien.Grall@arm.com>, "Alex Bennée" <alex.bennee@linaro.org>, linux-arm-kernel@lists.infradead.org Subject: [PATCH v4 22/25] KVM: arm64/sve: Allow userspace to enable SVE for vcpus Date: Thu, 17 Jan 2019 20:33:36 +0000 [thread overview] Message-ID: <1547757219-19439-23-git-send-email-Dave.Martin@arm.com> (raw) In-Reply-To: <1547757219-19439-1-git-send-email-Dave.Martin@arm.com> 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@arm.com> --- arch/arm64/include/asm/kvm_host.h | 2 +- arch/arm64/include/uapi/asm/kvm.h | 1 + arch/arm64/kvm/reset.c | 78 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 82a99f6..f77b780 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -45,7 +45,7 @@ #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS -#define KVM_VCPU_MAX_FEATURES 4 +#define KVM_VCPU_MAX_FEATURES 5 #define KVM_REQ_SLEEP \ KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 6dfbfa3..fc613af 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..5ff2360 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -23,11 +23,13 @@ #include <linux/kvm_host.h> #include <linux/kvm.h> #include <linux/hw_breakpoint.h> +#include <linux/slab.h> #include <kvm/arm_arch_timer.h> #include <asm/cpufeature.h> #include <asm/cputype.h> +#include <asm/fpsimd.h> #include <asm/ptrace.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> @@ -98,11 +100,77 @@ int kvm_arch_vm_ioctl_check_extension(struct kvm *kvm, long ext) return r; } +static size_t vcpu_sve_state_size(struct kvm_vcpu *vcpu) +{ + if (WARN_ON(!sve_vl_valid(vcpu->arch.sve_max_vl))) + return 0; + + return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vcpu->arch.sve_max_vl)); +} + +static int kvm_reset_sve(struct kvm_vcpu *vcpu) +{ + unsigned int vq; + + 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) + return -EINVAL; + + if (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; + for (vq = SVE_VQ_MIN; vq <= sve_vq_from_vl(sve_max_vl); ++vq) { + unsigned int i = vq - SVE_VQ_MIN; + + if (sve_vq_available(vq)) + vcpu->arch.sve_vqs[i / 64] |= (u64)1 << (i % 64); + } + + /* + * 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); + if (!vcpu->arch.sve_state) + return -ENOMEM; + } + vcpu->arch.flags |= KVM_ARM64_VCPU_FINALIZED; return 0; } @@ -113,12 +181,20 @@ int kvm_arm_vcpu_finalize(struct kvm_vcpu *vcpu) * * This function finds the right table above and sets the registers on * the virtual CPU struct to their architecturally defined reset - * values. + * values, except for registers whose reset is deferred until + * kvm_arm_vcpu_finalize(). */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { + int ret; const struct kvm_regs *cpu_reset; + if (test_bit(KVM_ARM_VCPU_SVE, vcpu->arch.features)) { + ret = kvm_reset_sve(vcpu); + if (ret) + return ret; + } + switch (vcpu->arch.target) { default: if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { -- 2.1.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-01-17 20:35 UTC|newest] Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-01-17 20:33 [PATCH v4 00/25] KVM: arm64: SVE guest support Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 01/25] KVM: Documentation: Document arm64 core registers in detail Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 02/25] arm64: fpsimd: Always set TIF_FOREIGN_FPSTATE on task state flush Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 03/25] KVM: arm64: Delete orphaned declaration for __fpsimd_enabled() Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 04/25] KVM: arm64: Refactor kvm_arm_num_regs() for easier maintenance Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 05/25] KVM: arm64: Add missing #include of <linux/bitmap.h> to kvm_host.h Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 06/25] arm64/sve: Check SVE virtualisability Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 07/25] arm64/sve: Clarify role of the VQ map maintenance functions Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 08/25] arm64/sve: Enable SVE state tracking for non-task contexts Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 09/25] KVM: arm64: Add a vcpu flag to control SVE visibility for the guest Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 10/25] KVM: arm64: Propagate vcpu into read_id_reg() Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 11/25] KVM: arm64: Extend reset_unknown() to handle mixed RES0/UNKNOWN registers Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 12/25] KVM: arm64: Support runtime sysreg filtering for KVM_GET_REG_LIST Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 13/25] KVM: arm64/sve: System register context switch and access support Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-18 16:42 ` Marc Zyngier 2019-01-18 16:42 ` Marc Zyngier 2019-01-22 16:27 ` Dave Martin 2019-01-22 16:27 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 14/25] KVM: arm64/sve: Context switch the SVE registers Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-18 17:15 ` Marc Zyngier 2019-01-18 17:15 ` Marc Zyngier 2019-01-22 17:12 ` Dave Martin 2019-01-22 17:12 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 15/25] KVM: Allow 2048-bit register access via ioctl interface Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 16/25] KVM: arm64: Reject ioctl access to FPSIMD V-regs on SVE vcpus Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 17/25] KVM: arm64/sve: Add SVE support to register access ioctl interface Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-18 17:58 ` Marc Zyngier 2019-01-18 17:58 ` Marc Zyngier 2019-01-22 17:24 ` Dave Martin 2019-01-22 17:24 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 18/25] KVM: arm64: Enumerate SVE register indices for KVM_GET_REG_LIST Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 19/25] arm64/sve: In-kernel vector length availability query interface Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 20/25] KVM: arm/arm64: Add hook to finalize the vcpu configuration Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 21/25] KVM: arm64/sve: Add pseudo-register for the guest's vector lengths Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` Dave Martin [this message] 2019-01-17 20:33 ` [PATCH v4 22/25] KVM: arm64/sve: Allow userspace to enable SVE for vcpus Dave Martin 2019-01-17 20:33 ` [PATCH v4 23/25] KVM: arm64: Add a capabillity to advertise SVE support Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 24/25] KVM: Document errors for KVM_GET_ONE_REG and KVM_SET_ONE_REG Dave Martin 2019-01-17 20:33 ` Dave Martin 2019-01-17 20:33 ` [PATCH v4 25/25] KVM: arm64/sve: Document KVM API extensions for SVE Dave Martin 2019-01-17 20:33 ` Dave Martin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1547757219-19439-23-git-send-email-Dave.Martin@arm.com \ --to=dave.martin@arm.com \ --cc=ard.biesheuvel@linaro.org \ --cc=catalin.marinas@arm.com \ --cc=cdall@kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=marc.zyngier@arm.com \ --cc=tokamoto@jp.fujitsu.com \ --cc=will.deacon@arm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.