]>
Commit | Line | Data |
---|---|---|
f6df304f TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Maxim Levitsky <mlevitsk@redhat.com> | |
83250735 | 3 | Date: Wed, 3 Aug 2022 18:50:03 +0300 |
f6df304f TL |
4 | Subject: [PATCH] KVM: x86: emulator: update the emulation mode after CR0 write |
5 | ||
6 | CR0.PE toggles real/protected mode, thus its update | |
7 | should update the emulation mode. | |
8 | ||
9 | This is likely a benign bug because there is no writeback | |
10 | of state, other than the RIP increment, and when toggling | |
11 | CR0.PE, the CPU has to execute code from a very low memory address. | |
12 | ||
83250735 TL |
13 | Also CR0.PG toggle when EFER.LMA is set, toggles the long mode. |
14 | ||
f6df304f TL |
15 | Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> |
16 | Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com> | |
17 | --- | |
83250735 TL |
18 | arch/x86/kvm/emulate.c | 14 +++++++++++++- |
19 | 1 file changed, 13 insertions(+), 1 deletion(-) | |
f6df304f TL |
20 | |
21 | diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c | |
3ae8384f | 22 | index f2a0a34f4687..874d124438d1 100644 |
f6df304f TL |
23 | --- a/arch/x86/kvm/emulate.c |
24 | +++ b/arch/x86/kvm/emulate.c | |
3ae8384f | 25 | @@ -3645,11 +3645,23 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt) |
f6df304f TL |
26 | |
27 | static int em_cr_write(struct x86_emulate_ctxt *ctxt) | |
28 | { | |
29 | - if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) | |
30 | + int cr_num = ctxt->modrm_reg; | |
31 | + int r; | |
32 | + | |
33 | + if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val)) | |
34 | return emulate_gp(ctxt, 0); | |
35 | ||
36 | /* Disable writeback. */ | |
37 | ctxt->dst.type = OP_NONE; | |
38 | + | |
39 | + if (cr_num == 0) { | |
83250735 TL |
40 | + /* CR0 write might have updated CR0.PE and/or CR0.PG |
41 | + * which can affect the cpu execution mode */ | |
42 | + r = emulator_recalc_and_set_mode(ctxt); | |
f6df304f TL |
43 | + if (r != X86EMUL_CONTINUE) |
44 | + return r; | |
45 | + } | |
46 | + | |
47 | return X86EMUL_CONTINUE; | |
48 | } | |
49 |