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

MIPS: KVM: Fix ASID restoration logic

ASID restoration on guest resume should determine the guest execution
mode based on the guest Status register rather than bit 30 of the guest
PC.

Fix the two places in locore.S that do this, loading the guest status
from the cop0 area. Note, this assembly is specific to the trap &
emulate implementation of KVM, so it doesn't need to check the
supervisor bit as that mode is not implemented in the guest.

Fixes: b680f70fc111 ("KVM/MIPS32: Entry point for trampolining to...")
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Gleb Natapov <gleb@kernel.org>
Cc: linux-mips@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: <stable@vger.kernel.org> # 3.10.x-
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

James Hogan and committed by
Paolo Bonzini
002374f3 8005c49d

+10 -6
+10 -6
arch/mips/kvm/locore.S
··· 157 157 158 158 FEXPORT(__kvm_mips_load_asid) 159 159 /* Set the ASID for the Guest Kernel */ 160 - INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ 161 - /* addresses shift to 0x80000000 */ 162 - bltz t0, 1f /* If kernel */ 160 + PTR_L t0, VCPU_COP0(k1) 161 + LONG_L t0, COP0_STATUS(t0) 162 + andi t0, KSU_USER | ST0_ERL | ST0_EXL 163 + xori t0, KSU_USER 164 + bnez t0, 1f /* If kernel */ 163 165 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ 164 166 INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ 165 167 1: ··· 476 474 mtc0 t0, CP0_EPC 477 475 478 476 /* Set the ASID for the Guest Kernel */ 479 - INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ 480 - /* addresses shift to 0x80000000 */ 481 - bltz t0, 1f /* If kernel */ 477 + PTR_L t0, VCPU_COP0(k1) 478 + LONG_L t0, COP0_STATUS(t0) 479 + andi t0, KSU_USER | ST0_ERL | ST0_EXL 480 + xori t0, KSU_USER 481 + bnez t0, 1f /* If kernel */ 482 482 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ 483 483 INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ 484 484 1: