All of lore.kernel.org
 help / color / mirror / Atom feed
* [kvmtool PATCH 0/2] arm64: Add MTE support
@ 2022-03-21 15:28 ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

This series does what it says on the can: adds Memory Tagging Extension
(MTE) support in kvmtool.

Alexandru Elisei (2):
  update_headers: Sync ABI headers with Linux v5.17-rc8
  aarch64: Add support for MTE

 arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
 arm/aarch64/include/asm/kvm.h             |  5 +++++
 arm/aarch64/include/kvm/kvm-arch.h        |  1 +
 arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
 arm/aarch64/kvm.c                         | 13 +++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm.c                                 |  3 +++
 include/linux/kvm.h                       | 18 ++++++++++++++++++
 x86/include/asm/kvm.h                     | 19 ++++++++++++++++++-
 9 files changed, 64 insertions(+), 1 deletion(-)

-- 
2.35.1


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

* [kvmtool PATCH 0/2] arm64: Add MTE support
@ 2022-03-21 15:28 ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

This series does what it says on the can: adds Memory Tagging Extension
(MTE) support in kvmtool.

Alexandru Elisei (2):
  update_headers: Sync ABI headers with Linux v5.17-rc8
  aarch64: Add support for MTE

 arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
 arm/aarch64/include/asm/kvm.h             |  5 +++++
 arm/aarch64/include/kvm/kvm-arch.h        |  1 +
 arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
 arm/aarch64/kvm.c                         | 13 +++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm.c                                 |  3 +++
 include/linux/kvm.h                       | 18 ++++++++++++++++++
 x86/include/asm/kvm.h                     | 19 ++++++++++++++++++-
 9 files changed, 64 insertions(+), 1 deletion(-)

-- 
2.35.1


_______________________________________________
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] 24+ messages in thread

* [kvmtool PATCH 1/2] update_headers: Sync ABI headers with Linux v5.17-rc8
  2022-03-21 15:28 ` Alexandru Elisei
@ 2022-03-21 15:28   ` Alexandru Elisei
  -1 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch64/include/asm/kvm.h |  5 +++++
 include/linux/kvm.h           | 18 ++++++++++++++++++
 x86/include/asm/kvm.h         | 19 ++++++++++++++++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index b3edde68bc3e..323e251ed37b 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/asm/kvm.h
@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED	3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED     	(1U << 4)
 
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3	KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL		0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL		1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED	2
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 1daa45268de2..507ee1f2aa96 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -1131,6 +1131,10 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_VM_GPA_BITS 207
+#define KVM_CAP_XSAVE2 208
+#define KVM_CAP_SYS_ATTRIBUTES 209
+#define KVM_CAP_PPC_AIL_MODE_3 210
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1162,11 +1166,20 @@ struct kvm_irq_routing_hv_sint {
 	__u32 sint;
 };
 
+struct kvm_irq_routing_xen_evtchn {
+	__u32 port;
+	__u32 vcpu;
+	__u32 priority;
+};
+
+#define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((__u32)(-1))
+
 /* gsi routing entry types */
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 #define KVM_IRQ_ROUTING_HV_SINT 4
+#define KVM_IRQ_ROUTING_XEN_EVTCHN 5
 
 struct kvm_irq_routing_entry {
 	__u32 gsi;
@@ -1178,6 +1191,7 @@ struct kvm_irq_routing_entry {
 		struct kvm_irq_routing_msi msi;
 		struct kvm_irq_routing_s390_adapter adapter;
 		struct kvm_irq_routing_hv_sint hv_sint;
+		struct kvm_irq_routing_xen_evtchn xen_evtchn;
 		__u32 pad[8];
 	} u;
 };
@@ -1208,6 +1222,7 @@ struct kvm_x86_mce {
 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL	(1 << 1)
 #define KVM_XEN_HVM_CONFIG_SHARED_INFO		(1 << 2)
 #define KVM_XEN_HVM_CONFIG_RUNSTATE		(1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL	(1 << 4)
 
 struct kvm_xen_hvm_config {
 	__u32 flags;
@@ -2031,4 +2046,7 @@ struct kvm_stats_desc {
 
 #define KVM_GET_STATS_FD  _IO(KVMIO,  0xce)
 
+/* Available with KVM_CAP_XSAVE2 */
+#define KVM_GET_XSAVE2		  _IOR(KVMIO,  0xcf, struct kvm_xsave)
+
 #endif /* __LINUX_KVM_H */
diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h
index 5a776a08f78c..bf6e96011dfe 100644
--- a/x86/include/asm/kvm.h
+++ b/x86/include/asm/kvm.h
@@ -373,9 +373,23 @@ struct kvm_debugregs {
 	__u64 reserved[9];
 };
 
-/* for KVM_CAP_XSAVE */
+/* for KVM_CAP_XSAVE and KVM_CAP_XSAVE2 */
 struct kvm_xsave {
+	/*
+	 * KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many bytes
+	 * as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * respectively, when invoked on the vm file descriptor.
+	 *
+	 * The size value returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * will always be at least 4096. Currently, it is only greater
+	 * than 4096 if a dynamic feature has been enabled with
+	 * ``arch_prctl()``, but this may change in the future.
+	 *
+	 * The offsets of the state save areas in struct kvm_xsave follow
+	 * the contents of CPUID leaf 0xD on the host.
+	 */
 	__u32 region[1024];
+	__u32 extra[0];
 };
 
 #define KVM_MAX_XCRS	16
@@ -438,6 +452,9 @@ struct kvm_sync_regs {
 
 #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE	0x00000001
 
+/* attributes for system fd (group 0) */
+#define KVM_X86_XCOMP_GUEST_SUPP	0
+
 struct kvm_vmx_nested_state_data {
 	__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
 	__u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
-- 
2.35.1


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

* [kvmtool PATCH 1/2] update_headers: Sync ABI headers with Linux v5.17-rc8
@ 2022-03-21 15:28   ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch64/include/asm/kvm.h |  5 +++++
 include/linux/kvm.h           | 18 ++++++++++++++++++
 x86/include/asm/kvm.h         | 19 ++++++++++++++++++-
 3 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index b3edde68bc3e..323e251ed37b 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/asm/kvm.h
@@ -281,6 +281,11 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED	3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED     	(1U << 4)
 
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3	KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_AVAIL		0
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_AVAIL		1
+#define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3_NOT_REQUIRED	2
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 1daa45268de2..507ee1f2aa96 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -1131,6 +1131,10 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_VM_GPA_BITS 207
+#define KVM_CAP_XSAVE2 208
+#define KVM_CAP_SYS_ATTRIBUTES 209
+#define KVM_CAP_PPC_AIL_MODE_3 210
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1162,11 +1166,20 @@ struct kvm_irq_routing_hv_sint {
 	__u32 sint;
 };
 
+struct kvm_irq_routing_xen_evtchn {
+	__u32 port;
+	__u32 vcpu;
+	__u32 priority;
+};
+
+#define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((__u32)(-1))
+
 /* gsi routing entry types */
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 #define KVM_IRQ_ROUTING_HV_SINT 4
+#define KVM_IRQ_ROUTING_XEN_EVTCHN 5
 
 struct kvm_irq_routing_entry {
 	__u32 gsi;
@@ -1178,6 +1191,7 @@ struct kvm_irq_routing_entry {
 		struct kvm_irq_routing_msi msi;
 		struct kvm_irq_routing_s390_adapter adapter;
 		struct kvm_irq_routing_hv_sint hv_sint;
+		struct kvm_irq_routing_xen_evtchn xen_evtchn;
 		__u32 pad[8];
 	} u;
 };
@@ -1208,6 +1222,7 @@ struct kvm_x86_mce {
 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL	(1 << 1)
 #define KVM_XEN_HVM_CONFIG_SHARED_INFO		(1 << 2)
 #define KVM_XEN_HVM_CONFIG_RUNSTATE		(1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL	(1 << 4)
 
 struct kvm_xen_hvm_config {
 	__u32 flags;
@@ -2031,4 +2046,7 @@ struct kvm_stats_desc {
 
 #define KVM_GET_STATS_FD  _IO(KVMIO,  0xce)
 
+/* Available with KVM_CAP_XSAVE2 */
+#define KVM_GET_XSAVE2		  _IOR(KVMIO,  0xcf, struct kvm_xsave)
+
 #endif /* __LINUX_KVM_H */
diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h
index 5a776a08f78c..bf6e96011dfe 100644
--- a/x86/include/asm/kvm.h
+++ b/x86/include/asm/kvm.h
@@ -373,9 +373,23 @@ struct kvm_debugregs {
 	__u64 reserved[9];
 };
 
-/* for KVM_CAP_XSAVE */
+/* for KVM_CAP_XSAVE and KVM_CAP_XSAVE2 */
 struct kvm_xsave {
+	/*
+	 * KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many bytes
+	 * as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * respectively, when invoked on the vm file descriptor.
+	 *
+	 * The size value returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * will always be at least 4096. Currently, it is only greater
+	 * than 4096 if a dynamic feature has been enabled with
+	 * ``arch_prctl()``, but this may change in the future.
+	 *
+	 * The offsets of the state save areas in struct kvm_xsave follow
+	 * the contents of CPUID leaf 0xD on the host.
+	 */
 	__u32 region[1024];
+	__u32 extra[0];
 };
 
 #define KVM_MAX_XCRS	16
@@ -438,6 +452,9 @@ struct kvm_sync_regs {
 
 #define KVM_STATE_VMX_PREEMPTION_TIMER_DEADLINE	0x00000001
 
+/* attributes for system fd (group 0) */
+#define KVM_X86_XCOMP_GUEST_SUPP	0
+
 struct kvm_vmx_nested_state_data {
 	__u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
 	__u8 shadow_vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE];
-- 
2.35.1


_______________________________________________
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] 24+ messages in thread

* [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-21 15:28 ` Alexandru Elisei
@ 2022-03-21 15:28   ` Alexandru Elisei
  -1 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
 arm/aarch64/include/kvm/kvm-arch.h        |  1 +
 arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
 arm/aarch64/kvm.c                         | 13 +++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm.c                                 |  3 +++
 6 files changed, 23 insertions(+)

diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index bee2fc255a82..5616b27e257e 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -5,6 +5,9 @@
 
 #define kvm__arch_get_kern_offset(...)	0x8000
 
+struct kvm;
+static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
+
 #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
 
 #define MAX_PAGE_SIZE	SZ_4K
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 5e5ee41211ed..9124f6919d0f 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -6,6 +6,7 @@
 struct kvm;
 unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
 int kvm__arch_get_ipa_limit(struct kvm *kvm);
+void kvm__arch_enable_mte(struct kvm *kvm);
 
 #define ARM_MAX_MEMORY(kvm)	({					\
 	u64 max_ram;							\
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 04be43dfa9b2..11250365d8d5 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -6,6 +6,8 @@
 			"Run AArch32 guest"),				\
 	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
 			"Create PMUv3 device"),				\
+	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
+			"Enable memory tagging extension"),		\
 	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
 			"Specify random seed for Kernel Address Space "	\
 			"Layout Randomization (KASLR)"),
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 56a0aedc263d..46548f8ee96e 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
 
 	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
 }
+
+void kvm__arch_enable_mte(struct kvm *kvm)
+{
+	struct kvm_enable_cap cap = {
+		.cap = KVM_CAP_ARM_MTE,
+	};
+
+	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
+		die("MTE capability is not supported");
+
+	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
+		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
+}
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 5734c46ab9e6..16e8d500a71b 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -9,6 +9,7 @@ struct kvm_config_arch {
 	bool		virtio_trans_pci;
 	bool		aarch32_guest;
 	bool		has_pmuv3;
+	bool		has_mte;
 	u64		kaslr_seed;
 	enum irqchip_type irqchip;
 	u64		fw_addr;
diff --git a/arm/kvm.c b/arm/kvm.c
index 80d233f13d0b..f2db93953778 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
+
+	if (kvm->cfg.arch.has_mte)
+		kvm__arch_enable_mte(kvm);
 }
 
 #define FDT_ALIGN	SZ_2M
-- 
2.35.1


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

* [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-21 15:28   ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 15:28 UTC (permalink / raw)
  To: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price, vladimir.murzin

MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.

Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
---
 arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
 arm/aarch64/include/kvm/kvm-arch.h        |  1 +
 arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
 arm/aarch64/kvm.c                         | 13 +++++++++++++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 arm/kvm.c                                 |  3 +++
 6 files changed, 23 insertions(+)

diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
index bee2fc255a82..5616b27e257e 100644
--- a/arm/aarch32/include/kvm/kvm-arch.h
+++ b/arm/aarch32/include/kvm/kvm-arch.h
@@ -5,6 +5,9 @@
 
 #define kvm__arch_get_kern_offset(...)	0x8000
 
+struct kvm;
+static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
+
 #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
 
 #define MAX_PAGE_SIZE	SZ_4K
diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
index 5e5ee41211ed..9124f6919d0f 100644
--- a/arm/aarch64/include/kvm/kvm-arch.h
+++ b/arm/aarch64/include/kvm/kvm-arch.h
@@ -6,6 +6,7 @@
 struct kvm;
 unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
 int kvm__arch_get_ipa_limit(struct kvm *kvm);
+void kvm__arch_enable_mte(struct kvm *kvm);
 
 #define ARM_MAX_MEMORY(kvm)	({					\
 	u64 max_ram;							\
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 04be43dfa9b2..11250365d8d5 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -6,6 +6,8 @@
 			"Run AArch32 guest"),				\
 	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
 			"Create PMUv3 device"),				\
+	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
+			"Enable memory tagging extension"),		\
 	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
 			"Specify random seed for Kernel Address Space "	\
 			"Layout Randomization (KASLR)"),
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 56a0aedc263d..46548f8ee96e 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
 
 	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
 }
