0020-KVM-x86-emulator-update-the-emulation-mode-after-CR0.patch 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. From 3a99d9781d2d3ccf58d70b1dc7edfda886f5d271 Mon Sep 17 00:00:00 2001
  2. From: Maxim Levitsky <[email protected]>
  3. Date: Tue, 25 Oct 2022 15:47:31 +0300
  4. Subject: [PATCH] KVM: x86: emulator: update the emulation mode after CR0 write
  5. Update the emulation mode when handling writes to CR0, because
  6. toggling CR0.PE switches between Real and Protected Mode, and toggling
  7. CR0.PG when EFER.LME=1 switches between Long and Protected Mode.
  8. This is likely a benign bug because there is no writeback of state,
  9. other than the RIP increment, and when toggling CR0.PE, the CPU has
  10. to execute code from a very low memory address.
  11. Signed-off-by: Maxim Levitsky <[email protected]>
  12. ---
  13. arch/x86/kvm/emulate.c | 16 +++++++++++++++-
  14. 1 file changed, 15 insertions(+), 1 deletion(-)
  15. diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
  16. index 4365137d823b..5d7d4c1be843 100644
  17. --- a/arch/x86/kvm/emulate.c
  18. +++ b/arch/x86/kvm/emulate.c
  19. @@ -3288,11 +3288,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt)
  20. static int em_cr_write(struct x86_emulate_ctxt *ctxt)
  21. {
  22. - if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val))
  23. + int cr_num = ctxt->modrm_reg;
  24. + int r;
  25. +
  26. + if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val))
  27. return emulate_gp(ctxt, 0);
  28. /* Disable writeback. */
  29. ctxt->dst.type = OP_NONE;
  30. +
  31. + if (cr_num == 0) {
  32. + /*
  33. + * CR0 write might have updated CR0.PE and/or CR0.PG
  34. + * which can affect the cpu's execution mode.
  35. + */
  36. + r = emulator_recalc_and_set_mode(ctxt);
  37. + if (r != X86EMUL_CONTINUE)
  38. + return r;
  39. + }
  40. +
  41. return X86EMUL_CONTINUE;
  42. }
  43. --
  44. 2.38.1