summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMaxim Levitsky <mlevitsk@redhat.com>2022-10-25 15:47:31 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-11-10 15:47:24 +0100
commit13156b255ac7a231c12439a33290b4632f04a1d3 (patch)
tree28b589c66f007f7bffd92e00e4fec874da4baa79 /arch
parente232e74a95dacf86408d12c793f5aa6c655de319 (diff)
downloadlinux-stable-13156b255ac7a231c12439a33290b4632f04a1d3.tar.gz
linux-stable-13156b255ac7a231c12439a33290b4632f04a1d3.tar.bz2
linux-stable-13156b255ac7a231c12439a33290b4632f04a1d3.zip
KVM: x86: emulator: update the emulation mode after CR0 write
commit ad8f9e69942c7db90758d9d774157e53bce94840 upstream. Update the emulation mode when handling writes to CR0, because toggling CR0.PE switches between Real and Protected Mode, and toggling CR0.PG when EFER.LME=1 switches between Long and Protected Mode. This is likely a benign bug because there is no writeback of state, other than the RIP increment, and when toggling CR0.PE, the CPU has to execute code from a very low memory address. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> Message-Id: <20221025124741.228045-14-mlevitsk@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 271fe269a92f..135c993e6768 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3651,11 +3651,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
static int em_cr_write(struct x86_emulate_ctxt *ctxt)
{
- if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
+ int cr_num = ctxt->modrm_reg;
+ int r;
+
+ if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val))
return emulate_gp(ctxt, 0);
/* Disable writeback. */
ctxt->dst.type = OP_NONE;
+
+ if (cr_num == 0) {
+ /*
+ * CR0 write might have updated CR0.PE and/or CR0.PG
+ * which can affect the cpu's execution mode.
+ */
+ r = emulator_recalc_and_set_mode(ctxt);
+ if (r != X86EMUL_CONTINUE)
+ return r;
+ }
+
return X86EMUL_CONTINUE;
}