+
+void kvm__arch_enable_mte(struct kvm *kvm)
+{
+	struct kvm_enable_cap cap = {
+		.cap = KVM_CAP_ARM_MTE,
+	};
+
+	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
+		die("MTE capability is not supported");
+
+	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
+		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
+}
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 5734c46ab9e6..16e8d500a71b 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -9,6 +9,7 @@ struct kvm_config_arch {
 	bool		virtio_trans_pci;
 	bool		aarch32_guest;
 	bool		has_pmuv3;
+	bool		has_mte;
 	u64		kaslr_seed;
 	enum irqchip_type irqchip;
 	u64		fw_addr;
diff --git a/arm/kvm.c b/arm/kvm.c
index 80d233f13d0b..f2db93953778 100644
--- a/arm/kvm.c
+++ b/arm/kvm.c
@@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	/* Create the virtual GIC. */
 	if (gic__create(kvm, kvm->cfg.arch.irqchip))
 		die("Failed to create virtual GIC");
+
+	if (kvm->cfg.arch.has_mte)
+		kvm__arch_enable_mte(kvm);
 }
 
 #define FDT_ALIGN	SZ_2M
-- 
2.35.1


_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-21 15:28   ` Alexandru Elisei
@ 2022-03-21 15:40     ` Vladimir Murzin
  -1 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-21 15:40 UTC (permalink / raw)
  To: Alexandru Elisei, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, catalin.marinas, steven.price

Hi Alexandru,

On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>  arm/aarch64/kvm.c                         | 13 +++++++++++++
>  arm/include/arm-common/kvm-config-arch.h  |  1 +
>  arm/kvm.c                                 |  3 +++
>  6 files changed, 23 insertions(+)
> 
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index bee2fc255a82..5616b27e257e 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -5,6 +5,9 @@
>  
>  #define kvm__arch_get_kern_offset(...)	0x8000
>  
> +struct kvm;
> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> +
>  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>  
>  #define MAX_PAGE_SIZE	SZ_4K
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index 5e5ee41211ed..9124f6919d0f 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -6,6 +6,7 @@
>  struct kvm;
>  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
> +void kvm__arch_enable_mte(struct kvm *kvm);
>  
>  #define ARM_MAX_MEMORY(kvm)	({					\
>  	u64 max_ram;							\
> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> index 04be43dfa9b2..11250365d8d5 100644
> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> @@ -6,6 +6,8 @@
>  			"Run AArch32 guest"),				\
>  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>  			"Create PMUv3 device"),				\
> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> +			"Enable memory tagging extension"),		\
>  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>  			"Specify random seed for Kernel Address Space "	\
>  			"Layout Randomization (KASLR)"),
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 56a0aedc263d..46548f8ee96e 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>  
>  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>  }
> +
> +void kvm__arch_enable_mte(struct kvm *kvm)
> +{
> +	struct kvm_enable_cap cap = {
> +		.cap = KVM_CAP_ARM_MTE,
> +	};
> +
> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> +		die("MTE capability is not supported");
> +
> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> +}
> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> index 5734c46ab9e6..16e8d500a71b 100644
> --- a/arm/include/arm-common/kvm-config-arch.h
> +++ b/arm/include/arm-common/kvm-config-arch.h
> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>  	bool		virtio_trans_pci;
>  	bool		aarch32_guest;
>  	bool		has_pmuv3;
> +	bool		has_mte;
>  	u64		kaslr_seed;
>  	enum irqchip_type irqchip;
>  	u64		fw_addr;
> diff --git a/arm/kvm.c b/arm/kvm.c
> index 80d233f13d0b..f2db93953778 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	/* Create the virtual GIC. */
>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>  		die("Failed to create virtual GIC");
> +
> +	if (kvm->cfg.arch.has_mte)
> +		kvm__arch_enable_mte(kvm);
>  }

Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
PAC and SVE?

Cheers
Vladimir

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-21 15:40     ` Vladimir Murzin
  0 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-21 15:40 UTC (permalink / raw)
  To: Alexandru Elisei, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, catalin.marinas, steven.price

Hi Alexandru,

On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> ---
>  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>  arm/aarch64/kvm.c                         | 13 +++++++++++++
>  arm/include/arm-common/kvm-config-arch.h  |  1 +
>  arm/kvm.c                                 |  3 +++
>  6 files changed, 23 insertions(+)
> 
> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> index bee2fc255a82..5616b27e257e 100644
> --- a/arm/aarch32/include/kvm/kvm-arch.h
> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> @@ -5,6 +5,9 @@
>  
>  #define kvm__arch_get_kern_offset(...)	0x8000
>  
> +struct kvm;
> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> +
>  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>  
>  #define MAX_PAGE_SIZE	SZ_4K
> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> index 5e5ee41211ed..9124f6919d0f 100644
> --- a/arm/aarch64/include/kvm/kvm-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> @@ -6,6 +6,7 @@
>  struct kvm;
>  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
> +void kvm__arch_enable_mte(struct kvm *kvm);
>  
>  #define ARM_MAX_MEMORY(kvm)	({					\
>  	u64 max_ram;							\
> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> index 04be43dfa9b2..11250365d8d5 100644
> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> @@ -6,6 +6,8 @@
>  			"Run AArch32 guest"),				\
>  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>  			"Create PMUv3 device"),				\
> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> +			"Enable memory tagging extension"),		\
>  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>  			"Specify random seed for Kernel Address Space "	\
>  			"Layout Randomization (KASLR)"),
> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> index 56a0aedc263d..46548f8ee96e 100644
> --- a/arm/aarch64/kvm.c
> +++ b/arm/aarch64/kvm.c
> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>  
>  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>  }
> +
> +void kvm__arch_enable_mte(struct kvm *kvm)
> +{
> +	struct kvm_enable_cap cap = {
> +		.cap = KVM_CAP_ARM_MTE,
> +	};
> +
> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> +		die("MTE capability is not supported");
> +
> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> +}
> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> index 5734c46ab9e6..16e8d500a71b 100644
> --- a/arm/include/arm-common/kvm-config-arch.h
> +++ b/arm/include/arm-common/kvm-config-arch.h
> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>  	bool		virtio_trans_pci;
>  	bool		aarch32_guest;
>  	bool		has_pmuv3;
> +	bool		has_mte;
>  	u64		kaslr_seed;
>  	enum irqchip_type irqchip;
>  	u64		fw_addr;
> diff --git a/arm/kvm.c b/arm/kvm.c
> index 80d233f13d0b..f2db93953778 100644
> --- a/arm/kvm.c
> +++ b/arm/kvm.c
> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>  	/* Create the virtual GIC. */
>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>  		die("Failed to create virtual GIC");
> +
> +	if (kvm->cfg.arch.has_mte)
> +		kvm__arch_enable_mte(kvm);
>  }

Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
PAC and SVE?

Cheers
Vladimir

_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-21 15:40     ` Vladimir Murzin
@ 2022-03-21 17:08       ` Alexandru Elisei
  -1 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 17:08 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> Hi Alexandru,
> 
> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> > MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> > Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> >  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> >  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> >  arm/aarch64/kvm.c                         | 13 +++++++++++++
> >  arm/include/arm-common/kvm-config-arch.h  |  1 +
> >  arm/kvm.c                                 |  3 +++
> >  6 files changed, 23 insertions(+)
> > 
> > diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> > index bee2fc255a82..5616b27e257e 100644
> > --- a/arm/aarch32/include/kvm/kvm-arch.h
> > +++ b/arm/aarch32/include/kvm/kvm-arch.h
> > @@ -5,6 +5,9 @@
> >  
> >  #define kvm__arch_get_kern_offset(...)	0x8000
> >  
> > +struct kvm;
> > +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> > +
> >  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> >  
> >  #define MAX_PAGE_SIZE	SZ_4K
> > diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> > index 5e5ee41211ed..9124f6919d0f 100644
> > --- a/arm/aarch64/include/kvm/kvm-arch.h
> > +++ b/arm/aarch64/include/kvm/kvm-arch.h
> > @@ -6,6 +6,7 @@
> >  struct kvm;
> >  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
> >  int kvm__arch_get_ipa_limit(struct kvm *kvm);
> > +void kvm__arch_enable_mte(struct kvm *kvm);
> >  
> >  #define ARM_MAX_MEMORY(kvm)	({					\
> >  	u64 max_ram;							\
> > diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> > index 04be43dfa9b2..11250365d8d5 100644
> > --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> > +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> > @@ -6,6 +6,8 @@
> >  			"Run AArch32 guest"),				\
> >  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
> >  			"Create PMUv3 device"),				\
> > +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> > +			"Enable memory tagging extension"),		\
> >  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
> >  			"Specify random seed for Kernel Address Space "	\
> >  			"Layout Randomization (KASLR)"),
> > diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> > index 56a0aedc263d..46548f8ee96e 100644
> > --- a/arm/aarch64/kvm.c
> > +++ b/arm/aarch64/kvm.c
> > @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> >  
> >  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> >  }
> > +
> > +void kvm__arch_enable_mte(struct kvm *kvm)
> > +{
> > +	struct kvm_enable_cap cap = {
> > +		.cap = KVM_CAP_ARM_MTE,
> > +	};
> > +
> > +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> > +		die("MTE capability is not supported");
> > +
> > +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> > +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> > +}
> > diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> > index 5734c46ab9e6..16e8d500a71b 100644
> > --- a/arm/include/arm-common/kvm-config-arch.h
> > +++ b/arm/include/arm-common/kvm-config-arch.h
> > @@ -9,6 +9,7 @@ struct kvm_config_arch {
> >  	bool		virtio_trans_pci;
> >  	bool		aarch32_guest;
> >  	bool		has_pmuv3;
> > +	bool		has_mte;
> >  	u64		kaslr_seed;
> >  	enum irqchip_type irqchip;
> >  	u64		fw_addr;
> > diff --git a/arm/kvm.c b/arm/kvm.c
> > index 80d233f13d0b..f2db93953778 100644
> > --- a/arm/kvm.c
> > +++ b/arm/kvm.c
> > @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> >  	/* Create the virtual GIC. */
> >  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
> >  		die("Failed to create virtual GIC");
> > +
> > +	if (kvm->cfg.arch.has_mte)
> > +		kvm__arch_enable_mte(kvm);
> >  }
> 
> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> PAC and SVE?

I thought about that, the reason I chose to enable it based a kvmtool
command line option, instead of always being enabled if available, is
because of the overhead of sanitising the MTE tags on each stage 2 data
abort. Steven, am I overreacting and that overhead is negligible?

Also, as far as I know, PAC and SVE incur basically no overhead in KVM
until the guest starts to use those features.

Do you have a specific reason for wanting MTE to always be enabled if
available? I'm happy to be convinced to make MTE enabled by default, I
don't have preference either way.

Thanks,
Alex

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-21 17:08       ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-21 17:08 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> Hi Alexandru,
> 
> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> > MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> > Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > ---
> >  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> >  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> >  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> >  arm/aarch64/kvm.c                         | 13 +++++++++++++
> >  arm/include/arm-common/kvm-config-arch.h  |  1 +
> >  arm/kvm.c                                 |  3 +++
> >  6 files changed, 23 insertions(+)
> > 
> > diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> > index bee2fc255a82..5616b27e257e 100644
> > --- a/arm/aarch32/include/kvm/kvm-arch.h
> > +++ b/arm/aarch32/include/kvm/kvm-arch.h
> > @@ -5,6 +5,9 @@
> >  
> >  #define kvm__arch_get_kern_offset(...)	0x8000
> >  
> > +struct kvm;
> > +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> > +
> >  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> >  
> >  #define MAX_PAGE_SIZE	SZ_4K
> > diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> > index 5e5ee41211ed..9124f6919d0f 100644
> > --- a/arm/aarch64/include/kvm/kvm-arch.h
> > +++ b/arm/aarch64/include/kvm/kvm-arch.h
> > @@ -6,6 +6,7 @@
> >  struct kvm;
> >  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
> >  int kvm__arch_get_ipa_limit(struct kvm *kvm);
> > +void kvm__arch_enable_mte(struct kvm *kvm);
> >  
> >  #define ARM_MAX_MEMORY(kvm)	({					\
> >  	u64 max_ram;							\
> > diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> > index 04be43dfa9b2..11250365d8d5 100644
> > --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> > +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> > @@ -6,6 +6,8 @@
> >  			"Run AArch32 guest"),				\
> >  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
> >  			"Create PMUv3 device"),				\
> > +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> > +			"Enable memory tagging extension"),		\
> >  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
> >  			"Specify random seed for Kernel Address Space "	\
> >  			"Layout Randomization (KASLR)"),
> > diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> > index 56a0aedc263d..46548f8ee96e 100644
> > --- a/arm/aarch64/kvm.c
> > +++ b/arm/aarch64/kvm.c
> > @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> >  
> >  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> >  }
> > +
> > +void kvm__arch_enable_mte(struct kvm *kvm)
> > +{
> > +	struct kvm_enable_cap cap = {
> > +		.cap = KVM_CAP_ARM_MTE,
> > +	};
> > +
> > +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> > +		die("MTE capability is not supported");
> > +
> > +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> > +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> > +}
> > diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> > index 5734c46ab9e6..16e8d500a71b 100644
> > --- a/arm/include/arm-common/kvm-config-arch.h
> > +++ b/arm/include/arm-common/kvm-config-arch.h
> > @@ -9,6 +9,7 @@ struct kvm_config_arch {
> >  	bool		virtio_trans_pci;
> >  	bool		aarch32_guest;
> >  	bool		has_pmuv3;
> > +	bool		has_mte;
> >  	u64		kaslr_seed;
> >  	enum irqchip_type irqchip;
> >  	u64		fw_addr;
> > diff --git a/arm/kvm.c b/arm/kvm.c
> > index 80d233f13d0b..f2db93953778 100644
> > --- a/arm/kvm.c
> > +++ b/arm/kvm.c
> > @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> >  	/* Create the virtual GIC. */
> >  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
> >  		die("Failed to create virtual GIC");
> > +
> > +	if (kvm->cfg.arch.has_mte)
> > +		kvm__arch_enable_mte(kvm);
> >  }
> 
> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> PAC and SVE?

I thought about that, the reason I chose to enable it based a kvmtool
command line option, instead of always being enabled if available, is
because of the overhead of sanitising the MTE tags on each stage 2 data
abort. Steven, am I overreacting and that overhead is negligible?

Also, as far as I know, PAC and SVE incur basically no overhead in KVM
until the guest starts to use those features.

Do you have a specific reason for wanting MTE to always be enabled if
available? I'm happy to be convinced to make MTE enabled by default, I
don't have preference either way.

Thanks,
Alex

_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-21 17:08       ` Alexandru Elisei
@ 2022-03-21 17:17         ` Steven Price
  -1 siblings, 0 replies; 24+ messages in thread
From: Steven Price @ 2022-03-21 17:17 UTC (permalink / raw)
  To: Alexandru Elisei, Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel, catalin.marinas

On 21/03/2022 17:08, Alexandru Elisei wrote:
> Hi,
> 
> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>> Hi Alexandru,
>>
>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>
>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>> ---
>>>  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>  arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>  arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>  arm/kvm.c                                 |  3 +++
>>>  6 files changed, 23 insertions(+)
>>>
>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>> index bee2fc255a82..5616b27e257e 100644
>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>> @@ -5,6 +5,9 @@
>>>  
>>>  #define kvm__arch_get_kern_offset(...)	0x8000
>>>  
>>> +struct kvm;
>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>> +
>>>  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>  
>>>  #define MAX_PAGE_SIZE	SZ_4K
>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>> index 5e5ee41211ed..9124f6919d0f 100644
>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>> @@ -6,6 +6,7 @@
>>>  struct kvm;
>>>  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>  
>>>  #define ARM_MAX_MEMORY(kvm)	({					\
>>>  	u64 max_ram;							\
>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> index 04be43dfa9b2..11250365d8d5 100644
>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> @@ -6,6 +6,8 @@
>>>  			"Run AArch32 guest"),				\
>>>  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>  			"Create PMUv3 device"),				\
>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>> +			"Enable memory tagging extension"),		\
>>>  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>  			"Specify random seed for Kernel Address Space "	\
>>>  			"Layout Randomization (KASLR)"),
>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>> index 56a0aedc263d..46548f8ee96e 100644
>>> --- a/arm/aarch64/kvm.c
>>> +++ b/arm/aarch64/kvm.c
>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>  
>>>  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>  }
>>> +
>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>> +{
>>> +	struct kvm_enable_cap cap = {
>>> +		.cap = KVM_CAP_ARM_MTE,
>>> +	};
>>> +
>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>> +		die("MTE capability is not supported");
>>> +
>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>> +}
>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>> index 5734c46ab9e6..16e8d500a71b 100644
>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>  	bool		virtio_trans_pci;
>>>  	bool		aarch32_guest;
>>>  	bool		has_pmuv3;
>>> +	bool		has_mte;
>>>  	u64		kaslr_seed;
>>>  	enum irqchip_type irqchip;
>>>  	u64		fw_addr;
>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>> index 80d233f13d0b..f2db93953778 100644
>>> --- a/arm/kvm.c
>>> +++ b/arm/kvm.c
>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>  	/* Create the virtual GIC. */
>>>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>  		die("Failed to create virtual GIC");
>>> +
>>> +	if (kvm->cfg.arch.has_mte)
>>> +		kvm__arch_enable_mte(kvm);
>>>  }
>>
>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>> PAC and SVE?
> 
> I thought about that, the reason I chose to enable it based a kvmtool
> command line option, instead of always being enabled if available, is
> because of the overhead of sanitising the MTE tags on each stage 2 data
> abort. Steven, am I overreacting and that overhead is negligible?

I don't have any figures from hardware I'm afraid, so I can't say what
the actual time overhead is in reality (but I suspect it's measurable).

However there is also a memory overhead when it comes to swapping MTE
tagged memory out. The tags have to be stored somewhere (currently they
remain in memory) so there's >3% overhead[1] in terms of memory when
swapped out.

So I think probably the opt-in approach makes sense, but I've no strong
feelings and I can see the benefits for the default being "every available".

Steve

[1] For each 4k page a 128 byte buffer is allocated for the pages
(3.125% overhead), but on top of that there's the kmalloc overhead and
an Xarray to store the pointer in. I haven't done the maths but it
probably comes out closer to 4%.

> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> until the guest starts to use those features.
> 
> Do you have a specific reason for wanting MTE to always be enabled if
> available? I'm happy to be convinced to make MTE enabled by default, I
> don't have preference either way.
> 
> Thanks,
> Alex


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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-21 17:17         ` Steven Price
  0 siblings, 0 replies; 24+ messages in thread
