All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvmtool v2 0/3] arm64: Basic SVE guest support
@ 2019-03-20 12:07 ` Dave Martin
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Peter Maydell, Okamoto Takayuki, Christoffer Dall,
	Ard Biesheuvel, Marc Zyngier, Catalin Marinas, Will Deacon,
	Zhang Lei, Julien Grall, Andre Przywara, Alex Bennée,
	linux-arm-kernel

This series, based on kvmtool master [1], contains development hacks
to accompany the recently posted v6 SVE guest support series for the
Linux kernel [2].

This series supersedes the previous posting [3], and is a clean(er)
rewrite of the minimal support required for SVE, without the debug/
testing cruft.

Due to an ABI change, this series does not work with the older (v5)
KVM series.

Testing and review welcome.

In particular, if people have a view on the --sve-vls parameter, I'd
be interested to discuss what that should look like.  See patch 3.

[1] 
git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git master
https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git/log/

Specifically, commit c57e001a3efb ("arm: Auto-detect guest GIC type").

[2] [PATCH v5 00/26] KVM: arm64: SVE guest support
https://lists.cs.columbia.edu/pipermail/kvmarm/2019-March/thread.html

(Note, the subject line for this posting was incorrect.  It should have
read: [PATCH v6 00/27] KVM: arm64: SVE guest support)

git://linux-arm.org/linux-dm.git sve-kvm/v6/head
http://linux-arm.org/git?p=linux-dm.git;a=shortlog;h=refs/heads/sve-kvm/v6/head


Dave Martin (3):
  arm/arm64: [HACK] Sync kernel headers from sve-guest v6
  arm64: Add basic SVE support
  arm64: Add command-line option to set the guest's SVE vector lengths

 arm/aarch32/include/kvm/kvm-cpu-arch.h    |  5 ++
 arm/aarch64/include/asm/kvm.h             | 22 +++++++
 arm/aarch64/include/kvm/kvm-config-arch.h | 10 +++-
 arm/aarch64/include/kvm/kvm-cpu-arch.h    |  7 ++-
 arm/aarch64/kvm-cpu.c                     | 97 +++++++++++++++++++++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  2 +
 arm/kvm-cpu.c                             |  3 +
 include/linux/kvm.h                       |  5 ++
 8 files changed, 149 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 0/3] arm64: Basic SVE guest support
@ 2019-03-20 12:07 ` Dave Martin
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Peter Maydell, Okamoto Takayuki, Christoffer Dall,
	Ard Biesheuvel, Marc Zyngier, Catalin Marinas, Will Deacon,
	Zhang Lei, Julien Grall, Andre Przywara, Alex Bennée,
	linux-arm-kernel

This series, based on kvmtool master [1], contains development hacks
to accompany the recently posted v6 SVE guest support series for the
Linux kernel [2].

This series supersedes the previous posting [3], and is a clean(er)
rewrite of the minimal support required for SVE, without the debug/
testing cruft.

Due to an ABI change, this series does not work with the older (v5)
KVM series.

Testing and review welcome.

In particular, if people have a view on the --sve-vls parameter, I'd
be interested to discuss what that should look like.  See patch 3.

[1] 
git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git master
https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git/log/

Specifically, commit c57e001a3efb ("arm: Auto-detect guest GIC type").

[2] [PATCH v5 00/26] KVM: arm64: SVE guest support
https://lists.cs.columbia.edu/pipermail/kvmarm/2019-March/thread.html

(Note, the subject line for this posting was incorrect.  It should have
read: [PATCH v6 00/27] KVM: arm64: SVE guest support)

git://linux-arm.org/linux-dm.git sve-kvm/v6/head
http://linux-arm.org/git?p=linux-dm.git;a=shortlog;h=refs/heads/sve-kvm/v6/head


Dave Martin (3):
  arm/arm64: [HACK] Sync kernel headers from sve-guest v6
  arm64: Add basic SVE support
  arm64: Add command-line option to set the guest's SVE vector lengths

 arm/aarch32/include/kvm/kvm-cpu-arch.h    |  5 ++
 arm/aarch64/include/asm/kvm.h             | 22 +++++++
 arm/aarch64/include/kvm/kvm-config-arch.h | 10 +++-
 arm/aarch64/include/kvm/kvm-cpu-arch.h    |  7 ++-
 arm/aarch64/kvm-cpu.c                     | 97 +++++++++++++++++++++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  2 +
 arm/kvm-cpu.c                             |  3 +
 include/linux/kvm.h                       |  5 ++
 8 files changed, 149 insertions(+), 2 deletions(-)

