diff mbox

[3/4] KVM: nVMX: Check all exceptions for intercept during delivery to L2

Message ID 1380102696-25267-4-git-send-email-gleb@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gleb Natapov Sept. 25, 2013, 9:51 a.m. UTC
All exceptions should be checked for intercept during delivery to L2,
but we check only #PF currently. Drop nested_run_pending while we are
at it since exception cannot be injected during vmentry anyway.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
---
 arch/x86/kvm/vmx.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

Comments

Paolo Bonzini Sept. 25, 2013, 10:38 a.m. UTC | #1
Il 25/09/2013 11:51, Gleb Natapov ha scritto:
> All exceptions should be checked for intercept during delivery to L2,
> but we check only #PF currently. Drop nested_run_pending while we are
> at it since exception cannot be injected during vmentry anyway.
> 
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
>  arch/x86/kvm/vmx.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 663bc5e..5bfa09d 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -1902,12 +1902,11 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
>   * a #PF exception (this is the only case in which KVM injects a #PF when L2
>   * is running).
>   */
> -static int nested_pf_handled(struct kvm_vcpu *vcpu)
> +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
>  {
>  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
>  
> -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
> -	if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR)))
> +	if (!(vmcs12->exception_bitmap & (1u << nr)))
>  		return 0;
>  
>  	nested_vmx_vmexit(vcpu);
> @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
>  
> -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
> -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
> +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))

The code is now pretty similar to what svm.c does.  Do we want to move
the is_guest_mode(vcpu) check into nested_ex_handled, too?  (Or vice
versa, take it out in svm.c).  Perhaps you could also name the function
nested_vmx_check_exception.

Paolo

>  		return;
>  
>  	if (has_error_code) {
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Sept. 25, 2013, 11 a.m. UTC | #2
On Wed, Sep 25, 2013 at 12:38:20PM +0200, Paolo Bonzini wrote:
> Il 25/09/2013 11:51, Gleb Natapov ha scritto:
> > All exceptions should be checked for intercept during delivery to L2,
> > but we check only #PF currently. Drop nested_run_pending while we are
> > at it since exception cannot be injected during vmentry anyway.
> > 
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > ---
> >  arch/x86/kvm/vmx.c | 8 +++-----
> >  1 file changed, 3 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 663bc5e..5bfa09d 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -1902,12 +1902,11 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
> >   * a #PF exception (this is the only case in which KVM injects a #PF when L2
> >   * is running).
> >   */
> > -static int nested_pf_handled(struct kvm_vcpu *vcpu)
> > +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
> >  {
> >  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
> >  
> > -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
> > -	if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR)))
> > +	if (!(vmcs12->exception_bitmap & (1u << nr)))
> >  		return 0;
> >  
> >  	nested_vmx_vmexit(vcpu);
> > @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
> >  	struct vcpu_vmx *vmx = to_vmx(vcpu);
> >  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
> >  
> > -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
> > -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
> > +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
> 
> The code is now pretty similar to what svm.c does.  Do we want to move
> the is_guest_mode(vcpu) check into nested_ex_handled, too?  (Or vice
> versa, take it out in svm.c).  Perhaps you could also name the function
> nested_vmx_check_exception.
> 
I want to try to move the logic into common code eventually. I do not
mind renaming for now, but it will have to wait for the next week :)


--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 25, 2013, 11:25 a.m. UTC | #3
Il 25/09/2013 13:00, Gleb Natapov ha scritto:
>>> > > @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
>>> > >  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>>> > >  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
>>> > >  
>>> > > -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
>>> > > -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
>>> > > +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
>> > 
>> > The code is now pretty similar to what svm.c does.  Do we want to move
>> > the is_guest_mode(vcpu) check into nested_ex_handled, too?  (Or vice
>> > versa, take it out in svm.c).  Perhaps you could also name the function
>> > nested_vmx_check_exception.
>> > 
> I want to try to move the logic into common code eventually. I do not
> mind renaming for now, but it will have to wait for the next week :)