From: Steven Price @ 2022-03-21 17:17 UTC (permalink / raw)
  To: Alexandru Elisei, Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel, catalin.marinas

On 21/03/2022 17:08, Alexandru Elisei wrote:
> Hi,
> 
> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>> Hi Alexandru,
>>
>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>
>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>> ---
>>>  arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>  arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>  arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>  arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>  arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>  arm/kvm.c                                 |  3 +++
>>>  6 files changed, 23 insertions(+)
>>>
>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>> index bee2fc255a82..5616b27e257e 100644
>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>> @@ -5,6 +5,9 @@
>>>  
>>>  #define kvm__arch_get_kern_offset(...)	0x8000
>>>  
>>> +struct kvm;
>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>> +
>>>  #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>  
>>>  #define MAX_PAGE_SIZE	SZ_4K
>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>> index 5e5ee41211ed..9124f6919d0f 100644
>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>> @@ -6,6 +6,7 @@
>>>  struct kvm;
>>>  unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>  int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>  
>>>  #define ARM_MAX_MEMORY(kvm)	({					\
>>>  	u64 max_ram;							\
>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> index 04be43dfa9b2..11250365d8d5 100644
>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> @@ -6,6 +6,8 @@
>>>  			"Run AArch32 guest"),				\
>>>  	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>  			"Create PMUv3 device"),				\
>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>> +			"Enable memory tagging extension"),		\
>>>  	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>  			"Specify random seed for Kernel Address Space "	\
>>>  			"Layout Randomization (KASLR)"),
>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>> index 56a0aedc263d..46548f8ee96e 100644
>>> --- a/arm/aarch64/kvm.c
>>> +++ b/arm/aarch64/kvm.c
>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>  
>>>  	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>  }
>>> +
>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>> +{
>>> +	struct kvm_enable_cap cap = {
>>> +		.cap = KVM_CAP_ARM_MTE,
>>> +	};
>>> +
>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>> +		die("MTE capability is not supported");
>>> +
>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>> +}
>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>> index 5734c46ab9e6..16e8d500a71b 100644
>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>  	bool		virtio_trans_pci;
>>>  	bool		aarch32_guest;
>>>  	bool		has_pmuv3;
>>> +	bool		has_mte;
>>>  	u64		kaslr_seed;
>>>  	enum irqchip_type irqchip;
>>>  	u64		fw_addr;
>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>> index 80d233f13d0b..f2db93953778 100644
>>> --- a/arm/kvm.c
>>> +++ b/arm/kvm.c
>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>  	/* Create the virtual GIC. */
>>>  	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>  		die("Failed to create virtual GIC");
>>> +
>>> +	if (kvm->cfg.arch.has_mte)
>>> +		kvm__arch_enable_mte(kvm);
>>>  }
>>
>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>> PAC and SVE?
> 
> I thought about that, the reason I chose to enable it based a kvmtool
> command line option, instead of always being enabled if available, is
> because of the overhead of sanitising the MTE tags on each stage 2 data
> abort. Steven, am I overreacting and that overhead is negligible?

I don't have any figures from hardware I'm afraid, so I can't say what
the actual time overhead is in reality (but I suspect it's measurable).

However there is also a memory overhead when it comes to swapping MTE
tagged memory out. The tags have to be stored somewhere (currently they
remain in memory) so there's >3% overhead[1] in terms of memory when
swapped out.

So I think probably the opt-in approach makes sense, but I've no strong
feelings and I can see the benefits for the default being "every available".

Steve

[1] For each 4k page a 128 byte buffer is allocated for the pages
(3.125% overhead), but on top of that there's the kmalloc overhead and
an Xarray to store the pointer in. I haven't done the maths but it
probably comes out closer to 4%.

> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> until the guest starts to use those features.
> 
> Do you have a specific reason for wanting MTE to always be enabled if
> available? I'm happy to be convinced to make MTE enabled by default, I
> don't have preference either way.
> 
> Thanks,
> Alex


_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-21 17:08       ` Alexandru Elisei
@ 2022-03-23 10:31         ` Vladimir Murzin
  -1 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-23 10:31 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> Hi,
> 
> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>> Hi Alexandru,
>>
>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>
>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>> ---
>>>   arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>   arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>   arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>   arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>   arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>   arm/kvm.c                                 |  3 +++
>>>   6 files changed, 23 insertions(+)
>>>
>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>> index bee2fc255a82..5616b27e257e 100644
>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>> @@ -5,6 +5,9 @@
>>>   
>>>   #define kvm__arch_get_kern_offset(...)	0x8000
>>>   
>>> +struct kvm;
>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>> +
>>>   #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>   
>>>   #define MAX_PAGE_SIZE	SZ_4K
>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>> index 5e5ee41211ed..9124f6919d0f 100644
>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>> @@ -6,6 +6,7 @@
>>>   struct kvm;
>>>   unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>   int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>   
>>>   #define ARM_MAX_MEMORY(kvm)	({					\
>>>   	u64 max_ram;							\
>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> index 04be43dfa9b2..11250365d8d5 100644
>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> @@ -6,6 +6,8 @@
>>>   			"Run AArch32 guest"),				\
>>>   	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>   			"Create PMUv3 device"),				\
>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>> +			"Enable memory tagging extension"),		\
>>>   	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>   			"Specify random seed for Kernel Address Space "	\
>>>   			"Layout Randomization (KASLR)"),
>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>> index 56a0aedc263d..46548f8ee96e 100644
>>> --- a/arm/aarch64/kvm.c
>>> +++ b/arm/aarch64/kvm.c
>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>   
>>>   	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>   }
>>> +
>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>> +{
>>> +	struct kvm_enable_cap cap = {
>>> +		.cap = KVM_CAP_ARM_MTE,
>>> +	};
>>> +
>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>> +		die("MTE capability is not supported");
>>> +
>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>> +}
>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>> index 5734c46ab9e6..16e8d500a71b 100644
>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>   	bool		virtio_trans_pci;
>>>   	bool		aarch32_guest;
>>>   	bool		has_pmuv3;
>>> +	bool		has_mte;
>>>   	u64		kaslr_seed;
>>>   	enum irqchip_type irqchip;
>>>   	u64		fw_addr;
>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>> index 80d233f13d0b..f2db93953778 100644
>>> --- a/arm/kvm.c
>>> +++ b/arm/kvm.c
>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>   	/* Create the virtual GIC. */
>>>   	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>   		die("Failed to create virtual GIC");
>>> +
>>> +	if (kvm->cfg.arch.has_mte)
>>> +		kvm__arch_enable_mte(kvm);
>>>   }
>>
>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>> PAC and SVE?
> 
> I thought about that, the reason I chose to enable it based a kvmtool
> command line option, instead of always being enabled if available, is
> because of the overhead of sanitising the MTE tags on each stage 2 data
> abort. Steven, am I overreacting and that overhead is negligible?
> 
> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> until the guest starts to use those features.
> 
> Do you have a specific reason for wanting MTE to always be enabled if
> available? I'm happy to be convinced to make MTE enabled by default, I
> don't have preference either way.

Well, automatically enabling if available would align with what we do 
for other features in kvmtool and Linux itself - we tend to default y 
for new features, even MTE, thus improving chances to get reports back 
early if something (even performance) goes wrong. Just my 2p.

Cheers
Vladimir

