Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-19 Thread Nadav Amit
Radim Krčmář  wrote:

> 2017-07-19 13:34+0800, Wanpeng Li:
>> Ping, :)
> 
> I misunderstood where the ball is ... is the patch below ok?
> 
> ---8<---
> This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it
> tries to emulate invalid guest state task-switch:
> 
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> 
> It appears that the task-switch emulation updates rflags (and vm86 flag)
> only after the segments are loaded, causing vmx->emulation_required to
> be set, when in fact invalid guest state emulation is not needed.
> 
> This patch fixes it by updating vmx->emulation_required after the rflags
> (and vm86 flag) is updated.
> 
> Suggested-by: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> [Wanpeng wrote the commit message with initial patch and Radim moved the
> update to vmx_set_rflags and added Paolo's suggestion for the check.]
> Signed-off-by: Radim Krčmář 
> ---
> arch/x86/kvm/vmx.c | 15 ++-
> 1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 84e62acf2dd8..a776aea0043a 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2326,6 +2326,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
>   __vmx_load_host_state(to_vmx(vcpu));
> }
> 
> +static bool emulation_required(struct kvm_vcpu *vcpu)
> +{
> + return emulate_invalid_guest_state && !guest_state_valid(vcpu);
> +}
> +
> static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
> 
> /*
> @@ -2363,6 +2368,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu 
> *vcpu)
> 
> static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
> {
> + unsigned long old_rflags = to_vmx(vcpu)->rflags;

It assumes rflags was decached from the VMCS before. Probably it is true, but…




Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-19 Thread Nadav Amit
Radim Krčmář  wrote:

> 2017-07-19 13:34+0800, Wanpeng Li:
>> Ping, :)
> 
> I misunderstood where the ball is ... is the patch below ok?
> 
> ---8<---
> This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it
> tries to emulate invalid guest state task-switch:
> 
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> 
> It appears that the task-switch emulation updates rflags (and vm86 flag)
> only after the segments are loaded, causing vmx->emulation_required to
> be set, when in fact invalid guest state emulation is not needed.
> 
> This patch fixes it by updating vmx->emulation_required after the rflags
> (and vm86 flag) is updated.
> 
> Suggested-by: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> [Wanpeng wrote the commit message with initial patch and Radim moved the
> update to vmx_set_rflags and added Paolo's suggestion for the check.]
> Signed-off-by: Radim Krčmář 
> ---
> arch/x86/kvm/vmx.c | 15 ++-
> 1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 84e62acf2dd8..a776aea0043a 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -2326,6 +2326,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
>   __vmx_load_host_state(to_vmx(vcpu));
> }
> 
> +static bool emulation_required(struct kvm_vcpu *vcpu)
> +{
> + return emulate_invalid_guest_state && !guest_state_valid(vcpu);
> +}
> +
> static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
> 
> /*
> @@ -2363,6 +2368,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu 
> *vcpu)
> 
> static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
> {
> + unsigned long old_rflags = to_vmx(vcpu)->rflags;

It assumes rflags was decached from the VMCS before. Probably it is true, but…




[PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-19 Thread Radim Krčmář
2017-07-19 13:34+0800, Wanpeng Li:
> Ping, :)

I misunderstood where the ball is ... is the patch below ok?

---8<---
This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it
tries to emulate invalid guest state task-switch:

kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
kvm_entry: vcpu 0
kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)

It appears that the task-switch emulation updates rflags (and vm86 flag)
only after the segments are loaded, causing vmx->emulation_required to
be set, when in fact invalid guest state emulation is not needed.

This patch fixes it by updating vmx->emulation_required after the rflags
(and vm86 flag) is updated.

Suggested-by: Nadav Amit 
Signed-off-by: Wanpeng Li 
[Wanpeng wrote the commit message with initial patch and Radim moved the
 update to vmx_set_rflags and added Paolo's suggestion for the check.]
Signed-off-by: Radim Krčmář 
---
 arch/x86/kvm/vmx.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 84e62acf2dd8..a776aea0043a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2326,6 +2326,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
__vmx_load_host_state(to_vmx(vcpu));
 }
 
+static bool emulation_required(struct kvm_vcpu *vcpu)
+{
+   return emulate_invalid_guest_state && !guest_state_valid(vcpu);
+}
+
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
 
 /*
@@ -2363,6 +2368,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+   unsigned long old_rflags = to_vmx(vcpu)->rflags;
+
__set_bit(VCPU_EXREG_RFLAGS, (ulong *)>arch.regs_avail);
to_vmx(vcpu)->rflags = rflags;
if (to_vmx(vcpu)->rmode.vm86_active) {
@@ -2370,6 +2377,9 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, 
unsigned long rflags)
rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
}
vmcs_writel(GUEST_RFLAGS, rflags);
+
+   if ((old_rflags ^ rflags) & X86_EFLAGS_VM)
+   to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
 }
 
 static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
@@ -3857,11 +3867,6 @@ static __init int alloc_kvm_area(void)
return 0;
 }
 
-static bool emulation_required(struct kvm_vcpu *vcpu)
-{
-   return emulate_invalid_guest_state && !guest_state_valid(vcpu);
-}
-
 static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
struct kvm_segment *save)
 {
-- 
2.13.2




[PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-19 Thread Radim Krčmář
2017-07-19 13:34+0800, Wanpeng Li:
> Ping, :)

I misunderstood where the ball is ... is the patch below ok?

---8<---
This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it
tries to emulate invalid guest state task-switch:

kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
kvm_entry: vcpu 0
kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)

It appears that the task-switch emulation updates rflags (and vm86 flag)
only after the segments are loaded, causing vmx->emulation_required to
be set, when in fact invalid guest state emulation is not needed.

This patch fixes it by updating vmx->emulation_required after the rflags
(and vm86 flag) is updated.

Suggested-by: Nadav Amit 
Signed-off-by: Wanpeng Li 
[Wanpeng wrote the commit message with initial patch and Radim moved the
 update to vmx_set_rflags and added Paolo's suggestion for the check.]
Signed-off-by: Radim Krčmář 
---
 arch/x86/kvm/vmx.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 84e62acf2dd8..a776aea0043a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2326,6 +2326,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
__vmx_load_host_state(to_vmx(vcpu));
 }
 
+static bool emulation_required(struct kvm_vcpu *vcpu)
+{
+   return emulate_invalid_guest_state && !guest_state_valid(vcpu);
+}
+
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
 
 /*
@@ -2363,6 +2368,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+   unsigned long old_rflags = to_vmx(vcpu)->rflags;
+
__set_bit(VCPU_EXREG_RFLAGS, (ulong *)>arch.regs_avail);
to_vmx(vcpu)->rflags = rflags;
if (to_vmx(vcpu)->rmode.vm86_active) {
@@ -2370,6 +2377,9 @@ static void vmx_set_rflags(struct kvm_vcpu *vcpu, 
unsigned long rflags)
rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
}
vmcs_writel(GUEST_RFLAGS, rflags);
+
+   if ((old_rflags ^ rflags) & X86_EFLAGS_VM)
+   to_vmx(vcpu)->emulation_required = emulation_required(vcpu);
 }
 
 static u32 vmx_get_pkru(struct kvm_vcpu *vcpu)
@@ -3857,11 +3867,6 @@ static __init int alloc_kvm_area(void)
return 0;
 }
 
-static bool emulation_required(struct kvm_vcpu *vcpu)
-{
-   return emulate_invalid_guest_state && !guest_state_valid(vcpu);
-}
-
 static void fix_pmode_seg(struct kvm_vcpu *vcpu, int seg,
struct kvm_segment *save)
 {
-- 
2.13.2




Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-18 Thread Wanpeng Li
Ping, :)
2017-07-11 15:13 GMT+08:00 Wanpeng Li :
> From: Wanpeng Li 
>
> This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it tries
> to emulate invalid guest state task-switch:
>
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> ..
>
> It appears that the task-switch emulation updates rflags (and vm86
> flag) only after the segments are loaded, causing vmx->emulation_required
> to be set, when in fact invalid guest state emulation is not needed.
>
> This patch fixes it by updating vmx->emulation_required after the
> rflags (and vm86 flag) is updated in task-switch emulation.
>
> Suggested-by: Nadav Amit 
> Cc: Paolo Bonzini 
> Cc: Radim Krčmář 
> Cc: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> ---
>  arch/x86/kvm/vmx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index f50cbfd..70270a2 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>  * TODO: What about debug traps on tss switch?
>  *   Are we supposed to inject them and update dr6?
>  */
> +   vmx->emulation_required = emulation_required(vcpu);
>
> return 1;
>  }
> --
> 2.7.4
>


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-18 Thread Wanpeng Li
Ping, :)
2017-07-11 15:13 GMT+08:00 Wanpeng Li :
> From: Wanpeng Li 
>
> This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it tries
> to emulate invalid guest state task-switch:
>
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> ..
>
> It appears that the task-switch emulation updates rflags (and vm86
> flag) only after the segments are loaded, causing vmx->emulation_required
> to be set, when in fact invalid guest state emulation is not needed.
>
> This patch fixes it by updating vmx->emulation_required after the
> rflags (and vm86 flag) is updated in task-switch emulation.
>
> Suggested-by: Nadav Amit 
> Cc: Paolo Bonzini 
> Cc: Radim Krčmář 
> Cc: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> ---
>  arch/x86/kvm/vmx.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index f50cbfd..70270a2 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>  * TODO: What about debug traps on tss switch?
>  *   Are we supposed to inject them and update dr6?
>  */
> +   vmx->emulation_required = emulation_required(vcpu);
>
> return 1;
>  }
> --
> 2.7.4
>


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-12 Thread Wanpeng Li
2017-07-12 0:09 GMT+08:00 Paolo Bonzini :
> On 11/07/2017 17:54, Radim Krčmář wrote:
>> 2017-07-11 00:13-0700, Wanpeng Li:
>>> From: Wanpeng Li 
>>>
>>> This can be reproduced by EPT=1, unrestricted_guest=N, 
>>> emulate_invalid_state=Y
>>> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
>>> tries
>>> to emulate invalid guest state task-switch:
>>>
>>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>>> kvm_inj_exception: #UD (0x0)
>>> kvm_entry: vcpu 0
>>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>>> kvm_inj_exception: #UD (0x0)
>>> ..
>>>
>>> It appears that the task-switch emulation updates rflags (and vm86
>>> flag) only after the segments are loaded, causing vmx->emulation_required
>>> to be set, when in fact invalid guest state emulation is not needed.
>>>
>>> This patch fixes it by updating vmx->emulation_required after the
>>> rflags (and vm86 flag) is updated in task-switch emulation.
>>>
>>> Suggested-by: Nadav Amit 
>>> Cc: Paolo Bonzini 
>>> Cc: Radim Krčmář 
>>> Cc: Nadav Amit 
>>> Signed-off-by: Wanpeng Li 
>>> ---
>>>  arch/x86/kvm/vmx.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>>> index f50cbfd..70270a2 100644
>>> --- a/arch/x86/kvm/vmx.c
>>> +++ b/arch/x86/kvm/vmx.c
>>> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>>>   * TODO: What about debug traps on tss switch?
>>>   *   Are we supposed to inject them and update dr6?
>>>   */
>>> +vmx->emulation_required = emulation_required(vcpu);
>>
>> Hm, so the problem happened because changes to rflags can flip the value
>> of emulation_required().  I would add this line to vmx_set_rflags() to
>> make sure that we fixed everything, thanks.
>
> Note that there is some extra complication, because emulation_required
> is expensive and you'll want to run it only when EFLAGS.VM changes.

