]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
KVM: arm64: Fix nVHE stacktrace VA bits mask
authorVincent Donnefort <vdonnefort@google.com>
Tue, 7 Jan 2025 11:28:21 +0000 (11:28 +0000)
committerMarc Zyngier <maz@kernel.org>
Wed, 8 Jan 2025 11:18:39 +0000 (11:18 +0000)
The hypervisor VA space size depends on both the ID map's
(IDMAP_VA_BITS) and the kernel stage-1 (VA_BITS). However, the
hypervisor stacktrace decoding is solely relying on VA_BITS. This is
especially an issue when VA_BITS < IDMAP_VA_BITS (i.e. VA_BITS is
39-bit): the hypervisor may have addresses bigger than the stacktrace is
masking.

Align this mask with hyp_va_bits.

Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Link: https://lore.kernel.org/r/20250107112821.416591-1-vdonnefort@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_mmu.h
arch/arm64/kvm/mmu.c
arch/arm64/kvm/stacktrace.c

index 66d93e320ec8eec222e4fc43b99d414ef0a0eac1..2ddd98fd2df45e0f8424386d4b59f656db402bd8 100644 (file)
@@ -139,6 +139,8 @@ static __always_inline unsigned long __kern_hyp_va(unsigned long v)
 
 #define kern_hyp_va(v)         ((typeof(v))(__kern_hyp_va((unsigned long)(v))))
 
+extern u32 __hyp_va_bits;
+
 /*
  * We currently support using a VM-specified IPA size. For backward
  * compatibility, the default IPA size is fixed to 40bits.
index c9d46ad57e52d3e06b58089dfe4a7838165ddf2d..d36be6d2ac91b8cadf9f9f186786f8b3893d04c0 100644 (file)
@@ -29,6 +29,8 @@ static unsigned long __ro_after_init hyp_idmap_start;
 static unsigned long __ro_after_init hyp_idmap_end;
 static phys_addr_t __ro_after_init hyp_idmap_vector;
 
+u32 __ro_after_init __hyp_va_bits;
+
 static unsigned long __ro_after_init io_map_base;
 
 static phys_addr_t __stage2_range_addr_end(phys_addr_t addr, phys_addr_t end,
@@ -2056,6 +2058,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits)
                goto out_destroy_pgtable;
 
        io_map_base = hyp_idmap_start;
+       __hyp_va_bits = *hyp_va_bits;
        return 0;
 
 out_destroy_pgtable:
index 3ace5b75813bd5aaf30352e31cc39ef4eb2de3fc..fdedd8a3ed6f963df6e9c98bc0382c2c11243b2f 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
+#include <asm/kvm_mmu.h>
 #include <asm/stacktrace/nvhe.h>
 
 static struct stack_info stackinfo_get_overflow(void)
@@ -145,7 +146,7 @@ static void unwind(struct unwind_state *state,
  */
 static bool kvm_nvhe_dump_backtrace_entry(void *arg, unsigned long where)
 {
-       unsigned long va_mask = GENMASK_ULL(vabits_actual - 1, 0);
+       unsigned long va_mask = GENMASK_ULL(__hyp_va_bits - 1, 0);
        unsigned long hyp_offset = (unsigned long)arg;
 
        /* Mask tags and convert to kern addr */