Message ID | 1343222672-25312-2-git-send-email-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
On 2012-07-25 15:24, Peter Maydell wrote: > On x86 interrupt injection is asynchronous (and therefore > VCPU idle management is done in the kernel) if and only > if there is an in-kernel irqchip. On other architectures this > isn't necessarily true (they may always do asynchronous > injection), so define a new kvm_async_interrupt_injection() > function instead of misusing kvm_irqchip_in_kernel(). > > Signed-off-by: Peter Maydell <peter.maydell@linaro.org> > --- > cpus.c | 3 ++- > kvm-all.c | 7 ++++++- > kvm-stub.c | 1 + > kvm.h | 11 +++++++++++ > 4 files changed, 20 insertions(+), 2 deletions(-) > > diff --git a/cpus.c b/cpus.c > index 756e624..584b298 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -69,7 +69,8 @@ static bool cpu_thread_is_idle(CPUArchState *env) > if (env->stopped || !runstate_is_running()) { > return true; > } > - if (!env->halted || qemu_cpu_has_work(env) || kvm_irqchip_in_kernel()) { > + if (!env->halted || qemu_cpu_has_work(env) || > + kvm_async_interrupt_injection()) { > return false; > } > return true; > diff --git a/kvm-all.c b/kvm-all.c > index 2148b20..3354c6f 100644 > --- a/kvm-all.c > +++ b/kvm-all.c > @@ -100,6 +100,7 @@ struct KVMState > > KVMState *kvm_state; > bool kvm_kernel_irqchip; > +bool kvm_async_interrupt_injection; > > static const KVMCapabilityInfo kvm_required_capabilites[] = { > KVM_CAP_INFO(USER_MEMORY), > @@ -857,7 +858,7 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level) > struct kvm_irq_level event; > int ret; > > - assert(kvm_irqchip_in_kernel()); > + assert(kvm_async_interrupt_injection()); > > event.level = level; > event.irq = irq; > @@ -1201,6 +1202,10 @@ static int kvm_irqchip_create(KVMState *s) > s->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS; > } > kvm_kernel_irqchip = true; > + /* If we have an in-kernel IRQ chip then we must have asynchronous > + * interrupt injection (though the reverse is not necessarily true) > + */ > + kvm_async_interrupt_injection = true; > > kvm_init_irq_routing(s); > > diff --git a/kvm-stub.c b/kvm-stub.c > index d23b11c..b4023d1 100644 > --- a/kvm-stub.c > +++ b/kvm-stub.c > @@ -19,6 +19,7 @@ > > KVMState *kvm_state; > bool kvm_kernel_irqchip; > +bool kvm_async_interrupt_injection; > > int kvm_init_vcpu(CPUArchState *env) > { > diff --git a/kvm.h b/kvm.h > index 2617dd5..00abe36 100644 > --- a/kvm.h > +++ b/kvm.h > @@ -24,13 +24,24 @@ > > extern int kvm_allowed; > extern bool kvm_kernel_irqchip; > +extern bool kvm_async_interrupt_injection; > > #if defined CONFIG_KVM || !defined NEED_CPU_H > #define kvm_enabled() (kvm_allowed) > #define kvm_irqchip_in_kernel() (kvm_kernel_irqchip) > +/** > + * kvm_async_interrupt_injection: > + * > + * Returns: true if we can inject interrupts into a KVM CPU > + * asynchronously (ie by ioctl from any thread at any time) > + * rather than having to do interrupt delivery synchronously > + * (where the vcpu must be stopped at a suitable point first). > + */ > +#define kvm_async_interrupt_injection() (kvm_async_interrupt_injection) > #else > #define kvm_enabled() (0) > #define kvm_irqchip_in_kernel() (false) > +#define kvm_async_interrupt_injection() (false) > #endif > > struct kvm_run; > Acked-by: Jan Kiszka <jan.kiszka@siemens.com>
diff --git a/cpus.c b/cpus.c index 756e624..584b298 100644 --- a/cpus.c +++ b/cpus.c @@ -69,7 +69,8 @@ static bool cpu_thread_is_idle(CPUArchState *env) if (env->stopped || !runstate_is_running()) { return true; } - if (!env->halted || qemu_cpu_has_work(env) || kvm_irqchip_in_kernel()) { + if (!env->halted || qemu_cpu_has_work(env) || + kvm_async_interrupt_injection()) { return false; } return true; diff --git a/kvm-all.c b/kvm-all.c index 2148b20..3354c6f 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -100,6 +100,7 @@ struct KVMState KVMState *kvm_state; bool kvm_kernel_irqchip; +bool kvm_async_interrupt_injection; static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(USER_MEMORY), @@ -857,7 +858,7 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level) struct kvm_irq_level event; int ret; - assert(kvm_irqchip_in_kernel()); + assert(kvm_async_interrupt_injection()); event.level = level; event.irq = irq; @@ -1201,6 +1202,10 @@ static int kvm_irqchip_create(KVMState *s) s->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS; } kvm_kernel_irqchip = true; + /* If we have an in-kernel IRQ chip then we must have asynchronous + * interrupt injection (though the reverse is not necessarily true) + */ + kvm_async_interrupt_injection = true; kvm_init_irq_routing(s); diff --git a/kvm-stub.c b/kvm-stub.c index d23b11c..b4023d1 100644 --- a/kvm-stub.c +++ b/kvm-stub.c @@ -19,6 +19,7 @@ KVMState *kvm_state; bool kvm_kernel_irqchip; +bool kvm_async_interrupt_injection; int kvm_init_vcpu(CPUArchState *env) { diff --git a/kvm.h b/kvm.h index 2617dd5..00abe36 100644 --- a/kvm.h +++ b/kvm.h @@ -24,13 +24,24 @@ extern int kvm_allowed; extern bool kvm_kernel_irqchip; +extern bool kvm_async_interrupt_injection; #if defined CONFIG_KVM || !defined NEED_CPU_H #define kvm_enabled() (kvm_allowed) #define kvm_irqchip_in_kernel() (kvm_kernel_irqchip) +/** + * kvm_async_interrupt_injection: + * + * Returns: true if we can inject interrupts into a KVM CPU + * asynchronously (ie by ioctl from any thread at any time) + * rather than having to do interrupt delivery synchronously + * (where the vcpu must be stopped at a suitable point first). + */ +#define kvm_async_interrupt_injection() (kvm_async_interrupt_injection) #else #define kvm_enabled() (0) #define kvm_irqchip_in_kernel() (false) +#define kvm_async_interrupt_injection() (false) #endif struct kvm_run;
On x86 interrupt injection is asynchronous (and therefore VCPU idle management is done in the kernel) if and only if there is an in-kernel irqchip. On other architectures this isn't necessarily true (they may always do asynchronous injection), so define a new kvm_async_interrupt_injection() function instead of misusing kvm_irqchip_in_kernel(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- cpus.c | 3 ++- kvm-all.c | 7 ++++++- kvm-stub.c | 1 + kvm.h | 11 +++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-)