summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorJames Hogan <james.hogan@imgtec.com>2016-06-15 19:29:45 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-05-10 10:25:44 +0200
commit439b0831e5743f12759cdd061f609d3faaee3e17 (patch)
tree5af978d02cb400d501d458d0cf0717e92eda5d72 /arch/mips
parentdce6c5bb915a5608226191d769122980382562c6 (diff)
downloadlinux-stable-439b0831e5743f12759cdd061f609d3faaee3e17.tar.gz
linux-stable-439b0831e5743f12759cdd061f609d3faaee3e17.tar.bz2
linux-stable-439b0831e5743f12759cdd061f609d3faaee3e17.zip
MIPS: KVM: Fix translation of MFC0 ErrCtl
commit 66ffc50c480e7ab6ad5642f47276435a8873c31a upstream. The MIPS KVM dynamic translation is meant to translate "MFC0 rt, ErrCtl" instructions into "ADD rt, zero, zero" to zero the destination register, however the rt register number was copied into rt of the ADD instruction encoding, which is the 2nd source operand. This results in "ADD zero, zero, rt" which is a no-op, so only the first execution of each such MFC0 from ErrCtl will actually read 0. Fix the shift to put the rt from the MFC0 encoding into the rd field of the ADD. Fixes: 50c8308538dc ("KVM/MIPS32: Binary patching of select privileged instructions.") Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Radim Krčmář <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.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>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kvm/dyntrans.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c
index 521121bdebff..4974bfc2c5c8 100644
--- a/arch/mips/kvm/dyntrans.c
+++ b/arch/mips/kvm/dyntrans.c
@@ -82,7 +82,7 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
if ((rd == MIPS_CP0_ERRCTL) && (sel == 0)) {
mfc0_inst = CLEAR_TEMPLATE;
- mfc0_inst |= ((rt & 0x1f) << 16);
+ mfc0_inst |= ((rt & 0x1f) << 11);
} else {
mfc0_inst = LW_TEMPLATE;
mfc0_inst |= ((rt & 0x1f) << 16);