diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
| -rw-r--r-- | arch/x86/kvm/emulate.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index f526acee2eed..f3284827c432 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
| @@ -2582,15 +2582,13 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt) | |||
| 2582 | * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU | 2582 | * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU |
| 2583 | * supports long mode. | 2583 | * supports long mode. |
| 2584 | */ | 2584 | */ |
| 2585 | cr4 = ctxt->ops->get_cr(ctxt, 4); | ||
| 2586 | if (emulator_has_longmode(ctxt)) { | 2585 | if (emulator_has_longmode(ctxt)) { |
| 2587 | struct desc_struct cs_desc; | 2586 | struct desc_struct cs_desc; |
| 2588 | 2587 | ||
| 2589 | /* Zero CR4.PCIDE before CR0.PG. */ | 2588 | /* Zero CR4.PCIDE before CR0.PG. */ |
| 2590 | if (cr4 & X86_CR4_PCIDE) { | 2589 | cr4 = ctxt->ops->get_cr(ctxt, 4); |
| 2590 | if (cr4 & X86_CR4_PCIDE) | ||
| 2591 | ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE); | 2591 | ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE); |
| 2592 | cr4 &= ~X86_CR4_PCIDE; | ||
| 2593 | } | ||
| 2594 | 2592 | ||
| 2595 | /* A 32-bit code segment is required to clear EFER.LMA. */ | 2593 | /* A 32-bit code segment is required to clear EFER.LMA. */ |
| 2596 | memset(&cs_desc, 0, sizeof(cs_desc)); | 2594 | memset(&cs_desc, 0, sizeof(cs_desc)); |
| @@ -2604,13 +2602,16 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt) | |||
| 2604 | if (cr0 & X86_CR0_PE) | 2602 | if (cr0 & X86_CR0_PE) |
| 2605 | ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE)); | 2603 | ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE)); |
| 2606 | 2604 | ||
| 2607 | /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */ | 2605 | if (emulator_has_longmode(ctxt)) { |
| 2608 | if (cr4 & X86_CR4_PAE) | 2606 | /* Clear CR4.PAE before clearing EFER.LME. */ |
| 2609 | ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); | 2607 | cr4 = ctxt->ops->get_cr(ctxt, 4); |
| 2608 | if (cr4 & X86_CR4_PAE) | ||
| 2609 | ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE); | ||
| 2610 | 2610 | ||
| 2611 | /* And finally go back to 32-bit mode. */ | 2611 | /* And finally go back to 32-bit mode. */ |
| 2612 | efer = 0; | 2612 | efer = 0; |
| 2613 | ctxt->ops->set_msr(ctxt, MSR_EFER, efer); | 2613 | ctxt->ops->set_msr(ctxt, MSR_EFER, efer); |
| 2614 | } | ||
| 2614 | 2615 | ||
| 2615 | /* | 2616 | /* |
| 2616 | * Give pre_leave_smm() a chance to make ISA-specific changes to the | 2617 | * Give pre_leave_smm() a chance to make ISA-specific changes to the |
