[PATCH 06/16] qemu-kvm: Refactor irqchip and routing initialization

Jan Kiszka
2011-05-13T12:14:16Z

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 <jan.kiszka@siemens.com>
---
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
--
1.7.1