-- 
2.1.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 1/3] arm/arm64: [HACK] Sync kernel headers from sve-guest v6
  2019-03-20 12:07 ` Dave Martin
@ 2019-03-20 12:07   ` Dave Martin
  -1 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Okamoto Takayuki, Christoffer Dall, Ard Biesheuvel, Marc Zyngier,
	Catalin Marinas, Will Deacon, Zhang Lei, Julien Grall,
	Andre Przywara, linux-arm-kernel

This patch imports the necessary UAPI header definitions for
building the SVE extensions for kvmtool.

This commit should be replaced by a header import from upstream
Linux once the SVE kvm patches have been merged.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
 arm/aarch64/include/asm/kvm.h | 22 ++++++++++++++++++++++
 include/linux/kvm.h           |  5 +++++
 2 files changed, 27 insertions(+)

diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index 97c3478..6963b7e 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/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;
@@ -226,6 +227,27 @@ struct kvm_vcpu_events {
 					 KVM_REG_ARM_FW | ((r) & 0xffff))
 #define KVM_REG_ARM_PSCI_VERSION	KVM_REG_ARM_FW_REG(0)
 
+/* SVE registers */
+#define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
+
+/* Z- and P-regs occupy blocks at the following offsets within this range: */
+#define KVM_REG_ARM64_SVE_ZREG_BASE	0
+#define KVM_REG_ARM64_SVE_PREG_BASE	0x400
+
+#define KVM_REG_ARM64_SVE_ZREG(n, i)	(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_ARM64_SVE_ZREG_BASE |	\
+					 KVM_REG_SIZE_U2048 |		\
+					 ((n) << 5) | (i))
+#define KVM_REG_ARM64_SVE_PREG(n, i)	(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_ARM64_SVE_PREG_BASE |	\
+					 KVM_REG_SIZE_U256 |		\
+					 ((n) << 5) | (i))
+#define KVM_REG_ARM64_SVE_FFR(i)	KVM_REG_ARM64_SVE_PREG(16, i)
+
+/* Vector lengths pseudo-register: */
+#define KVM_REG_ARM64_SVE_VLS		(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_SIZE_U512 | 0xffff)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR	0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS	1
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 6d4ea4b..1d56444 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -988,6 +988,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_VM_IPA_SIZE 165
 #define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166
 #define KVM_CAP_HYPERV_CPUID 167
