Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Alexander Graf

On 22.04.2010, at 12:33, Joerg Roedel wrote:

 The patch introducing nested nmi handling had a bug. The
 check does not belong to enable_nmi_window but must be in
 nmi_allowed. This patch fixes this.
 
 Signed-off-by: Joerg Roedel joerg.roe...@amd.com
 ---
 arch/x86/kvm/svm.c |   16 +---
 1 files changed, 9 insertions(+), 7 deletions(-)
 
 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
 index ab78eb8..ec20584 100644
 --- a/arch/x86/kvm/svm.c
 +++ b/arch/x86/kvm/svm.c
 @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
 {
   struct vcpu_svm *svm = to_svm(vcpu);
   struct vmcb *vmcb = svm-vmcb;
 - return !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 - !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 + int ret;
 + ret = !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 +   !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 + ret = ret  gif_set(svm)  nested_svm_nmi(svm);
 +
 + return ret;
 }
 
 static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
 @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
* Something prevents NMI from been injected. Single step over possible
* problem (IRET or exception injection or interrupt shadow)
*/
 - if (gif_set(svm)  nested_svm_nmi(svm)) {
 - svm-nmi_singlestep = true;
 - svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 - update_db_intercept(vcpu);
 - }
 + svm-nmi_singlestep = true;
 + svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 + update_db_intercept(vcpu);

So we're always messing with the nested guest state when the host wants to 
inject an nmi into the l1 guest? Is that safe?


Alex

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Joerg Roedel
On Fri, Apr 23, 2010 at 03:46:07PM +0200, Alexander Graf wrote:
 
 On 22.04.2010, at 12:33, Joerg Roedel wrote:
 
  The patch introducing nested nmi handling had a bug. The
  check does not belong to enable_nmi_window but must be in
  nmi_allowed. This patch fixes this.
  
  Signed-off-by: Joerg Roedel joerg.roe...@amd.com
  ---
  arch/x86/kvm/svm.c |   16 +---
  1 files changed, 9 insertions(+), 7 deletions(-)
  
  diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
  index ab78eb8..ec20584 100644
  --- a/arch/x86/kvm/svm.c
  +++ b/arch/x86/kvm/svm.c
  @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
  {
  struct vcpu_svm *svm = to_svm(vcpu);
  struct vmcb *vmcb = svm-vmcb;
  -   return !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
  -   !(svm-vcpu.arch.hflags  HF_NMI_MASK);
  +   int ret;
  +   ret = !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
  + !(svm-vcpu.arch.hflags  HF_NMI_MASK);
  +   ret = ret  gif_set(svm)  nested_svm_nmi(svm);
  +
  +   return ret;
  }
  
  static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
  @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
   * Something prevents NMI from been injected. Single step over possible
   * problem (IRET or exception injection or interrupt shadow)
   */
  -   if (gif_set(svm)  nested_svm_nmi(svm)) {
  -   svm-nmi_singlestep = true;
  -   svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
  -   update_db_intercept(vcpu);
  -   }
  +   svm-nmi_singlestep = true;
  +   svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
  +   update_db_intercept(vcpu);
 
 So we're always messing with the nested guest state when the host
 wants to inject an nmi into the l1 guest? Is that safe?

Why not? We can't inject an NMI directly into L2 if the nested
hypervisor intercepts it.

Joerg


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Alexander Graf

On 23.04.2010, at 16:13, Joerg Roedel wrote:

 On Fri, Apr 23, 2010 at 03:46:07PM +0200, Alexander Graf wrote:
 
 On 22.04.2010, at 12:33, Joerg Roedel wrote:
 
 The patch introducing nested nmi handling had a bug. The
 check does not belong to enable_nmi_window but must be in
 nmi_allowed. This patch fixes this.
 
 Signed-off-by: Joerg Roedel joerg.roe...@amd.com
 ---
 arch/x86/kvm/svm.c |   16 +---
 1 files changed, 9 insertions(+), 7 deletions(-)
 
 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
 index ab78eb8..ec20584 100644
 --- a/arch/x86/kvm/svm.c
 +++ b/arch/x86/kvm/svm.c
 @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
 {
 struct vcpu_svm *svm = to_svm(vcpu);
 struct vmcb *vmcb = svm-vmcb;
 -   return !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 -   !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 +   int ret;
 +   ret = !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 + !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 +   ret = ret  gif_set(svm)  nested_svm_nmi(svm);
 +
 +   return ret;
 }
 
 static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
 @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
  * Something prevents NMI from been injected. Single step over possible
  * problem (IRET or exception injection or interrupt shadow)
  */
 -   if (gif_set(svm)  nested_svm_nmi(svm)) {
 -   svm-nmi_singlestep = true;
 -   svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 -   update_db_intercept(vcpu);
 -   }
 +   svm-nmi_singlestep = true;
 +   svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 +   update_db_intercept(vcpu);
 
 So we're always messing with the nested guest state when the host
 wants to inject an nmi into the l1 guest? Is that safe?
 
 Why not? We can't inject an NMI directly into L2 if the nested
 hypervisor intercepts it.

