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@xxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html