+#define KVM_CAP_ARM_SVE 168
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1145,6 +1146,7 @@ struct kvm_dirty_tlb {
 #define KVM_REG_SIZE_U256	0x0050000000000000ULL
 #define KVM_REG_SIZE_U512	0x0060000000000000ULL
 #define KVM_REG_SIZE_U1024	0x0070000000000000ULL
+#define KVM_REG_SIZE_U2048	0x0080000000000000ULL
 
 struct kvm_reg_list {
 	__u64 n; /* number of regs */
@@ -1440,6 +1442,9 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_HYPERV_CPUID */
 #define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2)
 
+/* Available with KVM_CAP_ARM_SVE */
+#define KVM_ARM_VCPU_FINALIZE	  _IOW(KVMIO,  0xc2, int)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
 	/* Guest initialization commands */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 1/3] arm/arm64: [HACK] Sync kernel headers from sve-guest v6
@ 2019-03-20 12:07   ` Dave Martin
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Peter Maydell, Okamoto Takayuki, Christoffer Dall,
	Ard Biesheuvel, Marc Zyngier, Catalin Marinas, Will Deacon,
	Zhang Lei, Julien Grall, Andre Przywara, Alex Bennée,
	linux-arm-kernel

This patch imports the necessary UAPI header definitions for
building the SVE extensions for kvmtool.

This commit should be replaced by a header import from upstream
Linux once the SVE kvm patches have been merged.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
 arm/aarch64/include/asm/kvm.h | 22 ++++++++++++++++++++++
 include/linux/kvm.h           |  5 +++++
 2 files changed, 27 insertions(+)

diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index 97c3478..6963b7e 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/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;
@@ -226,6 +227,27 @@ struct kvm_vcpu_events {
 					 KVM_REG_ARM_FW | ((r) & 0xffff))
 #define KVM_REG_ARM_PSCI_VERSION	KVM_REG_ARM_FW_REG(0)
 
+/* SVE registers */
+#define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
+
+/* Z- and P-regs occupy blocks at the following offsets within this range: */
+#define KVM_REG_ARM64_SVE_ZREG_BASE	0
+#define KVM_REG_ARM64_SVE_PREG_BASE	0x400
+
+#define KVM_REG_ARM64_SVE_ZREG(n, i)	(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_ARM64_SVE_ZREG_BASE |	\
+					 KVM_REG_SIZE_U2048 |		\
+					 ((n) << 5) | (i))
+#define KVM_REG_ARM64_SVE_PREG(n, i)	(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_ARM64_SVE_PREG_BASE |	\
+					 KVM_REG_SIZE_U256 |		\
+					 ((n) << 5) | (i))
+#define KVM_REG_ARM64_SVE_FFR(i)	KVM_REG_ARM64_SVE_PREG(16, i)
+
+/* Vector lengths pseudo-register: */
+#define KVM_REG_ARM64_SVE_VLS		(KVM_REG_ARM64 | KVM_REG_ARM64_SVE | \
+					 KVM_REG_SIZE_U512 | 0xffff)
+
 /* Device Control API: ARM VGIC */
 #define KVM_DEV_ARM_VGIC_GRP_ADDR	0
 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS	1
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 6d4ea4b..1d56444 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -988,6 +988,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_ARM_VM_IPA_SIZE 165
 #define KVM_CAP_MANUAL_DIRTY_LOG_PROTECT 166
 #define KVM_CAP_HYPERV_CPUID 167
+#define KVM_CAP_ARM_SVE 168
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1145,6 +1146,7 @@ struct kvm_dirty_tlb {
 #define KVM_REG_SIZE_U256	0x0050000000000000ULL
 #define KVM_REG_SIZE_U512	0x0060000000000000ULL
 #define KVM_REG_SIZE_U1024	0x0070000000000000ULL
+#define KVM_REG_SIZE_U2048	0x0080000000000000ULL
 
 struct kvm_reg_list {
 	__u64 n; /* number of regs */
@@ -1440,6 +1442,9 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_HYPERV_CPUID */
 #define KVM_GET_SUPPORTED_HV_CPUID _IOWR(KVMIO, 0xc1, struct kvm_cpuid2)
 
+/* Available with KVM_CAP_ARM_SVE */
+#define KVM_ARM_VCPU_FINALIZE	  _IOW(KVMIO,  0xc2, int)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
 	/* Guest initialization commands */
-- 
2.1.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 2/3] arm64: Add basic SVE support
  2019-03-20 12:07 ` Dave Martin
@ 2019-03-20 12:07   ` Dave Martin
  -1 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Okamoto Takayuki, Christoffer Dall, Ard Biesheuvel, Marc Zyngier,
	Catalin Marinas, Will Deacon, Zhang Lei, Julien Grall,
	Andre Przywara, linux-arm-kernel

This patch adds an --sve command line option to allow the Scalable
Vector Extension to be enabled when creating a guest.

This requires use of the new KVM_ARM_VCPU_FINALIZE ioctl before the
vcpu is runnable, so a new hook kvm_cpu__configure_features() is
added to provide an appropiate place to do this work.

The kernel does not enable SVE by default, and for now kvmtool
adopts the same policy: without --sve, SVE is not enabled for the
guest even if the host supports it.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
 arm/aarch32/include/kvm/kvm-cpu-arch.h    |  5 +++++
 arm/aarch64/include/kvm/kvm-config-arch.h |  4 +++-
 arm/aarch64/include/kvm/kvm-cpu-arch.h    |  7 ++++++-
 arm/aarch64/kvm-cpu.c                     | 19 +++++++++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm-cpu.c                             |  3 +++
 6 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-cpu-arch.h b/arm/aarch32/include/kvm/kvm-cpu-arch.h
index d28ea67..04740d4 100644
--- a/arm/aarch32/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch32/include/kvm/kvm-cpu-arch.h
@@ -13,4 +13,9 @@
 #define ARM_CPU_ID		0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
 
+static inline int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
+{
+	return 0;
+}
+
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 04be43d..50b7aae 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -8,7 +8,9 @@
 			"Create PMUv3 device"),				\
 	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
 			"Specify random seed for Kernel Address Space "	\
-			"Layout Randomization (KASLR)"),
+			"Layout Randomization (KASLR)"),		\
+	OPT_BOOLEAN('\0', "sve", &(cfg)->has_sve,			\
+			"Enable SVE for the guest"),
 
 #include "arm-common/kvm-config-arch.h"
 
diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index a9d8563..7f2bfb9 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -8,13 +8,18 @@
 #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid)	{				\
 	[0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) |				\
 	       (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT) |	\
-	       (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3))		\
+	       (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3) |		\
+	       (!!(kvm)->cfg.arch.has_sve << KVM_ARM_VCPU_SVE))			\
 }
 
+
+
 #define ARM_MPIDR_HWID_BITMASK	0xFF00FFFFFFUL
 #define ARM_CPU_ID		3, 0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
 #define ARM_CPU_CTRL		3, 0, 1, 0
 #define ARM_CPU_CTRL_SCTLR_EL1	0
 
+int kvm_cpu__configure_features(struct kvm_cpu *vcpu);
+
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 0aaefaf..43eb69e 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -128,6 +128,25 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 	}
 }
 
+static int configure_sve(struct kvm_cpu *vcpu)
+{
+	int feature = KVM_ARM_VCPU_SVE;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_FINALIZE, &feature))
+		return -1;
+
+	return 0;
+}
+
+int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
+{
+	if (vcpu->kvm->cfg.arch.has_sve)
+		if (configure_sve(vcpu))
+			return -1;
+
+	return 0;
+}
+
 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
 {
 	if (vcpu->kvm->cfg.arch.aarch32_guest)
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 5734c46..bdab680 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -12,6 +12,7 @@ struct kvm_config_arch {
 	u64		kaslr_seed;
 	enum irqchip_type irqchip;
 	u64		fw_addr;
+	bool		has_sve;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7780251..91d5241 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -122,6 +122,9 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	vcpu->cpu_compatible	= target->compatible;
 	vcpu->is_running	= true;
 
+	if (kvm_cpu__configure_features(vcpu))
+		die("Unable to configure requested vcpu features");
+
 	return vcpu;
 }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 2/3] arm64: Add basic SVE support
@ 2019-03-20 12:07   ` Dave Martin
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Peter Maydell, Okamoto Takayuki, Christoffer Dall,
	Ard Biesheuvel, Marc Zyngier, Catalin Marinas, Will Deacon,
	Zhang Lei, Julien Grall, Andre Przywara, Alex Bennée,
	linux-arm-kernel

This patch adds an --sve command line option to allow the Scalable
Vector Extension to be enabled when creating a guest.

This requires use of the new KVM_ARM_VCPU_FINALIZE ioctl before the
vcpu is runnable, so a new hook kvm_cpu__configure_features() is
added to provide an appropiate place to do this work.

The kernel does not enable SVE by default, and for now kvmtool
adopts the same policy: without --sve, SVE is not enabled for the
guest even if the host supports it.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---
 arm/aarch32/include/kvm/kvm-cpu-arch.h    |  5 +++++
 arm/aarch64/include/kvm/kvm-config-arch.h |  4 +++-
 arm/aarch64/include/kvm/kvm-cpu-arch.h    |  7 ++++++-
 arm/aarch64/kvm-cpu.c                     | 19 +++++++++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm-cpu.c                             |  3 +++
 6 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-cpu-arch.h b/arm/aarch32/include/kvm/kvm-cpu-arch.h
index d28ea67..04740d4 100644
--- a/arm/aarch32/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch32/include/kvm/kvm-cpu-arch.h
@@ -13,4 +13,9 @@
 #define ARM_CPU_ID		0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
 
+static inline int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
+{
+	return 0;
+}
+
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 04be43d..50b7aae 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -8,7 +8,9 @@
 			"Create PMUv3 device"),				\
 	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
 			"Specify random seed for Kernel Address Space "	\
