X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/1aab16c28a0232d898d6f56f5a56019472296ee7..3e2cf187eb3954fc406f81247a3fa598437ce1de:/qom/cpu.c diff --git a/qom/cpu.c b/qom/cpu.c index 7e005af37a..deb8880930 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -26,12 +26,15 @@ #include "qemu/notify.h" #include "qemu/log.h" #include "exec/log.h" +#include "exec/cpu-common.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" #include "hw/qdev-properties.h" #include "trace-root.h" -bool cpu_exists(int64_t id) +CPUInterruptHandler cpu_interrupt_handler; + +CPUState *cpu_by_arch_id(int64_t id) { CPUState *cpu; @@ -39,36 +42,39 @@ bool cpu_exists(int64_t id) CPUClass *cc = CPU_GET_CLASS(cpu); if (cc->get_arch_id(cpu) == id) { - return true; + return cpu; } } - return false; + return NULL; +} + +bool cpu_exists(int64_t id) +{ + return !!cpu_by_arch_id(id); } CPUState *cpu_generic_init(const char *typename, const char *cpu_model) { - char *str, *name, *featurestr; CPUState *cpu = NULL; ObjectClass *oc; CPUClass *cc; Error *err = NULL; + gchar **model_pieces; - str = g_strdup(cpu_model); - name = strtok(str, ","); + model_pieces = g_strsplit(cpu_model, ",", 2); - oc = cpu_class_by_name(typename, name); + oc = cpu_class_by_name(typename, model_pieces[0]); if (oc == NULL) { - g_free(str); + g_strfreev(model_pieces); return NULL; } cc = CPU_CLASS(oc); - featurestr = strtok(NULL, ","); /* TODO: all callers of cpu_generic_init() need to be converted to * call parse_features() only once, before calling cpu_generic_init(). */ - cc->parse_features(object_class_get_name(oc), featurestr, &err); - g_free(str); + cc->parse_features(object_class_get_name(oc), model_pieces[1], &err); + g_strfreev(model_pieces); if (err != NULL) { goto out; } @@ -113,9 +119,19 @@ static void cpu_common_get_memory_mapping(CPUState *cpu, error_setg(errp, "Obtaining memory mappings is unsupported on this CPU."); } +/* Resetting the IRQ comes from across the code base so we take the + * BQL here if we need to. cpu_interrupt assumes it is held.*/ void cpu_reset_interrupt(CPUState *cpu, int mask) { + bool need_lock = !qemu_mutex_iothread_locked(); + + if (need_lock) { + qemu_mutex_lock_iothread(); + } cpu->interrupt_request &= ~mask; + if (need_lock) { + qemu_mutex_unlock_iothread(); + } } void cpu_exit(CPUState *cpu) @@ -264,7 +280,6 @@ void cpu_reset(CPUState *cpu) static void cpu_common_reset(CPUState *cpu) { CPUClass *cc = CPU_GET_CLASS(cpu); - int i; if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index); @@ -282,13 +297,9 @@ static void cpu_common_reset(CPUState *cpu) cpu->crash_occurred = false; if (tcg_enabled()) { - for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) { - atomic_set(&cpu->tb_jmp_cache[i], NULL); - } + cpu_tb_jmp_cache_clear(cpu); -#ifdef CONFIG_SOFTMMU - tlb_flush(cpu, 0); -#endif + tcg_flush_softmmu_tlb(cpu); } } @@ -386,15 +397,11 @@ static void cpu_common_initfn(Object *obj) QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); - cpu->trace_dstate = bitmap_new(trace_get_vcpu_event_count()); - cpu_exec_initfn(cpu); } static void cpu_common_finalize(Object *obj) { - CPUState *cpu = CPU(obj); - g_free(cpu->trace_dstate); } static int64_t cpu_common_get_arch_id(CPUState *cpu) @@ -407,6 +414,17 @@ static vaddr cpu_adjust_watchpoint_address(CPUState *cpu, vaddr addr, int len) return addr; } +static void generic_handle_interrupt(CPUState *cpu, int mask) +{ + cpu->interrupt_request |= mask; + + if (!qemu_cpu_is_self(cpu)) { + qemu_cpu_kick(cpu); + } +} + +CPUInterruptHandler cpu_interrupt_handler = generic_handle_interrupt; + static void cpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -435,11 +453,12 @@ static void cpu_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_CPU, dc->categories); dc->realize = cpu_common_realizefn; dc->unrealize = cpu_common_unrealizefn; + dc->props = cpu_common_props; /* * Reason: CPUs still need special care by board code: wiring up * IRQs, adding reset handlers, halting non-first CPUs, ... */ - dc->cannot_instantiate_with_device_add_yet = true; + dc->user_creatable = false; } static const TypeInfo cpu_type_info = {