1d9f24bf5SPaolo Bonzini /* 2d9f24bf5SPaolo Bonzini * Target-specific parts of the CPU object 3d9f24bf5SPaolo Bonzini * 4d9f24bf5SPaolo Bonzini * Copyright (c) 2003 Fabrice Bellard 5d9f24bf5SPaolo Bonzini * 6d9f24bf5SPaolo Bonzini * This library is free software; you can redistribute it and/or 7d9f24bf5SPaolo Bonzini * modify it under the terms of the GNU Lesser General Public 8d9f24bf5SPaolo Bonzini * License as published by the Free Software Foundation; either 9d9f24bf5SPaolo Bonzini * version 2 of the License, or (at your option) any later version. 10d9f24bf5SPaolo Bonzini * 11d9f24bf5SPaolo Bonzini * This library is distributed in the hope that it will be useful, 12d9f24bf5SPaolo Bonzini * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d9f24bf5SPaolo Bonzini * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14d9f24bf5SPaolo Bonzini * Lesser General Public License for more details. 15d9f24bf5SPaolo Bonzini * 16d9f24bf5SPaolo Bonzini * You should have received a copy of the GNU Lesser General Public 17d9f24bf5SPaolo Bonzini * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18d9f24bf5SPaolo Bonzini */ 19d9f24bf5SPaolo Bonzini 20d9f24bf5SPaolo Bonzini #include "qemu/osdep.h" 21d9f24bf5SPaolo Bonzini #include "qapi/error.h" 22d9f24bf5SPaolo Bonzini 23d9f24bf5SPaolo Bonzini #include "exec/target_page.h" 2474781c08SPhilippe Mathieu-Daudé #include "exec/page-protection.h" 25d9f24bf5SPaolo Bonzini #include "hw/qdev-core.h" 26d9f24bf5SPaolo Bonzini #include "hw/qdev-properties.h" 27d9f24bf5SPaolo Bonzini #include "qemu/error-report.h" 28dfa47531SGavin Shan #include "qemu/qemu-print.h" 29d9f24bf5SPaolo Bonzini #include "migration/vmstate.h" 30d9f24bf5SPaolo Bonzini #ifdef CONFIG_USER_ONLY 31d9f24bf5SPaolo Bonzini #include "qemu.h" 32d9f24bf5SPaolo Bonzini #else 338b80bd28SPhilippe Mathieu-Daudé #include "hw/core/sysemu-cpu-ops.h" 34d9f24bf5SPaolo Bonzini #include "exec/address-spaces.h" 355f8d88bdSPhilippe Mathieu-Daudé #include "exec/memory.h" 36d9f24bf5SPaolo Bonzini #endif 37*32cad1ffSPhilippe Mathieu-Daudé #include "system/cpus.h" 38*32cad1ffSPhilippe Mathieu-Daudé #include "system/tcg.h" 3942508261SPhilippe Mathieu-Daudé #include "exec/tswap.h" 405b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h" 41377bf6f3SPhilippe Mathieu-Daudé #include "exec/cpu-common.h" 423b04508cSPhilippe Mathieu-Daudé #include "exec/exec-all.h" 43548c9609SAlex Bennée #include "exec/tb-flush.h" 443b9bd3f4SPaolo Bonzini #include "exec/translate-all.h" 45d9f24bf5SPaolo Bonzini #include "exec/log.h" 4630565f10SClaudio Fontana #include "hw/core/accel-cpu.h" 47ad1a706fSRichard Henderson #include "trace/trace-root.h" 483b04508cSPhilippe Mathieu-Daudé #include "qemu/accel.h" 49d9f24bf5SPaolo Bonzini 50d9f24bf5SPaolo Bonzini #ifndef CONFIG_USER_ONLY 51d9f24bf5SPaolo Bonzini static int cpu_common_post_load(void *opaque, int version_id) 52d9f24bf5SPaolo Bonzini { 53d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 54d9f24bf5SPaolo Bonzini 55d9f24bf5SPaolo Bonzini /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 56d9f24bf5SPaolo Bonzini version_id is increased. */ 57d9f24bf5SPaolo Bonzini cpu->interrupt_request &= ~0x01; 58d9f24bf5SPaolo Bonzini tlb_flush(cpu); 59d9f24bf5SPaolo Bonzini 60d9f24bf5SPaolo Bonzini /* loadvm has just updated the content of RAM, bypassing the 61d9f24bf5SPaolo Bonzini * usual mechanisms that ensure we flush TBs for writes to 62d9f24bf5SPaolo Bonzini * memory we've translated code from. So we must flush all TBs, 63d9f24bf5SPaolo Bonzini * which will now be stale. 64d9f24bf5SPaolo Bonzini */ 65d9f24bf5SPaolo Bonzini tb_flush(cpu); 66d9f24bf5SPaolo Bonzini 67d9f24bf5SPaolo Bonzini return 0; 68d9f24bf5SPaolo Bonzini } 69d9f24bf5SPaolo Bonzini 70d9f24bf5SPaolo Bonzini static int cpu_common_pre_load(void *opaque) 71d9f24bf5SPaolo Bonzini { 72d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 73d9f24bf5SPaolo Bonzini 74d9f24bf5SPaolo Bonzini cpu->exception_index = -1; 75d9f24bf5SPaolo Bonzini 76d9f24bf5SPaolo Bonzini return 0; 77d9f24bf5SPaolo Bonzini } 78d9f24bf5SPaolo Bonzini 79d9f24bf5SPaolo Bonzini static bool cpu_common_exception_index_needed(void *opaque) 80d9f24bf5SPaolo Bonzini { 81d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 82d9f24bf5SPaolo Bonzini 83d9f24bf5SPaolo Bonzini return tcg_enabled() && cpu->exception_index != -1; 84d9f24bf5SPaolo Bonzini } 85d9f24bf5SPaolo Bonzini 86d9f24bf5SPaolo Bonzini static const VMStateDescription vmstate_cpu_common_exception_index = { 87d9f24bf5SPaolo Bonzini .name = "cpu_common/exception_index", 88d9f24bf5SPaolo Bonzini .version_id = 1, 89d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 90d9f24bf5SPaolo Bonzini .needed = cpu_common_exception_index_needed, 91ee1381ceSRichard Henderson .fields = (const VMStateField[]) { 92d9f24bf5SPaolo Bonzini VMSTATE_INT32(exception_index, CPUState), 93d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 94d9f24bf5SPaolo Bonzini } 95d9f24bf5SPaolo Bonzini }; 96d9f24bf5SPaolo Bonzini 97d9f24bf5SPaolo Bonzini static bool cpu_common_crash_occurred_needed(void *opaque) 98d9f24bf5SPaolo Bonzini { 99d9f24bf5SPaolo Bonzini CPUState *cpu = opaque; 100d9f24bf5SPaolo Bonzini 101d9f24bf5SPaolo Bonzini return cpu->crash_occurred; 102d9f24bf5SPaolo Bonzini } 103d9f24bf5SPaolo Bonzini 104d9f24bf5SPaolo Bonzini static const VMStateDescription vmstate_cpu_common_crash_occurred = { 105d9f24bf5SPaolo Bonzini .name = "cpu_common/crash_occurred", 106d9f24bf5SPaolo Bonzini .version_id = 1, 107d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 108d9f24bf5SPaolo Bonzini .needed = cpu_common_crash_occurred_needed, 109ee1381ceSRichard Henderson .fields = (const VMStateField[]) { 110d9f24bf5SPaolo Bonzini VMSTATE_BOOL(crash_occurred, CPUState), 111d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 112d9f24bf5SPaolo Bonzini } 113d9f24bf5SPaolo Bonzini }; 114d9f24bf5SPaolo Bonzini 115d9f24bf5SPaolo Bonzini const VMStateDescription vmstate_cpu_common = { 116d9f24bf5SPaolo Bonzini .name = "cpu_common", 117d9f24bf5SPaolo Bonzini .version_id = 1, 118d9f24bf5SPaolo Bonzini .minimum_version_id = 1, 119d9f24bf5SPaolo Bonzini .pre_load = cpu_common_pre_load, 120d9f24bf5SPaolo Bonzini .post_load = cpu_common_post_load, 121ee1381ceSRichard Henderson .fields = (const VMStateField[]) { 122d9f24bf5SPaolo Bonzini VMSTATE_UINT32(halted, CPUState), 123d9f24bf5SPaolo Bonzini VMSTATE_UINT32(interrupt_request, CPUState), 124d9f24bf5SPaolo Bonzini VMSTATE_END_OF_LIST() 125d9f24bf5SPaolo Bonzini }, 126ee1381ceSRichard Henderson .subsections = (const VMStateDescription * const []) { 127d9f24bf5SPaolo Bonzini &vmstate_cpu_common_exception_index, 128d9f24bf5SPaolo Bonzini &vmstate_cpu_common_crash_occurred, 129d9f24bf5SPaolo Bonzini NULL 130d9f24bf5SPaolo Bonzini } 131d9f24bf5SPaolo Bonzini }; 132d9f24bf5SPaolo Bonzini #endif 133d9f24bf5SPaolo Bonzini 13479a99091SPhilippe Mathieu-Daudé bool cpu_exec_realizefn(CPUState *cpu, Error **errp) 135d9f24bf5SPaolo Bonzini { 1366fbdff87SAlex Bennée /* cache the cpu class for the hotpath */ 1376fbdff87SAlex Bennée cpu->cc = CPU_GET_CLASS(cpu); 138d9f24bf5SPaolo Bonzini 139bd684b2fSPhilippe Mathieu-Daudé if (!accel_cpu_common_realize(cpu, errp)) { 14079a99091SPhilippe Mathieu-Daudé return false; 1419ea057dcSClaudio Fontana } 1424e4fa6c1SRichard Henderson 1434e4fa6c1SRichard Henderson /* Wait until cpu initialization complete before exposing cpu. */ 1444e4fa6c1SRichard Henderson cpu_list_add(cpu); 1454e4fa6c1SRichard Henderson 1467df5e3d6SClaudio Fontana #ifdef CONFIG_USER_ONLY 1474336073bSPhilippe Mathieu-Daudé assert(qdev_get_vmsd(DEVICE(cpu)) == NULL || 1484336073bSPhilippe Mathieu-Daudé qdev_get_vmsd(DEVICE(cpu))->unmigratable); 1497df5e3d6SClaudio Fontana #else 1507df5e3d6SClaudio Fontana if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 1517df5e3d6SClaudio Fontana vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 1527df5e3d6SClaudio Fontana } 1536fbdff87SAlex Bennée if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 1546fbdff87SAlex Bennée vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu); 1557df5e3d6SClaudio Fontana } 1567df5e3d6SClaudio Fontana #endif /* CONFIG_USER_ONLY */ 15779a99091SPhilippe Mathieu-Daudé 15879a99091SPhilippe Mathieu-Daudé return true; 1597df5e3d6SClaudio Fontana } 1607df5e3d6SClaudio Fontana 1617df5e3d6SClaudio Fontana void cpu_exec_unrealizefn(CPUState *cpu) 1627df5e3d6SClaudio Fontana { 163feece4d0SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 1647df5e3d6SClaudio Fontana CPUClass *cc = CPU_GET_CLASS(cpu); 165d9f24bf5SPaolo Bonzini 166feece4d0SPhilippe Mathieu-Daudé if (cc->sysemu_ops->legacy_vmsd != NULL) { 167feece4d0SPhilippe Mathieu-Daudé vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu); 168d9f24bf5SPaolo Bonzini } 169d9f24bf5SPaolo Bonzini if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 170d9f24bf5SPaolo Bonzini vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 171d9f24bf5SPaolo Bonzini } 172d9f24bf5SPaolo Bonzini #endif 1734731f89bSEmilio Cota 1747df5e3d6SClaudio Fontana cpu_list_remove(cpu); 1754731f89bSEmilio Cota /* 1764731f89bSEmilio Cota * Now that the vCPU has been removed from the RCU list, we can call 1771aa1d830SPhilippe Mathieu-Daudé * accel_cpu_common_unrealize, which may free fields using call_rcu. 1784731f89bSEmilio Cota */ 1791aa1d830SPhilippe Mathieu-Daudé accel_cpu_common_unrealize(cpu); 180d9f24bf5SPaolo Bonzini } 181d9f24bf5SPaolo Bonzini 182995b87deSRichard Henderson /* 1836e8dcacdSRichard Henderson * This can't go in hw/core/cpu.c because that file is compiled only 1846e8dcacdSRichard Henderson * once for both user-mode and system builds. 1856e8dcacdSRichard Henderson */ 1869aec5dc3SRichard Henderson static const Property cpu_common_props[] = { 1876e8dcacdSRichard Henderson #ifdef CONFIG_USER_ONLY 1886e8dcacdSRichard Henderson /* 1896e8dcacdSRichard Henderson * Create a property for the user-only object, so users can 1906e8dcacdSRichard Henderson * adjust prctl(PR_SET_UNALIGN) from the command-line. 1916e8dcacdSRichard Henderson * Has no effect if the target does not support the feature. 1926e8dcacdSRichard Henderson */ 1936e8dcacdSRichard Henderson DEFINE_PROP_BOOL("prctl-unalign-sigbus", CPUState, 1946e8dcacdSRichard Henderson prctl_unalign_sigbus, false), 1956e8dcacdSRichard Henderson #else 1966e8dcacdSRichard Henderson /* 19754b99122SPhilippe Mathieu-Daudé * Create a memory property for system CPU object, so users can 1986e8dcacdSRichard Henderson * wire up its memory. The default if no link is set up is to use 199995b87deSRichard Henderson * the system address space. 200995b87deSRichard Henderson */ 201995b87deSRichard Henderson DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 202995b87deSRichard Henderson MemoryRegion *), 203995b87deSRichard Henderson #endif 204995b87deSRichard Henderson DEFINE_PROP_END_OF_LIST(), 205995b87deSRichard Henderson }; 206995b87deSRichard Henderson 2070f9237f4SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 2080c3c25fcSPeter Maydell static bool cpu_get_start_powered_off(Object *obj, Error **errp) 2090c3c25fcSPeter Maydell { 2100c3c25fcSPeter Maydell CPUState *cpu = CPU(obj); 2110c3c25fcSPeter Maydell return cpu->start_powered_off; 2120c3c25fcSPeter Maydell } 2130c3c25fcSPeter Maydell 2140c3c25fcSPeter Maydell static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 2150c3c25fcSPeter Maydell { 2160c3c25fcSPeter Maydell CPUState *cpu = CPU(obj); 2170c3c25fcSPeter Maydell cpu->start_powered_off = value; 2180c3c25fcSPeter Maydell } 2190f9237f4SPhilippe Mathieu-Daudé #endif 2200c3c25fcSPeter Maydell 221995b87deSRichard Henderson void cpu_class_init_props(DeviceClass *dc) 222995b87deSRichard Henderson { 2230f9237f4SPhilippe Mathieu-Daudé #ifndef CONFIG_USER_ONLY 2240c3c25fcSPeter Maydell ObjectClass *oc = OBJECT_CLASS(dc); 2250c3c25fcSPeter Maydell 2260c3c25fcSPeter Maydell /* 2270c3c25fcSPeter Maydell * We can't use DEFINE_PROP_BOOL in the Property array for this 2280c3c25fcSPeter Maydell * property, because we want this to be settable after realize. 2290c3c25fcSPeter Maydell */ 2300c3c25fcSPeter Maydell object_class_property_add_bool(oc, "start-powered-off", 2310c3c25fcSPeter Maydell cpu_get_start_powered_off, 2320c3c25fcSPeter Maydell cpu_set_start_powered_off); 2330f9237f4SPhilippe Mathieu-Daudé #endif 2340f9237f4SPhilippe Mathieu-Daudé 2350f9237f4SPhilippe Mathieu-Daudé device_class_set_props(dc, cpu_common_props); 236995b87deSRichard Henderson } 237995b87deSRichard Henderson 238d9f24bf5SPaolo Bonzini void cpu_exec_initfn(CPUState *cpu) 239d9f24bf5SPaolo Bonzini { 240d9f24bf5SPaolo Bonzini cpu->as = NULL; 241d9f24bf5SPaolo Bonzini cpu->num_ases = 0; 242d9f24bf5SPaolo Bonzini 243d9f24bf5SPaolo Bonzini #ifndef CONFIG_USER_ONLY 244d9f24bf5SPaolo Bonzini cpu->memory = get_system_memory(); 245d9f24bf5SPaolo Bonzini object_ref(OBJECT(cpu->memory)); 246d9f24bf5SPaolo Bonzini #endif 247d9f24bf5SPaolo Bonzini } 248d9f24bf5SPaolo Bonzini 249445946f4SGavin Shan char *cpu_model_from_type(const char *typename) 250445946f4SGavin Shan { 251445946f4SGavin Shan const char *suffix = "-" CPU_RESOLVING_TYPE; 252445946f4SGavin Shan 253445946f4SGavin Shan if (!object_class_by_name(typename)) { 254445946f4SGavin Shan return NULL; 255445946f4SGavin Shan } 256445946f4SGavin Shan 257445946f4SGavin Shan if (g_str_has_suffix(typename, suffix)) { 258445946f4SGavin Shan return g_strndup(typename, strlen(typename) - strlen(suffix)); 259445946f4SGavin Shan } 260445946f4SGavin Shan 261445946f4SGavin Shan return g_strdup(typename); 262445946f4SGavin Shan } 263445946f4SGavin Shan 264d9f24bf5SPaolo Bonzini const char *parse_cpu_option(const char *cpu_option) 265d9f24bf5SPaolo Bonzini { 266d9f24bf5SPaolo Bonzini ObjectClass *oc; 267d9f24bf5SPaolo Bonzini CPUClass *cc; 268d9f24bf5SPaolo Bonzini gchar **model_pieces; 269d9f24bf5SPaolo Bonzini const char *cpu_type; 270d9f24bf5SPaolo Bonzini 271d9f24bf5SPaolo Bonzini model_pieces = g_strsplit(cpu_option, ",", 2); 272d9f24bf5SPaolo Bonzini if (!model_pieces[0]) { 273d9f24bf5SPaolo Bonzini error_report("-cpu option cannot be empty"); 274d9f24bf5SPaolo Bonzini exit(1); 275d9f24bf5SPaolo Bonzini } 276d9f24bf5SPaolo Bonzini 277d9f24bf5SPaolo Bonzini oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); 278d9f24bf5SPaolo Bonzini if (oc == NULL) { 279d9f24bf5SPaolo Bonzini error_report("unable to find CPU model '%s'", model_pieces[0]); 280d9f24bf5SPaolo Bonzini g_strfreev(model_pieces); 281d9f24bf5SPaolo Bonzini exit(EXIT_FAILURE); 282d9f24bf5SPaolo Bonzini } 283d9f24bf5SPaolo Bonzini 284d9f24bf5SPaolo Bonzini cpu_type = object_class_get_name(oc); 285d9f24bf5SPaolo Bonzini cc = CPU_CLASS(oc); 286d9f24bf5SPaolo Bonzini cc->parse_features(cpu_type, model_pieces[1], &error_fatal); 287d9f24bf5SPaolo Bonzini g_strfreev(model_pieces); 288d9f24bf5SPaolo Bonzini return cpu_type; 289d9f24bf5SPaolo Bonzini } 290d9f24bf5SPaolo Bonzini 291dfa47531SGavin Shan #ifndef cpu_list 292dfa47531SGavin Shan static void cpu_list_entry(gpointer data, gpointer user_data) 293dfa47531SGavin Shan { 294dfa47531SGavin Shan CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data)); 295dfa47531SGavin Shan const char *typename = object_class_get_name(OBJECT_CLASS(data)); 296dfa47531SGavin Shan g_autofree char *model = cpu_model_from_type(typename); 297dfa47531SGavin Shan 298dfa47531SGavin Shan if (cc->deprecation_note) { 299dfa47531SGavin Shan qemu_printf(" %s (deprecated)\n", model); 300dfa47531SGavin Shan } else { 301dfa47531SGavin Shan qemu_printf(" %s\n", model); 302dfa47531SGavin Shan } 303dfa47531SGavin Shan } 304dfa47531SGavin Shan 305dfa47531SGavin Shan static void cpu_list(void) 306dfa47531SGavin Shan { 307dfa47531SGavin Shan GSList *list; 308dfa47531SGavin Shan 309dfa47531SGavin Shan list = object_class_get_list_sorted(TYPE_CPU, false); 310dfa47531SGavin Shan qemu_printf("Available CPUs:\n"); 311dfa47531SGavin Shan g_slist_foreach(list, cpu_list_entry, NULL); 312dfa47531SGavin Shan g_slist_free(list); 313dfa47531SGavin Shan } 314dfa47531SGavin Shan #endif 315dfa47531SGavin Shan 316c138c3b8SThomas Huth void list_cpus(void) 317377bf6f3SPhilippe Mathieu-Daudé { 318377bf6f3SPhilippe Mathieu-Daudé cpu_list(); 319377bf6f3SPhilippe Mathieu-Daudé } 320377bf6f3SPhilippe Mathieu-Daudé 321d9f24bf5SPaolo Bonzini /* enable or disable single step mode. EXCP_DEBUG is returned by the 322d9f24bf5SPaolo Bonzini CPU loop after each instruction */ 323d9f24bf5SPaolo Bonzini void cpu_single_step(CPUState *cpu, int enabled) 324d9f24bf5SPaolo Bonzini { 325d9f24bf5SPaolo Bonzini if (cpu->singlestep_enabled != enabled) { 326d9f24bf5SPaolo Bonzini cpu->singlestep_enabled = enabled; 327412ae126SMads Ynddal 328412ae126SMads Ynddal #if !defined(CONFIG_USER_ONLY) 329412ae126SMads Ynddal const AccelOpsClass *ops = cpus_get_accel(); 330412ae126SMads Ynddal if (ops->update_guest_debug) { 331412ae126SMads Ynddal ops->update_guest_debug(cpu); 332d9f24bf5SPaolo Bonzini } 333412ae126SMads Ynddal #endif 334412ae126SMads Ynddal 335ad1a706fSRichard Henderson trace_breakpoint_singlestep(cpu->cpu_index, enabled); 336d9f24bf5SPaolo Bonzini } 337d9f24bf5SPaolo Bonzini } 338d9f24bf5SPaolo Bonzini 339d9f24bf5SPaolo Bonzini void cpu_abort(CPUState *cpu, const char *fmt, ...) 340d9f24bf5SPaolo Bonzini { 341d9f24bf5SPaolo Bonzini va_list ap; 342d9f24bf5SPaolo Bonzini va_list ap2; 343d9f24bf5SPaolo Bonzini 344d9f24bf5SPaolo Bonzini va_start(ap, fmt); 345d9f24bf5SPaolo Bonzini va_copy(ap2, ap); 346d9f24bf5SPaolo Bonzini fprintf(stderr, "qemu: fatal: "); 347d9f24bf5SPaolo Bonzini vfprintf(stderr, fmt, ap); 348d9f24bf5SPaolo Bonzini fprintf(stderr, "\n"); 349d9f24bf5SPaolo Bonzini cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP); 350d9f24bf5SPaolo Bonzini if (qemu_log_separate()) { 351c60f599bSRichard Henderson FILE *logfile = qemu_log_trylock(); 35278b54858SRichard Henderson if (logfile) { 35378b54858SRichard Henderson fprintf(logfile, "qemu: fatal: "); 35478b54858SRichard Henderson vfprintf(logfile, fmt, ap2); 35578b54858SRichard Henderson fprintf(logfile, "\n"); 35678b54858SRichard Henderson cpu_dump_state(cpu, logfile, CPU_DUMP_FPU | CPU_DUMP_CCOP); 357d9f24bf5SPaolo Bonzini qemu_log_unlock(logfile); 35878b54858SRichard Henderson } 359d9f24bf5SPaolo Bonzini } 360d9f24bf5SPaolo Bonzini va_end(ap2); 361d9f24bf5SPaolo Bonzini va_end(ap); 362d9f24bf5SPaolo Bonzini replay_finish(); 363d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY) 364d9f24bf5SPaolo Bonzini { 365d9f24bf5SPaolo Bonzini struct sigaction act; 366d9f24bf5SPaolo Bonzini sigfillset(&act.sa_mask); 367d9f24bf5SPaolo Bonzini act.sa_handler = SIG_DFL; 368d9f24bf5SPaolo Bonzini act.sa_flags = 0; 369d9f24bf5SPaolo Bonzini sigaction(SIGABRT, &act, NULL); 370d9f24bf5SPaolo Bonzini } 371d9f24bf5SPaolo Bonzini #endif 372d9f24bf5SPaolo Bonzini abort(); 373d9f24bf5SPaolo Bonzini } 374d9f24bf5SPaolo Bonzini 375d9f24bf5SPaolo Bonzini /* physical memory access (slow version, mainly for debug) */ 376d9f24bf5SPaolo Bonzini #if defined(CONFIG_USER_ONLY) 37773842ef0SPhilippe Mathieu-Daudé int cpu_memory_rw_debug(CPUState *cpu, vaddr addr, 37873842ef0SPhilippe Mathieu-Daudé void *ptr, size_t len, bool is_write) 379d9f24bf5SPaolo Bonzini { 380d9f24bf5SPaolo Bonzini int flags; 38173842ef0SPhilippe Mathieu-Daudé vaddr l, page; 382d9f24bf5SPaolo Bonzini void * p; 383d9f24bf5SPaolo Bonzini uint8_t *buf = ptr; 38487ab2704SIlya Leoshkevich ssize_t written; 38587ab2704SIlya Leoshkevich int ret = -1; 38687ab2704SIlya Leoshkevich int fd = -1; 387d9f24bf5SPaolo Bonzini 388d9f24bf5SPaolo Bonzini while (len > 0) { 389d9f24bf5SPaolo Bonzini page = addr & TARGET_PAGE_MASK; 390d9f24bf5SPaolo Bonzini l = (page + TARGET_PAGE_SIZE) - addr; 391d9f24bf5SPaolo Bonzini if (l > len) 392d9f24bf5SPaolo Bonzini l = len; 393d9f24bf5SPaolo Bonzini flags = page_get_flags(page); 39487ab2704SIlya Leoshkevich if (!(flags & PAGE_VALID)) { 39587ab2704SIlya Leoshkevich goto out_close; 39687ab2704SIlya Leoshkevich } 397d9f24bf5SPaolo Bonzini if (is_write) { 39887ab2704SIlya Leoshkevich if (flags & PAGE_WRITE) { 399d9f24bf5SPaolo Bonzini /* XXX: this code should not depend on lock_user */ 40087ab2704SIlya Leoshkevich p = lock_user(VERIFY_WRITE, addr, l, 0); 40187ab2704SIlya Leoshkevich if (!p) { 40287ab2704SIlya Leoshkevich goto out_close; 40387ab2704SIlya Leoshkevich } 404d9f24bf5SPaolo Bonzini memcpy(p, buf, l); 405d9f24bf5SPaolo Bonzini unlock_user(p, addr, l); 406d9f24bf5SPaolo Bonzini } else { 40787ab2704SIlya Leoshkevich /* Bypass the host page protection using ptrace. */ 40887ab2704SIlya Leoshkevich if (fd == -1) { 40987ab2704SIlya Leoshkevich fd = open("/proc/self/mem", O_WRONLY); 41087ab2704SIlya Leoshkevich if (fd == -1) { 41187ab2704SIlya Leoshkevich goto out; 41287ab2704SIlya Leoshkevich } 41387ab2704SIlya Leoshkevich } 41487ab2704SIlya Leoshkevich /* 41587ab2704SIlya Leoshkevich * If there is a TranslationBlock and we weren't bypassing the 41687ab2704SIlya Leoshkevich * host page protection, the memcpy() above would SEGV, 41787ab2704SIlya Leoshkevich * ultimately leading to page_unprotect(). So invalidate the 41887ab2704SIlya Leoshkevich * translations manually. Both invalidation and pwrite() must 41987ab2704SIlya Leoshkevich * be under mmap_lock() in order to prevent the creation of 42087ab2704SIlya Leoshkevich * another TranslationBlock in between. 42187ab2704SIlya Leoshkevich */ 42287ab2704SIlya Leoshkevich mmap_lock(); 42387ab2704SIlya Leoshkevich tb_invalidate_phys_range(addr, addr + l - 1); 42487ab2704SIlya Leoshkevich written = pwrite(fd, buf, l, 42587ab2704SIlya Leoshkevich (off_t)(uintptr_t)g2h_untagged(addr)); 42687ab2704SIlya Leoshkevich mmap_unlock(); 42787ab2704SIlya Leoshkevich if (written != l) { 42887ab2704SIlya Leoshkevich goto out_close; 42987ab2704SIlya Leoshkevich } 43087ab2704SIlya Leoshkevich } 43187ab2704SIlya Leoshkevich } else if (flags & PAGE_READ) { 432d9f24bf5SPaolo Bonzini /* XXX: this code should not depend on lock_user */ 43387ab2704SIlya Leoshkevich p = lock_user(VERIFY_READ, addr, l, 1); 43487ab2704SIlya Leoshkevich if (!p) { 43587ab2704SIlya Leoshkevich goto out_close; 43687ab2704SIlya Leoshkevich } 437d9f24bf5SPaolo Bonzini memcpy(buf, p, l); 438d9f24bf5SPaolo Bonzini unlock_user(p, addr, 0); 43987ab2704SIlya Leoshkevich } else { 44087ab2704SIlya Leoshkevich /* Bypass the host page protection using ptrace. */ 44187ab2704SIlya Leoshkevich if (fd == -1) { 44287ab2704SIlya Leoshkevich fd = open("/proc/self/mem", O_RDONLY); 44387ab2704SIlya Leoshkevich if (fd == -1) { 44487ab2704SIlya Leoshkevich goto out; 44587ab2704SIlya Leoshkevich } 44687ab2704SIlya Leoshkevich } 44787ab2704SIlya Leoshkevich if (pread(fd, buf, l, 44887ab2704SIlya Leoshkevich (off_t)(uintptr_t)g2h_untagged(addr)) != l) { 44987ab2704SIlya Leoshkevich goto out_close; 45087ab2704SIlya Leoshkevich } 451d9f24bf5SPaolo Bonzini } 452d9f24bf5SPaolo Bonzini len -= l; 453d9f24bf5SPaolo Bonzini buf += l; 454d9f24bf5SPaolo Bonzini addr += l; 455d9f24bf5SPaolo Bonzini } 45687ab2704SIlya Leoshkevich ret = 0; 45787ab2704SIlya Leoshkevich out_close: 45887ab2704SIlya Leoshkevich if (fd != -1) { 45987ab2704SIlya Leoshkevich close(fd); 46087ab2704SIlya Leoshkevich } 46187ab2704SIlya Leoshkevich out: 46287ab2704SIlya Leoshkevich return ret; 463d9f24bf5SPaolo Bonzini } 464d9f24bf5SPaolo Bonzini #endif 465d9f24bf5SPaolo Bonzini 466d9f24bf5SPaolo Bonzini bool target_words_bigendian(void) 467d9f24bf5SPaolo Bonzini { 468ded625e7SThomas Huth return TARGET_BIG_ENDIAN; 469d9f24bf5SPaolo Bonzini } 470d9f24bf5SPaolo Bonzini 4711077f50bSThomas Huth const char *target_name(void) 4721077f50bSThomas Huth { 4731077f50bSThomas Huth return TARGET_NAME; 4741077f50bSThomas Huth } 475