-			"Layout Randomization (KASLR)"),
+			"Layout Randomization (KASLR)"),		\
+	OPT_BOOLEAN('\0', "sve", &(cfg)->has_sve,			\
+			"Enable SVE for the guest"),
 
 #include "arm-common/kvm-config-arch.h"
 
diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index a9d8563..7f2bfb9 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -8,13 +8,18 @@
 #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid)	{				\
 	[0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) |				\
 	       (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT) |	\
-	       (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3))		\
+	       (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3) |		\
+	       (!!(kvm)->cfg.arch.has_sve << KVM_ARM_VCPU_SVE))			\
 }
 
+
+
 #define ARM_MPIDR_HWID_BITMASK	0xFF00FFFFFFUL
 #define ARM_CPU_ID		3, 0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
 #define ARM_CPU_CTRL		3, 0, 1, 0
 #define ARM_CPU_CTRL_SCTLR_EL1	0
 
+int kvm_cpu__configure_features(struct kvm_cpu *vcpu);
+
 #endif /* KVM__KVM_CPU_ARCH_H */
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 0aaefaf..43eb69e 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -128,6 +128,25 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 	}
 }
 
+static int configure_sve(struct kvm_cpu *vcpu)
+{
+	int feature = KVM_ARM_VCPU_SVE;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_FINALIZE, &feature))
+		return -1;
+
+	return 0;
+}
+
+int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
+{
+	if (vcpu->kvm->cfg.arch.has_sve)
+		if (configure_sve(vcpu))
+			return -1;
+
+	return 0;
+}
+
 void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
 {
 	if (vcpu->kvm->cfg.arch.aarch32_guest)
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 5734c46..bdab680 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -12,6 +12,7 @@ struct kvm_config_arch {
 	u64		kaslr_seed;
 	enum irqchip_type irqchip;
 	u64		fw_addr;
+	bool		has_sve;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 7780251..91d5241 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -122,6 +122,9 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	vcpu->cpu_compatible	= target->compatible;
 	vcpu->is_running	= true;
 
+	if (kvm_cpu__configure_features(vcpu))
+		die("Unable to configure requested vcpu features");
+
 	return vcpu;
 }
 
-- 
2.1.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 3/3] arm64: Add command-line option to set the guest's SVE vector lengths
  2019-03-20 12:07 ` Dave Martin
@ 2019-03-20 12:07   ` Dave Martin
  -1 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Okamoto Takayuki, Christoffer Dall, Ard Biesheuvel, Marc Zyngier,
	Catalin Marinas, Will Deacon, Zhang Lei, Julien Grall,
	Andre Przywara, linux-arm-kernel