> 
> Thanks,
> Alex


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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 10:31         ` Vladimir Murzin
  0 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-23 10:31 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> Hi,
> 
> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>> Hi Alexandru,
>>
>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>
>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>> ---
>>>   arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>   arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>   arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>   arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>   arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>   arm/kvm.c                                 |  3 +++
>>>   6 files changed, 23 insertions(+)
>>>
>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>> index bee2fc255a82..5616b27e257e 100644
>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>> @@ -5,6 +5,9 @@
>>>   
>>>   #define kvm__arch_get_kern_offset(...)	0x8000
>>>   
>>> +struct kvm;
>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>> +
>>>   #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>   
>>>   #define MAX_PAGE_SIZE	SZ_4K
>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>> index 5e5ee41211ed..9124f6919d0f 100644
>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>> @@ -6,6 +6,7 @@
>>>   struct kvm;
>>>   unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>   int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>   
>>>   #define ARM_MAX_MEMORY(kvm)	({					\
>>>   	u64 max_ram;							\
>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> index 04be43dfa9b2..11250365d8d5 100644
>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>> @@ -6,6 +6,8 @@
>>>   			"Run AArch32 guest"),				\
>>>   	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>   			"Create PMUv3 device"),				\
>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>> +			"Enable memory tagging extension"),		\
>>>   	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>   			"Specify random seed for Kernel Address Space "	\
>>>   			"Layout Randomization (KASLR)"),
>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>> index 56a0aedc263d..46548f8ee96e 100644
>>> --- a/arm/aarch64/kvm.c
>>> +++ b/arm/aarch64/kvm.c
>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>   
>>>   	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>   }
>>> +
>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>> +{
>>> +	struct kvm_enable_cap cap = {
>>> +		.cap = KVM_CAP_ARM_MTE,
>>> +	};
>>> +
>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>> +		die("MTE capability is not supported");
>>> +
>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>> +}
>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>> index 5734c46ab9e6..16e8d500a71b 100644
>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>   	bool		virtio_trans_pci;
>>>   	bool		aarch32_guest;
>>>   	bool		has_pmuv3;
>>> +	bool		has_mte;
>>>   	u64		kaslr_seed;
>>>   	enum irqchip_type irqchip;
>>>   	u64		fw_addr;
>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>> index 80d233f13d0b..f2db93953778 100644
>>> --- a/arm/kvm.c
>>> +++ b/arm/kvm.c
>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>   	/* Create the virtual GIC. */
>>>   	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>   		die("Failed to create virtual GIC");
>>> +
>>> +	if (kvm->cfg.arch.has_mte)
>>> +		kvm__arch_enable_mte(kvm);
>>>   }
>>
>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>> PAC and SVE?
> 
> I thought about that, the reason I chose to enable it based a kvmtool
> command line option, instead of always being enabled if available, is
> because of the overhead of sanitising the MTE tags on each stage 2 data
> abort. Steven, am I overreacting and that overhead is negligible?
> 
> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> until the guest starts to use those features.
> 
> Do you have a specific reason for wanting MTE to always be enabled if
> available? I'm happy to be convinced to make MTE enabled by default, I
> don't have preference either way.

Well, automatically enabling if available would align with what we do 
for other features in kvmtool and Linux itself - we tend to default y 
for new features, even MTE, thus improving chances to get reports back 
early if something (even performance) goes wrong. Just my 2p.

Cheers
Vladimir

> 
> Thanks,
> Alex


_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-23 10:31         ` Vladimir Murzin
@ 2022-03-23 12:03           ` Alexandru Elisei
  -1 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-23 12:03 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> > Hi,
> > 
> > On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> > > Hi Alexandru,
> > > 
> > > On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> > > > MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> > > > Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> > > > 
> > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > ---
> > > >   arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> > > >   arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> > > >   arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> > > >   arm/aarch64/kvm.c                         | 13 +++++++++++++
> > > >   arm/include/arm-common/kvm-config-arch.h  |  1 +
> > > >   arm/kvm.c                                 |  3 +++
> > > >   6 files changed, 23 insertions(+)
> > > > 
> > > > diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> > > > index bee2fc255a82..5616b27e257e 100644
> > > > --- a/arm/aarch32/include/kvm/kvm-arch.h
> > > > +++ b/arm/aarch32/include/kvm/kvm-arch.h
> > > > @@ -5,6 +5,9 @@
> > > >   #define kvm__arch_get_kern_offset(...)	0x8000
> > > > +struct kvm;
> > > > +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> > > > +
> > > >   #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> > > >   #define MAX_PAGE_SIZE	SZ_4K
> > > > diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> > > > index 5e5ee41211ed..9124f6919d0f 100644
> > > > --- a/arm/aarch64/include/kvm/kvm-arch.h
> > > > +++ b/arm/aarch64/include/kvm/kvm-arch.h
> > > > @@ -6,6 +6,7 @@
> > > >   struct kvm;
> > > >   unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
> > > >   int kvm__arch_get_ipa_limit(struct kvm *kvm);
> > > > +void kvm__arch_enable_mte(struct kvm *kvm);
> > > >   #define ARM_MAX_MEMORY(kvm)	({					\
> > > >   	u64 max_ram;							\
> > > > diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > index 04be43dfa9b2..11250365d8d5 100644
> > > > --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > @@ -6,6 +6,8 @@
> > > >   			"Run AArch32 guest"),				\
> > > >   	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
> > > >   			"Create PMUv3 device"),				\
> > > > +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> > > > +			"Enable memory tagging extension"),		\
> > > >   	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
> > > >   			"Specify random seed for Kernel Address Space "	\
> > > >   			"Layout Randomization (KASLR)"),
> > > > diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> > > > index 56a0aedc263d..46548f8ee96e 100644
> > > > --- a/arm/aarch64/kvm.c
> > > > +++ b/arm/aarch64/kvm.c
> > > > @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> > > >   	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> > > >   }
> > > > +
> > > > +void kvm__arch_enable_mte(struct kvm *kvm)
> > > > +{
> > > > +	struct kvm_enable_cap cap = {
> > > > +		.cap = KVM_CAP_ARM_MTE,
> > > > +	};
> > > > +
> > > > +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> > > > +		die("MTE capability is not supported");
> > > > +
> > > > +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> > > > +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> > > > +}
> > > > diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> > > > index 5734c46ab9e6..16e8d500a71b 100644
> > > > --- a/arm/include/arm-common/kvm-config-arch.h
> > > > +++ b/arm/include/arm-common/kvm-config-arch.h
> > > > @@ -9,6 +9,7 @@ struct kvm_config_arch {
> > > >   	bool		virtio_trans_pci;
> > > >   	bool		aarch32_guest;
> > > >   	bool		has_pmuv3;
> > > > +	bool		has_mte;
> > > >   	u64		kaslr_seed;
> > > >   	enum irqchip_type irqchip;
> > > >   	u64		fw_addr;
> > > > diff --git a/arm/kvm.c b/arm/kvm.c
> > > > index 80d233f13d0b..f2db93953778 100644
> > > > --- a/arm/kvm.c
> > > > +++ b/arm/kvm.c
> > > > @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> > > >   	/* Create the virtual GIC. */
> > > >   	if (gic__create(kvm, kvm->cfg.arch.irqchip))
> > > >   		die("Failed to create virtual GIC");
> > > > +
> > > > +	if (kvm->cfg.arch.has_mte)
> > > > +		kvm__arch_enable_mte(kvm);
> > > >   }
> > > 
> > > Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> > > PAC and SVE?
> > 
> > I thought about that, the reason I chose to enable it based a kvmtool
> > command line option, instead of always being enabled if available, is
> > because of the overhead of sanitising the MTE tags on each stage 2 data
> > abort. Steven, am I overreacting and that overhead is negligible?
> > 
> > Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> > until the guest starts to use those features.
> > 
> > Do you have a specific reason for wanting MTE to always be enabled if
> > available? I'm happy to be convinced to make MTE enabled by default, I
> > don't have preference either way.
> 
> Well, automatically enabling if available would align with what we do for
> other features in kvmtool and Linux itself - we tend to default y for new
> features, even MTE, thus improving chances to get reports back early if
> something (even performance) goes wrong. Just my 2p.

According to Steven, for each 4k page the kernel uses an 128 byte buffer to
store the tags, and then some extra memory is used to keep track of the
buffers. Let's take the case of a VM with 1GB of memory, and be
conservative and only account for the tag buffer. In this case, the tag
buffers alone will be 32MB.

For a VM with 1GB of memory created with kvmtool built from current master
(commit faae833a746f), pmap shows a total memory usage of 1268388K.
Subtracting the memory of the VM, we are left with 214MB of memory consumed
by kvmtool. Having MTE enabled would increase the memory overhead of
kvmtool by 32/214*100 = 15%.

Of course, this memory overhead scales with the amount of memory the VM
has. The buffer size that KVM uses might change in the future, but since we
cannot predict the future (might become larger or smaller), I'm working
with what is implement today.

The kernel documentation for MTE suggests that in order to take advantage
of it, software must be modified and recompiled. That means that users that
don't want to use MTE won't get to exercise MTE because they won't be using
MTE enabled software, but they will pay the overhead regardless. This of
course assumes that going forward software won't be using MTE by default.

kvmtool is supposed to be simple, fast and less resource intensive than
other hypervisors, that's why I think having MTE disabled by default is the
best way to implement the capability.

Thanks,
Alex

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 12:03           ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-23 12:03 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> > Hi,
> > 
> > On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> > > Hi Alexandru,
> > > 
> > > On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> > > > MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
> > > > Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> > > > 
> > > > Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> > > > ---
> > > >   arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> > > >   arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> > > >   arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> > > >   arm/aarch64/kvm.c                         | 13 +++++++++++++
> > > >   arm/include/arm-common/kvm-config-arch.h  |  1 +
> > > >   arm/kvm.c                                 |  3 +++
> > > >   6 files changed, 23 insertions(+)
> > > > 
> > > > diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
> > > > index bee2fc255a82..5616b27e257e 100644
> > > > --- a/arm/aarch32/include/kvm/kvm-arch.h
> > > > +++ b/arm/aarch32/include/kvm/kvm-arch.h
> > > > @@ -5,6 +5,9 @@
> > > >   #define kvm__arch_get_kern_offset(...)	0x8000
> > > > +struct kvm;
> > > > +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> > > > +
> > > >   #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
> > > >   #define MAX_PAGE_SIZE	SZ_4K
> > > > diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
> > > > index 5e5ee41211ed..9124f6919d0f 100644
> > > > --- a/arm/aarch64/include/kvm/kvm-arch.h
> > > > +++ b/arm/aarch64/include/kvm/kvm-arch.h
> > > > @@ -6,6 +6,7 @@
> > > >   struct kvm;
> > > >   unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
> > > >   int kvm__arch_get_ipa_limit(struct kvm *kvm);
> > > > +void kvm__arch_enable_mte(struct kvm *kvm);
> > > >   #define ARM_MAX_MEMORY(kvm)	({					\
> > > >   	u64 max_ram;							\
> > > > diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > index 04be43dfa9b2..11250365d8d5 100644
> > > > --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> > > > @@ -6,6 +6,8 @@
> > > >   			"Run AArch32 guest"),				\
> > > >   	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
> > > >   			"Create PMUv3 device"),				\
> > > > +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
> > > > +			"Enable memory tagging extension"),		\
> > > >   	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
> > > >   			"Specify random seed for Kernel Address Space "	\
> > > >   			"Layout Randomization (KASLR)"),
> > > > diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> > > > index 56a0aedc263d..46548f8ee96e 100644
> > > > --- a/arm/aarch64/kvm.c
> > > > +++ b/arm/aarch64/kvm.c
> > > > @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> > > >   	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> > > >   }
> > > > +
> > > > +void kvm__arch_enable_mte(struct kvm *kvm)
> > > > +{
> > > > +	struct kvm_enable_cap cap = {
> > > > +		.cap = KVM_CAP_ARM_MTE,
> > > > +	};
> > > > +
> > > > +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> > > > +		die("MTE capability is not supported");
> > > > +
> > > > +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> > > > +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> > > > +}
> > > > diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
> > > > index 5734c46ab9e6..16e8d500a71b 100644
> > > > --- a/arm/include/arm-common/kvm-config-arch.h
> > > > +++ b/arm/include/arm-common/kvm-config-arch.h
> > > > @@ -9,6 +9,7 @@ struct kvm_config_arch {
> > > >   	bool		virtio_trans_pci;
> > > >   	bool		aarch32_guest;
> > > >   	bool		has_pmuv3;
> > > > +	bool		has_mte;
> > > >   	u64		kaslr_seed;
> > > >   	enum irqchip_type irqchip;
> > > >   	u64		fw_addr;
> > > > diff --git a/arm/kvm.c b/arm/kvm.c
> > > > index 80d233f13d0b..f2db93953778 100644
> > > > --- a/arm/kvm.c
> > > > +++ b/arm/kvm.c
> > > > @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
> > > >   	/* Create the virtual GIC. */
> > > >   	if (gic__create(kvm, kvm->cfg.arch.irqchip))
> > > >   		die("Failed to create virtual GIC");
> > > > +
> > > > +	if (kvm->cfg.arch.has_mte)
> > > > +		kvm__arch_enable_mte(kvm);
> > > >   }
> > > 
> > > Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> > > PAC and SVE?
> > 
> > I thought about that, the reason I chose to enable it based a kvmtool
> > command line option, instead of always being enabled if available, is
> > because of the overhead of sanitising the MTE tags on each stage 2 data
> > abort. Steven, am I overreacting and that overhead is negligible?
> > 
> > Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> > until the guest starts to use those features.
> > 
> > Do you have a specific reason for wanting MTE to always be enabled if
> > available? I'm happy to be convinced to make MTE enabled by default, I
> > don't have preference either way.
> 
> Well, automatically enabling if available would align with what we do for
> other features in kvmtool and Linux itself - we tend to default y for new
> features, even MTE, thus improving chances to get reports back early if
> something (even performance) goes wrong. Just my 2p.

According to Steven, for each 4k page the kernel uses an 128 byte buffer to
store the tags, and then some extra memory is used to keep track of the
buffers. Let's take the case of a VM with 1GB of memory, and be
conservative and only account for the tag buffer. In this case, the tag
buffers alone will be 32MB.

For a VM with 1GB of memory created with kvmtool built from current master
(commit faae833a746f), pmap shows a total memory usage of 1268388K.
Subtracting the memory of the VM, we are left with 214MB of memory consumed
by kvmtool. Having MTE enabled would increase the memory overhead of
kvmtool by 32/214*100 = 15%.

Of course, this memory overhead scales with the amount of memory the VM
has. The buffer size that KVM uses might change in the future, but since we
cannot predict the future (might become larger or smaller), I'm working
with what is implement today.

The kernel documentation for MTE suggests that in order to take advantage
of it, software must be modified and recompiled. That means that users that
don't want to use MTE won't get to exercise MTE because they won't be using
MTE enabled software, but they will pay the overhead regardless. This of
course assumes that going forward software won't be using MTE by default.

kvmtool is supposed to be simple, fast and less resource intensive than
other hypervisors, that's why I think having MTE disabled by default is the
best way to implement the capability.

Thanks,
Alex

_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-23 12:03           ` Alexandru Elisei
@ 2022-03-23 13:50             ` Catalin Marinas
  -1 siblings, 0 replies; 24+ messages in thread
From: Catalin Marinas @ 2022-03-23 13:50 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: Vladimir Murzin, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, steven.price

On Wed, Mar 23, 2022 at 12:03:33PM +0000, Alexandru Elisei wrote:
> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> > On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> > > On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> > > > Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> > > > PAC and SVE?
> > > 
> > > I thought about that, the reason I chose to enable it based a kvmtool
> > > command line option, instead of always being enabled if available, is
> > > because of the overhead of sanitising the MTE tags on each stage 2 data
> > > abort. Steven, am I overreacting and that overhead is negligible?
> > > 
> > > Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> > > until the guest starts to use those features.
> > > 
> > > Do you have a specific reason for wanting MTE to always be enabled if
> > > available? I'm happy to be convinced to make MTE enabled by default, I
> > > don't have preference either way.
> > 
> > Well, automatically enabling if available would align with what we do for
> > other features in kvmtool and Linux itself - we tend to default y for new
> > features, even MTE, thus improving chances to get reports back early if
> > something (even performance) goes wrong. Just my 2p.
> 
> According to Steven, for each 4k page the kernel uses an 128 byte buffer to
> store the tags, and then some extra memory is used to keep track of the
> buffers. Let's take the case of a VM with 1GB of memory, and be
> conservative and only account for the tag buffer. In this case, the tag
> buffers alone will be 32MB.

The 128 byte buffer is only allocated *if* the page is swapped out. So
if the host swaps out the entire 1GB guest memory, it will incur the
32MB cost. But a fully swapped out VM is pretty useless, so this doesn't
happen very often.

We do have the cost of zeroing the tags when the page is mapped into
guests. I don't remember the KVM implementation but maybe we can
optimise this to zero the tags at the same time with zeroing the data
as we do for anonymous pages in the host (unless it does this already).

We could use the fine-grained traps to detect when MAIR_EL1 was
configured by the guest for Tagged memory but, at least with Linux, we
do this at boot irrespective of whether any application will use MTE or
not. Future architecture versions may address this problem.

> The kernel documentation for MTE suggests that in order to take advantage
> of it, software must be modified and recompiled. That means that users that
> don't want to use MTE won't get to exercise MTE because they won't be using
> MTE enabled software, but they will pay the overhead regardless. This of
> course assumes that going forward software won't be using MTE by default.

Not all software needs to be recompiled. It's sufficient most of the
time to replace the glibc with an MTE-aware one.

I have a slight preference for MTE default in kvmtool, maybe with an
option to disable it if one doesn't care about the feature or we find
the overhead to be significant (I don't think it would be).

-- 
Catalin

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 13:50             ` Catalin Marinas
  0 siblings, 0 replies; 24+ messages in thread