Agreed.

Regards,
Wanpeng Li


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-12 Thread Wanpeng Li
2017-07-12 0:09 GMT+08:00 Paolo Bonzini :
> On 11/07/2017 17:54, Radim Krčmář wrote:
>> 2017-07-11 00:13-0700, Wanpeng Li:
>>> From: Wanpeng Li 
>>>
>>> This can be reproduced by EPT=1, unrestricted_guest=N, 
>>> emulate_invalid_state=Y
>>> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
>>> tries
>>> to emulate invalid guest state task-switch:
>>>
>>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>>> kvm_inj_exception: #UD (0x0)
>>> kvm_entry: vcpu 0
>>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>>> kvm_inj_exception: #UD (0x0)
>>> ..
>>>
>>> It appears that the task-switch emulation updates rflags (and vm86
>>> flag) only after the segments are loaded, causing vmx->emulation_required
>>> to be set, when in fact invalid guest state emulation is not needed.
>>>
>>> This patch fixes it by updating vmx->emulation_required after the
>>> rflags (and vm86 flag) is updated in task-switch emulation.
>>>
>>> Suggested-by: Nadav Amit 
>>> Cc: Paolo Bonzini 
>>> Cc: Radim Krčmář 
>>> Cc: Nadav Amit 
>>> Signed-off-by: Wanpeng Li 
>>> ---
>>>  arch/x86/kvm/vmx.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>>> index f50cbfd..70270a2 100644
>>> --- a/arch/x86/kvm/vmx.c
>>> +++ b/arch/x86/kvm/vmx.c
>>> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>>>   * TODO: What about debug traps on tss switch?
>>>   *   Are we supposed to inject them and update dr6?
>>>   */
>>> +vmx->emulation_required = emulation_required(vcpu);
>>
>> Hm, so the problem happened because changes to rflags can flip the value
>> of emulation_required().  I would add this line to vmx_set_rflags() to
>> make sure that we fixed everything, thanks.
>
> Note that there is some extra complication, because emulation_required
> is expensive and you'll want to run it only when EFLAGS.VM changes.