In order to support use cases such as migration, it may be
important in some situations to restrict the set of SVE vector
lengths available to the guest.  It can also be usefule to observe
the behaviour of guest OSes with different vector lengths.

To enable testing and experimentation for such configurations, this
patch adds a command-line option to allow setting of the set of
vector lengths to be made available to the guest.

For now, the setting is global: no means is offered to configure
individual guest vcpus independently of each other.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---

It wasn't clear to me what the most user-friendly form for the
 --sve-vls parameter would be.  Possibilities include:

	--sve-max-vl=<n>	# all host vector lengths not exceeding <n>
	--sve-vls=16,32,64	# i.e., byte ("vl") units, not 128-bit
	--sve-vls=1-2,4		# i.e., similar syntax to taskset -c etc.
	--sve-vls=16-32,64	# combination of the above
	--sve-vqs=1,2,4		# for more consistent terminology

In the end, to avoid premature overengineering, I went with the
easiest choice.  (--sve-vls=1,2,4)

There's also the question of how to specify different features and
configurations per-vcpu.  I don't currently attempt this, but it would
be useful for KVM testing and development.  I think that any solution
to this shouldn't be SVE-specific: we should aim for a common approach
that can be reused for other features too.

---
 arm/aarch64/include/kvm/kvm-config-arch.h |  8 +++-
 arm/aarch64/kvm-cpu.c                     | 80 ++++++++++++++++++++++++++++++-
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 50b7aae..1eb8cfc 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -1,6 +1,8 @@
 #ifndef KVM__KVM_CONFIG_ARCH_H
 #define KVM__KVM_CONFIG_ARCH_H
 
