* [PATCH 0/3] Optimize STI; HLT while an interrupt is pending
@ 2011-02-14 14:42 Avi Kivity
2011-02-14 14:42 ` [PATCH 1/3] KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field Avi Kivity
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Avi Kivity @ 2011-02-14 14:42 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
If the guest executes the following code sequence
CLI
...
(interrupt becomes pending)
STI
HLT
then we will exit on HLT, enter the guest, and exit immediately again on
virtual interrupt pending. As this is wasteful, this patch set short
circuits the whole operation to inject the interrupt immediately.
(as I've seen this occur very rarely in ftrace, compared to what I saw
before I wrote the patch, please don't apply patches 2 and 3 until I've
had a chance to benchmark it)
Avi Kivity (3):
KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field
KVM: VMX: Short circuit STI; HLT while an interrupt is pending
KVM: SVM: Short circuit STI; HLT while an interrupt is pending
arch/x86/kvm/svm.c | 9 +++++++
arch/x86/kvm/vmx.c | 69 ++++++++++++++++++++++++++++-----------------------
2 files changed, 47 insertions(+), 31 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field
2011-02-14 14:42 [PATCH 0/3] Optimize STI; HLT while an interrupt is pending Avi Kivity
@ 2011-02-14 14:42 ` Avi Kivity
2011-02-14 14:42 ` [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending Avi Kivity
2011-02-14 14:42 ` [PATCH 3/3] KVM: SVM: " Avi Kivity
2 siblings, 0 replies; 10+ messages in thread
From: Avi Kivity @ 2011-02-14 14:42 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
The CPU_BASED_VM_EXEC_CONTROL VMCS field is write-only, so we can cache it
in the vcpu structure and avoid a costly vmcs_read32() every time we want
to change a bit.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/vmx.c | 60 +++++++++++++++++++++++++--------------------------
1 files changed, 29 insertions(+), 31 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f76137c..ee1cd1a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -130,6 +130,7 @@ struct vcpu_vmx {
u8 fail;
u32 exit_intr_info;
u32 idt_vectoring_info;
+ u32 cpu_based_vm_exec_control;
struct shared_msr_entry *guest_msrs;
int nmsrs;
int save_nmsrs;
@@ -643,6 +644,18 @@ static void vmcs_set_bits(unsigned long field, u32 mask)
vmcs_writel(field, vmcs_readl(field) | mask);
}
+static void set_cpu_based_vm_exec_ctrl_bits(struct vcpu_vmx *vmx, u32 mask)
+{
+ vmx->cpu_based_vm_exec_control |= mask;
+ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx->cpu_based_vm_exec_control);
+}
+
+static void clear_cpu_based_vm_exec_ctrl_bits(struct vcpu_vmx *vmx, u32 mask)
+{
+ vmx->cpu_based_vm_exec_control &= ~mask;
+ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx->cpu_based_vm_exec_control);
+}
+
static void update_exception_bitmap(struct kvm_vcpu *vcpu)
{
u32 eb;
@@ -1932,18 +1945,16 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0,
vmx_decache_cr3(vcpu);
if (!(cr0 & X86_CR0_PG)) {
/* From paging/starting to nonpaging */
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
- vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) |
- (CPU_BASED_CR3_LOAD_EXITING |
- CPU_BASED_CR3_STORE_EXITING));
+ set_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_CR3_STORE_EXITING);
vcpu->arch.cr0 = cr0;
vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
} else if (!is_paging(vcpu)) {
/* From nonpaging to paging */
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
- vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) &
- ~(CPU_BASED_CR3_LOAD_EXITING |
- CPU_BASED_CR3_STORE_EXITING));
+ clear_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_CR3_STORE_EXITING);
vcpu->arch.cr0 = cr0;
vmx_set_cr4(vcpu, kvm_read_cr4(vcpu));
}
@@ -2622,6 +2633,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
exec_control |= CPU_BASED_CR3_STORE_EXITING |
CPU_BASED_CR3_LOAD_EXITING |
CPU_BASED_INVLPG_EXITING;
+ vmx->cpu_based_vm_exec_control = exec_control;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
if (cpu_has_secondary_exec_ctrls()) {
@@ -2873,17 +2885,12 @@ out:
static void enable_irq_window(struct kvm_vcpu *vcpu)
{
- u32 cpu_based_vm_exec_control;
-
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ set_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_VIRTUAL_INTR_PENDING);
}
static void enable_nmi_window(struct kvm_vcpu *vcpu)
{
- u32 cpu_based_vm_exec_control;
-
if (!cpu_has_virtual_nmis()) {
enable_irq_window(vcpu);
return;
@@ -2893,9 +2900,8 @@ static void enable_nmi_window(struct kvm_vcpu *vcpu)
enable_irq_window(vcpu);
return;
}
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control |= CPU_BASED_VIRTUAL_NMI_PENDING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ set_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_VIRTUAL_NMI_PENDING);
}
static void vmx_inject_irq(struct kvm_vcpu *vcpu)
@@ -3408,13 +3414,9 @@ static int handle_tpr_below_threshold(struct kvm_vcpu *vcpu)
static int handle_interrupt_window(struct kvm_vcpu *vcpu)
{
- u32 cpu_based_vm_exec_control;
-
/* clear pending irq */
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
-
+ clear_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_VIRTUAL_INTR_PENDING);
kvm_make_request(KVM_REQ_EVENT, vcpu);
++vcpu->stat.irq_window_exits;
@@ -3671,12 +3673,8 @@ static int handle_ept_misconfig(struct kvm_vcpu *vcpu)
static int handle_nmi_window(struct kvm_vcpu *vcpu)
{
- u32 cpu_based_vm_exec_control;
-
- /* clear pending NMI */
- cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
- cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
- vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control);
+ clear_cpu_based_vm_exec_ctrl_bits(to_vmx(vcpu),
+ CPU_BASED_VIRTUAL_NMI_PENDING);
++vcpu->stat.nmi_window_exits;
kvm_make_request(KVM_REQ_EVENT, vcpu);
@@ -3691,7 +3689,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
u32 cpu_exec_ctrl;
bool intr_window_requested;
- cpu_exec_ctrl = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
+ cpu_exec_ctrl = vmx->cpu_based_vm_exec_control;
intr_window_requested = cpu_exec_ctrl & CPU_BASED_VIRTUAL_INTR_PENDING;
while (!guest_state_valid(vcpu)) {
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-14 14:42 [PATCH 0/3] Optimize STI; HLT while an interrupt is pending Avi Kivity
2011-02-14 14:42 ` [PATCH 1/3] KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field Avi Kivity
@ 2011-02-14 14:42 ` Avi Kivity
2011-02-15 20:36 ` Marcelo Tosatti
2011-02-14 14:42 ` [PATCH 3/3] KVM: SVM: " Avi Kivity
2 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2011-02-14 14:42 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
Short-circuit an STI; HLT sequence while an interrupt is pending:
instead of halting, re-entering the guest, and exiting immediately
on an interrupt window exit, go directly to the last step.
Saves a vmexit on workloads where interrupts are received synchronously;
an example is a disk backed by the host page cache where there is no
latency (from the guest's point of view) between the request and fulfilment.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/vmx.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index ee1cd1a..541da0e 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
static int handle_halt(struct kvm_vcpu *vcpu)
{
skip_emulated_instruction(vcpu);
+ /*
+ * Short-circuit an STI; HLT sequence while an interrupt is pending:
+ * instead of halting, re-entering the guest, and exiting immediately
+ * on an interrupt window exit, go directly to the last step.
+ */
+ if ((to_vmx(vcpu)->cpu_based_vm_exec_control
+ & CPU_BASED_VIRTUAL_INTR_PENDING)
+ && (kvm_get_rflags(vcpu) & X86_EFLAGS_IF))
+ return handle_interrupt_window(vcpu);
return kvm_emulate_halt(vcpu);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] KVM: SVM: Short circuit STI; HLT while an interrupt is pending
2011-02-14 14:42 [PATCH 0/3] Optimize STI; HLT while an interrupt is pending Avi Kivity
2011-02-14 14:42 ` [PATCH 1/3] KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field Avi Kivity
2011-02-14 14:42 ` [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending Avi Kivity
@ 2011-02-14 14:42 ` Avi Kivity
2 siblings, 0 replies; 10+ messages in thread
From: Avi Kivity @ 2011-02-14 14:42 UTC (permalink / raw)
To: Marcelo Tosatti, kvm
Short-circuit an STI; HLT sequence while an interrupt is pending:
instead of halting, re-entering the guest, and exiting immediately
on an interrupt window exit, go directly to the last step.
Saves a vmexit on workloads where interrupts are received synchronously;
an example is a disk backed by the host page cache where there is no
latency (from the guest's point of view) between the request and fulfilment.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kvm/svm.c | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 53c5d8a..b70af8b 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -184,6 +184,7 @@ module_param(nested, int, S_IRUGO);
static void svm_flush_tlb(struct kvm_vcpu *vcpu);
static void svm_complete_interrupts(struct vcpu_svm *svm);
+static int interrupt_window_interception(struct vcpu_svm *svm);
static int nested_svm_exit_handled(struct vcpu_svm *svm);
static int nested_svm_intercept(struct vcpu_svm *svm);
@@ -1745,6 +1746,14 @@ static int halt_interception(struct vcpu_svm *svm)
{
svm->next_rip = kvm_rip_read(&svm->vcpu) + 1;
skip_emulated_instruction(&svm->vcpu);
+ /*
+ * Short-circuit an STI; HLT sequence while an interrupt is pending:
+ * instead of halting, re-entering the guest, and exiting immediately
+ * on an interrupt window exit, go directly to the last step.
+ */
+ if ((svm->vmcb->control.intercept & (1ULL << INTERCEPT_VINTR))
+ && (kvm_get_rflags(&svm->vcpu) & X86_EFLAGS_IF))
+ return interrupt_window_interception(svm);
return kvm_emulate_halt(&svm->vcpu);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-14 14:42 ` [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending Avi Kivity
@ 2011-02-15 20:36 ` Marcelo Tosatti
2011-02-16 9:01 ` Avi Kivity
0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2011-02-15 20:36 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
On Mon, Feb 14, 2011 at 04:42:16PM +0200, Avi Kivity wrote:
> Short-circuit an STI; HLT sequence while an interrupt is pending:
> instead of halting, re-entering the guest, and exiting immediately
> on an interrupt window exit, go directly to the last step.
>
> Saves a vmexit on workloads where interrupts are received synchronously;
> an example is a disk backed by the host page cache where there is no
> latency (from the guest's point of view) between the request and fulfilment.
>
> Signed-off-by: Avi Kivity <avi@redhat.com>
> ---
> arch/x86/kvm/vmx.c | 9 +++++++++
> 1 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index ee1cd1a..541da0e 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> static int handle_halt(struct kvm_vcpu *vcpu)
> {
> skip_emulated_instruction(vcpu);
> + /*
> + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> + * instead of halting, re-entering the guest, and exiting immediately
> + * on an interrupt window exit, go directly to the last step.
> + */
> + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> + & CPU_BASED_VIRTUAL_INTR_PENDING)
> + && (kvm_get_rflags(vcpu) & X86_EFLAGS_IF))
> + return handle_interrupt_window(vcpu);
> return kvm_emulate_halt(vcpu);
> }
Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
KVM_REQ_EVENT is not set?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-15 20:36 ` Marcelo Tosatti
@ 2011-02-16 9:01 ` Avi Kivity
2011-02-16 16:51 ` Marcelo Tosatti
0 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2011-02-16 9:01 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: kvm
On 02/15/2011 10:36 PM, Marcelo Tosatti wrote:
> On Mon, Feb 14, 2011 at 04:42:16PM +0200, Avi Kivity wrote:
> > Short-circuit an STI; HLT sequence while an interrupt is pending:
> > instead of halting, re-entering the guest, and exiting immediately
> > on an interrupt window exit, go directly to the last step.
> >
> > Saves a vmexit on workloads where interrupts are received synchronously;
> > an example is a disk backed by the host page cache where there is no
> > latency (from the guest's point of view) between the request and fulfilment.
> >
> > Signed-off-by: Avi Kivity<avi@redhat.com>
> > ---
> > arch/x86/kvm/vmx.c | 9 +++++++++
> > 1 files changed, 9 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index ee1cd1a..541da0e 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> > static int handle_halt(struct kvm_vcpu *vcpu)
> > {
> > skip_emulated_instruction(vcpu);
> > + /*
> > + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> > + * instead of halting, re-entering the guest, and exiting immediately
> > + * on an interrupt window exit, go directly to the last step.
> > + */
> > + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> > + & CPU_BASED_VIRTUAL_INTR_PENDING)
> > + && (kvm_get_rflags(vcpu)& X86_EFLAGS_IF))
> > + return handle_interrupt_window(vcpu);
> > return kvm_emulate_halt(vcpu);
> > }
>
> Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
> KVM_REQ_EVENT is not set?
Yes. Also, we want to clear CPU_BASED_VIRTUAL_INTR_PENDING.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-16 9:01 ` Avi Kivity
@ 2011-02-16 16:51 ` Marcelo Tosatti
2011-02-17 9:12 ` Avi Kivity
0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2011-02-16 16:51 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
On Wed, Feb 16, 2011 at 11:01:47AM +0200, Avi Kivity wrote:
> On 02/15/2011 10:36 PM, Marcelo Tosatti wrote:
> >On Mon, Feb 14, 2011 at 04:42:16PM +0200, Avi Kivity wrote:
> >> Short-circuit an STI; HLT sequence while an interrupt is pending:
> >> instead of halting, re-entering the guest, and exiting immediately
> >> on an interrupt window exit, go directly to the last step.
> >>
> >> Saves a vmexit on workloads where interrupts are received synchronously;
> >> an example is a disk backed by the host page cache where there is no
> >> latency (from the guest's point of view) between the request and fulfilment.
> >>
> >> Signed-off-by: Avi Kivity<avi@redhat.com>
> >> ---
> >> arch/x86/kvm/vmx.c | 9 +++++++++
> >> 1 files changed, 9 insertions(+), 0 deletions(-)
> >>
> >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> >> index ee1cd1a..541da0e 100644
> >> --- a/arch/x86/kvm/vmx.c
> >> +++ b/arch/x86/kvm/vmx.c
> >> @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> >> static int handle_halt(struct kvm_vcpu *vcpu)
> >> {
> >> skip_emulated_instruction(vcpu);
> >> + /*
> >> + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> >> + * instead of halting, re-entering the guest, and exiting immediately
> >> + * on an interrupt window exit, go directly to the last step.
> >> + */
> >> + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> >> + & CPU_BASED_VIRTUAL_INTR_PENDING)
> >> + && (kvm_get_rflags(vcpu)& X86_EFLAGS_IF))
> >> + return handle_interrupt_window(vcpu);
> >> return kvm_emulate_halt(vcpu);
> >> }
> >
> >Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
> >KVM_REQ_EVENT is not set?
>
> Yes. Also, we want to clear CPU_BASED_VIRTUAL_INTR_PENDING.
Is there a reason why it cannot be handled in the main loop?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-16 16:51 ` Marcelo Tosatti
@ 2011-02-17 9:12 ` Avi Kivity
2011-02-17 16:16 ` Marcelo Tosatti
0 siblings, 1 reply; 10+ messages in thread
From: Avi Kivity @ 2011-02-17 9:12 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: kvm
On 02/16/2011 06:51 PM, Marcelo Tosatti wrote:
> On Wed, Feb 16, 2011 at 11:01:47AM +0200, Avi Kivity wrote:
> > On 02/15/2011 10:36 PM, Marcelo Tosatti wrote:
> > >On Mon, Feb 14, 2011 at 04:42:16PM +0200, Avi Kivity wrote:
> > >> Short-circuit an STI; HLT sequence while an interrupt is pending:
> > >> instead of halting, re-entering the guest, and exiting immediately
> > >> on an interrupt window exit, go directly to the last step.
> > >>
> > >> Saves a vmexit on workloads where interrupts are received synchronously;
> > >> an example is a disk backed by the host page cache where there is no
> > >> latency (from the guest's point of view) between the request and fulfilment.
> > >>
> > >> Signed-off-by: Avi Kivity<avi@redhat.com>
> > >> ---
> > >> arch/x86/kvm/vmx.c | 9 +++++++++
> > >> 1 files changed, 9 insertions(+), 0 deletions(-)
> > >>
> > >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > >> index ee1cd1a..541da0e 100644
> > >> --- a/arch/x86/kvm/vmx.c
> > >> +++ b/arch/x86/kvm/vmx.c
> > >> @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> > >> static int handle_halt(struct kvm_vcpu *vcpu)
> > >> {
> > >> skip_emulated_instruction(vcpu);
> > >> + /*
> > >> + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> > >> + * instead of halting, re-entering the guest, and exiting immediately
> > >> + * on an interrupt window exit, go directly to the last step.
> > >> + */
> > >> + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> > >> + & CPU_BASED_VIRTUAL_INTR_PENDING)
> > >> + && (kvm_get_rflags(vcpu)& X86_EFLAGS_IF))
> > >> + return handle_interrupt_window(vcpu);
> > >> return kvm_emulate_halt(vcpu);
> > >> }
> > >
> > >Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
> > >KVM_REQ_EVENT is not set?
> >
> > Yes. Also, we want to clear CPU_BASED_VIRTUAL_INTR_PENDING.
>
> Is there a reason why it cannot be handled in the main loop?
Don't follow. What are you suggesting?
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-17 9:12 ` Avi Kivity
@ 2011-02-17 16:16 ` Marcelo Tosatti
2011-02-20 9:04 ` Avi Kivity
0 siblings, 1 reply; 10+ messages in thread
From: Marcelo Tosatti @ 2011-02-17 16:16 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
On Thu, Feb 17, 2011 at 11:12:43AM +0200, Avi Kivity wrote:
> >> >> index ee1cd1a..541da0e 100644
> >> >> --- a/arch/x86/kvm/vmx.c
> >> >> +++ b/arch/x86/kvm/vmx.c
> >> >> @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> >> >> static int handle_halt(struct kvm_vcpu *vcpu)
> >> >> {
> >> >> skip_emulated_instruction(vcpu);
> >> >> + /*
> >> >> + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> >> >> + * instead of halting, re-entering the guest, and exiting immediately
> >> >> + * on an interrupt window exit, go directly to the last step.
> >> >> + */
> >> >> + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> >> >> + & CPU_BASED_VIRTUAL_INTR_PENDING)
> >> >> + && (kvm_get_rflags(vcpu)& X86_EFLAGS_IF))
> >> >> + return handle_interrupt_window(vcpu);
> >> >> return kvm_emulate_halt(vcpu);
> >> >> }
> >> >
> >> >Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
> >> >KVM_REQ_EVENT is not set?
> >>
> >> Yes. Also, we want to clear CPU_BASED_VIRTUAL_INTR_PENDING.
> >
> >Is there a reason why it cannot be handled in the main loop?
>
> Don't follow. What are you suggesting?
That vcpu main loop (inject_pending_events etc) should be able to inject
the interrupt and clear interrupt exiting, instead of a short circuit
in specific exit handlers, as an improvement on top of the current
patchset. Any numbers, BTW?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending
2011-02-17 16:16 ` Marcelo Tosatti
@ 2011-02-20 9:04 ` Avi Kivity
0 siblings, 0 replies; 10+ messages in thread
From: Avi Kivity @ 2011-02-20 9:04 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: kvm
On 02/17/2011 06:16 PM, Marcelo Tosatti wrote:
> On Thu, Feb 17, 2011 at 11:12:43AM +0200, Avi Kivity wrote:
> > >> >> index ee1cd1a..541da0e 100644
> > >> >> --- a/arch/x86/kvm/vmx.c
> > >> >> +++ b/arch/x86/kvm/vmx.c
> > >> >> @@ -3437,6 +3437,15 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu)
> > >> >> static int handle_halt(struct kvm_vcpu *vcpu)
> > >> >> {
> > >> >> skip_emulated_instruction(vcpu);
> > >> >> + /*
> > >> >> + * Short-circuit an STI; HLT sequence while an interrupt is pending:
> > >> >> + * instead of halting, re-entering the guest, and exiting immediately
> > >> >> + * on an interrupt window exit, go directly to the last step.
> > >> >> + */
> > >> >> + if ((to_vmx(vcpu)->cpu_based_vm_exec_control
> > >> >> + & CPU_BASED_VIRTUAL_INTR_PENDING)
> > >> >> + && (kvm_get_rflags(vcpu)& X86_EFLAGS_IF))
> > >> >> + return handle_interrupt_window(vcpu);
> > >> >> return kvm_emulate_halt(vcpu);
> > >> >> }
> > >> >
> > >> >Why does the normal vcpu entry path fails to inject the interrupt? Because after halt,
> > >> >KVM_REQ_EVENT is not set?
> > >>
> > >> Yes. Also, we want to clear CPU_BASED_VIRTUAL_INTR_PENDING.
> > >
> > >Is there a reason why it cannot be handled in the main loop?
> >
> > Don't follow. What are you suggesting?
>
> That vcpu main loop (inject_pending_events etc) should be able to inject
> the interrupt and clear interrupt exiting, instead of a short circuit
> in specific exit handlers, as an improvement on top of the current
> patchset.
Yes, it makes sense to make move virtual interrupt pending logic into
x86.c. On the other hand, it may conflict with using the hardware
interrupt queue on svm (which we don't make use of yet).
> Any numbers, BTW?
Not yet.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-02-20 9:05 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-14 14:42 [PATCH 0/3] Optimize STI; HLT while an interrupt is pending Avi Kivity
2011-02-14 14:42 ` [PATCH 1/3] KVM: VMX: Cache CPU_BASED_VM_EXEC_CONTROL VMCS field Avi Kivity
2011-02-14 14:42 ` [PATCH 2/3] KVM: VMX: Short circuit STI; HLT while an interrupt is pending Avi Kivity
2011-02-15 20:36 ` Marcelo Tosatti
2011-02-16 9:01 ` Avi Kivity
2011-02-16 16:51 ` Marcelo Tosatti
2011-02-17 9:12 ` Avi Kivity
2011-02-17 16:16 ` Marcelo Tosatti
2011-02-20 9:04 ` Avi Kivity
2011-02-14 14:42 ` [PATCH 3/3] KVM: SVM: " Avi Kivity
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.