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-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-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
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.org/majordomo-info.html


[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