Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-27 Thread Avi Kivity

Alexander Graf wrote:


Hmm yes, this is a problem. So this optimization will not work. We need
other ways to optimize :)


Well it would work for the KVM-in-KVM case, where we know that VMRUN 
is always triggered with IF=1 and V_INTR=1. The only case that hack 
fails is when we have IF=0 and V_INTR=1. Everything else should work 
just fine. And in this case we would simply issue some VMEXITs 0x60, 
so no big deal IMHO. It should be worth the tradeoff of making most 
VMMs a lot faster.


There should be a compile-option to enable the "correct" behavior 
though. If we join that with the VMLOAD and VMSAVE hack there would be 
only the VMRUN and DR exits left. That sounds like a really good 
improvement where I wouldn't mind to break some specs :-).


Maybe a hypercall, so it can be enabled on a guest-by-guest basis.

I must say that if we do guest-specific hacking this way, a paravirt 
approach doesn't look so bad.


--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

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


Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-27 Thread Avi Kivity

Joerg Roedel wrote:

I had another possible idea for performance improvement here. Since we
only inject normal interrupts and exceptions (and not NMI and such) we
can patch clgi to cli and stgi to sti to save these two intercepts in
the guests vmrun path.
Any objections/problems with this?

  


The sequence 'clgi; sti' will break.


--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

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


Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-26 Thread Alexander Graf


On 25.09.2008, at 23:27, Joerg Roedel wrote:


On Thu, Sep 25, 2008 at 09:55:27PM +0200, Alexander Graf wrote:


On 25.09.2008, at 20:47, Joerg Roedel wrote:

I had another possible idea for performance improvement here.  
Since we
only inject normal interrupts and exceptions (and not NMI and  
such) we
can patch clgi to cli and stgi to sti to save these two intercepts  
in

the guests vmrun path.
Any objections/problems with this?


How do we know if we're allowed to inject interrupts with V_INTR set?
Usually IF is on and GIF is off when entering the VM in KVM, so we
allow interrupts to arrive even when IF is clear in the guest...


Hmm yes, this is a problem. So this optimization will not work. We  
need

other ways to optimize :)


Well it would work for the KVM-in-KVM case, where we know that VMRUN  
is always triggered with IF=1 and V_INTR=1. The only case that hack  
fails is when we have IF=0 and V_INTR=1. Everything else should work  
just fine. And in this case we would simply issue some VMEXITs 0x60,  
so no big deal IMHO. It should be worth the tradeoff of making most  
VMMs a lot faster.


There should be a compile-option to enable the "correct" behavior  
though. If we join that with the VMLOAD and VMSAVE hack there would be  
only the VMRUN and DR exits left. That sounds like a really good  
improvement where I wouldn't mind to break some specs :-).


Alex
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-25 Thread Joerg Roedel
On Thu, Sep 25, 2008 at 09:55:27PM +0200, Alexander Graf wrote:
> 
> On 25.09.2008, at 20:47, Joerg Roedel wrote:
> 
> >I had another possible idea for performance improvement here. Since we
> >only inject normal interrupts and exceptions (and not NMI and such) we
> >can patch clgi to cli and stgi to sti to save these two intercepts in
> >the guests vmrun path.
> >Any objections/problems with this?
> 
> How do we know if we're allowed to inject interrupts with V_INTR set?  
> Usually IF is on and GIF is off when entering the VM in KVM, so we  
> allow interrupts to arrive even when IF is clear in the guest...

Hmm yes, this is a problem. So this optimization will not work. We need
other ways to optimize :)

Joerg
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-25 Thread Alexander Graf


On 25.09.2008, at 20:47, Joerg Roedel wrote:


I had another possible idea for performance improvement here. Since we
only inject normal interrupts and exceptions (and not NMI and such) we
can patch clgi to cli and stgi to sti to save these two intercepts in
the guests vmrun path.
Any objections/problems with this?


How do we know if we're allowed to inject interrupts with V_INTR set?  
Usually IF is on and GIF is off when entering the VM in KVM, so we  
allow interrupts to arrive even when IF is clear in the guest...





