| From 002374f371bd02df864cce1fe85d90dc5b292837 Mon Sep 17 00:00:00 2001 |
| From: James Hogan <james.hogan@imgtec.com> |
| Date: Wed, 11 Nov 2015 14:21:18 +0000 |
| Subject: MIPS: KVM: Fix ASID restoration logic |
| |
| From: James Hogan <james.hogan@imgtec.com> |
| |
| commit 002374f371bd02df864cce1fe85d90dc5b292837 upstream. |
| |
| 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 |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/mips/kvm/locore.S | 16 ++++++++++------ |
| 1 file changed, 10 insertions(+), 6 deletions(-) |
| |
| --- a/arch/mips/kvm/locore.S |
| +++ b/arch/mips/kvm/locore.S |
| @@ -165,9 +165,11 @@ FEXPORT(__kvm_mips_vcpu_run) |
| |
| FEXPORT(__kvm_mips_load_asid) |
| /* Set the ASID for the Guest Kernel */ |
| - INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
| - /* addresses shift to 0x80000000 */ |
| - bltz t0, 1f /* If kernel */ |
| + PTR_L t0, VCPU_COP0(k1) |
| + LONG_L t0, COP0_STATUS(t0) |
| + andi t0, KSU_USER | ST0_ERL | ST0_EXL |
| + xori t0, KSU_USER |
| + bnez t0, 1f /* If kernel */ |
| INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
| INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
| 1: |
| @@ -482,9 +484,11 @@ __kvm_mips_return_to_guest: |
| mtc0 t0, CP0_EPC |
| |
| /* Set the ASID for the Guest Kernel */ |
| - INT_SLL t0, t0, 1 /* with kseg0 @ 0x40000000, kernel */ |
| - /* addresses shift to 0x80000000 */ |
| - bltz t0, 1f /* If kernel */ |
| + PTR_L t0, VCPU_COP0(k1) |
| + LONG_L t0, COP0_STATUS(t0) |
| + andi t0, KSU_USER | ST0_ERL | ST0_EXL |
| + xori t0, KSU_USER |
| + bnez t0, 1f /* If kernel */ |
| INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ |
| INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ |
| 1: |