Agreed.

Regards,
Wanpeng Li


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Paolo Bonzini
On 11/07/2017 17:54, Radim Krčmář wrote:
> 2017-07-11 00:13-0700, Wanpeng Li:
>> From: Wanpeng Li 
>>
>> This can be reproduced by EPT=1, unrestricted_guest=N, 
>> emulate_invalid_state=Y 
>> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
>> tries 
>> to emulate invalid guest state task-switch:
>>
>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>> kvm_inj_exception: #UD (0x0)
>> kvm_entry: vcpu 0
>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>> kvm_inj_exception: #UD (0x0)
>> ..
>>
>> It appears that the task-switch emulation updates rflags (and vm86 
>> flag) only after the segments are loaded, causing vmx->emulation_required 
>> to be set, when in fact invalid guest state emulation is not needed.
>>
>> This patch fixes it by updating vmx->emulation_required after the 
>> rflags (and vm86 flag) is updated in task-switch emulation.
>>
>> Suggested-by: Nadav Amit 
>> Cc: Paolo Bonzini 
>> Cc: Radim Krčmář 
>> Cc: Nadav Amit 
>> Signed-off-by: Wanpeng Li 
>> ---
>>  arch/x86/kvm/vmx.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index f50cbfd..70270a2 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>>   * TODO: What about debug traps on tss switch?
>>   *   Are we supposed to inject them and update dr6?
>>   */
>> +vmx->emulation_required = emulation_required(vcpu);
> 
> Hm, so the problem happened because changes to rflags can flip the value
> of emulation_required().  I would add this line to vmx_set_rflags() to
> make sure that we fixed everything, thanks.