I can rename while applying the patch.  Making more logic common to vmx
and svm can wait.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Sept. 25, 2013, 11:52 a.m. UTC | #4
On Wed, Sep 25, 2013 at 01:25:39PM +0200, Paolo Bonzini wrote:
> Il 25/09/2013 13:00, Gleb Natapov ha scritto:
> >>> > > @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
> >>> > >  	struct vcpu_vmx *vmx = to_vmx(vcpu);
> >>> > >  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
> >>> > >  
> >>> > > -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
> >>> > > -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
> >>> > > +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
> >> > 
> >> > The code is now pretty similar to what svm.c does.  Do we want to move
> >> > the is_guest_mode(vcpu) check into nested_ex_handled, too?  (Or vice
> >> > versa, take it out in svm.c).  Perhaps you could also name the function
> >> > nested_vmx_check_exception.
> >> > 
> > I want to try to move the logic into common code eventually. I do not
> > mind renaming for now, but it will have to wait for the next week :)
> 
> I can rename while applying the patch.  Making more logic common to vmx
> and svm can wait.
> 
Yes, of course, logic unification is not for the immediate feature.

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 25, 2013, 2 p.m. UTC | #5
Il 25/09/2013 11:51, Gleb Natapov ha scritto:
> All exceptions should be checked for intercept during delivery to L2,
> but we check only #PF currently. Drop nested_run_pending while we are
> at it since exception cannot be injected during vmentry anyway.
> 
> Signed-off-by: Gleb Natapov <gleb@redhat.com>
> ---
>  arch/x86/kvm/vmx.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 663bc5e..5bfa09d 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -1902,12 +1902,11 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
>   * a #PF exception (this is the only case in which KVM injects a #PF when L2
>   * is running).
>   */
> -static int nested_pf_handled(struct kvm_vcpu *vcpu)
> +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
>  {
>  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
>  
> -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */

Just one more question, why drop this comment?  It doesn't seem
incorrect in the particular case where nr == PF_VECTOR.

> -	if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR)))
> +	if (!(vmcs12->exception_bitmap & (1u << nr)))
>  		return 0;
>  
>  	nested_vmx_vmexit(vcpu);
> @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
>  	struct vcpu_vmx *vmx = to_vmx(vcpu);
>  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
>  
> -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
> -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
> +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
>  		return;
>  
>  	if (has_error_code) {
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Sept. 25, 2013, 2:19 p.m. UTC | #6
On Wed, Sep 25, 2013 at 04:00:16PM +0200, Paolo Bonzini wrote:
> Il 25/09/2013 11:51, Gleb Natapov ha scritto:
> > All exceptions should be checked for intercept during delivery to L2,
> > but we check only #PF currently. Drop nested_run_pending while we are
> > at it since exception cannot be injected during vmentry anyway.
> > 
> > Signed-off-by: Gleb Natapov <gleb@redhat.com>
> > ---
> >  arch/x86/kvm/vmx.c | 8 +++-----
> >  1 file changed, 3 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 663bc5e..5bfa09d 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -1902,12 +1902,11 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
> >   * a #PF exception (this is the only case in which KVM injects a #PF when L2
> >   * is running).
> >   */
> > -static int nested_pf_handled(struct kvm_vcpu *vcpu)
> > +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
> >  {
> >  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
> >  
> > -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
> 
> Just one more question, why drop this comment?  It doesn't seem
> incorrect in the particular case where nr == PF_VECTOR.
> 
I moved it to vmx_inject_page_fault_nested().


> > -	if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR)))
> > +	if (!(vmcs12->exception_bitmap & (1u << nr)))
> >  		return 0;
> >  
> >  	nested_vmx_vmexit(vcpu);
> > @@ -1921,8 +1920,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
> >  	struct vcpu_vmx *vmx = to_vmx(vcpu);
> >  	u32 intr_info = nr | INTR_INFO_VALID_MASK;
> >  
> > -	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
> > -	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
> > +	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
> >  		return;
> >  
> >  	if (has_error_code) {
> > 

--
			Gleb.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paolo Bonzini Sept. 25, 2013, 2:22 p.m. UTC | #7
Il 25/09/2013 16:19, Gleb Natapov ha scritto:
>>> > > -static int nested_pf_handled(struct kvm_vcpu *vcpu)
>>> > > +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
>>> > >  {
>>> > >  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
>>> > >  
>>> > > -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
>> > 
>> > Just one more question, why drop this comment?  It doesn't seem
>> > incorrect in the particular case where nr == PF_VECTOR.
> 
> I moved it to vmx_inject_page_fault_nested().

Ah, so if you test it there, you shouldn't get here unless the
PFEC_MASK/MATCH matches.  In the case of EPT, you run with L1
PFEC_MASK/MATCH so you do not need any check.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gleb Natapov Sept. 25, 2013, 4:31 p.m. UTC | #8
On Wed, Sep 25, 2013 at 04:22:48PM +0200, Paolo Bonzini wrote:
> Il 25/09/2013 16:19, Gleb Natapov ha scritto:
> >>> > > -static int nested_pf_handled(struct kvm_vcpu *vcpu)
> >>> > > +static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
> >>> > >  {
> >>> > >  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
> >>> > >  
> >>> > > -	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
> >> > 
> >> > Just one more question, why drop this comment?  It doesn't seem
> >> > incorrect in the particular case where nr == PF_VECTOR.
> > 
> > I moved it to vmx_inject_page_fault_nested().
> 
> Ah, so if you test it there, you shouldn't get here unless the
> PFEC_MASK/MATCH matches.
Yes, PF will never reach here in case of shadow on shadow.


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

Patch

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 663bc5e..5bfa09d 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1902,12 +1902,11 @@  static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
  * a #PF exception (this is the only case in which KVM injects a #PF when L2
  * is running).
  */
-static int nested_pf_handled(struct kvm_vcpu *vcpu)
+static int nested_ex_handled(struct kvm_vcpu *vcpu, unsigned nr)
 {
 	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 
-	/* TODO: also check PFEC_MATCH/MASK, not just EB.PF. */
-	if (!(vmcs12->exception_bitmap & (1u << PF_VECTOR)))
+	if (!(vmcs12->exception_bitmap & (1u << nr)))
 		return 0;
 
 	nested_vmx_vmexit(vcpu);
@@ -1921,8 +1920,7 @@  static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
 	u32 intr_info = nr | INTR_INFO_VALID_MASK;
 
-	if (!reinject && nr == PF_VECTOR && is_guest_mode(vcpu) &&
-	    !vmx->nested.nested_run_pending && nested_pf_handled(vcpu))
+	if (!reinject && is_guest_mode(vcpu) && nested_ex_handled(vcpu, nr))
 		return;
 
 	if (has_error_code) {