diff options
author | Yingchao Deng <yingchao.deng@oss.qualcomm.com> | 2025-09-02 11:48:25 +0800 |
---|---|---|
committer | Marc Zyngier <maz@kernel.org> | 2025-09-15 11:38:07 +0100 |
commit | 27d2b47eef033f1fc6c0452dc1017e43dad5fe14 (patch) | |
tree | ece8b9027daee43b758412236f31418ffd314d4d | |
parent | 2ba972bf71cb71d2127ec6c3db1ceb6dd0c73173 (diff) |
KVM: arm64: Return early from trace helpers when KVM isn't available
When Linux is booted at EL1, host_data_ptr() resolves to the nVHE
hypervisor's copy of host data. When hyp mode isn't available for
KVM the nVHE percpu bases remain uninitialized. Consequently, any usage
of host_data_ptr() will result in a NULL dereference which has been
observed in KVM's trace filtering helpers.
Add an early return to the trace filtering helpers if KVM isn't
initialized, avoiding the NULL dereference. Take this opportunity
to move the TRBE-skipping checks to a common helper.
Fixes: 054b88391bbe2 ("KVM: arm64: Support trace filtering for guests")
Signed-off-by: Yingchao Deng <yingchao.deng@oss.qualcomm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
[maz: repainted the helpers to be readable, and the commit message
with Oliver's suggestion]
Signed-off-by: Marc Zyngier <maz@kernel.org>
-rw-r--r-- | arch/arm64/kvm/debug.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 381382c19fe4..1aaeb40a9a38 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -230,29 +230,29 @@ void kvm_debug_handle_oslar(struct kvm_vcpu *vcpu, u64 val) preempt_enable(); } -void kvm_enable_trbe(void) +static bool skip_trbe_access(bool skip_condition) { - if (has_vhe() || is_protected_kvm_enabled() || - WARN_ON_ONCE(preemptible())) - return; + return (WARN_ON_ONCE(preemptible()) || skip_condition || + is_protected_kvm_enabled() || !is_kvm_arm_initialised()); +} - host_data_set_flag(TRBE_ENABLED); +void kvm_enable_trbe(void) +{ + if (!skip_trbe_access(has_vhe())) + host_data_set_flag(TRBE_ENABLED); } EXPORT_SYMBOL_GPL(kvm_enable_trbe); void kvm_disable_trbe(void) { - if (has_vhe() || is_protected_kvm_enabled() || - WARN_ON_ONCE(preemptible())) - return; - - host_data_clear_flag(TRBE_ENABLED); + if (!skip_trbe_access(has_vhe())) + 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())) + if (skip_trbe_access(false)) return; if (has_vhe()) { |