From patchwork Fri May 13 12:14:00 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 782792 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p4DCEiI2012256 for ; Fri, 13 May 2011 12:14:44 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932686Ab1EMMOi (ORCPT ); Fri, 13 May 2011 08:14:38 -0400 Received: from goliath.siemens.de ([192.35.17.28]:30163 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758598Ab1EMMOQ (ORCPT ); Fri, 13 May 2011 08:14:16 -0400 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.13.6/8.13.6) with ESMTP id p4DCEBCn028856; Fri, 13 May 2011 14:14:11 +0200 Received: from mchn199C.mchp.siemens.de ([139.25.109.49]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p4DCEAvB019933; Fri, 13 May 2011 14:14:11 +0200 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org Subject: [PATCH 06/16] qemu-kvm: Refactor irqchip and routing initialization Date: Fri, 13 May 2011 14:14:00 +0200 Message-Id: <29a2e9629d245b7f7ffa75df356168d72f9f5eff.1305288845.git.jan.kiszka@siemens.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 13 May 2011 12:14:44 +0000 (UTC) Push all irq routing setup into kvm_init_irq_routing and move arch dependent bits into kvm_arch_init_irq_routing. This will also help to merge qemu-kvm's init into upstream kvm_init. Signed-off-by: Jan Kiszka --- qemu-kvm-x86.c | 13 ++++++- qemu-kvm.c | 115 ++++++++++++++++++++++++++++---------------------------- qemu-kvm.h | 4 +- 3 files changed, 70 insertions(+), 62 deletions(-) diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index c039e16..53083bd 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -299,7 +299,7 @@ int kvm_arch_init_irq_routing(void) { int i, r; - if (kvm_irqchip && kvm_has_gsi_routing()) { + if (kvm_has_gsi_routing()) { kvm_clear_gsi_routes(); for (i = 0; i < 8; ++i) { if (i == 2) { @@ -327,7 +327,18 @@ int kvm_arch_init_irq_routing(void) } } kvm_commit_irq_routes(); + + if (!qemu_kvm_has_pit_state2()) { + no_hpet = 1; + } + } else { + /* If kernel can't do irq routing, interrupt source + * override 0->2 can not be set up as required by HPET. + * so we have to disable it. + */ + no_hpet = 1; } + return 0; } diff --git a/qemu-kvm.c b/qemu-kvm.c index fee6cdf..196c516 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -127,7 +127,7 @@ static int kvm_create_context(void); int kvm_init(void) { int fd; - int r, gsi_count, i; + int r, i; fd = open("/dev/kvm", O_RDWR); @@ -177,21 +177,6 @@ int kvm_init(void) #error Hypervisor too old: KVM_CAP_USER_MEMORY extension not supported #endif - gsi_count = kvm_get_gsi_count(kvm_context); - if (gsi_count > 0) { - int gsi_bits, i; - - /* Round up so we can search ints using ffs */ - gsi_bits = ALIGN(gsi_count, 32); - kvm_context->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8); - kvm_context->max_gsi = gsi_bits; - - /* Mark any over-allocated bits as already in use */ - for (i = gsi_count; i < gsi_bits; i++) { - set_gsi(kvm_context, i); - } - } - cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client); pthread_mutex_lock(&qemu_mutex); @@ -227,30 +212,68 @@ static int kvm_set_boot_vcpu_id(kvm_context_t kvm, uint32_t id) #endif } -void kvm_create_irqchip(kvm_context_t kvm) +static int kvm_init_irq_routing(kvm_context_t kvm) { - int r; +#ifdef KVM_CAP_IRQ_ROUTING + int r, gsi_count; + + gsi_count = kvm_get_gsi_count(kvm); + if (gsi_count > 0) { + int gsi_bits, i; + + /* Round up so we can search ints using ffs */ + gsi_bits = ALIGN(gsi_count, 32); + kvm->used_gsi_bitmap = qemu_mallocz(gsi_bits / 8); + kvm->max_gsi = gsi_bits; + + /* Mark any over-allocated bits as already in use */ + for (i = gsi_count; i < gsi_bits; i++) { + set_gsi(kvm, i); + } + } + + kvm->irq_routes = qemu_mallocz(sizeof(*kvm_context->irq_routes)); + kvm->nr_allocated_irq_routes = 0; + + r = kvm_arch_init_irq_routing(); + if (r < 0) { + return r; + } +#endif + + return 0; +} +int kvm_create_irqchip(kvm_context_t kvm) +{ #ifdef KVM_CAP_IRQCHIP - if (kvm_irqchip) { - r = kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_IRQCHIP); - if (r > 0) { /* kernel irqchip supported */ - r = kvm_vm_ioctl(kvm_state, KVM_CREATE_IRQCHIP); - if (r >= 0) { - kvm->irqchip_inject_ioctl = KVM_IRQ_LINE; + int r; + + if (!kvm_irqchip || !kvm_check_extension(kvm_state, KVM_CAP_IRQCHIP)) { + return 0; + } + + r = kvm_vm_ioctl(kvm_state, KVM_CREATE_IRQCHIP); + if (r < 0) { + fprintf(stderr, "Create kernel PIC irqchip failed\n"); + return r; + } + + kvm->irqchip_inject_ioctl = KVM_IRQ_LINE; #if defined(KVM_CAP_IRQ_INJECT_STATUS) && defined(KVM_IRQ_LINE_STATUS) - r = kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION, - KVM_CAP_IRQ_INJECT_STATUS); - if (r > 0) { - kvm->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS; - } + if (kvm_check_extension(kvm_state, KVM_CAP_IRQ_INJECT_STATUS)) { + kvm->irqchip_inject_ioctl = KVM_IRQ_LINE_STATUS; + } #endif - kvm_state->irqchip_in_kernel = 1; - } else - fprintf(stderr, "Create kernel PIC irqchip failed\n"); - } + kvm_state->irqchip_in_kernel = 1; + + r = kvm_init_irq_routing(kvm); + if (r < 0) { + return r; } #endif + + return 0; } #ifdef KVM_CAP_IRQCHIP @@ -1348,8 +1371,6 @@ int kvm_arch_init_irq_routing(void) } #endif -extern int no_hpet; - static int kvm_create_context(void) { static const char upgrade_note[] = @@ -1360,11 +1381,6 @@ static int kvm_create_context(void) kvm_state->pit_in_kernel = kvm_pit; -#ifdef KVM_CAP_IRQ_ROUTING - kvm_context->irq_routes = qemu_mallocz(sizeof(*kvm_context->irq_routes)); - kvm_context->nr_allocated_irq_routes = 0; -#endif - kvm_state->vmfd = kvm_ioctl(kvm_state, KVM_CREATE_VM, 0); if (kvm_state->vmfd < 0) { fprintf(stderr, "kvm_create_vm: %m\n"); @@ -1378,8 +1394,6 @@ static int kvm_create_context(void) return r; } - kvm_create_irqchip(kvm_context); - /* There was a nasty bug in < kvm-80 that prevents memory slots from being * destroyed properly. Since we rely on this capability, refuse to work * with any kernel without this capability. */ @@ -1390,7 +1404,7 @@ static int kvm_create_context(void) return -EINVAL; } - r = kvm_arch_init_irq_routing(); + r = kvm_create_irqchip(kvm_context); if (r < 0) { return r; } @@ -1424,21 +1438,6 @@ static int kvm_create_context(void) kvm_state->many_ioeventfds = kvm_check_many_ioeventfds(); kvm_init_ap(); - if (kvm_irqchip) { - if (!qemu_kvm_has_gsi_routing()) { -#ifdef TARGET_I386 - /* if kernel can't do irq routing, interrupt source - * override 0->2 can not be set up as required by hpet, - * so disable hpet. - */ - no_hpet = 1; - } else if (!qemu_kvm_has_pit_state2()) { - no_hpet = 1; - } -#else - } -#endif - } return 0; } diff --git a/qemu-kvm.h b/qemu-kvm.h index bf03be8..40d607b 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -74,7 +74,7 @@ int pre_kvm_run(kvm_context_t kvm, CPUState *env); int handle_io_window(kvm_context_t kvm); int try_push_interrupts(kvm_context_t kvm); -void kvm_create_irqchip(kvm_context_t kvm); +int kvm_create_irqchip(kvm_context_t kvm); /*! * \brief Start the VCPU @@ -449,13 +449,11 @@ int kvm_arch_halt(CPUState *env); int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip, int is_write); -#define qemu_kvm_has_gsi_routing() kvm_has_gsi_routing() #ifdef TARGET_I386 #define qemu_kvm_has_pit_state2() kvm_has_pit_state2(kvm_context) #endif #else #define kvm_nested 0 -#define qemu_kvm_has_gsi_routing() (0) #ifdef TARGET_I386 #define qemu_kvm_has_pit_state2() (0) #endif