Merge tag 'mm-nonmm-stable-2023-06-24-19-23' of git://git.kernel.org/pub/scm/linux...
[sfrench/cifs-2.6.git] / drivers / perf / arm_pmuv3.c
index c98e4039386dbcbdb1de1f3c8848dbf038b0ceb9..08b3a1bf0ef62a8ce126b9506507a67a25a81b5f 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/sched_clock.h>
 #include <linux/smp.h>
+#include <linux/nmi.h>
 
 #include <asm/arm_pmuv3.h>
 
@@ -677,9 +678,25 @@ static inline u32 armv8pmu_getreset_flags(void)
        return value;
 }
 
+static void update_pmuserenr(u64 val)
+{
+       lockdep_assert_irqs_disabled();
+
+       /*
+        * The current PMUSERENR_EL0 value might be the value for the guest.
+        * If that's the case, have KVM keep tracking of the register value
+        * for the host EL0 so that KVM can restore it before returning to
+        * the host EL0. Otherwise, update the register now.
+        */
+       if (kvm_set_pmuserenr(val))
+               return;
+
+       write_pmuserenr(val);
+}
+
 static void armv8pmu_disable_user_access(void)
 {
-       write_pmuserenr(0);
+       update_pmuserenr(0);
 }
 
 static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
@@ -695,8 +712,7 @@ static void armv8pmu_enable_user_access(struct arm_pmu *cpu_pmu)
                        armv8pmu_write_evcntr(i, 0);
        }
 
-       write_pmuserenr(0);
-       write_pmuserenr(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR);
+       update_pmuserenr(ARMV8_PMU_USERENR_ER | ARMV8_PMU_USERENR_CR);
 }
 
 static void armv8pmu_enable_event(struct perf_event *event)
@@ -1348,10 +1364,17 @@ static struct platform_driver armv8_pmu_driver = {
 
 static int __init armv8_pmu_driver_init(void)
 {
+       int ret;
+
        if (acpi_disabled)
-               return platform_driver_register(&armv8_pmu_driver);
+               ret = platform_driver_register(&armv8_pmu_driver);
        else
-               return arm_pmu_acpi_probe(armv8_pmuv3_pmu_init);
+               ret = arm_pmu_acpi_probe(armv8_pmuv3_pmu_init);
+
+       if (!ret)
+               lockup_detector_retry_init();
+
+       return ret;
 }
 device_initcall(armv8_pmu_driver_init)