From: Catalin Marinas @ 2022-03-23 13:50 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: Vladimir Murzin, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, steven.price

On Wed, Mar 23, 2022 at 12:03:33PM +0000, Alexandru Elisei wrote:
> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> > On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> > > On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> > > > Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
> > > > PAC and SVE?
> > > 
> > > I thought about that, the reason I chose to enable it based a kvmtool
> > > command line option, instead of always being enabled if available, is
> > > because of the overhead of sanitising the MTE tags on each stage 2 data
> > > abort. Steven, am I overreacting and that overhead is negligible?
> > > 
> > > Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> > > until the guest starts to use those features.
> > > 
> > > Do you have a specific reason for wanting MTE to always be enabled if
> > > available? I'm happy to be convinced to make MTE enabled by default, I
> > > don't have preference either way.
> > 
> > Well, automatically enabling if available would align with what we do for
> > other features in kvmtool and Linux itself - we tend to default y for new
> > features, even MTE, thus improving chances to get reports back early if
> > something (even performance) goes wrong. Just my 2p.
> 
> According to Steven, for each 4k page the kernel uses an 128 byte buffer to
> store the tags, and then some extra memory is used to keep track of the
> buffers. Let's take the case of a VM with 1GB of memory, and be
> conservative and only account for the tag buffer. In this case, the tag
> buffers alone will be 32MB.

The 128 byte buffer is only allocated *if* the page is swapped out. So
if the host swaps out the entire 1GB guest memory, it will incur the
32MB cost. But a fully swapped out VM is pretty useless, so this doesn't
happen very often.

We do have the cost of zeroing the tags when the page is mapped into
guests. I don't remember the KVM implementation but maybe we can
optimise this to zero the tags at the same time with zeroing the data
as we do for anonymous pages in the host (unless it does this already).

We could use the fine-grained traps to detect when MAIR_EL1 was
configured by the guest for Tagged memory but, at least with Linux, we
do this at boot irrespective of whether any application will use MTE or
not. Future architecture versions may address this problem.

> The kernel documentation for MTE suggests that in order to take advantage
> of it, software must be modified and recompiled. That means that users that
> don't want to use MTE won't get to exercise MTE because they won't be using
> MTE enabled software, but they will pay the overhead regardless. This of
> course assumes that going forward software won't be using MTE by default.

Not all software needs to be recompiled. It's sufficient most of the
time to replace the glibc with an MTE-aware one.

I have a slight preference for MTE default in kvmtool, maybe with an
option to disable it if one doesn't care about the feature or we find
the overhead to be significant (I don't think it would be).

-- 
Catalin

_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-23 12:03           ` Alexandru Elisei
@ 2022-03-23 13:57             ` Vladimir Murzin
  -1 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-23 13:57 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On 3/23/22 12:03 PM, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
>>> Hi,
>>>
>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>>>> Hi Alexandru,
>>>>
>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>>>
>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>>>> ---
>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>>>    arm/kvm.c                                 |  3 +++
>>>>>    6 files changed, 23 insertions(+)
>>>>>
>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>>>> index bee2fc255a82..5616b27e257e 100644
>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>>>> @@ -5,6 +5,9 @@
>>>>>    #define kvm__arch_get_kern_offset(...)	0x8000
>>>>> +struct kvm;
>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>>>> +
>>>>>    #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>>>    #define MAX_PAGE_SIZE	SZ_4K
>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>>>> index 5e5ee41211ed..9124f6919d0f 100644
>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>>>> @@ -6,6 +6,7 @@
>>>>>    struct kvm;
>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>>>    #define ARM_MAX_MEMORY(kvm)	({					\
>>>>>    	u64 max_ram;							\
>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> index 04be43dfa9b2..11250365d8d5 100644
>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> @@ -6,6 +6,8 @@
>>>>>    			"Run AArch32 guest"),				\
>>>>>    	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>>>    			"Create PMUv3 device"),				\
>>>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>>>> +			"Enable memory tagging extension"),		\
>>>>>    	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>>>    			"Specify random seed for Kernel Address Space "	\
>>>>>    			"Layout Randomization (KASLR)"),
>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>>>> index 56a0aedc263d..46548f8ee96e 100644
>>>>> --- a/arm/aarch64/kvm.c
>>>>> +++ b/arm/aarch64/kvm.c
>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>>>    	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>>>    }
>>>>> +
>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>>>> +{
>>>>> +	struct kvm_enable_cap cap = {
>>>>> +		.cap = KVM_CAP_ARM_MTE,
>>>>> +	};
>>>>> +
>>>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>>>> +		die("MTE capability is not supported");
>>>>> +
>>>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>>>> +}
>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>>>> index 5734c46ab9e6..16e8d500a71b 100644
>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>>>    	bool		virtio_trans_pci;
>>>>>    	bool		aarch32_guest;
>>>>>    	bool		has_pmuv3;
>>>>> +	bool		has_mte;
>>>>>    	u64		kaslr_seed;
>>>>>    	enum irqchip_type irqchip;
>>>>>    	u64		fw_addr;
>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>>>> index 80d233f13d0b..f2db93953778 100644
>>>>> --- a/arm/kvm.c
>>>>> +++ b/arm/kvm.c
>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>>>    	/* Create the virtual GIC. */
>>>>>    	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>>>    		die("Failed to create virtual GIC");
>>>>> +
>>>>> +	if (kvm->cfg.arch.has_mte)
>>>>> +		kvm__arch_enable_mte(kvm);
>>>>>    }
>>>>
>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>>>> PAC and SVE?
>>>
>>> I thought about that, the reason I chose to enable it based a kvmtool
>>> command line option, instead of always being enabled if available, is
>>> because of the overhead of sanitising the MTE tags on each stage 2 data
>>> abort. Steven, am I overreacting and that overhead is negligible?
>>>
>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
>>> until the guest starts to use those features.
>>>
>>> Do you have a specific reason for wanting MTE to always be enabled if
>>> available? I'm happy to be convinced to make MTE enabled by default, I
>>> don't have preference either way.
>>
>> Well, automatically enabling if available would align with what we do for
>> other features in kvmtool and Linux itself - we tend to default y for new
>> features, even MTE, thus improving chances to get reports back early if
>> something (even performance) goes wrong. Just my 2p.
> 
> According to Steven, for each 4k page the kernel uses an 128 byte buffer to
> store the tags, and then some extra memory is used to keep track of the
> buffers. Let's take the case of a VM with 1GB of memory, and be
> conservative and only account for the tag buffer. In this case, the tag
> buffers alone will be 32MB.

Right, IIUC, that memory is allocated on demand when we about to swap the page
out or perform hibernation, so there is no reservation done upfront or I'm
missing something?

> 
> For a VM with 1GB of memory created with kvmtool built from current master
> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
> Subtracting the memory of the VM, we are left with 214MB of memory consumed
> by kvmtool. Having MTE enabled would increase the memory overhead of
> kvmtool by 32/214*100 = 15%.
> 

I admit, I might be missing something, but given that extra tag storage
allocated for swap/hibernation overhead can be applied to any process which
uses MTE, no?

> Of course, this memory overhead scales with the amount of memory the VM
> has. The buffer size that KVM uses might change in the future, but since we
> cannot predict the future (might become larger or smaller), I'm working
> with what is implement today.
>

Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory overhead
won't magically disappear, so should we start thinking how to reduce it?
I noticed that code saves tags one to one, so for guest which doesn't
actively use MTE whole page would be tagged with zero, cannot that case be
optimized? or maybe be go further and compress tags?
  
> The kernel documentation for MTE suggests that in order to take advantage
> of it, software must be modified and recompiled. That means that users that
> don't want to use MTE won't get to exercise MTE because they won't be using
> MTE enabled software, but they will pay the overhead regardless. This of
> course assumes that going forward software won't be using MTE by default.
> 
> kvmtool is supposed to be simple, fast and less resource intensive than
> other hypervisors, that's why I think having MTE disabled by default is the
> best way to implement the capability.

I see kvmtool as bleeding edge hacking tool, so closer it to the edge is better :)

Cheers
Vladimir