+int sve_vls_parser(const struct option *opt, const char *arg, int unset);
+
 #define ARM_OPT_ARCH_RUN(cfg)						\
 	OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest,		\
 			"Run AArch32 guest"),				\
@@ -10,7 +12,11 @@
 			"Specify random seed for Kernel Address Space "	\
 			"Layout Randomization (KASLR)"),		\
 	OPT_BOOLEAN('\0', "sve", &(cfg)->has_sve,			\
-			"Enable SVE for the guest"),
+			"Enable SVE for the guest"),			\
+	OPT_CALLBACK('\0', "sve-vls", &(cfg)->sve_vqs,			\
+		     "comma-separated list of vector lengths, in 128-bit units", \
+		     "Set of vector lengths to enable for the guest",	\
+		     sve_vls_parser, NULL),
 
 #include "arm-common/kvm-config-arch.h"
 
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 43eb69e..d917c8b 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -1,8 +1,13 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
 #include "kvm/kvm-cpu.h"
 #include "kvm/kvm.h"
 #include "kvm/virtio.h"
 
 #include <asm/ptrace.h>
+#include <asm/sigcontext.h>
 
 #define COMPAT_PSR_F_BIT	0x00000040
 #define COMPAT_PSR_I_BIT	0x00000080
@@ -12,6 +17,65 @@
 #define SCTLR_EL1_E0E_MASK	(1 << 24)
 #define SCTLR_EL1_EE_MASK	(1 << 25)
 
+/*
+ * Work around old kernel headers that lack these definitions in
+ * <asm/sigcontext.h>:
+ */
+#ifndef SVE_VQ_MIN
+#define SVE_VQ_MIN 1
+#endif
+
+#ifndef SVE_VQ_MAX
+#define SVE_VQ_MAX 512
+#endif
+
+int sve_vls_parser(const struct option *opt, const char *arg, int unset)
+{
+	size_t offset = 0;
+	int vq, n, t;
+	u64 (*vqs)[(SVE_VQ_MAX + 1 - SVE_VQ_MIN + 63) / 64];
+	u64 **cfg_vqs = opt->value;
+
+	if (*cfg_vqs) {
+		pr_err("sve-vls: SVE vector lengths set may only be specified once");
+		return -1;
+	}
+
+	vqs = calloc(1, sizeof *vqs);
+	if (!vqs)
+		die("%s", strerror(errno));
+
+	offset = 0;
+	while (arg[offset]) {
+		n = -1;
+
+		t = sscanf(arg + offset,
+			   offset == 0 ? "%i%n" : ",%i%n",
+			   &vq, &n);
+		if (t == EOF || t < 1 || n <= 0) {
+			pr_err("sve-vls: Comma-separated list of vector lengths required");
+			goto error;
+		}
+
+		if (vq < SVE_VQ_MIN || vq > SVE_VQ_MAX) {
+			pr_err("sve-vls: Invalid vector length %d", vq);
+			goto error;
+		}
+
+		vq -= SVE_VQ_MIN;
+		(*vqs)[vq / 64] |= (u64)1 << (vq % 64);
+
+		offset += n;
+	}
+
+	*cfg_vqs = *vqs;
+	return 0;
+
+error:
+	free(vqs);
+	return -1;
+}
+
 static __u64 __core_reg_id(__u64 offset)
 {
 	__u64 id = KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset;
@@ -131,6 +195,16 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 static int configure_sve(struct kvm_cpu *vcpu)
 {
 	int feature = KVM_ARM_VCPU_SVE;
+	struct kvm_one_reg r = {
+		.id = KVM_REG_ARM64_SVE_VLS,
+		.addr = (u64)vcpu->kvm->cfg.arch.sve_vqs,
+	};
+
+	if (vcpu->kvm->cfg.arch.sve_vqs)
+		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &r)) {
+			pr_err("Cannot set requested SVE vector lengths");
+			return -1;
+		}
 
 	if (ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_FINALIZE, &feature))
 		return -1;
