1 /* 2 * Target-specific parts of the CPU object 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "qapi/error.h" 22 23 #include "exec/target_page.h" 24 #include "hw/qdev-core.h" 25 #include "hw/qdev-properties.h" 26 #include "qemu/error-report.h" 27 #include "migration/vmstate.h" 28 #ifdef CONFIG_USER_ONLY 29 #include "qemu.h" 30 #else 31 #include "hw/core/sysemu-cpu-ops.h" 32 #include "exec/address-spaces.h" 33 #endif 34 #include "sysemu/cpus.h" 35 #include "sysemu/tcg.h" 36 #include "exec/replay-core.h" 37 #include "exec/cpu-common.h" 38 #include "exec/exec-all.h" 39 #include "exec/tb-flush.h" 40 #include "exec/translate-all.h" 41 #include "exec/log.h" 42 #include "hw/core/accel-cpu.h" 43 #include "trace/trace-root.h" 44 #include "qemu/accel.h" 45 #include "qemu/plugin.h" 46 47 uintptr_t qemu_host_page_size; 48 intptr_t qemu_host_page_mask; 49 50 #ifndef CONFIG_USER_ONLY 51 static int cpu_common_post_load(void *opaque, int version_id) 52 { 53 CPUState *cpu = opaque; 54 55 /* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the 56 version_id is increased. */ 57 cpu->interrupt_request &= ~0x01; 58 tlb_flush(cpu); 59 60 /* loadvm has just updated the content of RAM, bypassing the 61 * usual mechanisms that ensure we flush TBs for writes to 62 * memory we've translated code from. So we must flush all TBs, 63 * which will now be stale. 64 */ 65 tb_flush(cpu); 66 67 return 0; 68 } 69 70 static int cpu_common_pre_load(void *opaque) 71 { 72 CPUState *cpu = opaque; 73 74 cpu->exception_index = -1; 75 76 return 0; 77 } 78 79 static bool cpu_common_exception_index_needed(void *opaque) 80 { 81 CPUState *cpu = opaque; 82 83 return tcg_enabled() && cpu->exception_index != -1; 84 } 85 86 static const VMStateDescription vmstate_cpu_common_exception_index = { 87 .name = "cpu_common/exception_index", 88 .version_id = 1, 89 .minimum_version_id = 1, 90 .needed = cpu_common_exception_index_needed, 91 .fields = (VMStateField[]) { 92 VMSTATE_INT32(exception_index, CPUState), 93 VMSTATE_END_OF_LIST() 94 } 95 }; 96 97 static bool cpu_common_crash_occurred_needed(void *opaque) 98 { 99 CPUState *cpu = opaque; 100 101 return cpu->crash_occurred; 102 } 103 104 static const VMStateDescription vmstate_cpu_common_crash_occurred = { 105 .name = "cpu_common/crash_occurred", 106 .version_id = 1, 107 .minimum_version_id = 1, 108 .needed = cpu_common_crash_occurred_needed, 109 .fields = (VMStateField[]) { 110 VMSTATE_BOOL(crash_occurred, CPUState), 111 VMSTATE_END_OF_LIST() 112 } 113 }; 114 115 const VMStateDescription vmstate_cpu_common = { 116 .name = "cpu_common", 117 .version_id = 1, 118 .minimum_version_id = 1, 119 .pre_load = cpu_common_pre_load, 120 .post_load = cpu_common_post_load, 121 .fields = (VMStateField[]) { 122 VMSTATE_UINT32(halted, CPUState), 123 VMSTATE_UINT32(interrupt_request, CPUState), 124 VMSTATE_END_OF_LIST() 125 }, 126 .subsections = (const VMStateDescription*[]) { 127 &vmstate_cpu_common_exception_index, 128 &vmstate_cpu_common_crash_occurred, 129 NULL 130 } 131 }; 132 #endif 133 134 bool cpu_exec_realizefn(CPUState *cpu, Error **errp) 135 { 136 /* cache the cpu class for the hotpath */ 137 cpu->cc = CPU_GET_CLASS(cpu); 138 139 if (!accel_cpu_common_realize(cpu, errp)) { 140 return false; 141 } 142 143 /* Wait until cpu initialization complete before exposing cpu. */ 144 cpu_list_add(cpu); 145 146 /* Plugin initialization must wait until cpu_index assigned. */ 147 if (tcg_enabled()) { 148 qemu_plugin_vcpu_init_hook(cpu); 149 } 150 151 #ifdef CONFIG_USER_ONLY 152 assert(qdev_get_vmsd(DEVICE(cpu)) == NULL || 153 qdev_get_vmsd(DEVICE(cpu))->unmigratable); 154 #else 155 if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 156 vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu); 157 } 158 if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) { 159 vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu); 160 } 161 #endif /* CONFIG_USER_ONLY */ 162 163 return true; 164 } 165 166 void cpu_exec_unrealizefn(CPUState *cpu) 167 { 168 #ifndef CONFIG_USER_ONLY 169 CPUClass *cc = CPU_GET_CLASS(cpu); 170 171 if (cc->sysemu_ops->legacy_vmsd != NULL) { 172 vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu); 173 } 174 if (qdev_get_vmsd(DEVICE(cpu)) == NULL) { 175 vmstate_unregister(NULL, &vmstate_cpu_common, cpu); 176 } 177 #endif 178 179 /* Call the plugin hook before clearing cpu->cpu_index in cpu_list_remove */ 180 if (tcg_enabled()) { 181 qemu_plugin_vcpu_exit_hook(cpu); 182 } 183 184 cpu_list_remove(cpu); 185 /* 186 * Now that the vCPU has been removed from the RCU list, we can call 187 * accel_cpu_common_unrealize, which may free fields using call_rcu. 188 */ 189 accel_cpu_common_unrealize(cpu); 190 } 191 192 /* 193 * This can't go in hw/core/cpu.c because that file is compiled only 194 * once for both user-mode and system builds. 195 */ 196 static Property cpu_common_props[] = { 197 #ifdef CONFIG_USER_ONLY 198 /* 199 * Create a property for the user-only object, so users can 200 * adjust prctl(PR_SET_UNALIGN) from the command-line. 201 * Has no effect if the target does not support the feature. 202 */ 203 DEFINE_PROP_BOOL("prctl-unalign-sigbus", CPUState, 204 prctl_unalign_sigbus, false), 205 #else 206 /* 207 * Create a memory property for system CPU object, so users can 208 * wire up its memory. The default if no link is set up is to use 209 * the system address space. 210 */ 211 DEFINE_PROP_LINK("memory", CPUState, memory, TYPE_MEMORY_REGION, 212 MemoryRegion *), 213 #endif 214 DEFINE_PROP_END_OF_LIST(), 215 }; 216 217 static bool cpu_get_start_powered_off(Object *obj, Error **errp) 218 { 219 CPUState *cpu = CPU(obj); 220 return cpu->start_powered_off; 221 } 222 223 static void cpu_set_start_powered_off(Object *obj, bool value, Error **errp) 224 { 225 CPUState *cpu = CPU(obj); 226 cpu->start_powered_off = value; 227 } 228 229 void cpu_class_init_props(DeviceClass *dc) 230 { 231 ObjectClass *oc = OBJECT_CLASS(dc); 232 233 device_class_set_props(dc, cpu_common_props); 234 /* 235 * We can't use DEFINE_PROP_BOOL in the Property array for this 236 * property, because we want this to be settable after realize. 237 */ 238 object_class_property_add_bool(oc, "start-powered-off", 239 cpu_get_start_powered_off, 240 cpu_set_start_powered_off); 241 } 242 243 void cpu_exec_initfn(CPUState *cpu) 244 { 245 cpu->as = NULL; 246 cpu->num_ases = 0; 247 248 #ifndef CONFIG_USER_ONLY 249 cpu->thread_id = qemu_get_thread_id(); 250 cpu->memory = get_system_memory(); 251 object_ref(OBJECT(cpu->memory)); 252 #endif 253 } 254 255 const char *parse_cpu_option(const char *cpu_option) 256 { 257 ObjectClass *oc; 258 CPUClass *cc; 259 gchar **model_pieces; 260 const char *cpu_type; 261 262 model_pieces = g_strsplit(cpu_option, ",", 2); 263 if (!model_pieces[0]) { 264 error_report("-cpu option cannot be empty"); 265 exit(1); 266 } 267 268 oc = cpu_class_by_name(CPU_RESOLVING_TYPE, model_pieces[0]); 269 if (oc == NULL) { 270 error_report("unable to find CPU model '%s'", model_pieces[0]); 271 g_strfreev(model_pieces); 272 exit(EXIT_FAILURE); 273 } 274 275 cpu_type = object_class_get_name(oc); 276 cc = CPU_CLASS(oc); 277 cc->parse_features(cpu_type, model_pieces[1], &error_fatal); 278 g_strfreev(model_pieces); 279 return cpu_type; 280 } 281 282 void list_cpus(void) 283 { 284 /* XXX: implement xxx_cpu_list for targets that still miss it */ 285 #if defined(cpu_list) 286 cpu_list(); 287 #endif 288 } 289 290 #if defined(CONFIG_USER_ONLY) 291 void tb_invalidate_phys_addr(hwaddr addr) 292 { 293 mmap_lock(); 294 tb_invalidate_phys_page(addr); 295 mmap_unlock(); 296 } 297 #else 298 void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs) 299 { 300 ram_addr_t ram_addr; 301 MemoryRegion *mr; 302 hwaddr l = 1; 303 304 if (!tcg_enabled()) { 305 return; 306 } 307 308 RCU_READ_LOCK_GUARD(); 309 mr = address_space_translate(as, addr, &addr, &l, false, attrs); 310 if (!(memory_region_is_ram(mr) 311 || memory_region_is_romd(mr))) { 312 return; 313 } 314 ram_addr = memory_region_get_ram_addr(mr) + addr; 315 tb_invalidate_phys_page(ram_addr); 316 } 317 #endif 318 319 /* enable or disable single step mode. EXCP_DEBUG is returned by the 320 CPU loop after each instruction */ 321 void cpu_single_step(CPUState *cpu, int enabled) 322 { 323 if (cpu->singlestep_enabled != enabled) { 324 cpu->singlestep_enabled = enabled; 325 326 #if !defined(CONFIG_USER_ONLY) 327 const AccelOpsClass *ops = cpus_get_accel(); 328 if (ops->update_guest_debug) { 329 ops->update_guest_debug(cpu); 330 } 331 #endif 332 333 trace_breakpoint_singlestep(cpu->cpu_index, enabled); 334 } 335 } 336 337 void cpu_abort(CPUState *cpu, const char *fmt, ...) 338 { 339 va_list ap; 340 va_list ap2; 341 342 va_start(ap, fmt); 343 va_copy(ap2, ap); 344 fprintf(stderr, "qemu: fatal: "); 345 vfprintf(stderr, fmt, ap); 346 fprintf(stderr, "\n"); 347 cpu_dump_state(cpu, stderr, CPU_DUMP_FPU | CPU_DUMP_CCOP); 348 if (qemu_log_separate()) { 349 FILE *logfile = qemu_log_trylock(); 350 if (logfile) { 351 fprintf(logfile, "qemu: fatal: "); 352 vfprintf(logfile, fmt, ap2); 353 fprintf(logfile, "\n"); 354 cpu_dump_state(cpu, logfile, CPU_DUMP_FPU | CPU_DUMP_CCOP); 355 qemu_log_unlock(logfile); 356 } 357 } 358 va_end(ap2); 359 va_end(ap); 360 replay_finish(); 361 #if defined(CONFIG_USER_ONLY) 362 { 363 struct sigaction act; 364 sigfillset(&act.sa_mask); 365 act.sa_handler = SIG_DFL; 366 act.sa_flags = 0; 367 sigaction(SIGABRT, &act, NULL); 368 } 369 #endif 370 abort(); 371 } 372 373 /* physical memory access (slow version, mainly for debug) */ 374 #if defined(CONFIG_USER_ONLY) 375 int cpu_memory_rw_debug(CPUState *cpu, vaddr addr, 376 void *ptr, size_t len, bool is_write) 377 { 378 int flags; 379 vaddr l, page; 380 void * p; 381 uint8_t *buf = ptr; 382 383 while (len > 0) { 384 page = addr & TARGET_PAGE_MASK; 385 l = (page + TARGET_PAGE_SIZE) - addr; 386 if (l > len) 387 l = len; 388 flags = page_get_flags(page); 389 if (!(flags & PAGE_VALID)) 390 return -1; 391 if (is_write) { 392 if (!(flags & PAGE_WRITE)) 393 return -1; 394 /* XXX: this code should not depend on lock_user */ 395 if (!(p = lock_user(VERIFY_WRITE, addr, l, 0))) 396 return -1; 397 memcpy(p, buf, l); 398 unlock_user(p, addr, l); 399 } else { 400 if (!(flags & PAGE_READ)) 401 return -1; 402 /* XXX: this code should not depend on lock_user */ 403 if (!(p = lock_user(VERIFY_READ, addr, l, 1))) 404 return -1; 405 memcpy(buf, p, l); 406 unlock_user(p, addr, 0); 407 } 408 len -= l; 409 buf += l; 410 addr += l; 411 } 412 return 0; 413 } 414 #endif 415 416 bool target_words_bigendian(void) 417 { 418 return TARGET_BIG_ENDIAN; 419 } 420 421 const char *target_name(void) 422 { 423 return TARGET_NAME; 424 } 425 426 void page_size_init(void) 427 { 428 /* NOTE: we can always suppose that qemu_host_page_size >= 429 TARGET_PAGE_SIZE */ 430 if (qemu_host_page_size == 0) { 431 qemu_host_page_size = qemu_real_host_page_size(); 432 } 433 if (qemu_host_page_size < TARGET_PAGE_SIZE) { 434 qemu_host_page_size = TARGET_PAGE_SIZE; 435 } 436 qemu_host_page_mask = -(intptr_t)qemu_host_page_size; 437 } 438