On Wed, Sep 17, 2008 at 03:41:21PM +0200, Alexander Graf wrote:
This patch implements the GIF flag and the clgi and stgi  
instructions that
set this flag. Only if the flag is set (default), interrupts can be  
received by

the CPU.

To keep the information about that somewhere, this patch adds a new  
hidden
flags vector. that is used to store information that does not go  
into the

vmcb, but is SVM specific.

v2 moves the hflags to x86 generic code
v3 makes use of the new permission helper

Signed-off-by: Alexander Graf <[EMAIL PROTECTED]>
---
arch/x86/kvm/svm.c |   42 ++ 
+---

include/asm-x86/kvm_host.h |3 +++
2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c72e728..469ecc5 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -612,6 +612,8 @@ static void init_vmcb(struct vcpu_svm *svm)
save->cr4 = 0;
}
force_new_asid(&svm->vcpu);
+
+   svm->vcpu.arch.hflags = HF_GIF_MASK;
}

static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -1227,6 +1229,36 @@ static int nested_svm_do(struct vcpu_svm *svm,
return retval;
}

+static int stgi_interception(struct vcpu_svm *svm, struct kvm_run  
*kvm_run)

+{
+   if (nested_svm_check_permissions(svm))
+   return 1;
+
+   svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+   skip_emulated_instruction(&svm->vcpu);
+
+   svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+   return 1;
+}
+
+static int clgi_interception(struct vcpu_svm *svm, struct kvm_run  
*kvm_run)

