All of lore.kernel.org
 help / color / mirror / Atom feed
From: Glauber Costa <glommer@redhat.com>
To: kvm@vger.kernel.org
Cc: avi@redhat.com
Subject: [PATCH] execute kvm_init_vcpu in the end of pc_new_cpu
Date: Tue,  5 May 2009 23:16:19 -0400	[thread overview]
Message-ID: <1241579779-17974-1-git-send-email-glommer@redhat.com> (raw)

When we create a new vcpu, we need to make sure that
all of the state it is going to use (apic state, for example)
already exists. We can do it nicely by making sure kvm_init_vcpu
is executed after everything else in cpu creation.

After that, the first call to KVM_SET_LAPIC ioctl will not find an
existant vcpu. So we introduce a function that tell us that the vcpu
is already initialized, and is it safe to call the ioctl. Otherwise,
just don't botter.

We then force the execution of the KVM_SET_LAPIC from within the new
vcpu thread.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 hw/apic.c            |   21 +++++++++++----------
 hw/pc.c              |    2 ++
 qemu-kvm.c           |   10 ++++++++++
 qemu-kvm.h           |    4 ++++
 target-i386/helper.c |    2 --
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/hw/apic.c b/hw/apic.c
index 8c059f6..b8112f1 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -891,6 +891,15 @@ static void kvm_kernel_lapic_load_from_user(APICState *s)
 
 #endif
 
+void qemu_kvm_load_lapic(CPUState *env)
+{
+#ifdef KVM_CAP_IRQCHIP
+    if (kvm_enabled() && kvm_vcpu_inited(env) && qemu_kvm_irqchip_in_kernel()) {
+        kvm_kernel_lapic_load_from_user(env->apic_state);
+    }
+#endif
+}
+
 static void apic_save(QEMUFile *f, void *opaque)
 {
     APICState *s = opaque;
@@ -965,11 +974,7 @@ static int apic_load(QEMUFile *f, void *opaque, int version_id)
     if (version_id >= 2)
         qemu_get_timer(f, s->timer);
 
-#ifdef KVM_CAP_IRQCHIP
-    if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) {
-        kvm_kernel_lapic_load_from_user(s);
-    }
-#endif
+    qemu_kvm_load_lapic(s->cpu_env);
 
     return 0;
 }
@@ -991,11 +996,7 @@ static void apic_reset(void *opaque)
          */
         s->lvt[APIC_LVT_LINT0] = 0x700;
     }
-#ifdef KVM_CAP_IRQCHIP
-    if (kvm_enabled() && qemu_kvm_irqchip_in_kernel()) {
-        kvm_kernel_lapic_load_from_user(s);
-    }
-#endif
+    qemu_kvm_load_lapic(s->cpu_env);
 }
 
 static CPUReadMemoryFunc *apic_mem_read[3] = {
diff --git a/hw/pc.c b/hw/pc.c
index db34f53..afa9eac 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -853,6 +853,8 @@ CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled)
         if (pci_enabled) {
             apic_init(env);
         }
+    if (kvm_enabled())
+        kvm_init_vcpu(env);
 	return env;
 }
 
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 68a9218..2e94693 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -427,6 +427,9 @@ static void *ap_main_loop(void *_env)
     kvm_create_vcpu(kvm_context, env->cpu_index);
     kvm_qemu_init_env(env);
 
+    /* APIC state creation takes place before we get here. So despite the fact that
+     * apic_reset() (called by apic_init) will also load the apic state, we have to redo it here
+     */
 #ifdef USE_KVM_DEVICE_ASSIGNMENT
     /* do ioperm for io ports of assigned devices */
     LIST_FOREACH(data, &ioperm_head, entries)
@@ -438,6 +441,8 @@ static void *ap_main_loop(void *_env)
     current_env->kvm_cpu_state.created = 1;
     pthread_cond_signal(&qemu_vcpu_cond);
 
+    qemu_kvm_load_lapic(env);
+
     /* and wait for machine initialization */
     while (!qemu_system_ready)
 	qemu_cond_wait(&qemu_system_cond);
@@ -455,6 +460,11 @@ void kvm_init_vcpu(CPUState *env)
 	qemu_cond_wait(&qemu_vcpu_cond);
 }
 
+int kvm_vcpu_inited(CPUState *env)
+{
+    return env->kvm_cpu_state.created;
+}
+
 int kvm_init_ap(void)
 {
 #ifdef TARGET_I386
diff --git a/qemu-kvm.h b/qemu-kvm.h
index ca59af8..a307976 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -16,6 +16,7 @@ int kvm_main_loop(void);
 int kvm_qemu_init(void);
 int kvm_qemu_create_context(void);
 int kvm_init_ap(void);
+int kvm_vcpu_inited(CPUState *env);
 void kvm_qemu_destroy(void);
 void kvm_load_registers(CPUState *env);
 void kvm_save_registers(CPUState *env);
@@ -31,6 +32,9 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
 int kvm_qemu_init_env(CPUState *env);
 int kvm_qemu_check_extension(int ext);
 void kvm_apic_init(CPUState *env);
+/* called from vcpu initialization */
+void qemu_kvm_load_lapic(CPUState *env);
+
 int kvm_set_irq(int irq, int level, int *status);
 
 int kvm_physical_memory_set_dirty_tracking(int enable);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 7440983..a273cac 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1695,7 +1695,5 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 #ifdef CONFIG_KQEMU
     kqemu_init(env);
 #endif
-    if (kvm_enabled())
-        kvm_init_vcpu(env);
     return env;
 }
-- 
1.5.6.6


             reply	other threads:[~2009-05-06  3:16 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-06  3:16 Glauber Costa [this message]
2009-05-06 13:53 ` [PATCH] execute kvm_init_vcpu in the end of pc_new_cpu Marcelo Tosatti
2009-05-06 14:03   ` Glauber Costa
2009-05-06 14:10 Glauber Costa
2009-05-06 14:56 ` Jan Kiszka
2009-05-06 15:17   ` Glauber Costa
2009-05-06 15:43     ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1241579779-17974-1-git-send-email-glommer@redhat.com \
    --to=glommer@redhat.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.