The SDM says that exiting system management mode from 64-bit mode
is invalid, but that would be too good to be true. But actually,
most of the code is already there to support exiting from compat
mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
mode to real mode only requires clearing CS.L and CR4.PCIDE.
Cc: [email protected]
Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
Cc: Laszlo Ersek <[email protected]>
Cc: Radim Krčmář <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
---
arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index b60fed56671b..1505587d06e9 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
/*
* Get back to real mode, to prepare a safe state in which to load
- * CR0/CR3/CR4/EFER.
- *
- * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
+ * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
+ * supports long mode.
*/
+ cr4 = ctxt->ops->get_cr(ctxt, 4);
+ if (emulator_has_longmode(ctxt)) {
+ struct desc_struct cs_desc;
+
+ /* Zero CR4.PCIDE before CR0.PG. */
+ if (cr4 & X86_CR4_PCIDE) {
+ ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
+ cr4 &= ~X86_CR4_PCIDE;
+ }
+
+ /* A 32-bit code segment is required to clear EFER.LMA. */
+ memset(&cs_desc, 0, sizeof(cs_desc));
+ cs_desc.type = 0xb;
+ cs_desc.s = cs_desc.g = cs_desc.p = 1;
+ ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
+ }
+
+ /* For the 64-bit case, this will clear EFER.LMA. */
cr0 = ctxt->ops->get_cr(ctxt, 0);
if (cr0 & X86_CR0_PE)
ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
- cr4 = ctxt->ops->get_cr(ctxt, 4);
+
+ /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
if (cr4 & X86_CR4_PAE)
ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
+
+ /* And finally go back to 32-bit mode. */
efer = 0;
ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
@@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
/* 0xA8 - 0xAF */
I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
- II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
+ II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
--
1.8.3.1
On 11/03/15 14:29, Paolo Bonzini wrote:
> The SDM says that exiting system management mode from 64-bit mode
> is invalid, but that would be too good to be true. But actually,
> most of the code is already there to support exiting from compat
> mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
> mode to real mode only requires clearing CS.L and CR4.PCIDE.
>
> Cc: [email protected]
> Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
> Cc: Laszlo Ersek <[email protected]>
> Cc: Radim Krčmář <[email protected]>
> Signed-off-by: Paolo Bonzini <[email protected]>
> ---
> arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
> 1 file changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index b60fed56671b..1505587d06e9 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
>
> /*
> * Get back to real mode, to prepare a safe state in which to load
> - * CR0/CR3/CR4/EFER.
> - *
> - * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
> + * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
> + * supports long mode.
> */
> + cr4 = ctxt->ops->get_cr(ctxt, 4);
> + if (emulator_has_longmode(ctxt)) {
> + struct desc_struct cs_desc;
> +
> + /* Zero CR4.PCIDE before CR0.PG. */
> + if (cr4 & X86_CR4_PCIDE) {
> + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
> + cr4 &= ~X86_CR4_PCIDE;
> + }
> +
> + /* A 32-bit code segment is required to clear EFER.LMA. */
> + memset(&cs_desc, 0, sizeof(cs_desc));
> + cs_desc.type = 0xb;
> + cs_desc.s = cs_desc.g = cs_desc.p = 1;
> + ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
> + }
> +
> + /* For the 64-bit case, this will clear EFER.LMA. */
> cr0 = ctxt->ops->get_cr(ctxt, 0);
> if (cr0 & X86_CR0_PE)
> ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
> - cr4 = ctxt->ops->get_cr(ctxt, 4);
> +
> + /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
> if (cr4 & X86_CR4_PAE)
> ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
> +
> + /* And finally go back to 32-bit mode. */
> efer = 0;
> ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
>
> @@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
> F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
> /* 0xA8 - 0xAF */
> I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
> - II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
> + II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
> F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
> F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
> F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
>
What branch should I test this on top of?
Thank you!
Laszlo
On 03/11/2015 14:40, Laszlo Ersek wrote:
> On 11/03/15 14:29, Paolo Bonzini wrote:
>> The SDM says that exiting system management mode from 64-bit mode
>> is invalid, but that would be too good to be true. But actually,
>> most of the code is already there to support exiting from compat
>> mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
>> mode to real mode only requires clearing CS.L and CR4.PCIDE.
>>
>> Cc: [email protected]
>> Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
>> Cc: Laszlo Ersek <[email protected]>
>> Cc: Radim Krčmář <[email protected]>
>> Signed-off-by: Paolo Bonzini <[email protected]>
>> ---
>> arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
>> 1 file changed, 25 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>> index b60fed56671b..1505587d06e9 100644
>> --- a/arch/x86/kvm/emulate.c
>> +++ b/arch/x86/kvm/emulate.c
>> @@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
>>
>> /*
>> * Get back to real mode, to prepare a safe state in which to load
>> - * CR0/CR3/CR4/EFER.
>> - *
>> - * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
>> + * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
>> + * supports long mode.
>> */
>> + cr4 = ctxt->ops->get_cr(ctxt, 4);
>> + if (emulator_has_longmode(ctxt)) {
>> + struct desc_struct cs_desc;
>> +
>> + /* Zero CR4.PCIDE before CR0.PG. */
>> + if (cr4 & X86_CR4_PCIDE) {
>> + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
>> + cr4 &= ~X86_CR4_PCIDE;
>> + }
>> +
>> + /* A 32-bit code segment is required to clear EFER.LMA. */
>> + memset(&cs_desc, 0, sizeof(cs_desc));
>> + cs_desc.type = 0xb;
>> + cs_desc.s = cs_desc.g = cs_desc.p = 1;
>> + ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
>> + }
>> +
>> + /* For the 64-bit case, this will clear EFER.LMA. */
>> cr0 = ctxt->ops->get_cr(ctxt, 0);
>> if (cr0 & X86_CR0_PE)
>> ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
>> - cr4 = ctxt->ops->get_cr(ctxt, 4);
>> +
>> + /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
>> if (cr4 & X86_CR4_PAE)
>> ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
>> +
>> + /* And finally go back to 32-bit mode. */
>> efer = 0;
>> ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
>>
>> @@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
>> F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
>> /* 0xA8 - 0xAF */
>> I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
>> - II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
>> + II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
>> F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
>> F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
>> F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
>>
>
> What branch should I test this on top of?
Just use whatever you were using before, and revert commit c9db607
("UefiCpuPkg: PiSmmCpuDxeSmm: do not execute RSM from 64-bit mode",
2015-10-14) from your OVMF branch. This is how I tested it, in fact.
Paolo
On 11/03/15 14:46, Paolo Bonzini wrote:
>
>
> On 03/11/2015 14:40, Laszlo Ersek wrote:
>> On 11/03/15 14:29, Paolo Bonzini wrote:
>>> The SDM says that exiting system management mode from 64-bit mode
>>> is invalid, but that would be too good to be true. But actually,
>>> most of the code is already there to support exiting from compat
>>> mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
>>> mode to real mode only requires clearing CS.L and CR4.PCIDE.
>>>
>>> Cc: [email protected]
>>> Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
>>> Cc: Laszlo Ersek <[email protected]>
>>> Cc: Radim Krčmář <[email protected]>
>>> Signed-off-by: Paolo Bonzini <[email protected]>
>>> ---
>>> arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
>>> 1 file changed, 25 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>>> index b60fed56671b..1505587d06e9 100644
>>> --- a/arch/x86/kvm/emulate.c
>>> +++ b/arch/x86/kvm/emulate.c
>>> @@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
>>>
>>> /*
>>> * Get back to real mode, to prepare a safe state in which to load
>>> - * CR0/CR3/CR4/EFER.
>>> - *
>>> - * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
>>> + * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
>>> + * supports long mode.
>>> */
>>> + cr4 = ctxt->ops->get_cr(ctxt, 4);
>>> + if (emulator_has_longmode(ctxt)) {
>>> + struct desc_struct cs_desc;
>>> +
>>> + /* Zero CR4.PCIDE before CR0.PG. */
>>> + if (cr4 & X86_CR4_PCIDE) {
>>> + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
>>> + cr4 &= ~X86_CR4_PCIDE;
>>> + }
>>> +
>>> + /* A 32-bit code segment is required to clear EFER.LMA. */
>>> + memset(&cs_desc, 0, sizeof(cs_desc));
>>> + cs_desc.type = 0xb;
>>> + cs_desc.s = cs_desc.g = cs_desc.p = 1;
>>> + ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
>>> + }
>>> +
>>> + /* For the 64-bit case, this will clear EFER.LMA. */
>>> cr0 = ctxt->ops->get_cr(ctxt, 0);
>>> if (cr0 & X86_CR0_PE)
>>> ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
>>> - cr4 = ctxt->ops->get_cr(ctxt, 4);
>>> +
>>> + /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
>>> if (cr4 & X86_CR4_PAE)
>>> ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
>>> +
>>> + /* And finally go back to 32-bit mode. */
>>> efer = 0;
>>> ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
>>>
>>> @@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
>>> /* 0xA8 - 0xAF */
>>> I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
>>> - II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>> + II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>> F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
>>> F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
>>>
>>
>> What branch should I test this on top of?
>
> Just use whatever you were using before, and revert commit c9db607
> ("UefiCpuPkg: PiSmmCpuDxeSmm: do not execute RSM from 64-bit mode",
> 2015-10-14) from your OVMF branch.
Right, I planned to do that OVMF-side revert; I just wasn't sure if e.g.
kvm/queue had some prerequisite patches for this.
> This is how I tested it, in fact.
I'll try to report back soon.
Thanks!
Laszlo
On 03/11/2015 15:02, Laszlo Ersek wrote:
> On 11/03/15 14:46, Paolo Bonzini wrote:
>>
>>
>> On 03/11/2015 14:40, Laszlo Ersek wrote:
>>> On 11/03/15 14:29, Paolo Bonzini wrote:
>>>> The SDM says that exiting system management mode from 64-bit mode
>>>> is invalid, but that would be too good to be true. But actually,
>>>> most of the code is already there to support exiting from compat
>>>> mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
>>>> mode to real mode only requires clearing CS.L and CR4.PCIDE.
>>>>
>>>> Cc: [email protected]
>>>> Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
>>>> Cc: Laszlo Ersek <[email protected]>
>>>> Cc: Radim Krčmář <[email protected]>
>>>> Signed-off-by: Paolo Bonzini <[email protected]>
>>>> ---
>>>> arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
>>>> 1 file changed, 25 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>>>> index b60fed56671b..1505587d06e9 100644
>>>> --- a/arch/x86/kvm/emulate.c
>>>> +++ b/arch/x86/kvm/emulate.c
>>>> @@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
>>>>
>>>> /*
>>>> * Get back to real mode, to prepare a safe state in which to load
>>>> - * CR0/CR3/CR4/EFER.
>>>> - *
>>>> - * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
>>>> + * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
>>>> + * supports long mode.
>>>> */
>>>> + cr4 = ctxt->ops->get_cr(ctxt, 4);
>>>> + if (emulator_has_longmode(ctxt)) {
>>>> + struct desc_struct cs_desc;
>>>> +
>>>> + /* Zero CR4.PCIDE before CR0.PG. */
>>>> + if (cr4 & X86_CR4_PCIDE) {
>>>> + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
>>>> + cr4 &= ~X86_CR4_PCIDE;
>>>> + }
>>>> +
>>>> + /* A 32-bit code segment is required to clear EFER.LMA. */
>>>> + memset(&cs_desc, 0, sizeof(cs_desc));
>>>> + cs_desc.type = 0xb;
>>>> + cs_desc.s = cs_desc.g = cs_desc.p = 1;
>>>> + ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
>>>> + }
>>>> +
>>>> + /* For the 64-bit case, this will clear EFER.LMA. */
>>>> cr0 = ctxt->ops->get_cr(ctxt, 0);
>>>> if (cr0 & X86_CR0_PE)
>>>> ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
>>>> - cr4 = ctxt->ops->get_cr(ctxt, 4);
>>>> +
>>>> + /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
>>>> if (cr4 & X86_CR4_PAE)
>>>> ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
>>>> +
>>>> + /* And finally go back to 32-bit mode. */
>>>> efer = 0;
>>>> ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
>>>>
>>>> @@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
>>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
>>>> /* 0xA8 - 0xAF */
>>>> I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
>>>> - II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>>> + II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>>> F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
>>>> F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
>>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
>>>>
>>>
>>> What branch should I test this on top of?
>>
>> Just use whatever you were using before, and revert commit c9db607
>> ("UefiCpuPkg: PiSmmCpuDxeSmm: do not execute RSM from 64-bit mode",
>> 2015-10-14) from your OVMF branch.
>
> Right, I planned to do that OVMF-side revert; I just wasn't sure if e.g.
> kvm/queue had some prerequisite patches for this.
Indeed, you can use either your "part 2" series or Radim's patches from
kvm/queue, it's the same.
Paolo
On 11/03/15 15:04, Paolo Bonzini wrote:
>
>
> On 03/11/2015 15:02, Laszlo Ersek wrote:
>> On 11/03/15 14:46, Paolo Bonzini wrote:
>>>
>>>
>>> On 03/11/2015 14:40, Laszlo Ersek wrote:
>>>> On 11/03/15 14:29, Paolo Bonzini wrote:
>>>>> The SDM says that exiting system management mode from 64-bit mode
>>>>> is invalid, but that would be too good to be true. But actually,
>>>>> most of the code is already there to support exiting from compat
>>>>> mode (EFER.LME=1, EFER.LMA=0). Getting all the way from 64-bit
>>>>> mode to real mode only requires clearing CS.L and CR4.PCIDE.
>>>>>
>>>>> Cc: [email protected]
>>>>> Fixes: 660a5d517aaab9187f93854425c4c63f4a09195c
>>>>> Cc: Laszlo Ersek <[email protected]>
>>>>> Cc: Radim Krčmář <[email protected]>
>>>>> Signed-off-by: Paolo Bonzini <[email protected]>
>>>>> ---
>>>>> arch/x86/kvm/emulate.c | 30 +++++++++++++++++++++++++-----
>>>>> 1 file changed, 25 insertions(+), 5 deletions(-)
>>>>>
>>>>> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
>>>>> index b60fed56671b..1505587d06e9 100644
>>>>> --- a/arch/x86/kvm/emulate.c
>>>>> +++ b/arch/x86/kvm/emulate.c
>>>>> @@ -2484,16 +2484,36 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt)
>>>>>
>>>>> /*
>>>>> * Get back to real mode, to prepare a safe state in which to load
>>>>> - * CR0/CR3/CR4/EFER.
>>>>> - *
>>>>> - * CR4.PCIDE must be zero, because it is a 64-bit mode only feature.
>>>>> + * CR0/CR3/CR4/EFER. It's all a bit more complicated if the vCPU
>>>>> + * supports long mode.
>>>>> */
>>>>> + cr4 = ctxt->ops->get_cr(ctxt, 4);
>>>>> + if (emulator_has_longmode(ctxt)) {
>>>>> + struct desc_struct cs_desc;
>>>>> +
>>>>> + /* Zero CR4.PCIDE before CR0.PG. */
>>>>> + if (cr4 & X86_CR4_PCIDE) {
>>>>> + ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PCIDE);
>>>>> + cr4 &= ~X86_CR4_PCIDE;
>>>>> + }
>>>>> +
>>>>> + /* A 32-bit code segment is required to clear EFER.LMA. */
>>>>> + memset(&cs_desc, 0, sizeof(cs_desc));
>>>>> + cs_desc.type = 0xb;
>>>>> + cs_desc.s = cs_desc.g = cs_desc.p = 1;
>>>>> + ctxt->ops->set_segment(ctxt, 0, &cs_desc, 0, VCPU_SREG_CS);
>>>>> + }
>>>>> +
>>>>> + /* For the 64-bit case, this will clear EFER.LMA. */
>>>>> cr0 = ctxt->ops->get_cr(ctxt, 0);
>>>>> if (cr0 & X86_CR0_PE)
>>>>> ctxt->ops->set_cr(ctxt, 0, cr0 & ~(X86_CR0_PG | X86_CR0_PE));
>>>>> - cr4 = ctxt->ops->get_cr(ctxt, 4);
>>>>> +
>>>>> + /* Now clear CR4.PAE (which must be done before clearing EFER.LME). */
>>>>> if (cr4 & X86_CR4_PAE)
>>>>> ctxt->ops->set_cr(ctxt, 4, cr4 & ~X86_CR4_PAE);
>>>>> +
>>>>> + /* And finally go back to 32-bit mode. */
>>>>> efer = 0;
>>>>> ctxt->ops->set_msr(ctxt, MSR_EFER, efer);
>>>>>
>>>>> @@ -4454,7 +4474,7 @@ static const struct opcode twobyte_table[256] = {
>>>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shld), N, N,
>>>>> /* 0xA8 - 0xAF */
>>>>> I(Stack | Src2GS, em_push_sreg), I(Stack | Src2GS, em_pop_sreg),
>>>>> - II(No64 | EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>>>> + II(EmulateOnUD | ImplicitOps, em_rsm, rsm),
>>>>> F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts),
>>>>> F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd),
>>>>> F(DstMem | SrcReg | Src2CL | ModRM, em_shrd),
>>>>>
>>>>
>>>> What branch should I test this on top of?
>>>
>>> Just use whatever you were using before, and revert commit c9db607
>>> ("UefiCpuPkg: PiSmmCpuDxeSmm: do not execute RSM from 64-bit mode",
>>> 2015-10-14) from your OVMF branch.
>>
>> Right, I planned to do that OVMF-side revert; I just wasn't sure if e.g.
>> kvm/queue had some prerequisite patches for this.
>
> Indeed, you can use either your "part 2" series or Radim's patches from
> kvm/queue, it's the same.
I noticed that you applied this patch to kvm/queue, at
9f64d2c75fa6a5aac0a5657400f3473f8144c3be. So I simply tested kvm/queue
in that state. (I did not forget to drop the workaround OVMF patch first.)
Tested-by: Laszlo Ersek <[email protected]>
Thank you!
Laszlo