So where did the code go that does the #vmexit in case the nested hypervisor 
does intercept it? It used to be nested_svm_nmi(), right?


Alex

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Joerg Roedel
On Fri, Apr 23, 2010 at 04:19:40PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:13, Joerg Roedel wrote:
 
  On Fri, Apr 23, 2010 at 03:46:07PM +0200, Alexander Graf wrote:
  
  On 22.04.2010, at 12:33, Joerg Roedel wrote:
  
  The patch introducing nested nmi handling had a bug. The
  check does not belong to enable_nmi_window but must be in
  nmi_allowed. This patch fixes this.
  
  Signed-off-by: Joerg Roedel joerg.roe...@amd.com
  ---
  arch/x86/kvm/svm.c |   16 +---
  1 files changed, 9 insertions(+), 7 deletions(-)
  
  diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
  index ab78eb8..ec20584 100644
  --- a/arch/x86/kvm/svm.c
  +++ b/arch/x86/kvm/svm.c
  @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
  {
struct vcpu_svm *svm = to_svm(vcpu);
struct vmcb *vmcb = svm-vmcb;
  - return !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
  - !(svm-vcpu.arch.hflags  HF_NMI_MASK);
  + int ret;
  + ret = !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
  +   !(svm-vcpu.arch.hflags  HF_NMI_MASK);
  + ret = ret  gif_set(svm)  nested_svm_nmi(svm);
  +
  + return ret;
  }
  
  static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
  @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu 
  *vcpu)
 * Something prevents NMI from been injected. Single step over possible
 * problem (IRET or exception injection or interrupt shadow)
 */
  - if (gif_set(svm)  nested_svm_nmi(svm)) {
  - svm-nmi_singlestep = true;
  - svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
  - update_db_intercept(vcpu);
  - }
  + svm-nmi_singlestep = true;
  + svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
  + update_db_intercept(vcpu);
  
  So we're always messing with the nested guest state when the host
  wants to inject an nmi into the l1 guest? Is that safe?
  
  Why not? We can't inject an NMI directly into L2 if the nested
  hypervisor intercepts it.
 
 So where did the code go that does the #vmexit in case the nested
 hypervisor does intercept it? It used to be nested_svm_nmi(), right?

No, nested_svm_nmi runs in atomic context where we can't emulate a
vmexit. We set exit_required and emulate the vmexit later.

Joerg


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Alexander Graf

On 23.04.2010, at 16:22, Joerg Roedel wrote:

 On Fri, Apr 23, 2010 at 04:19:40PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:13, Joerg Roedel wrote:
 
 On Fri, Apr 23, 2010 at 03:46:07PM +0200, Alexander Graf wrote:
 
 On 22.04.2010, at 12:33, Joerg Roedel wrote:
 
 The patch introducing nested nmi handling had a bug. The
 check does not belong to enable_nmi_window but must be in
 nmi_allowed. This patch fixes this.
 
 Signed-off-by: Joerg Roedel joerg.roe...@amd.com
 ---
 arch/x86/kvm/svm.c |   16 +---
 1 files changed, 9 insertions(+), 7 deletions(-)
 
 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
 index ab78eb8..ec20584 100644
 --- a/arch/x86/kvm/svm.c
 +++ b/arch/x86/kvm/svm.c
 @@ -2771,8 +2771,12 @@ static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
 {
   struct vcpu_svm *svm = to_svm(vcpu);
   struct vmcb *vmcb = svm-vmcb;
 - return !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 - !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 + int ret;
 + ret = !(vmcb-control.int_state  SVM_INTERRUPT_SHADOW_MASK) 
 +   !(svm-vcpu.arch.hflags  HF_NMI_MASK);
 + ret = ret  gif_set(svm)  nested_svm_nmi(svm);
 +
 + return ret;
 }
 
 static bool svm_get_nmi_mask(struct kvm_vcpu *vcpu)
 @@ -2841,11 +2845,9 @@ static void enable_nmi_window(struct kvm_vcpu 
 *vcpu)