Note that there is some extra complication, because emulation_required
is expensive and you'll want to run it only when EFLAGS.VM changes.

Paolo


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Paolo Bonzini
On 11/07/2017 17:54, Radim Krčmář wrote:
> 2017-07-11 00:13-0700, Wanpeng Li:
>> From: Wanpeng Li 
>>
>> This can be reproduced by EPT=1, unrestricted_guest=N, 
>> emulate_invalid_state=Y 
>> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
>> tries 
>> to emulate invalid guest state task-switch:
>>
>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>> kvm_inj_exception: #UD (0x0)
>> kvm_entry: vcpu 0
>> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
>> kvm_emulate_insn: 42000:0:0f 0b (0x2)
>> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
>> kvm_inj_exception: #UD (0x0)
>> ..
>>
>> It appears that the task-switch emulation updates rflags (and vm86 
>> flag) only after the segments are loaded, causing vmx->emulation_required 
>> to be set, when in fact invalid guest state emulation is not needed.
>>
>> This patch fixes it by updating vmx->emulation_required after the 
>> rflags (and vm86 flag) is updated in task-switch emulation.
>>
>> Suggested-by: Nadav Amit 
>> Cc: Paolo Bonzini 
>> Cc: Radim Krčmář 
>> Cc: Nadav Amit 
>> Signed-off-by: Wanpeng Li 
>> ---
>>  arch/x86/kvm/vmx.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
>> index f50cbfd..70270a2 100644
>> --- a/arch/x86/kvm/vmx.c
>> +++ b/arch/x86/kvm/vmx.c
>> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>>   * TODO: What about debug traps on tss switch?
>>   *   Are we supposed to inject them and update dr6?
>>   */
>> +vmx->emulation_required = emulation_required(vcpu);
> 
> Hm, so the problem happened because changes to rflags can flip the value
> of emulation_required().  I would add this line to vmx_set_rflags() to
> make sure that we fixed everything, thanks.

Note that there is some extra complication, because emulation_required
is expensive and you'll want to run it only when EFLAGS.VM changes.

Paolo


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Radim Krčmář
2017-07-11 00:13-0700, Wanpeng Li:
> From: Wanpeng Li 
> 
> This can be reproduced by EPT=1, unrestricted_guest=N, 
> emulate_invalid_state=Y 
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
> tries 
> to emulate invalid guest state task-switch:
> 
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> ..
> 
> It appears that the task-switch emulation updates rflags (and vm86 
> flag) only after the segments are loaded, causing vmx->emulation_required 
> to be set, when in fact invalid guest state emulation is not needed.
> 
> This patch fixes it by updating vmx->emulation_required after the 
> rflags (and vm86 flag) is updated in task-switch emulation.
> 
> Suggested-by: Nadav Amit 
> Cc: Paolo Bonzini 
> Cc: Radim Krčmář 
> Cc: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> ---
>  arch/x86/kvm/vmx.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index f50cbfd..70270a2 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>* TODO: What about debug traps on tss switch?
>*   Are we supposed to inject them and update dr6?
>*/
> + vmx->emulation_required = emulation_required(vcpu);

