]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: arm64: Support trace filtering for guests
authorJames Clark <james.clark@linaro.org>
Mon, 6 Jan 2025 14:24:41 +0000 (14:24 +0000)
committerMarc Zyngier <maz@kernel.org>
Sun, 12 Jan 2025 12:50:11 +0000 (12:50 +0000)
For nVHE, switch the filter value in and out if the Coresight driver
asks for it. This will support filters for guests when sinks other than
TRBE are used.

For VHE, just write the filter directly to TRFCR_EL1 where trace can be
used even with TRBE sinks.

Signed-off-by: James Clark <james.clark@linaro.org>
Link: https://lore.kernel.org/r/20250106142446.628923-7-james.clark@linaro.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/debug.c

index fec53d84e99067973451b1f275340252ea144af6..05931a846e4efdab3a5880d8b1fcfa061a2c2898 100644 (file)
@@ -1388,6 +1388,7 @@ void kvm_clr_pmu_events(u64 clr);
 bool kvm_set_pmuserenr(u64 val);
 void kvm_enable_trbe(void);
 void kvm_disable_trbe(void);
+void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest);
 #else
 static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {}
 static inline void kvm_clr_pmu_events(u64 clr) {}
@@ -1397,6 +1398,7 @@ static inline bool kvm_set_pmuserenr(u64 val)
 }
 static inline void kvm_enable_trbe(void) {}
 static inline void kvm_disable_trbe(void) {}
+static inline void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest) {}
 #endif
 
 void kvm_vcpu_load_vhe(struct kvm_vcpu *vcpu);
index 92a24adadb0eb1ff7dcf569b190f6d0b17783c0d..0e4c805e7e89191de89b0af573213b2148661303 100644 (file)
@@ -245,3 +245,21 @@ void kvm_disable_trbe(void)
        host_data_clear_flag(TRBE_ENABLED);
 }
 EXPORT_SYMBOL_GPL(kvm_disable_trbe);
+
+void kvm_tracing_set_el1_configuration(u64 trfcr_while_in_guest)
+{
+       if (is_protected_kvm_enabled() || WARN_ON_ONCE(preemptible()))
+               return;
+
+       if (has_vhe()) {
+               write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12);
+               return;
+       }
+
+       *host_data_ptr(trfcr_while_in_guest) = trfcr_while_in_guest;
+       if (read_sysreg_s(SYS_TRFCR_EL1) != trfcr_while_in_guest)
+               host_data_set_flag(EL1_TRACING_CONFIGURED);
+       else
+               host_data_clear_flag(EL1_TRACING_CONFIGURED);
+}
+EXPORT_SYMBOL_GPL(kvm_tracing_set_el1_configuration);