> 
> Thanks,
> Alex


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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 13:57             ` Vladimir Murzin
  0 siblings, 0 replies; 24+ messages in thread
From: Vladimir Murzin @ 2022-03-23 13:57 UTC (permalink / raw)
  To: Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel,
	catalin.marinas, steven.price

Hi,

On 3/23/22 12:03 PM, Alexandru Elisei wrote:
> Hi,
> 
> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
>>> Hi,
>>>
>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>>>> Hi Alexandru,
>>>>
>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM: arm64:
>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>>>
>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>>>> ---
>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>>>    arm/kvm.c                                 |  3 +++
>>>>>    6 files changed, 23 insertions(+)
>>>>>
>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h b/arm/aarch32/include/kvm/kvm-arch.h
>>>>> index bee2fc255a82..5616b27e257e 100644
>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>>>> @@ -5,6 +5,9 @@
>>>>>    #define kvm__arch_get_kern_offset(...)	0x8000
>>>>> +struct kvm;
>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>>>> +
>>>>>    #define ARM_MAX_MEMORY(...)	ARM_LOMAP_MAX_MEMORY
>>>>>    #define MAX_PAGE_SIZE	SZ_4K
>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h b/arm/aarch64/include/kvm/kvm-arch.h
>>>>> index 5e5ee41211ed..9124f6919d0f 100644
>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>>>> @@ -6,6 +6,7 @@
>>>>>    struct kvm;
>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm, int fd);
>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>>>    #define ARM_MAX_MEMORY(kvm)	({					\
>>>>>    	u64 max_ram;							\
>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> index 04be43dfa9b2..11250365d8d5 100644
>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>> @@ -6,6 +6,8 @@
>>>>>    			"Run AArch32 guest"),				\
>>>>>    	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
>>>>>    			"Create PMUv3 device"),				\
>>>>> +	OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,			\
>>>>> +			"Enable memory tagging extension"),		\
>>>>>    	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
>>>>>    			"Specify random seed for Kernel Address Space "	\
>>>>>    			"Layout Randomization (KASLR)"),
>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>>>> index 56a0aedc263d..46548f8ee96e 100644
>>>>> --- a/arm/aarch64/kvm.c
>>>>> +++ b/arm/aarch64/kvm.c
>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>>>    	return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>>>    }
>>>>> +
>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>>>> +{
>>>>> +	struct kvm_enable_cap cap = {
>>>>> +		.cap = KVM_CAP_ARM_MTE,
>>>>> +	};
>>>>> +
>>>>> +	if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>>>> +		die("MTE capability is not supported");
>>>>> +
>>>>> +	if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>>>> +		die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>>>> +}
>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
>>>>> index 5734c46ab9e6..16e8d500a71b 100644
>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>>>    	bool		virtio_trans_pci;
>>>>>    	bool		aarch32_guest;
>>>>>    	bool		has_pmuv3;
>>>>> +	bool		has_mte;
>>>>>    	u64		kaslr_seed;
>>>>>    	enum irqchip_type irqchip;
>>>>>    	u64		fw_addr;
>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>>>> index 80d233f13d0b..f2db93953778 100644
>>>>> --- a/arm/kvm.c
>>>>> +++ b/arm/kvm.c
>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
>>>>>    	/* Create the virtual GIC. */
>>>>>    	if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>>>    		die("Failed to create virtual GIC");
>>>>> +
>>>>> +	if (kvm->cfg.arch.has_mte)
>>>>> +		kvm__arch_enable_mte(kvm);
>>>>>    }
>>>>
>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported like we do for
>>>> PAC and SVE?
>>>
>>> I thought about that, the reason I chose to enable it based a kvmtool
>>> command line option, instead of always being enabled if available, is
>>> because of the overhead of sanitising the MTE tags on each stage 2 data
>>> abort. Steven, am I overreacting and that overhead is negligible?
>>>
>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
>>> until the guest starts to use those features.
>>>
>>> Do you have a specific reason for wanting MTE to always be enabled if
>>> available? I'm happy to be convinced to make MTE enabled by default, I
>>> don't have preference either way.
>>
>> Well, automatically enabling if available would align with what we do for
>> other features in kvmtool and Linux itself - we tend to default y for new
>> features, even MTE, thus improving chances to get reports back early if
>> something (even performance) goes wrong. Just my 2p.
> 
> According to Steven, for each 4k page the kernel uses an 128 byte buffer to
> store the tags, and then some extra memory is used to keep track of the
> buffers. Let's take the case of a VM with 1GB of memory, and be
> conservative and only account for the tag buffer. In this case, the tag
> buffers alone will be 32MB.

Right, IIUC, that memory is allocated on demand when we about to swap the page
out or perform hibernation, so there is no reservation done upfront or I'm
missing something?

> 
> For a VM with 1GB of memory created with kvmtool built from current master
> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
> Subtracting the memory of the VM, we are left with 214MB of memory consumed
> by kvmtool. Having MTE enabled would increase the memory overhead of
> kvmtool by 32/214*100 = 15%.
> 

I admit, I might be missing something, but given that extra tag storage
allocated for swap/hibernation overhead can be applied to any process which
uses MTE, no?

> Of course, this memory overhead scales with the amount of memory the VM
> has. The buffer size that KVM uses might change in the future, but since we
> cannot predict the future (might become larger or smaller), I'm working
> with what is implement today.
>

Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory overhead
won't magically disappear, so should we start thinking how to reduce it?
I noticed that code saves tags one to one, so for guest which doesn't
actively use MTE whole page would be tagged with zero, cannot that case be
optimized? or maybe be go further and compress tags?
  
> The kernel documentation for MTE suggests that in order to take advantage
> of it, software must be modified and recompiled. That means that users that
> don't want to use MTE won't get to exercise MTE because they won't be using
> MTE enabled software, but they will pay the overhead regardless. This of
> course assumes that going forward software won't be using MTE by default.
> 
> kvmtool is supposed to be simple, fast and less resource intensive than
> other hypervisors, that's why I think having MTE disabled by default is the
> best way to implement the capability.

I see kvmtool as bleeding edge hacking tool, so closer it to the edge is better :)

Cheers
Vladimir

> 
> Thanks,
> Alex


_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-23 13:57             ` Vladimir Murzin
@ 2022-03-23 14:15               ` Steven Price
  -1 siblings, 0 replies; 24+ messages in thread
From: Steven Price @ 2022-03-23 14:15 UTC (permalink / raw)
  To: Vladimir Murzin, Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel, catalin.marinas

On 23/03/2022 13:57, Vladimir Murzin wrote:
> Hi,
> 
> On 3/23/22 12:03 PM, Alexandru Elisei wrote:
>> Hi,
>>
>> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
>>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
>>>> Hi,
>>>>
>>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>>>>> Hi Alexandru,
>>>>>
>>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM:
>>>>>> arm64:
>>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>>>>
>>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>>>>> ---
>>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>>>>    arm/kvm.c                                 |  3 +++
>>>>>>    6 files changed, 23 insertions(+)
>>>>>>
>>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> b/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> index bee2fc255a82..5616b27e257e 100644
>>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> @@ -5,6 +5,9 @@
>>>>>>    #define kvm__arch_get_kern_offset(...)    0x8000
>>>>>> +struct kvm;
>>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>>>>> +
>>>>>>    #define ARM_MAX_MEMORY(...)    ARM_LOMAP_MAX_MEMORY
>>>>>>    #define MAX_PAGE_SIZE    SZ_4K
>>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> b/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> index 5e5ee41211ed..9124f6919d0f 100644
>>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> @@ -6,6 +6,7 @@
>>>>>>    struct kvm;
>>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm,
>>>>>> int fd);
>>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>>>>    #define ARM_MAX_MEMORY(kvm)    ({                    \
>>>>>>        u64 max_ram;                            \
>>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> index 04be43dfa9b2..11250365d8d5 100644
>>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> @@ -6,6 +6,8 @@
>>>>>>                "Run AArch32 guest"),                \
>>>>>>        OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,            \
>>>>>>                "Create PMUv3 device"),                \
>>>>>> +    OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,            \
>>>>>> +            "Enable memory tagging extension"),        \
>>>>>>        OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,            \
>>>>>>                "Specify random seed for Kernel Address Space "    \
>>>>>>                "Layout Randomization (KASLR)"),
>>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>>>>> index 56a0aedc263d..46548f8ee96e 100644
>>>>>> --- a/arm/aarch64/kvm.c
>>>>>> +++ b/arm/aarch64/kvm.c
>>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>>>>        return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>>>>    }
>>>>>> +
>>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>>>>> +{
>>>>>> +    struct kvm_enable_cap cap = {
>>>>>> +        .cap = KVM_CAP_ARM_MTE,
>>>>>> +    };
>>>>>> +
>>>>>> +    if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>>>>> +        die("MTE capability is not supported");
>>>>>> +
>>>>>> +    if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>>>>> +        die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>>>>> +}
>>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h
>>>>>> b/arm/include/arm-common/kvm-config-arch.h
>>>>>> index 5734c46ab9e6..16e8d500a71b 100644
>>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>>>>        bool        virtio_trans_pci;
>>>>>>        bool        aarch32_guest;
>>>>>>        bool        has_pmuv3;
>>>>>> +    bool        has_mte;
>>>>>>        u64        kaslr_seed;
>>>>>>        enum irqchip_type irqchip;
>>>>>>        u64        fw_addr;
>>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>>>>> index 80d233f13d0b..f2db93953778 100644
>>>>>> --- a/arm/kvm.c
>>>>>> +++ b/arm/kvm.c
>>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char
>>>>>> *hugetlbfs_path, u64 ram_size)
>>>>>>        /* Create the virtual GIC. */
>>>>>>        if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>>>>            die("Failed to create virtual GIC");
>>>>>> +
>>>>>> +    if (kvm->cfg.arch.has_mte)
>>>>>> +        kvm__arch_enable_mte(kvm);
>>>>>>    }
>>>>>
>>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported
>>>>> like we do for
>>>>> PAC and SVE?
>>>>
>>>> I thought about that, the reason I chose to enable it based a kvmtool
>>>> command line option, instead of always being enabled if available, is
>>>> because of the overhead of sanitising the MTE tags on each stage 2 data
>>>> abort. Steven, am I overreacting and that overhead is negligible?
>>>>
>>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
>>>> until the guest starts to use those features.
>>>>
>>>> Do you have a specific reason for wanting MTE to always be enabled if
>>>> available? I'm happy to be convinced to make MTE enabled by default, I
>>>> don't have preference either way.
>>>
>>> Well, automatically enabling if available would align with what we do
>>> for
>>> other features in kvmtool and Linux itself - we tend to default y for
>>> new
>>> features, even MTE, thus improving chances to get reports back early if
>>> something (even performance) goes wrong. Just my 2p.
>>
>> According to Steven, for each 4k page the kernel uses an 128 byte
>> buffer to
>> store the tags, and then some extra memory is used to keep track of the
>> buffers. Let's take the case of a VM with 1GB of memory, and be
>> conservative and only account for the tag buffer. In this case, the tag
>> buffers alone will be 32MB.
> 
> Right, IIUC, that memory is allocated on demand when we about to swap
> the page
> out or perform hibernation, so there is no reservation done upfront or I'm
> missing something?

That's correct, sorry if I didn't make that clear earlier. The host
memory is only allocated when the MTE-enabled guest's pages are swapped
out. So if they are never swapped out there's no memory overhead.

>>
>> For a VM with 1GB of memory created with kvmtool built from current
>> master
>> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
>> Subtracting the memory of the VM, we are left with 214MB of memory
>> consumed
>> by kvmtool. Having MTE enabled would increase the memory overhead of
>> kvmtool by 32/214*100 = 15%.
>>
> 
> I admit, I might be missing something, but given that extra tag storage
> allocated for swap/hibernation overhead can be applied to any process which
> uses MTE, no?

One difference is that the entire VM is considered MTE memory, whereas
in a normal application only those pages mapped with PROT_MTE take the
overhead. So the memory overhead of applications running in the VM is
higher than the same application outside of the VM (assuming the memory
is swapped out by the host).

>> Of course, this memory overhead scales with the amount of memory the VM
>> has. The buffer size that KVM uses might change in the future, but
>> since we
>> cannot predict the future (might become larger or smaller), I'm working
>> with what is implement today.
>>
> 
> Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory
> overhead
> won't magically disappear, so should we start thinking how to reduce it?
> I noticed that code saves tags one to one, so for guest which doesn't
> actively use MTE whole page would be tagged with zero, cannot that case be
> optimized? or maybe be go further and compress tags?

Compressing tags is certainly something that could be considered (an
early revision of the MTE swap did optimise the zero case).

However Linux is lazy with the tags - if an application needs memory but
doesn't use the tags then only the data portion will be zeroed and the
tags will be left with whatever value they had previously (as they are
not accessible by the application). This could mean that a MTE-enabled
guest ends with with remarkably few pages with zeroed tags after it has
been running for a while.

From the host it's not possible to determine whether the tags are useful
or not so they have to be saved regardless.

That said I don't have a strong opinion on the default, as long as
there's an option to disable MTE then having the default with it turned
on is fine by me.

>> The kernel documentation for MTE suggests that in order to take advantage
>> of it, software must be modified and recompiled. That means that users
>> that
>> don't want to use MTE won't get to exercise MTE because they won't be
>> using
>> MTE enabled software, but they will pay the overhead regardless. This of
>> course assumes that going forward software won't be using MTE by default.
>>
>> kvmtool is supposed to be simple, fast and less resource intensive than
>> other hypervisors, that's why I think having MTE disabled by default
>> is the
>> best way to implement the capability.
> 
> I see kvmtool as bleeding edge hacking tool, so closer it to the edge is
> better :)

I have to admit I like the "just works" approach that the defaults give
you (e.g. p9 filesystem from host, no need to configure root filesystems
etc), so there's definitely something to be said for MTE "just working"
in kvmtool too.

Steve

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 14:15               ` Steven Price
  0 siblings, 0 replies; 24+ messages in thread
From: Steven Price @ 2022-03-23 14:15 UTC (permalink / raw)
  To: Vladimir Murzin, Alexandru Elisei
  Cc: will, kvm, julien.thierry.kdev, linux-arm-kernel, catalin.marinas

On 23/03/2022 13:57, Vladimir Murzin wrote:
> Hi,
> 
> On 3/23/22 12:03 PM, Alexandru Elisei wrote:
>> Hi,
>>
>> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
>>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
>>>> Hi,
>>>>
>>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
>>>>> Hi Alexandru,
>>>>>
>>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
>>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM:
>>>>>> arm64:
>>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
>>>>>>
>>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
>>>>>> ---
>>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
>>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
>>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
>>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
>>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
>>>>>>    arm/kvm.c                                 |  3 +++
>>>>>>    6 files changed, 23 insertions(+)
>>>>>>
>>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> b/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> index bee2fc255a82..5616b27e257e 100644
>>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
>>>>>> @@ -5,6 +5,9 @@
>>>>>>    #define kvm__arch_get_kern_offset(...)    0x8000
>>>>>> +struct kvm;
>>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
>>>>>> +
>>>>>>    #define ARM_MAX_MEMORY(...)    ARM_LOMAP_MAX_MEMORY
>>>>>>    #define MAX_PAGE_SIZE    SZ_4K
>>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> b/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> index 5e5ee41211ed..9124f6919d0f 100644
>>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
>>>>>> @@ -6,6 +6,7 @@
>>>>>>    struct kvm;
>>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm,
>>>>>> int fd);
>>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
>>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
>>>>>>    #define ARM_MAX_MEMORY(kvm)    ({                    \
>>>>>>        u64 max_ram;                            \
>>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> index 04be43dfa9b2..11250365d8d5 100644
>>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
>>>>>> @@ -6,6 +6,8 @@
>>>>>>                "Run AArch32 guest"),                \
>>>>>>        OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,            \
>>>>>>                "Create PMUv3 device"),                \
>>>>>> +    OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,            \
>>>>>> +            "Enable memory tagging extension"),        \
>>>>>>        OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,            \
>>>>>>                "Specify random seed for Kernel Address Space "    \
>>>>>>                "Layout Randomization (KASLR)"),
>>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
>>>>>> index 56a0aedc263d..46548f8ee96e 100644
>>>>>> --- a/arm/aarch64/kvm.c
>>>>>> +++ b/arm/aarch64/kvm.c
>>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
>>>>>>        return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
>>>>>>    }
>>>>>> +
>>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
>>>>>> +{
>>>>>> +    struct kvm_enable_cap cap = {
>>>>>> +        .cap = KVM_CAP_ARM_MTE,
>>>>>> +    };
>>>>>> +
>>>>>> +    if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
>>>>>> +        die("MTE capability is not supported");
>>>>>> +
>>>>>> +    if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
>>>>>> +        die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
>>>>>> +}
>>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h
>>>>>> b/arm/include/arm-common/kvm-config-arch.h
>>>>>> index 5734c46ab9e6..16e8d500a71b 100644
>>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
>>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
>>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
>>>>>>        bool        virtio_trans_pci;
>>>>>>        bool        aarch32_guest;
>>>>>>        bool        has_pmuv3;
>>>>>> +    bool        has_mte;
>>>>>>        u64        kaslr_seed;
>>>>>>        enum irqchip_type irqchip;
>>>>>>        u64        fw_addr;
>>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
>>>>>> index 80d233f13d0b..f2db93953778 100644
>>>>>> --- a/arm/kvm.c
>>>>>> +++ b/arm/kvm.c
>>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char
>>>>>> *hugetlbfs_path, u64 ram_size)
>>>>>>        /* Create the virtual GIC. */
>>>>>>        if (gic__create(kvm, kvm->cfg.arch.irqchip))
>>>>>>            die("Failed to create virtual GIC");
>>>>>> +
>>>>>> +    if (kvm->cfg.arch.has_mte)
>>>>>> +        kvm__arch_enable_mte(kvm);
>>>>>>    }
>>>>>
>>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported
>>>>> like we do for
>>>>> PAC and SVE?
>>>>
>>>> I thought about that, the reason I chose to enable it based a kvmtool
>>>> command line option, instead of always being enabled if available, is
>>>> because of the overhead of sanitising the MTE tags on each stage 2 data
>>>> abort. Steven, am I overreacting and that overhead is negligible?
>>>>
>>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
>>>> until the guest starts to use those features.
>>>>
>>>> Do you have a specific reason for wanting MTE to always be enabled if
>>>> available? I'm happy to be convinced to make MTE enabled by default, I
>>>> don't have preference either way.
>>>
>>> Well, automatically enabling if available would align with what we do
>>> for
>>> other features in kvmtool and Linux itself - we tend to default y for
>>> new
>>> features, even MTE, thus improving chances to get reports back early if
>>> something (even performance) goes wrong. Just my 2p.
>>
>> According to Steven, for each 4k page the kernel uses an 128 byte
>> buffer to
>> store the tags, and then some extra memory is used to keep track of the
>> buffers. Let's take the case of a VM with 1GB of memory, and be
>> conservative and only account for the tag buffer. In this case, the tag
>> buffers alone will be 32MB.
> 
> Right, IIUC, that memory is allocated on demand when we about to swap
> the page
> out or perform hibernation, so there is no reservation done upfront or I'm
> missing something?