Hm, so the problem happened because changes to rflags can flip the value
of emulation_required().  I would add this line to vmx_set_rflags() to
make sure that we fixed everything, thanks.


Re: [PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Radim Krčmář
2017-07-11 00:13-0700, Wanpeng Li:
> From: Wanpeng Li 
> 
> This can be reproduced by EPT=1, unrestricted_guest=N, 
> emulate_invalid_state=Y 
> or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it 
> tries 
> to emulate invalid guest state task-switch:
> 
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> kvm_entry: vcpu 0
> kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
> kvm_emulate_insn: 42000:0:0f 0b (0x2)
> kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
> kvm_inj_exception: #UD (0x0)
> ..
> 
> It appears that the task-switch emulation updates rflags (and vm86 
> flag) only after the segments are loaded, causing vmx->emulation_required 
> to be set, when in fact invalid guest state emulation is not needed.
> 
> This patch fixes it by updating vmx->emulation_required after the 
> rflags (and vm86 flag) is updated in task-switch emulation.
> 
> Suggested-by: Nadav Amit 
> Cc: Paolo Bonzini 
> Cc: Radim Krčmář 
> Cc: Nadav Amit 
> Signed-off-by: Wanpeng Li 
> ---
>  arch/x86/kvm/vmx.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index f50cbfd..70270a2 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
>* TODO: What about debug traps on tss switch?
>*   Are we supposed to inject them and update dr6?
>*/
> + vmx->emulation_required = emulation_required(vcpu);

Hm, so the problem happened because changes to rflags can flip the value
of emulation_required().  I would add this line to vmx_set_rflags() to
make sure that we fixed everything, thanks.


[PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Wanpeng Li
From: Wanpeng Li 

This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y 
or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it tries 
to emulate invalid guest state task-switch:

kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
kvm_entry: vcpu 0
kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
..

It appears that the task-switch emulation updates rflags (and vm86 
flag) only after the segments are loaded, causing vmx->emulation_required 
to be set, when in fact invalid guest state emulation is not needed.

This patch fixes it by updating vmx->emulation_required after the 
rflags (and vm86 flag) is updated in task-switch emulation.

Suggested-by: Nadav Amit 
Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Cc: Nadav Amit 
Signed-off-by: Wanpeng Li 
---
 arch/x86/kvm/vmx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f50cbfd..70270a2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
 * TODO: What about debug traps on tss switch?
 *   Are we supposed to inject them and update dr6?
 */
+   vmx->emulation_required = emulation_required(vcpu);
 
return 1;
 }
-- 
2.7.4



[PATCH] KVM: VMX: Fix invalid guest state detection after task-switch emulation

2017-07-11 Thread Wanpeng Li
From: Wanpeng Li 

This can be reproduced by EPT=1, unrestricted_guest=N, emulate_invalid_state=Y 
or EPT=0, the trace of kvm-unit-tests/taskswitch2.flat is like below, it tries 
to emulate invalid guest state task-switch:

kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
kvm_entry: vcpu 0
kvm_exit: reason TASK_SWITCH rip 0x0 info 4058 0
kvm_emulate_insn: 42000:0:0f 0b (0x2)
kvm_emulate_insn: 42000:0:0f 0b (0x2) failed
kvm_inj_exception: #UD (0x0)
..

It appears that the task-switch emulation updates rflags (and vm86 
flag) only after the segments are loaded, causing vmx->emulation_required 
to be set, when in fact invalid guest state emulation is not needed.

This patch fixes it by updating vmx->emulation_required after the 
rflags (and vm86 flag) is updated in task-switch emulation.

Suggested-by: Nadav Amit 
Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Cc: Nadav Amit 
Signed-off-by: Wanpeng Li 
---
 arch/x86/kvm/vmx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f50cbfd..70270a2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6255,6 +6255,7 @@ static int handle_task_switch(struct kvm_vcpu *vcpu)
 * TODO: What about debug traps on tss switch?
 *   Are we supposed to inject them and update dr6?
 */
+   vmx->emulation_required = emulation_required(vcpu);
 
return 1;
 }
-- 
2.7.4