+{
+   if (nested_svm_check_permissions(svm))
+   return 1;
+
+   svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+   skip_emulated_instruction(&svm->vcpu);
+
+   svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+
+   /* After a CLGI no interrupts should come */
+   svm_clear_vintr(svm);
+   svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+
+   return 1;
+}
+
static int invalid_op_interception(struct vcpu_svm *svm,
   struct kvm_run *kvm_run)
{
@@ -1521,8 +1553,8 @@ static int (*svm_exit_handlers[])(struct  
vcpu_svm *svm,

[SVM_EXIT_VMMCALL]  = vmmcall_interception,
[SVM_EXIT_VMLOAD]   = invalid_op_interception,
[SVM_EXIT_VMSAVE]   = invalid_op_interception,
-   [SVM_EXIT_STGI] = invalid_op_interception,
-   [SVM_EXIT_CLGI] = invalid_op_interception,
+   [SVM_EXIT_STGI] = stgi_interception,
+   [SVM_EXIT_CLGI] = clgi_interception,
[SVM_EXIT_SKINIT]   = invalid_op_interception,
[SVM_EXIT_WBINVD]   = emulate_on_interception,
[SVM_EXIT_MONITOR]  = invalid_op_interception,
@@ -1669,6 +1701,9 @@ static void svm_intr_assist(struct kvm_vcpu  
*vcpu)

if (!kvm_cpu_has_interrupt(vcpu))
goto out;

+   if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
+   goto out;
+
if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
(vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
@@ -1720,7 +1755,8 @@ static void do_interrupt_requests(struct  
kvm_vcpu *vcpu,


svm->vcpu.arch.interrupt_window_open =
(!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-(svm->vmcb->save.rflags & X86_EFLAGS_IF));
+(svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
+(svm->vcpu.arch.hflags & HF_GIF_MASK));

	if (svm->vcpu.arch.interrupt_window_open && svm- 
>vcpu.arch.irq_summary)

/*
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 982b6b2..3e25004 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -245,6 +245,7 @@ struct kvm_vcpu_arch {
unsigned long cr3;
unsigned long cr4;
unsigned long cr8;
+   u32 hflags;
u64 pdptrs[4]; /* pae */
u64 shadow_efer;
u64 apic_base;
@@ -734,6 +735,8 @@ enum {
TASK_SWITCH_GATE = 3,
};

+#define HF_GIF_MASK(1 << 0)
+
/*
 * Hardware virtualization extension instructions may fault if a
 * reboot turns off virtualization while processes are running.
--
1.5.6


--
To unsubscribe from 

Re: [PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-25 Thread Joerg Roedel
I had another possible idea for performance improvement here. Since we
only inject normal interrupts and exceptions (and not NMI and such) we
can patch clgi to cli and stgi to sti to save these two intercepts in
the guests vmrun path.
Any objections/problems with this?

On Wed, Sep 17, 2008 at 03:41:21PM +0200, Alexander Graf wrote:
> This patch implements the GIF flag and the clgi and stgi instructions that
> set this flag. Only if the flag is set (default), interrupts can be received 
> by
> the CPU.
> 
> To keep the information about that somewhere, this patch adds a new hidden
> flags vector. that is used to store information that does not go into the
> vmcb, but is SVM specific.
> 
> v2 moves the hflags to x86 generic code
> v3 makes use of the new permission helper
> 
> Signed-off-by: Alexander Graf <[EMAIL PROTECTED]>
> ---
>  arch/x86/kvm/svm.c |   42 +++---
>  include/asm-x86/kvm_host.h |3 +++
>  2 files changed, 42 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
> index c72e728..469ecc5 100644
> --- a/arch/x86/kvm/svm.c
> +++ b/arch/x86/kvm/svm.c
> @@ -612,6 +612,8 @@ static void init_vmcb(struct vcpu_svm *svm)
>   save->cr4 = 0;
>   }
>   force_new_asid(&svm->vcpu);
> +
> + svm->vcpu.arch.hflags = HF_GIF_MASK;
>  }
>  
>  static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
> @@ -1227,6 +1229,36 @@ static int nested_svm_do(struct vcpu_svm *svm,
>   return retval;
>  }
>  
> +static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
> +{
> + if (nested_svm_check_permissions(svm))
> + return 1;
> +
> + svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
> + skip_emulated_instruction(&svm->vcpu);
> +
> + svm->vcpu.arch.hflags |= HF_GIF_MASK;
> +
> + return 1;
> +}
> +
> +static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
> +{
> + if (nested_svm_check_permissions(svm))
> + return 1;
> +
> + svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
> + skip_emulated_instruction(&svm->vcpu);
> +
> + svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
> +
> + /* After a CLGI no interrupts should come */
> + svm_clear_vintr(svm);
> + svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
> +
> + return 1;
> +}
> +
>  static int invalid_op_interception(struct vcpu_svm *svm,
>  struct kvm_run *kvm_run)
>  {
> @@ -1521,8 +1553,8 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
>   [SVM_EXIT_VMMCALL]  = vmmcall_interception,
>   [SVM_EXIT_VMLOAD]   = invalid_op_interception,
>   [SVM_EXIT_VMSAVE]   = invalid_op_interception,
> - [SVM_EXIT_STGI] = invalid_op_interception,
> - [SVM_EXIT_CLGI] = invalid_op_interception,
> + [SVM_EXIT_STGI] = stgi_interception,
> + [SVM_EXIT_CLGI] = clgi_interception,
>   [SVM_EXIT_SKINIT]   = invalid_op_interception,
>   [SVM_EXIT_WBINVD]   = emulate_on_interception,
>   [SVM_EXIT_MONITOR]  = invalid_op_interception,
> @@ -1669,6 +1701,9 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
>   if (!kvm_cpu_has_interrupt(vcpu))
>   goto out;
>  
> + if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
> + goto out;
> +
>   if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
>   (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
>   (vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
> @@ -1720,7 +1755,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
>  
>   svm->vcpu.arch.interrupt_window_open =
>   (!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
> -  (svm->vmcb->save.rflags & X86_EFLAGS_IF));
> +  (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
> +  (svm->vcpu.arch.hflags & HF_GIF_MASK));
>  
>   if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
>   /*
> diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
> index 982b6b2..3e25004 100644
> --- a/include/asm-x86/kvm_host.h
> +++ b/include/asm-x86/kvm_host.h
> @@ -245,6 +245,7 @@ struct kvm_vcpu_arch {
>   unsigned long cr3;
>   unsigned long cr4;
>   unsigned long cr8;
> + u32 hflags;
>   u64 pdptrs[4]; /* pae */
>   u64 shadow_efer;
>   u64 apic_base;
> @@ -734,6 +735,8 @@ enum {
>   TASK_SWITCH_GATE = 3,
>  };
>  
> +#define HF_GIF_MASK  (1 << 0)
> +
>  /*
>   * Hardware virtualization extension instructions may fault if a
>   * reboot turns off virtualization while processes are running.
> -- 
> 1.5.6
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel

[PATCH 4/9] Implement GIF, clgi and stgi v3

2008-09-17 Thread Alexander Graf
This patch implements the GIF flag and the clgi and stgi instructions that
set this flag. Only if the flag is set (default), interrupts can be received by
the CPU.

To keep the information about that somewhere, this patch adds a new hidden
flags vector. that is used to store information that does not go into the
vmcb, but is SVM specific.

v2 moves the hflags to x86 generic code
v3 makes use of the new permission helper

Signed-off-by: Alexander Graf <[EMAIL PROTECTED]>
---
 arch/x86/kvm/svm.c |   42 +++---
 include/asm-x86/kvm_host.h |3 +++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c72e728..469ecc5 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -612,6 +612,8 @@ static void init_vmcb(struct vcpu_svm *svm)
save->cr4 = 0;
}
force_new_asid(&svm->vcpu);
+
+   svm->vcpu.arch.hflags = HF_GIF_MASK;
 }
 
 static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
@@ -1227,6 +1229,36 @@ static int nested_svm_do(struct vcpu_svm *svm,
return retval;
 }
 
+static int stgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+   if (nested_svm_check_permissions(svm))
+   return 1;
+
+   svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+   skip_emulated_instruction(&svm->vcpu);
+
+   svm->vcpu.arch.hflags |= HF_GIF_MASK;
+
+   return 1;
+}
+
+static int clgi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+   if (nested_svm_check_permissions(svm))
+   return 1;
+
+   svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+   skip_emulated_instruction(&svm->vcpu);
+
+   svm->vcpu.arch.hflags &= ~HF_GIF_MASK;
+
+   /* After a CLGI no interrupts should come */
+   svm_clear_vintr(svm);
+   svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
+
+   return 1;
+}
+
 static int invalid_op_interception(struct vcpu_svm *svm,
   struct kvm_run *kvm_run)
 {
@@ -1521,8 +1553,8 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_VMMCALL]  = vmmcall_interception,
[SVM_EXIT_VMLOAD]   = invalid_op_interception,
[SVM_EXIT_VMSAVE]   = invalid_op_interception,
-   [SVM_EXIT_STGI] = invalid_op_interception,
-   [SVM_EXIT_CLGI] = invalid_op_interception,
+   [SVM_EXIT_STGI] = stgi_interception,
+   [SVM_EXIT_CLGI] = clgi_interception,
[SVM_EXIT_SKINIT]   = invalid_op_interception,
[SVM_EXIT_WBINVD]   = emulate_on_interception,
[SVM_EXIT_MONITOR]  = invalid_op_interception,
@@ -1669,6 +1701,9 @@ static void svm_intr_assist(struct kvm_vcpu *vcpu)
if (!kvm_cpu_has_interrupt(vcpu))
goto out;
 
+   if (!(svm->vcpu.arch.hflags & HF_GIF_MASK))
+   goto out;
+
if (!(vmcb->save.rflags & X86_EFLAGS_IF) ||
(vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK) ||
(vmcb->control.event_inj & SVM_EVTINJ_VALID)) {
@@ -1720,7 +1755,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
 
svm->vcpu.arch.interrupt_window_open =
(!(control->int_state & SVM_INTERRUPT_SHADOW_MASK) &&
-(svm->vmcb->save.rflags & X86_EFLAGS_IF));
+(svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
+(svm->vcpu.arch.hflags & HF_GIF_MASK));
 
if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary)
/*
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 982b6b2..3e25004 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -245,6 +245,7 @@ struct kvm_vcpu_arch {
unsigned long cr3;
unsigned long cr4;
unsigned long cr8;
+   u32 hflags;
u64 pdptrs[4]; /* pae */
u64 shadow_efer;
u64 apic_base;
@@ -734,6 +735,8 @@ enum {
TASK_SWITCH_GATE = 3,
 };
 
+#define HF_GIF_MASK(1 << 0)
+
 /*
  * Hardware virtualization extension instructions may fault if a
  * reboot turns off virtualization while processes are running.
-- 
1.5.6

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