That's correct, sorry if I didn't make that clear earlier. The host
memory is only allocated when the MTE-enabled guest's pages are swapped
out. So if they are never swapped out there's no memory overhead.

>>
>> For a VM with 1GB of memory created with kvmtool built from current
>> master
>> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
>> Subtracting the memory of the VM, we are left with 214MB of memory
>> consumed
>> by kvmtool. Having MTE enabled would increase the memory overhead of
>> kvmtool by 32/214*100 = 15%.
>>
> 
> I admit, I might be missing something, but given that extra tag storage
> allocated for swap/hibernation overhead can be applied to any process which
> uses MTE, no?

One difference is that the entire VM is considered MTE memory, whereas
in a normal application only those pages mapped with PROT_MTE take the
overhead. So the memory overhead of applications running in the VM is
higher than the same application outside of the VM (assuming the memory
is swapped out by the host).

>> Of course, this memory overhead scales with the amount of memory the VM
>> has. The buffer size that KVM uses might change in the future, but
>> since we
>> cannot predict the future (might become larger or smaller), I'm working
>> with what is implement today.
>>
> 
> Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory
> overhead
> won't magically disappear, so should we start thinking how to reduce it?
> I noticed that code saves tags one to one, so for guest which doesn't
> actively use MTE whole page would be tagged with zero, cannot that case be
> optimized? or maybe be go further and compress tags?

Compressing tags is certainly something that could be considered (an
early revision of the MTE swap did optimise the zero case).

However Linux is lazy with the tags - if an application needs memory but
doesn't use the tags then only the data portion will be zeroed and the
tags will be left with whatever value they had previously (as they are
not accessible by the application). This could mean that a MTE-enabled
guest ends with with remarkably few pages with zeroed tags after it has
been running for a while.

From the host it's not possible to determine whether the tags are useful
or not so they have to be saved regardless.

That said I don't have a strong opinion on the default, as long as
there's an option to disable MTE then having the default with it turned
on is fine by me.

>> The kernel documentation for MTE suggests that in order to take advantage
>> of it, software must be modified and recompiled. That means that users
>> that
>> don't want to use MTE won't get to exercise MTE because they won't be
>> using
>> MTE enabled software, but they will pay the overhead regardless. This of
>> course assumes that going forward software won't be using MTE by default.
>>
>> kvmtool is supposed to be simple, fast and less resource intensive than
>> other hypervisors, that's why I think having MTE disabled by default
>> is the
>> best way to implement the capability.
> 
> I see kvmtool as bleeding edge hacking tool, so closer it to the edge is
> better :)

I have to admit I like the "just works" approach that the defaults give
you (e.g. p9 filesystem from host, no need to configure root filesystems
etc), so there's definitely something to be said for MTE "just working"
in kvmtool too.

Steve

_______________________________________________
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] 24+ messages in thread

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
  2022-03-23 14:15               ` Steven Price
@ 2022-03-23 15:48                 ` Alexandru Elisei
  -1 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-23 15:48 UTC (permalink / raw)
  To: Steven Price
  Cc: Vladimir Murzin, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, catalin.marinas

Hi,

Catalin, Steven, Vladimir, thank you all for the feedback. I'll make MTE
enabled by default in the next iteration of this series.

Thanks,
Alex

On Wed, Mar 23, 2022 at 02:15:55PM +0000, Steven Price wrote:
> On 23/03/2022 13:57, Vladimir Murzin wrote:
> > Hi,
> > 
> > On 3/23/22 12:03 PM, Alexandru Elisei wrote:
> >> Hi,
> >>
> >> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> >>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> >>>> Hi,
> >>>>
> >>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> >>>>> Hi Alexandru,
> >>>>>
> >>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> >>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM:
> >>>>>> arm64:
> >>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> >>>>>>
> >>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> >>>>>> ---
> >>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> >>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> >>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> >>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
> >>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
> >>>>>>    arm/kvm.c                                 |  3 +++
> >>>>>>    6 files changed, 23 insertions(+)
> >>>>>>
> >>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> b/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> index bee2fc255a82..5616b27e257e 100644
> >>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> @@ -5,6 +5,9 @@
> >>>>>>    #define kvm__arch_get_kern_offset(...)    0x8000
> >>>>>> +struct kvm;
> >>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> >>>>>> +
> >>>>>>    #define ARM_MAX_MEMORY(...)    ARM_LOMAP_MAX_MEMORY
> >>>>>>    #define MAX_PAGE_SIZE    SZ_4K
> >>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> b/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> index 5e5ee41211ed..9124f6919d0f 100644
> >>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> @@ -6,6 +6,7 @@
> >>>>>>    struct kvm;
> >>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm,
> >>>>>> int fd);
> >>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
> >>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
> >>>>>>    #define ARM_MAX_MEMORY(kvm)    ({                    \
> >>>>>>        u64 max_ram;                            \
> >>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> b/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> index 04be43dfa9b2..11250365d8d5 100644
> >>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> @@ -6,6 +6,8 @@
> >>>>>>                "Run AArch32 guest"),                \
> >>>>>>        OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,            \
> >>>>>>                "Create PMUv3 device"),                \
> >>>>>> +    OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,            \
> >>>>>> +            "Enable memory tagging extension"),        \
> >>>>>>        OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,            \
> >>>>>>                "Specify random seed for Kernel Address Space "    \
> >>>>>>                "Layout Randomization (KASLR)"),
> >>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> >>>>>> index 56a0aedc263d..46548f8ee96e 100644
> >>>>>> --- a/arm/aarch64/kvm.c
> >>>>>> +++ b/arm/aarch64/kvm.c
> >>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> >>>>>>        return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> >>>>>>    }
> >>>>>> +
> >>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
> >>>>>> +{
> >>>>>> +    struct kvm_enable_cap cap = {
> >>>>>> +        .cap = KVM_CAP_ARM_MTE,
> >>>>>> +    };
> >>>>>> +
> >>>>>> +    if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> >>>>>> +        die("MTE capability is not supported");
> >>>>>> +
> >>>>>> +    if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> >>>>>> +        die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> >>>>>> +}
> >>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h
> >>>>>> b/arm/include/arm-common/kvm-config-arch.h
> >>>>>> index 5734c46ab9e6..16e8d500a71b 100644
> >>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
> >>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
> >>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
> >>>>>>        bool        virtio_trans_pci;
> >>>>>>        bool        aarch32_guest;
> >>>>>>        bool        has_pmuv3;
> >>>>>> +    bool        has_mte;
> >>>>>>        u64        kaslr_seed;
> >>>>>>        enum irqchip_type irqchip;
> >>>>>>        u64        fw_addr;
> >>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
> >>>>>> index 80d233f13d0b..f2db93953778 100644
> >>>>>> --- a/arm/kvm.c
> >>>>>> +++ b/arm/kvm.c
> >>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char
> >>>>>> *hugetlbfs_path, u64 ram_size)
> >>>>>>        /* Create the virtual GIC. */
> >>>>>>        if (gic__create(kvm, kvm->cfg.arch.irqchip))
> >>>>>>            die("Failed to create virtual GIC");
> >>>>>> +
> >>>>>> +    if (kvm->cfg.arch.has_mte)
> >>>>>> +        kvm__arch_enable_mte(kvm);
> >>>>>>    }
> >>>>>
> >>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported
> >>>>> like we do for
> >>>>> PAC and SVE?
> >>>>
> >>>> I thought about that, the reason I chose to enable it based a kvmtool
> >>>> command line option, instead of always being enabled if available, is
> >>>> because of the overhead of sanitising the MTE tags on each stage 2 data
> >>>> abort. Steven, am I overreacting and that overhead is negligible?
> >>>>
> >>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> >>>> until the guest starts to use those features.
> >>>>
> >>>> Do you have a specific reason for wanting MTE to always be enabled if
> >>>> available? I'm happy to be convinced to make MTE enabled by default, I
> >>>> don't have preference either way.
> >>>
> >>> Well, automatically enabling if available would align with what we do
> >>> for
> >>> other features in kvmtool and Linux itself - we tend to default y for
> >>> new
> >>> features, even MTE, thus improving chances to get reports back early if
> >>> something (even performance) goes wrong. Just my 2p.
> >>
> >> According to Steven, for each 4k page the kernel uses an 128 byte
> >> buffer to
> >> store the tags, and then some extra memory is used to keep track of the
> >> buffers. Let's take the case of a VM with 1GB of memory, and be
> >> conservative and only account for the tag buffer. In this case, the tag
> >> buffers alone will be 32MB.
> > 
> > Right, IIUC, that memory is allocated on demand when we about to swap
> > the page
> > out or perform hibernation, so there is no reservation done upfront or I'm
> > missing something?
> 
> That's correct, sorry if I didn't make that clear earlier. The host
> memory is only allocated when the MTE-enabled guest's pages are swapped
> out. So if they are never swapped out there's no memory overhead.
> 
> >>
> >> For a VM with 1GB of memory created with kvmtool built from current
> >> master
> >> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
> >> Subtracting the memory of the VM, we are left with 214MB of memory
> >> consumed
> >> by kvmtool. Having MTE enabled would increase the memory overhead of
> >> kvmtool by 32/214*100 = 15%.
> >>
> > 
> > I admit, I might be missing something, but given that extra tag storage
> > allocated for swap/hibernation overhead can be applied to any process which
> > uses MTE, no?
> 
> One difference is that the entire VM is considered MTE memory, whereas
> in a normal application only those pages mapped with PROT_MTE take the
> overhead. So the memory overhead of applications running in the VM is
> higher than the same application outside of the VM (assuming the memory
> is swapped out by the host).
> 
> >> Of course, this memory overhead scales with the amount of memory the VM
> >> has. The buffer size that KVM uses might change in the future, but
> >> since we
> >> cannot predict the future (might become larger or smaller), I'm working
> >> with what is implement today.
> >>
> > 
> > Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory
> > overhead
> > won't magically disappear, so should we start thinking how to reduce it?
> > I noticed that code saves tags one to one, so for guest which doesn't
> > actively use MTE whole page would be tagged with zero, cannot that case be
> > optimized? or maybe be go further and compress tags?
> 
> Compressing tags is certainly something that could be considered (an
> early revision of the MTE swap did optimise the zero case).
> 
> However Linux is lazy with the tags - if an application needs memory but
> doesn't use the tags then only the data portion will be zeroed and the
> tags will be left with whatever value they had previously (as they are
> not accessible by the application). This could mean that a MTE-enabled
> guest ends with with remarkably few pages with zeroed tags after it has
> been running for a while.
> 
> From the host it's not possible to determine whether the tags are useful
> or not so they have to be saved regardless.
> 
> That said I don't have a strong opinion on the default, as long as
> there's an option to disable MTE then having the default with it turned
> on is fine by me.
> 
> >> The kernel documentation for MTE suggests that in order to take advantage
> >> of it, software must be modified and recompiled. That means that users
> >> that
> >> don't want to use MTE won't get to exercise MTE because they won't be
> >> using
> >> MTE enabled software, but they will pay the overhead regardless. This of
> >> course assumes that going forward software won't be using MTE by default.
> >>
> >> kvmtool is supposed to be simple, fast and less resource intensive than
> >> other hypervisors, that's why I think having MTE disabled by default
> >> is the
> >> best way to implement the capability.
> > 
> > I see kvmtool as bleeding edge hacking tool, so closer it to the edge is
> > better :)
> 
> I have to admit I like the "just works" approach that the defaults give
> you (e.g. p9 filesystem from host, no need to configure root filesystems
> etc), so there's definitely something to be said for MTE "just working"
> in kvmtool too.
> 
> Steve

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

