new file mode 100644
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ */
+
+#ifndef __ARM64_KVM_SPE_H__
+#define __ARM64_KVM_SPE_H__
+
+#ifdef CONFIG_KVM_ARM_SPE
+DECLARE_STATIC_KEY_FALSE(kvm_spe_available);
+
+static __always_inline bool kvm_supports_spe(void)
+{
+ return static_branch_likely(&kvm_spe_available);
+}
+#else
+#define kvm_supports_spe() (false)
+#endif /* CONFIG_KVM_ARM_SPE */
+
+#endif /* __ARM64_KVM_SPE_H__ */
@@ -25,3 +25,4 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
vgic/vgic-its.o vgic/vgic-debug.o
kvm-$(CONFIG_HW_PERF_EVENTS) += pmu-emul.o
+kvm-$(CONFIG_KVM_ARM_SPE) += spe.o
@@ -37,6 +37,7 @@
#include <asm/kvm_arm.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_mmu.h>
+#include <asm/kvm_spe.h>
#include <asm/kvm_emulate.h>
#include <asm/sections.h>
new file mode 100644
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - ARM Ltd
+ */
+
+#include <linux/cpumask.h>
+#include <linux/kvm_host.h>
+#include <linux/perf/arm_spe_pmu.h>
+
+#include <asm/kvm_spe.h>
+
+DEFINE_STATIC_KEY_FALSE(kvm_spe_available);
+
+static cpumask_t supported_cpus;
+static DEFINE_MUTEX(supported_cpus_lock);
+
+void kvm_host_spe_init(struct arm_spe_pmu *spe_pmu)
+{
+ if (!spe_pmu->pmsver)
+ return;
+
+ mutex_lock(&supported_cpus_lock);
+
+ static_branch_enable(&kvm_spe_available);
+ cpumask_or(&supported_cpus, &supported_cpus, &spe_pmu->supported_cpus);
+
+ mutex_unlock(&supported_cpus_lock);
+}
@@ -1183,6 +1183,8 @@ static int arm_spe_pmu_device_probe(struct platform_device *pdev)
if (ret)
goto out_teardown_dev;
+ kvm_host_spe_init(spe_pmu);
+
return 0;
out_teardown_dev:
@@ -44,6 +44,12 @@ struct arm_spe_pmu {
#define ARMV8_SPE_PDEV_NAME "arm,spe-v1"
+#ifdef CONFIG_KVM_ARM_SPE
+void kvm_host_spe_init(struct arm_spe_pmu *spe_pmu);
+#else
+#define kvm_host_spe_init(x) do { } while(0)
+#endif
+
#endif /* CONFIG_ARM_SPE_PMU */
#endif /* __ARM_SPE_PMU_H__ */
KVM SPE emulation requires at least one physical CPU to support SPE. Each time the SPE driver successfully probes the SPE hardware, keep track of the CPUs that belong to the SPE instance and enable the static key that allows SPE to emulated by KVM. Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com> --- arch/arm64/include/asm/kvm_spe.h | 20 ++++++++++++++++++++ arch/arm64/kvm/Makefile | 1 + arch/arm64/kvm/arm.c | 1 + arch/arm64/kvm/spe.c | 28 ++++++++++++++++++++++++++++ drivers/perf/arm_spe_pmu.c | 2 ++ include/linux/perf/arm_spe_pmu.h | 6 ++++++ 6 files changed, 58 insertions(+) create mode 100644 arch/arm64/include/asm/kvm_spe.h create mode 100644 arch/arm64/kvm/spe.c