@@ -140,9 +214,13 @@ static int configure_sve(struct kvm_cpu *vcpu)
 
 int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
 {
-	if (vcpu->kvm->cfg.arch.has_sve)
+	if (vcpu->kvm->cfg.arch.has_sve) {
 		if (configure_sve(vcpu))
 			return -1;
+	} else { /* !vcpu->kvm->cfg.arch.has_sve */
+		if (vcpu->kvm->cfg.arch.sve_vqs)
+			pr_warning("SVE vector lengths ignored");
+	}
 
 	return 0;
 }
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index bdab680..ca11e55 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -13,6 +13,7 @@ struct kvm_config_arch {
 	enum irqchip_type irqchip;
 	u64		fw_addr;
 	bool		has_sve;
+	u64		*sve_vqs;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH kvmtool v2 3/3] arm64: Add command-line option to set the guest's SVE vector lengths
@ 2019-03-20 12:07   ` Dave Martin
  0 siblings, 0 replies; 8+ messages in thread
From: Dave Martin @ 2019-03-20 12:07 UTC (permalink / raw)
  To: kvmarm
  Cc: Peter Maydell, Okamoto Takayuki, Christoffer Dall,
	Ard Biesheuvel, Marc Zyngier, Catalin Marinas, Will Deacon,
	Zhang Lei, Julien Grall, Andre Przywara, Alex Bennée,
	linux-arm-kernel

In order to support use cases such as migration, it may be
important in some situations to restrict the set of SVE vector
lengths available to the guest.  It can also be usefule to observe
the behaviour of guest OSes with different vector lengths.

To enable testing and experimentation for such configurations, this
patch adds a command-line option to allow setting of the set of
vector lengths to be made available to the guest.

For now, the setting is global: no means is offered to configure
individual guest vcpus independently of each other.

Signed-off-by: Dave Martin <Dave.Martin@arm.com>
---

It wasn't clear to me what the most user-friendly form for the
 --sve-vls parameter would be.  Possibilities include:

	--sve-max-vl=<n>	# all host vector lengths not exceeding <n>
	--sve-vls=16,32,64	# i.e., byte ("vl") units, not 128-bit
	--sve-vls=1-2,4		# i.e., similar syntax to taskset -c etc.
	--sve-vls=16-32,64	# combination of the above
	--sve-vqs=1,2,4		# for more consistent terminology

In the end, to avoid premature overengineering, I went with the
easiest choice.  (--sve-vls=1,2,4)

There's also the question of how to specify different features and
configurations per-vcpu.  I don't currently attempt this, but it would
be useful for KVM testing and development.  I think that any solution
to this shouldn't be SVE-specific: we should aim for a common approach
that can be reused for other features too.

---
 arm/aarch64/include/kvm/kvm-config-arch.h |  8 +++-
 arm/aarch64/kvm-cpu.c                     | 80 ++++++++++++++++++++++++++++++-
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 50b7aae..1eb8cfc 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -1,6 +1,8 @@
 #ifndef KVM__KVM_CONFIG_ARCH_H
 #define KVM__KVM_CONFIG_ARCH_H
 
+int sve_vls_parser(const struct option *opt, const char *arg, int unset);
+
 #define ARM_OPT_ARCH_RUN(cfg)						\
 	OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest,		\
 			"Run AArch32 guest"),				\
@@ -10,7 +12,11 @@
 			"Specify random seed for Kernel Address Space "	\
 			"Layout Randomization (KASLR)"),		\
 	OPT_BOOLEAN('\0', "sve", &(cfg)->has_sve,			\
-			"Enable SVE for the guest"),
+			"Enable SVE for the guest"),			\
+	OPT_CALLBACK('\0', "sve-vls", &(cfg)->sve_vqs,			\
+		     "comma-separated list of vector lengths, in 128-bit units", \
+		     "Set of vector lengths to enable for the guest",	\
+		     sve_vls_parser, NULL),
 
 #include "arm-common/kvm-config-arch.h"
 
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 43eb69e..d917c8b 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -1,8 +1,13 @@
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
 #include "kvm/kvm-cpu.h"
 #include "kvm/kvm.h"
 #include "kvm/virtio.h"
 
 #include <asm/ptrace.h>
+#include <asm/sigcontext.h>
 
 #define COMPAT_PSR_F_BIT	0x00000040
 #define COMPAT_PSR_I_BIT	0x00000080
@@ -12,6 +17,65 @@
 #define SCTLR_EL1_E0E_MASK	(1 << 24)
 #define SCTLR_EL1_EE_MASK	(1 << 25)
 
+/*
+ * Work around old kernel headers that lack these definitions in
+ * <asm/sigcontext.h>:
+ */
+#ifndef SVE_VQ_MIN
+#define SVE_VQ_MIN 1
+#endif
+
+#ifndef SVE_VQ_MAX
+#define SVE_VQ_MAX 512
+#endif
+
+int sve_vls_parser(const struct option *opt, const char *arg, int unset)
+{
+	size_t offset = 0;
+	int vq, n, t;
+	u64 (*vqs)[(SVE_VQ_MAX + 1 - SVE_VQ_MIN + 63) / 64];
+	u64 **cfg_vqs = opt->value;
+
+	if (*cfg_vqs) {
+		pr_err("sve-vls: SVE vector lengths set may only be specified once");
+		return -1;
+	}
+
+	vqs = calloc(1, sizeof *vqs);
+	if (!vqs)
+		die("%s", strerror(errno));
+
+	offset = 0;
+	while (arg[offset]) {
+		n = -1;
+
+		t = sscanf(arg + offset,
+			   offset == 0 ? "%i%n" : ",%i%n",
+			   &vq, &n);
+		if (t == EOF || t < 1 || n <= 0) {
+			pr_err("sve-vls: Comma-separated list of vector lengths required");
+			goto error;
+		}
+
+		if (vq < SVE_VQ_MIN || vq > SVE_VQ_MAX) {
+			pr_err("sve-vls: Invalid vector length %d", vq);
+			goto error;
+		}
+
+		vq -= SVE_VQ_MIN;
+		(*vqs)[vq / 64] |= (u64)1 << (vq % 64);
+
+		offset += n;
+	}
+
+	*cfg_vqs = *vqs;
+	return 0;
+
+error:
+	free(vqs);
+	return -1;
+}
+
 static __u64 __core_reg_id(__u64 offset)
 {
 	__u64 id = KVM_REG_ARM64 | KVM_REG_ARM_CORE | offset;
@@ -131,6 +195,16 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 static int configure_sve(struct kvm_cpu *vcpu)
 {
 	int feature = KVM_ARM_VCPU_SVE;
+	struct kvm_one_reg r = {
+		.id = KVM_REG_ARM64_SVE_VLS,
+		.addr = (u64)vcpu->kvm->cfg.arch.sve_vqs,
+	};
+
+	if (vcpu->kvm->cfg.arch.sve_vqs)
+		if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &r)) {
+			pr_err("Cannot set requested SVE vector lengths");
+			return -1;
+		}
 
 	if (ioctl(vcpu->vcpu_fd, KVM_ARM_VCPU_FINALIZE, &feature))
 		return -1;
@@ -140,9 +214,13 @@ static int configure_sve(struct kvm_cpu *vcpu)
 
 int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
 {
-	if (vcpu->kvm->cfg.arch.has_sve)
+	if (vcpu->kvm->cfg.arch.has_sve) {
 		if (configure_sve(vcpu))
 			return -1;
+	} else { /* !vcpu->kvm->cfg.arch.has_sve */
+		if (vcpu->kvm->cfg.arch.sve_vqs)
+			pr_warning("SVE vector lengths ignored");
+	}
 
 	return 0;
 }
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index bdab680..ca11e55 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -13,6 +13,7 @@ struct kvm_config_arch {
 	enum irqchip_type irqchip;
 	u64		fw_addr;
 	bool		has_sve;
+	u64		*sve_vqs;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
-- 
2.1.4


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-03-20 12:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-20 12:07 [PATCH kvmtool v2 0/3] arm64: Basic SVE guest support Dave Martin
2019-03-20 12:07 ` Dave Martin
2019-03-20 12:07 ` [PATCH kvmtool v2 1/3] arm/arm64: [HACK] Sync kernel headers from sve-guest v6 Dave Martin
2019-03-20 12:07   ` Dave Martin
2019-03-20 12:07 ` [PATCH kvmtool v2 2/3] arm64: Add basic SVE support Dave Martin
2019-03-20 12:07   ` Dave Martin
2019-03-20 12:07 ` [PATCH kvmtool v2 3/3] arm64: Add command-line option to set the guest's SVE vector lengths Dave Martin
2019-03-20 12:07   ` Dave Martin

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.