* Re: [kvmtool PATCH 2/2] aarch64: Add support for MTE
@ 2022-03-23 15:48                 ` Alexandru Elisei
  0 siblings, 0 replies; 24+ messages in thread
From: Alexandru Elisei @ 2022-03-23 15:48 UTC (permalink / raw)
  To: Steven Price
  Cc: Vladimir Murzin, will, kvm, julien.thierry.kdev,
	linux-arm-kernel, catalin.marinas

Hi,

Catalin, Steven, Vladimir, thank you all for the feedback. I'll make MTE
enabled by default in the next iteration of this series.

Thanks,
Alex

On Wed, Mar 23, 2022 at 02:15:55PM +0000, Steven Price wrote:
> On 23/03/2022 13:57, Vladimir Murzin wrote:
> > Hi,
> > 
> > On 3/23/22 12:03 PM, Alexandru Elisei wrote:
> >> Hi,
> >>
> >> On Wed, Mar 23, 2022 at 10:31:15AM +0000, Vladimir Murzin wrote:
> >>> On 3/21/22 5:08 PM, Alexandru Elisei wrote:
> >>>> Hi,
> >>>>
> >>>> On Mon, Mar 21, 2022 at 03:40:18PM +0000, Vladimir Murzin wrote:
> >>>>> Hi Alexandru,
> >>>>>
> >>>>> On 3/21/22 3:28 PM, Alexandru Elisei wrote:
> >>>>>> MTE has been supported in Linux since commit 673638f434ee ("KVM:
> >>>>>> arm64:
> >>>>>> Expose KVM_ARM_CAP_MTE"), add support for it in kvmtool.
> >>>>>>
> >>>>>> Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
> >>>>>> ---
> >>>>>>    arm/aarch32/include/kvm/kvm-arch.h        |  3 +++
> >>>>>>    arm/aarch64/include/kvm/kvm-arch.h        |  1 +
> >>>>>>    arm/aarch64/include/kvm/kvm-config-arch.h |  2 ++
> >>>>>>    arm/aarch64/kvm.c                         | 13 +++++++++++++
> >>>>>>    arm/include/arm-common/kvm-config-arch.h  |  1 +
> >>>>>>    arm/kvm.c                                 |  3 +++
> >>>>>>    6 files changed, 23 insertions(+)
> >>>>>>
> >>>>>> diff --git a/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> b/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> index bee2fc255a82..5616b27e257e 100644
> >>>>>> --- a/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> +++ b/arm/aarch32/include/kvm/kvm-arch.h
> >>>>>> @@ -5,6 +5,9 @@
> >>>>>>    #define kvm__arch_get_kern_offset(...)    0x8000
> >>>>>> +struct kvm;
> >>>>>> +static inline void kvm__arch_enable_mte(struct kvm *kvm) {}
> >>>>>> +
> >>>>>>    #define ARM_MAX_MEMORY(...)    ARM_LOMAP_MAX_MEMORY
> >>>>>>    #define MAX_PAGE_SIZE    SZ_4K
> >>>>>> diff --git a/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> b/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> index 5e5ee41211ed..9124f6919d0f 100644
> >>>>>> --- a/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> +++ b/arm/aarch64/include/kvm/kvm-arch.h
> >>>>>> @@ -6,6 +6,7 @@
> >>>>>>    struct kvm;
> >>>>>>    unsigned long long kvm__arch_get_kern_offset(struct kvm *kvm,
> >>>>>> int fd);
> >>>>>>    int kvm__arch_get_ipa_limit(struct kvm *kvm);
> >>>>>> +void kvm__arch_enable_mte(struct kvm *kvm);
> >>>>>>    #define ARM_MAX_MEMORY(kvm)    ({                    \
> >>>>>>        u64 max_ram;                            \
> >>>>>> diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> b/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> index 04be43dfa9b2..11250365d8d5 100644
> >>>>>> --- a/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> +++ b/arm/aarch64/include/kvm/kvm-config-arch.h
> >>>>>> @@ -6,6 +6,8 @@
> >>>>>>                "Run AArch32 guest"),                \
> >>>>>>        OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,            \
> >>>>>>                "Create PMUv3 device"),                \
> >>>>>> +    OPT_BOOLEAN('\0', "mte", &(cfg)->has_mte,            \
> >>>>>> +            "Enable memory tagging extension"),        \
> >>>>>>        OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,            \
> >>>>>>                "Specify random seed for Kernel Address Space "    \
> >>>>>>                "Layout Randomization (KASLR)"),
> >>>>>> diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
> >>>>>> index 56a0aedc263d..46548f8ee96e 100644
> >>>>>> --- a/arm/aarch64/kvm.c
> >>>>>> +++ b/arm/aarch64/kvm.c
> >>>>>> @@ -81,3 +81,16 @@ int kvm__get_vm_type(struct kvm *kvm)
> >>>>>>        return KVM_VM_TYPE_ARM_IPA_SIZE(ipa_bits);
> >>>>>>    }
> >>>>>> +
> >>>>>> +void kvm__arch_enable_mte(struct kvm *kvm)
> >>>>>> +{
> >>>>>> +    struct kvm_enable_cap cap = {
> >>>>>> +        .cap = KVM_CAP_ARM_MTE,
> >>>>>> +    };
> >>>>>> +
> >>>>>> +    if (!kvm__supports_extension(kvm, KVM_CAP_ARM_MTE))
> >>>>>> +        die("MTE capability is not supported");
> >>>>>> +
> >>>>>> +    if (ioctl(kvm->vm_fd, KVM_ENABLE_CAP, &cap))
> >>>>>> +        die_perror("KVM_ENABLE_CAP(KVM_CAP_ARM_MTE)");
> >>>>>> +}
> >>>>>> diff --git a/arm/include/arm-common/kvm-config-arch.h
> >>>>>> b/arm/include/arm-common/kvm-config-arch.h
> >>>>>> index 5734c46ab9e6..16e8d500a71b 100644
> >>>>>> --- a/arm/include/arm-common/kvm-config-arch.h
> >>>>>> +++ b/arm/include/arm-common/kvm-config-arch.h
> >>>>>> @@ -9,6 +9,7 @@ struct kvm_config_arch {
> >>>>>>        bool        virtio_trans_pci;
> >>>>>>        bool        aarch32_guest;
> >>>>>>        bool        has_pmuv3;
> >>>>>> +    bool        has_mte;
> >>>>>>        u64        kaslr_seed;
> >>>>>>        enum irqchip_type irqchip;
> >>>>>>        u64        fw_addr;
> >>>>>> diff --git a/arm/kvm.c b/arm/kvm.c
> >>>>>> index 80d233f13d0b..f2db93953778 100644
> >>>>>> --- a/arm/kvm.c
> >>>>>> +++ b/arm/kvm.c
> >>>>>> @@ -86,6 +86,9 @@ void kvm__arch_init(struct kvm *kvm, const char
> >>>>>> *hugetlbfs_path, u64 ram_size)
> >>>>>>        /* Create the virtual GIC. */
> >>>>>>        if (gic__create(kvm, kvm->cfg.arch.irqchip))
> >>>>>>            die("Failed to create virtual GIC");
> >>>>>> +
> >>>>>> +    if (kvm->cfg.arch.has_mte)
> >>>>>> +        kvm__arch_enable_mte(kvm);
> >>>>>>    }
> >>>>>
> >>>>> Can we enable it unconditionally if KVM_CAP_ARM_MTE is supported
> >>>>> like we do for
> >>>>> PAC and SVE?
> >>>>
> >>>> I thought about that, the reason I chose to enable it based a kvmtool
> >>>> command line option, instead of always being enabled if available, is
> >>>> because of the overhead of sanitising the MTE tags on each stage 2 data
> >>>> abort. Steven, am I overreacting and that overhead is negligible?
> >>>>
> >>>> Also, as far as I know, PAC and SVE incur basically no overhead in KVM
> >>>> until the guest starts to use those features.
> >>>>
> >>>> Do you have a specific reason for wanting MTE to always be enabled if
> >>>> available? I'm happy to be convinced to make MTE enabled by default, I
> >>>> don't have preference either way.
> >>>
> >>> Well, automatically enabling if available would align with what we do
> >>> for
> >>> other features in kvmtool and Linux itself - we tend to default y for
> >>> new
> >>> features, even MTE, thus improving chances to get reports back early if
> >>> something (even performance) goes wrong. Just my 2p.
> >>
> >> According to Steven, for each 4k page the kernel uses an 128 byte
> >> buffer to
> >> store the tags, and then some extra memory is used to keep track of the
> >> buffers. Let's take the case of a VM with 1GB of memory, and be
> >> conservative and only account for the tag buffer. In this case, the tag
> >> buffers alone will be 32MB.
> > 
> > Right, IIUC, that memory is allocated on demand when we about to swap
> > the page
> > out or perform hibernation, so there is no reservation done upfront or I'm
> > missing something?
> 
> That's correct, sorry if I didn't make that clear earlier. The host
> memory is only allocated when the MTE-enabled guest's pages are swapped
> out. So if they are never swapped out there's no memory overhead.
> 
> >>
> >> For a VM with 1GB of memory created with kvmtool built from current
> >> master
> >> (commit faae833a746f), pmap shows a total memory usage of 1268388K.
> >> Subtracting the memory of the VM, we are left with 214MB of memory
> >> consumed
> >> by kvmtool. Having MTE enabled would increase the memory overhead of
> >> kvmtool by 32/214*100 = 15%.
> >>
> > 
> > I admit, I might be missing something, but given that extra tag storage
> > allocated for swap/hibernation overhead can be applied to any process which
> > uses MTE, no?
> 
> One difference is that the entire VM is considered MTE memory, whereas
> in a normal application only those pages mapped with PROT_MTE take the
> overhead. So the memory overhead of applications running in the VM is
> higher than the same application outside of the VM (assuming the memory
> is swapped out by the host).
> 
> >> Of course, this memory overhead scales with the amount of memory the VM
> >> has. The buffer size that KVM uses might change in the future, but
> >> since we
> >> cannot predict the future (might become larger or smaller), I'm working
> >> with what is implement today.
> >>
> > 
> > Fair enough. IMO, we will see more MTE capable hardware, OTOH, memory
> > overhead
> > won't magically disappear, so should we start thinking how to reduce it?
> > I noticed that code saves tags one to one, so for guest which doesn't
> > actively use MTE whole page would be tagged with zero, cannot that case be
> > optimized? or maybe be go further and compress tags?
> 
> Compressing tags is certainly something that could be considered (an
> early revision of the MTE swap did optimise the zero case).
> 
> However Linux is lazy with the tags - if an application needs memory but
> doesn't use the tags then only the data portion will be zeroed and the
> tags will be left with whatever value they had previously (as they are
> not accessible by the application). This could mean that a MTE-enabled
> guest ends with with remarkably few pages with zeroed tags after it has
> been running for a while.
> 
> From the host it's not possible to determine whether the tags are useful
> or not so they have to be saved regardless.
> 
> That said I don't have a strong opinion on the default, as long as
> there's an option to disable MTE then having the default with it turned
> on is fine by me.
> 
> >> The kernel documentation for MTE suggests that in order to take advantage
> >> of it, software must be modified and recompiled. That means that users
> >> that
> >> don't want to use MTE won't get to exercise MTE because they won't be
> >> using
> >> MTE enabled software, but they will pay the overhead regardless. This of
> >> course assumes that going forward software won't be using MTE by default.
> >>
> >> kvmtool is supposed to be simple, fast and less resource intensive than
> >> other hypervisors, that's why I think having MTE disabled by default
> >> is the
> >> best way to implement the capability.
> > 
> > I see kvmtool as bleeding edge hacking tool, so closer it to the edge is
> > better :)
> 
> I have to admit I like the "just works" approach that the defaults give
> you (e.g. p9 filesystem from host, no need to configure root filesystems
> etc), so there's definitely something to be said for MTE "just working"
> in kvmtool too.
> 
> Steve

_______________________________________________
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] 24+ messages in thread

end of thread, other threads:[~2022-03-23 15:49 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-21 15:28 [kvmtool PATCH 0/2] arm64: Add MTE support Alexandru Elisei
2022-03-21 15:28 ` Alexandru Elisei
2022-03-21 15:28 ` [kvmtool PATCH 1/2] update_headers: Sync ABI headers with Linux v5.17-rc8 Alexandru Elisei
2022-03-21 15:28   ` Alexandru Elisei
2022-03-21 15:28 ` [kvmtool PATCH 2/2] aarch64: Add support for MTE Alexandru Elisei
2022-03-21 15:28   ` Alexandru Elisei
2022-03-21 15:40   ` Vladimir Murzin
2022-03-21 15:40     ` Vladimir Murzin
2022-03-21 17:08     ` Alexandru Elisei
2022-03-21 17:08       ` Alexandru Elisei
2022-03-21 17:17       ` Steven Price
2022-03-21 17:17         ` Steven Price
2022-03-23 10:31       ` Vladimir Murzin
2022-03-23 10:31         ` Vladimir Murzin
2022-03-23 12:03         ` Alexandru Elisei
2022-03-23 12:03           ` Alexandru Elisei
2022-03-23 13:50           ` Catalin Marinas
2022-03-23 13:50             ` Catalin Marinas
2022-03-23 13:57           ` Vladimir Murzin
2022-03-23 13:57             ` Vladimir Murzin
2022-03-23 14:15             ` Steven Price
2022-03-23 14:15               ` Steven Price
2022-03-23 15:48               ` Alexandru Elisei
2022-03-23 15:48                 ` Alexandru Elisei

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.