Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: KVM: Don't hardcode restored HWREna

KVM modifies CP0_HWREna during guest execution so it can trap and
emulate RDHWR instructions, however it always restores the hardcoded
value 0x2000000F. This assumes the presence of the UserLocal register,
and the absence of any implementation dependent or future HW registers.

Fix by exporting the value that traps.c write into CP0_HWREna, and
loading from there instead of hard coding.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: linux-mips@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

James Hogan and committed by
Paolo Bonzini
b937ff62 aff565aa

+7 -3
+1
arch/mips/include/asm/setup.h
··· 21 21 22 22 extern void *set_except_vector(int n, void *addr); 23 23 extern unsigned long ebase; 24 + extern unsigned int hwrena; 24 25 extern void per_cpu_trap_init(bool); 25 26 extern void cpu_cache_init(void); 26 27
+4 -1
arch/mips/kernel/traps.c
··· 2064 2064 status_set); 2065 2065 } 2066 2066 2067 + unsigned int hwrena; 2068 + EXPORT_SYMBOL_GPL(hwrena); 2069 + 2067 2070 /* configure HWRENA register */ 2068 2071 static void configure_hwrena(void) 2069 2072 { 2070 - unsigned int hwrena = cpu_hwrena_impl_bits; 2073 + hwrena = cpu_hwrena_impl_bits; 2071 2074 2072 2075 if (cpu_has_mips_r2_r6) 2073 2076 hwrena |= MIPS_HWRENA_CPUNUM |
+2 -2
arch/mips/kvm/locore.S
··· 381 381 mtc0 k0, CP0_DDATA_LO 382 382 383 383 /* Restore RDHWR access */ 384 - PTR_LI k0, 0x2000000F 384 + INT_L k0, hwrena 385 385 mtc0 k0, CP0_HWRENA 386 386 387 387 /* Jump to handler */ ··· 553 553 mtlo k0 554 554 555 555 /* Restore RDHWR access */ 556 - PTR_LI k0, 0x2000000F 556 + INT_L k0, hwrena 557 557 mtc0 k0, CP0_HWRENA 558 558 559 559 /* Restore RA, which is the address we will return to */