* Something prevents NMI from been injected. Single step over possible
* problem (IRET or exception injection or interrupt shadow)
*/
 - if (gif_set(svm)  nested_svm_nmi(svm)) {
 - svm-nmi_singlestep = true;
 - svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 - update_db_intercept(vcpu);
 - }
 + svm-nmi_singlestep = true;
 + svm-vmcb-save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
 + update_db_intercept(vcpu);
 
 So we're always messing with the nested guest state when the host
 wants to inject an nmi into the l1 guest? Is that safe?
 
 Why not? We can't inject an NMI directly into L2 if the nested
 hypervisor intercepts it.
 
 So where did the code go that does the #vmexit in case the nested
 hypervisor does intercept it? It used to be nested_svm_nmi(), right?
 
 No, nested_svm_nmi runs in atomic context where we can't emulate a
 vmexit. We set exit_required and emulate the vmexit later.

So we modify the L2 rflags and then trigger a #vmexit, leaving the l2 state 
broken?

Alex

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Joerg Roedel
On Fri, Apr 23, 2010 at 04:24:54PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:22, Joerg Roedel wrote:

  No, nested_svm_nmi runs in atomic context where we can't emulate a
  vmexit. We set exit_required and emulate the vmexit later.
 
 So we modify the L2 rflags and then trigger a #vmexit, leaving the l2
 state broken?

No, the rflags are changed in enable_nmi_window which isn't called when
we run nested and the nested hypervisor intercepts nmi. So it only runs
in the !nested case where it can't corrupt L2 state.

Joerg


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Alexander Graf

On 23.04.2010, at 16:31, Joerg Roedel wrote:

 On Fri, Apr 23, 2010 at 04:24:54PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:22, Joerg Roedel wrote:
 
 No, nested_svm_nmi runs in atomic context where we can't emulate a
 vmexit. We set exit_required and emulate the vmexit later.
 
 So we modify the L2 rflags and then trigger a #vmexit, leaving the l2
 state broken?
 
 No, the rflags are changed in enable_nmi_window which isn't called when
 we run nested and the nested hypervisor intercepts nmi. So it only runs
 in the !nested case where it can't corrupt L2 state.

Last time I checked the code enable_nmi_window was the function triggering the 
#vmexit, so it should run in that exact scenario. If what you say is true, 
where do we #vmexit instead then?


Alex

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Joerg Roedel
On Fri, Apr 23, 2010 at 04:42:52PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:31, Joerg Roedel wrote:
 
  On Fri, Apr 23, 2010 at 04:24:54PM +0200, Alexander Graf wrote:
  
  On 23.04.2010, at 16:22, Joerg Roedel wrote:
  
  No, nested_svm_nmi runs in atomic context where we can't emulate a
  vmexit. We set exit_required and emulate the vmexit later.
  
  So we modify the L2 rflags and then trigger a #vmexit, leaving the l2
  state broken?
  
  No, the rflags are changed in enable_nmi_window which isn't called when
  we run nested and the nested hypervisor intercepts nmi. So it only runs
  in the !nested case where it can't corrupt L2 state.
 
 Last time I checked the code enable_nmi_window was the function
 triggering the #vmexit,

Yes, thats the bug which this patch fixes :-)

so it should run in that exact scenario. If what you say is true, where
do we #vmexit instead then?

After setting exit_required we run into svm.c:svm_vcpu_run. There the
exit_required flag is checked and if set, the function immediatly
returns without doing a vmrun. A few cycles later we run into
svm.c:handle_exit() where at the beginning exit_required is checked, and
if set the vmexit is emulated.

Joerg


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/8] KVM: SVM: Fix nested nmi handling

2010-04-23 Thread Alexander Graf

On 23.04.2010, at 16:51, Joerg Roedel wrote:

 On Fri, Apr 23, 2010 at 04:42:52PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:31, Joerg Roedel wrote:
 
 On Fri, Apr 23, 2010 at 04:24:54PM +0200, Alexander Graf wrote:
 
 On 23.04.2010, at 16:22, Joerg Roedel wrote:
 
 No, nested_svm_nmi runs in atomic context where we can't emulate a
 vmexit. We set exit_required and emulate the vmexit later.
 
 So we modify the L2 rflags and then trigger a #vmexit, leaving the l2
 state broken?
 
 No, the rflags are changed in enable_nmi_window which isn't called when
 we run nested and the nested hypervisor intercepts nmi. So it only runs
 in the !nested case where it can't corrupt L2 state.
 
 Last time I checked the code enable_nmi_window was the function
 triggering the #vmexit,
 
 Yes, thats the bug which this patch fixes :-)
 
 so it should run in that exact scenario. If what you say is true, where
 do we #vmexit instead then?
 
 After setting exit_required we run into svm.c:svm_vcpu_run. There the
 exit_required flag is checked and if set, the function immediatly
 returns without doing a vmrun. A few cycles later we run into
 svm.c:handle_exit() where at the beginning exit_required is checked, and
 if set the vmexit is emulated.

Oh well, I guess I have to trust you on this one :)


Alex

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html