[PATCH 2/4] sipi and init: move common code

Glauber Costa
2009-06-03T21:19:34Z

provide functions to query and reset the state of sipi and
init in cpu's apic. This way we can move the kvm specific functions
out of the apic path.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
cpu-defs.h | 2 --
hw/apic.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
qemu-kvm.c | 26 ++++++--------------------
qemu-kvm.h | 7 +++++--
4 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/cpu-defs.h b/cpu-defs.h
index 1e071e7..e66e928 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -140,8 +140,6 @@ typedef struct CPUWatchpoint {
struct qemu_work_item;

struct KVMCPUState {
- int sipi_needed;
- int init;
pthread_t thread;
int signalled;
int stop;
diff --git a/hw/apic.c b/hw/apic.c
index 862289d..39e1675 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -86,6 +86,8 @@ typedef struct APICState {
uint32_t initial_count;
int64_t initial_count_load_time, next_time;
QEMUTimer *timer;
+ int sipi_needed;
+ int init;
} APICState;

static int apic_io_memory;
@@ -93,6 +95,45 @@ static APICState *local_apics[MAX_APICS + 1];
static int last_apic_id = 0;
static int apic_irq_delivered;

+int apic_init_received(CPUState *env)
+{
+ if (!env)
+ return 0;
+ if (!env->apic_state)
+ return 0;
+
+ return env->apic_state->init;
+}
+
+int apic_sipi_needed(CPUState *env)
+{
+ if (!env)
+ return 0;
+ if (!env->apic_state)
+ return 0;
+
+ return env->apic_state->sipi_needed;
+}
+
+void apic_reset_sipi(CPUState *env)
+{
+ if (!env)
+ return;
+ if (!env->apic_state)
+ return;
+
+ env->apic_state->sipi_needed = 0;
+}
+
+void apic_reset_init(CPUState *env)
+{
+ if (!env)
+ return;
+ if (!env->apic_state)
+ return;
+
+ env->apic_state->init = 0;
+}

static void apic_init_ipi(APICState *s);
static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
@@ -475,9 +516,8 @@ static void apic_init_ipi(APICState *s)
(!kvm_enabled() || !qemu_kvm_irqchip_in_kernel()))
s->cpu_env->halted = 1;

- if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel())
- if (s->cpu_env)
- kvm_apic_init(s->cpu_env);
+ if (s->cpu_env && s->cpu_env->cpu_index != 0)
+ s->init = 1;
}

/* send a SIPI message to the CPU to start it */
@@ -490,8 +530,7 @@ static void apic_startup(APICState *s, int vector_num)
cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
0xffff, 0);
env->halted = 0;
- if (kvm_enabled() && !qemu_kvm_irqchip_in_kernel())
- kvm_update_after_sipi(env);
+ s->sipi_needed = 1;
}

static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 68d3b92..b5954bc 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -134,19 +134,6 @@ void kvm_update_interrupt_request(CPUState *env)
}
}

-void kvm_update_after_sipi(CPUState *env)
-{
- env->kvm_cpu_state.sipi_needed = 1;
- kvm_update_interrupt_request(env);
-}
-
-void kvm_apic_init(CPUState *env)
-{
- if (env->cpu_index != 0)
- env->kvm_cpu_state.init = 1;
- kvm_update_interrupt_request(env);
-}
-
#include <signal.h>

static int try_push_interrupts(void *opaque)
@@ -332,7 +319,7 @@ static void kvm_vm_state_change_handler(void *context, int running, int reason)
static void update_regs_for_sipi(CPUState *env)
{
kvm_arch_update_regs_for_sipi(env);
- env->kvm_cpu_state.sipi_needed = 0;
+ apic_reset_sipi(env);
}

static void update_regs_for_init(CPUState *env)
@@ -345,11 +332,10 @@ static void update_regs_for_init(CPUState *env)

#ifdef TARGET_I386
/* restore SIPI vector */
- if(env->kvm_cpu_state.sipi_needed)
+ if (apic_sipi_needed(env))
env->segs[R_CS] = cs;
#endif
-
- env->kvm_cpu_state.init = 0;
+ apic_reset_init(env);
kvm_arch_load_regs(env);
}

@@ -407,12 +393,12 @@ static int kvm_main_loop_cpu(CPUState *env)
if (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI))
env->halted = 0;
if (!kvm_irqchip_in_kernel(kvm_context)) {
- if (env->kvm_cpu_state.init)
+ if (apic_init_received(env))
update_regs_for_init(env);
- if (env->kvm_cpu_state.sipi_needed)
+ if (apic_sipi_needed(env))
update_regs_for_sipi(env);
}
- if (!env->halted && !env->kvm_cpu_state.init)
+ if (!env->halted && !apic_init_received(env))
kvm_cpu_exec(env);
env->exit_request = 0;
env->exception_index = EXCP_INTERRUPT;
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 725589b..eb7dc29 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -31,9 +31,13 @@ void kvm_remove_all_breakpoints(CPUState *current_env);
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);
+/* FIXME: there should be an apic.h file */
/* called from vcpu initialization */
void qemu_kvm_load_lapic(CPUState *env);
+int apic_init_received(CPUState *env);
+int apic_sipi_needed(CPUState *env);
+void apic_reset_sipi(CPUState *env);
+void apic_reset_init(CPUState *env);

int kvm_set_irq(int irq, int level, int *status);

@@ -44,7 +48,6 @@ int kvm_get_phys_ram_page_bitmap(unsigned char *bitmap);
void qemu_kvm_call_with_env(void (*func)(void *), void *data, CPUState *env);
void qemu_kvm_cpuid_on_env(CPUState *env);
void kvm_inject_interrupt(CPUState *env, int mask);
-void kvm_update_after_sipi(CPUState *env);
void kvm_update_interrupt_request(CPUState *env);
void kvm_cpu_register_physical_memory(target_phys_addr_t start_addr,
unsigned long size,
--
1.5.6.6