Message ID | 20090407090811.2074.19043.stgit@trex.usersys.redhat.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
On Tuesday 07 April 2009 17:08:12 Gleb Natapov wrote: > Signed-off-by: Gleb Natapov <gleb@redhat.com> > --- > > arch/x86/kvm/irq.c | 39 +++++++++++++++++++++++---------------- > arch/x86/kvm/svm.c | 11 +++++++---- > arch/x86/kvm/vmx.c | 18 +++++++++--------- > arch/x86/kvm/x86.c | 4 ++-- > 4 files changed, 41 insertions(+), 31 deletions(-) > > diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c > index cf17ed5..6974e7c 100644 > --- a/arch/x86/kvm/irq.c > +++ b/arch/x86/kvm/irq.c > @@ -24,6 +24,7 @@ > > #include "irq.h" > #include "i8254.h" > +#include "x86.h" > > /* > * check if there are pending timer events > @@ -48,14 +49,17 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) > { > struct kvm_pic *s; > > - if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ > - if (kvm_apic_accept_pic_intr(v)) { > - s = pic_irqchip(v->kvm); /* PIC */ > - return s->output; > - } else > - return 0; > + if (irqchip_in_kernel(v->kvm)) { > + if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ > + if (kvm_apic_accept_pic_intr(v)) { > + s = pic_irqchip(v->kvm); /* PIC */ > + return s->output; > + } else > + return 0; > + } > + return 1; > } > - return 1; > + return v->arch.irq_summary; > } Use if (!irqchip_in_kernel(v->kvm)) for userspace seems more simple(rather than a series of indention...). > EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); > > @@ -64,18 +68,21 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); > */ > int kvm_cpu_get_interrupt(struct kvm_vcpu *v) > { > - struct kvm_pic *s; > - int vector; > + if (irqchip_in_kernel(v->kvm)) { > + struct kvm_pic *s; > + int vector; > > - vector = kvm_get_apic_interrupt(v); /* APIC */ > - if (vector == -1) { > - if (kvm_apic_accept_pic_intr(v)) { > - s = pic_irqchip(v->kvm); > - s->output = 0; /* PIC */ > - vector = kvm_pic_read_irq(v->kvm); > + vector = kvm_get_apic_interrupt(v); /* APIC */ > + if (vector == -1) { > + if (kvm_apic_accept_pic_intr(v)) { > + s = pic_irqchip(v->kvm); > + s->output = 0; /* PIC */ > + vector = kvm_pic_read_irq(v->kvm); > + } > } > + return vector; > } > - return vector; > + return kvm_pop_irq(v); > } > EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); > > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index 053f3c5..1903c27 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -2089,8 +2089,9 @@ static int interrupt_window_interception(struct > vcpu_svm *svm, * If the user space waits to inject interrupts, exit as soon > as * possible > */ > - if (kvm_run->request_interrupt_window && > - !svm->vcpu.arch.irq_summary) { > + if (!irqchip_in_kernel(svm->vcpu.kvm) && > + kvm_run->request_interrupt_window && > + !kvm_cpu_has_interrupt(&svm->vcpu)) { > ++svm->vcpu.stat.irq_window_exits; > kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; > return 0; > @@ -2371,7 +2372,8 @@ static void do_interrupt_requests(struct kvm_vcpu > *vcpu, (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) > + if (svm->vcpu.arch.interrupt_window_open && > + kvm_cpu_has_interrupt(&svm->vcpu)) > /* > * If interrupts enabled, and not blocked by sti or mov ss. Good. > */ > @@ -2381,7 +2383,8 @@ static void do_interrupt_requests(struct kvm_vcpu > *vcpu, * Interrupts blocked. Wait for unblock. > */ > if (!svm->vcpu.arch.interrupt_window_open && > - (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window)) > + (kvm_cpu_has_interrupt(&svm->vcpu) || > + kvm_run->request_interrupt_window)) > svm_set_vintr(svm); > else > svm_clear_vintr(svm); > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index c6997c0..b3292c1 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -2535,21 +2535,20 @@ static void do_interrupt_requests(struct kvm_vcpu > *vcpu, vmx_inject_nmi(vcpu); > if (vcpu->arch.nmi_pending) > enable_nmi_window(vcpu); > - else if (vcpu->arch.irq_summary > - || kvm_run->request_interrupt_window) > + else if (kvm_cpu_has_interrupt(vcpu) || > + kvm_run->request_interrupt_window) > enable_irq_window(vcpu); > return; > } > > if (vcpu->arch.interrupt_window_open) { > - if (vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending) > - kvm_queue_interrupt(vcpu, kvm_pop_irq(vcpu)); > + if (kvm_cpu_has_interrupt(vcpu) && !vcpu->arch.interrupt.pending) > + kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu)); > > if (vcpu->arch.interrupt.pending) > vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); > - } > - if (!vcpu->arch.interrupt_window_open && > - (vcpu->arch.irq_summary || kvm_run->request_interrupt_window)) > + } else if(kvm_cpu_has_interrupt(vcpu) || > + kvm_run->request_interrupt_window) > enable_irq_window(vcpu); > } > > @@ -2976,8 +2975,9 @@ static int handle_interrupt_window(struct kvm_vcpu > *vcpu, * If the user space waits to inject interrupts, exit as soon as * > possible > */ > - if (kvm_run->request_interrupt_window && > - !vcpu->arch.irq_summary) { > + if (!irqchip_in_kernel(vcpu->kvm) && > + kvm_run->request_interrupt_window && I think kvm_run->request_interrupt_window can indicate it's userspace irqchip? > + !kvm_cpu_has_interrupt(vcpu)) { > kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; > return 0; > } > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 52c7a29..6e30cef 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -3064,7 +3064,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); > static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, > struct kvm_run *kvm_run) > { > - return (!vcpu->arch.irq_summary && > + return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) && > kvm_run->request_interrupt_window && ditto.
> > * check if there are pending timer events > > @@ -48,14 +49,17 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) > > { > > struct kvm_pic *s; > > > > - if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ > > - if (kvm_apic_accept_pic_intr(v)) { > > - s = pic_irqchip(v->kvm); /* PIC */ > > - return s->output; > > - } else > > - return 0; > > + if (irqchip_in_kernel(v->kvm)) { > > + if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ > > + if (kvm_apic_accept_pic_intr(v)) { > > + s = pic_irqchip(v->kvm); /* PIC */ > > + return s->output; > > + } else > > + return 0; > > + } > > + return 1; > > } > > - return 1; > > + return v->arch.irq_summary; > > } > > Use if (!irqchip_in_kernel(v->kvm)) for userspace seems more simple(rather > than a series of indention...). > As long as lines are smaller then 80 chars I don't care much :) If new version of the patch will be needed I'll change this. > > > > @@ -2976,8 +2975,9 @@ static int handle_interrupt_window(struct kvm_vcpu > > *vcpu, * If the user space waits to inject interrupts, exit as soon as * > > possible > > */ > > - if (kvm_run->request_interrupt_window && > > - !vcpu->arch.irq_summary) { > > + if (!irqchip_in_kernel(vcpu->kvm) && > > + kvm_run->request_interrupt_window && > > I think kvm_run->request_interrupt_window can indicate it's userspace irqchip? > You are correct, but this value is directly controlled by userspase, so I added irqchip_in_kernel() check to protect from buggy userspace. -- 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
Gleb Natapov wrote: >>> * check if there are pending timer events >>> @@ -48,14 +49,17 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) >>> { >>> struct kvm_pic *s; >>> >>> - if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ >>> - if (kvm_apic_accept_pic_intr(v)) { >>> - s = pic_irqchip(v->kvm); /* PIC */ >>> - return s->output; >>> - } else >>> - return 0; >>> + if (irqchip_in_kernel(v->kvm)) { >>> + if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ >>> + if (kvm_apic_accept_pic_intr(v)) { >>> + s = pic_irqchip(v->kvm); /* PIC */ >>> + return s->output; >>> + } else >>> + return 0; >>> + } >>> + return 1; >>> } >>> - return 1; >>> + return v->arch.irq_summary; >>> } >>> >> Use if (!irqchip_in_kernel(v->kvm)) for userspace seems more simple(rather >> than a series of indention...). >> >> > As long as lines are smaller then 80 chars I don't care much :) If new > version of the patch will be needed I'll change this. > Please change it, the less indentation levels the better.
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index cf17ed5..6974e7c 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c @@ -24,6 +24,7 @@ #include "irq.h" #include "i8254.h" +#include "x86.h" /* * check if there are pending timer events @@ -48,14 +49,17 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) { struct kvm_pic *s; - if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ - if (kvm_apic_accept_pic_intr(v)) { - s = pic_irqchip(v->kvm); /* PIC */ - return s->output; - } else - return 0; + if (irqchip_in_kernel(v->kvm)) { + if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ + if (kvm_apic_accept_pic_intr(v)) { + s = pic_irqchip(v->kvm); /* PIC */ + return s->output; + } else + return 0; + } + return 1; } - return 1; + return v->arch.irq_summary; } EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); @@ -64,18 +68,21 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); */ int kvm_cpu_get_interrupt(struct kvm_vcpu *v) { - struct kvm_pic *s; - int vector; + if (irqchip_in_kernel(v->kvm)) { + struct kvm_pic *s; + int vector; - vector = kvm_get_apic_interrupt(v); /* APIC */ - if (vector == -1) { - if (kvm_apic_accept_pic_intr(v)) { - s = pic_irqchip(v->kvm); - s->output = 0; /* PIC */ - vector = kvm_pic_read_irq(v->kvm); + vector = kvm_get_apic_interrupt(v); /* APIC */ + if (vector == -1) { + if (kvm_apic_accept_pic_intr(v)) { + s = pic_irqchip(v->kvm); + s->output = 0; /* PIC */ + vector = kvm_pic_read_irq(v->kvm); + } } + return vector; } - return vector; + return kvm_pop_irq(v); } EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 053f3c5..1903c27 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2089,8 +2089,9 @@ static int interrupt_window_interception(struct vcpu_svm *svm, * If the user space waits to inject interrupts, exit as soon as * possible */ - if (kvm_run->request_interrupt_window && - !svm->vcpu.arch.irq_summary) { + if (!irqchip_in_kernel(svm->vcpu.kvm) && + kvm_run->request_interrupt_window && + !kvm_cpu_has_interrupt(&svm->vcpu)) { ++svm->vcpu.stat.irq_window_exits; kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; return 0; @@ -2371,7 +2372,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu, (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) + if (svm->vcpu.arch.interrupt_window_open && + kvm_cpu_has_interrupt(&svm->vcpu)) /* * If interrupts enabled, and not blocked by sti or mov ss. Good. */ @@ -2381,7 +2383,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu, * Interrupts blocked. Wait for unblock. */ if (!svm->vcpu.arch.interrupt_window_open && - (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window)) + (kvm_cpu_has_interrupt(&svm->vcpu) || + kvm_run->request_interrupt_window)) svm_set_vintr(svm); else svm_clear_vintr(svm); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c6997c0..b3292c1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2535,21 +2535,20 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu, vmx_inject_nmi(vcpu); if (vcpu->arch.nmi_pending) enable_nmi_window(vcpu); - else if (vcpu->arch.irq_summary - || kvm_run->request_interrupt_window) + else if (kvm_cpu_has_interrupt(vcpu) || + kvm_run->request_interrupt_window) enable_irq_window(vcpu); return; } if (vcpu->arch.interrupt_window_open) { - if (vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending) - kvm_queue_interrupt(vcpu, kvm_pop_irq(vcpu)); + if (kvm_cpu_has_interrupt(vcpu) && !vcpu->arch.interrupt.pending) + kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu)); if (vcpu->arch.interrupt.pending) vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); - } - if (!vcpu->arch.interrupt_window_open && - (vcpu->arch.irq_summary || kvm_run->request_interrupt_window)) + } else if(kvm_cpu_has_interrupt(vcpu) || + kvm_run->request_interrupt_window) enable_irq_window(vcpu); } @@ -2976,8 +2975,9 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu, * If the user space waits to inject interrupts, exit as soon as * possible */ - if (kvm_run->request_interrupt_window && - !vcpu->arch.irq_summary) { + if (!irqchip_in_kernel(vcpu->kvm) && + kvm_run->request_interrupt_window && + !kvm_cpu_has_interrupt(vcpu)) { kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; return 0; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 52c7a29..6e30cef 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3064,7 +3064,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - return (!vcpu->arch.irq_summary && + return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) && kvm_run->request_interrupt_window && vcpu->arch.interrupt_window_open && (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF)); @@ -3081,7 +3081,7 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu, else kvm_run->ready_for_interrupt_injection = (vcpu->arch.interrupt_window_open && - vcpu->arch.irq_summary == 0); + !kvm_cpu_has_interrupt(vcpu)); } static void vapic_enter(struct kvm_vcpu *vcpu)
Signed-off-by: Gleb Natapov <gleb@redhat.com> --- arch/x86/kvm/irq.c | 39 +++++++++++++++++++++++---------------- arch/x86/kvm/svm.c | 11 +++++++---- arch/x86/kvm/vmx.c | 18 +++++++++--------- arch/x86/kvm/x86.c | 4 ++-- 4 files changed, 41 insertions(+), 31 deletions(-) -- 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