1 /* 2 * i386 helpers (without register variable usage) 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 "cpu.h" 22 #include "exec/exec-all.h" 23 #include "qemu/qemu-print.h" 24 #include "sysemu/kvm.h" 25 #include "kvm_i386.h" 26 #ifndef CONFIG_USER_ONLY 27 #include "sysemu/sysemu.h" 28 #include "sysemu/tcg.h" 29 #include "sysemu/hw_accel.h" 30 #include "monitor/monitor.h" 31 #include "hw/i386/apic_internal.h" 32 #endif 33 34 void cpu_sync_bndcs_hflags(CPUX86State *env) 35 { 36 uint32_t hflags = env->hflags; 37 uint32_t hflags2 = env->hflags2; 38 uint32_t bndcsr; 39 40 if ((hflags & HF_CPL_MASK) == 3) { 41 bndcsr = env->bndcs_regs.cfgu; 42 } else { 43 bndcsr = env->msr_bndcfgs; 44 } 45 46 if ((env->cr[4] & CR4_OSXSAVE_MASK) 47 && (env->xcr0 & XSTATE_BNDCSR_MASK) 48 && (bndcsr & BNDCFG_ENABLE)) { 49 hflags |= HF_MPX_EN_MASK; 50 } else { 51 hflags &= ~HF_MPX_EN_MASK; 52 } 53 54 if (bndcsr & BNDCFG_BNDPRESERVE) { 55 hflags2 |= HF2_MPX_PR_MASK; 56 } else { 57 hflags2 &= ~HF2_MPX_PR_MASK; 58 } 59 60 env->hflags = hflags; 61 env->hflags2 = hflags2; 62 } 63 64 static void cpu_x86_version(CPUX86State *env, int *family, int *model) 65 { 66 int cpuver = env->cpuid_version; 67 68 if (family == NULL || model == NULL) { 69 return; 70 } 71 72 *family = (cpuver >> 8) & 0x0f; 73 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f); 74 } 75 76 /* Broadcast MCA signal for processor version 06H_EH and above */ 77 int cpu_x86_support_mca_broadcast(CPUX86State *env) 78 { 79 int family = 0; 80 int model = 0; 81 82 cpu_x86_version(env, &family, &model); 83 if ((family == 6 && model >= 14) || family > 6) { 84 return 1; 85 } 86 87 return 0; 88 } 89 90 /***********************************************************/ 91 /* x86 debug */ 92 93 static const char *cc_op_str[CC_OP_NB] = { 94 "DYNAMIC", 95 "EFLAGS", 96 97 "MULB", 98 "MULW", 99 "MULL", 100 "MULQ", 101 102 "ADDB", 103 "ADDW", 104 "ADDL", 105 "ADDQ", 106 107 "ADCB", 108 "ADCW", 109 "ADCL", 110 "ADCQ", 111 112 "SUBB", 113 "SUBW", 114 "SUBL", 115 "SUBQ", 116 117 "SBBB", 118 "SBBW", 119 "SBBL", 120 "SBBQ", 121 122 "LOGICB", 123 "LOGICW", 124 "LOGICL", 125 "LOGICQ", 126 127 "INCB", 128 "INCW", 129 "INCL", 130 "INCQ", 131 132 "DECB", 133 "DECW", 134 "DECL", 135 "DECQ", 136 137 "SHLB", 138 "SHLW", 139 "SHLL", 140 "SHLQ", 141 142 "SARB", 143 "SARW", 144 "SARL", 145 "SARQ", 146 147 "BMILGB", 148 "BMILGW", 149 "BMILGL", 150 "BMILGQ", 151 152 "ADCX", 153 "ADOX", 154 "ADCOX", 155 156 "CLR", 157 }; 158 159 static void 160 cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, 161 const char *name, struct SegmentCache *sc) 162 { 163 #ifdef TARGET_X86_64 164 if (env->hflags & HF_CS64_MASK) { 165 qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name, 166 sc->selector, sc->base, sc->limit, 167 sc->flags & 0x00ffff00); 168 } else 169 #endif 170 { 171 qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector, 172 (uint32_t)sc->base, sc->limit, 173 sc->flags & 0x00ffff00); 174 } 175 176 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK)) 177 goto done; 178 179 qemu_fprintf(f, " DPL=%d ", 180 (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT); 181 if (sc->flags & DESC_S_MASK) { 182 if (sc->flags & DESC_CS_MASK) { 183 qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" : 184 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16")); 185 qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-', 186 (sc->flags & DESC_R_MASK) ? 'R' : '-'); 187 } else { 188 qemu_fprintf(f, (sc->flags & DESC_B_MASK 189 || env->hflags & HF_LMA_MASK) 190 ? "DS " : "DS16"); 191 qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-', 192 (sc->flags & DESC_W_MASK) ? 'W' : '-'); 193 } 194 qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-'); 195 } else { 196 static const char *sys_type_name[2][16] = { 197 { /* 32 bit mode */ 198 "Reserved", "TSS16-avl", "LDT", "TSS16-busy", 199 "CallGate16", "TaskGate", "IntGate16", "TrapGate16", 200 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy", 201 "CallGate32", "Reserved", "IntGate32", "TrapGate32" 202 }, 203 { /* 64 bit mode */ 204 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved", 205 "Reserved", "Reserved", "Reserved", "Reserved", 206 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64", 207 "Reserved", "IntGate64", "TrapGate64" 208 } 209 }; 210 qemu_fprintf(f, "%s", 211 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0] 212 [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]); 213 } 214 done: 215 qemu_fprintf(f, "\n"); 216 } 217 218 #ifndef CONFIG_USER_ONLY 219 220 /* ARRAY_SIZE check is not required because 221 * DeliveryMode(dm) has a size of 3 bit. 222 */ 223 static inline const char *dm2str(uint32_t dm) 224 { 225 static const char *str[] = { 226 "Fixed", 227 "...", 228 "SMI", 229 "...", 230 "NMI", 231 "INIT", 232 "...", 233 "ExtINT" 234 }; 235 return str[dm]; 236 } 237 238 static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer) 239 { 240 uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT; 241 qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s", 242 name, lvt, 243 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi", 244 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge", 245 lvt & APIC_LVT_MASKED ? "masked" : "", 246 lvt & APIC_LVT_DELIV_STS ? "pending" : "", 247 !is_timer ? 248 "" : lvt & APIC_LVT_TIMER_PERIODIC ? 249 "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ? 250 "tsc-deadline" : "one-shot", 251 dm2str(dm)); 252 if (dm != APIC_DM_NMI) { 253 qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK); 254 } else { 255 qemu_printf("\n"); 256 } 257 } 258 259 /* ARRAY_SIZE check is not required because 260 * destination shorthand has a size of 2 bit. 261 */ 262 static inline const char *shorthand2str(uint32_t shorthand) 263 { 264 const char *str[] = { 265 "no-shorthand", "self", "all-self", "all" 266 }; 267 return str[shorthand]; 268 } 269 270 static inline uint8_t divider_conf(uint32_t divide_conf) 271 { 272 uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3); 273 274 return divide_val == 7 ? 1 : 2 << divide_val; 275 } 276 277 static inline void mask2str(char *str, uint32_t val, uint8_t size) 278 { 279 while (size--) { 280 *str++ = (val >> size) & 1 ? '1' : '0'; 281 } 282 *str = 0; 283 } 284 285 #define MAX_LOGICAL_APIC_ID_MASK_SIZE 16 286 287 static void dump_apic_icr(APICCommonState *s, CPUX86State *env) 288 { 289 uint32_t icr = s->icr[0], icr2 = s->icr[1]; 290 uint8_t dest_shorthand = \ 291 (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT; 292 bool logical_mod = icr & APIC_ICR_DEST_MOD; 293 char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1]; 294 uint32_t dest_field; 295 bool x2apic; 296 297 qemu_printf("ICR\t 0x%08x %s %s %s %s\n", 298 icr, 299 logical_mod ? "logical" : "physical", 300 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge", 301 icr & APIC_ICR_LEVEL ? "assert" : "de-assert", 302 shorthand2str(dest_shorthand)); 303 304 qemu_printf("ICR2\t 0x%08x", icr2); 305 if (dest_shorthand != 0) { 306 qemu_printf("\n"); 307 return; 308 } 309 x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC; 310 dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT; 311 312 if (!logical_mod) { 313 if (x2apic) { 314 qemu_printf(" cpu %u (X2APIC ID)\n", dest_field); 315 } else { 316 qemu_printf(" cpu %u (APIC ID)\n", 317 dest_field & APIC_LOGDEST_XAPIC_ID); 318 } 319 return; 320 } 321 322 if (s->dest_mode == 0xf) { /* flat mode */ 323 mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8); 324 qemu_printf(" mask %s (APIC ID)\n", apic_id_str); 325 } else if (s->dest_mode == 0) { /* cluster mode */ 326 if (x2apic) { 327 mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16); 328 qemu_printf(" cluster %u mask %s (X2APIC ID)\n", 329 dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str); 330 } else { 331 mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4); 332 qemu_printf(" cluster %u mask %s (APIC ID)\n", 333 dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str); 334 } 335 } 336 } 337 338 static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab, 339 uint32_t *tmr_tab) 340 { 341 int i, empty = true; 342 343 qemu_printf("%s\t ", name); 344 for (i = 0; i < 256; i++) { 345 if (apic_get_bit(ireg_tab, i)) { 346 qemu_printf("%u%s ", i, 347 apic_get_bit(tmr_tab, i) ? "(level)" : ""); 348 empty = false; 349 } 350 } 351 qemu_printf("%s\n", empty ? "(none)" : ""); 352 } 353 354 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags) 355 { 356 X86CPU *cpu = X86_CPU(cs); 357 APICCommonState *s = APIC_COMMON(cpu->apic_state); 358 if (!s) { 359 qemu_printf("local apic state not available\n"); 360 return; 361 } 362 uint32_t *lvt = s->lvt; 363 364 qemu_printf("dumping local APIC state for CPU %-2u\n\n", 365 CPU(cpu)->cpu_index); 366 dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false); 367 dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false); 368 dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false); 369 dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false); 370 dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false); 371 dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true); 372 373 qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u\n", 374 s->divide_conf & APIC_DCR_MASK, 375 divider_conf(s->divide_conf), 376 s->initial_count); 377 378 qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n", 379 s->spurious_vec, 380 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled", 381 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off", 382 s->spurious_vec & APIC_VECTOR_MASK); 383 384 dump_apic_icr(s, &cpu->env); 385 386 qemu_printf("ESR\t 0x%08x\n", s->esr); 387 388 dump_apic_interrupt("ISR", s->isr, s->tmr); 389 dump_apic_interrupt("IRR", s->irr, s->tmr); 390 391 qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x", 392 s->arb_id, s->tpr, s->dest_mode, s->log_dest); 393 if (s->dest_mode == 0) { 394 qemu_printf("(cluster %u: id %u)", 395 s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT, 396 s->log_dest & APIC_LOGDEST_XAPIC_ID); 397 } 398 qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s)); 399 } 400 #else 401 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags) 402 { 403 } 404 #endif /* !CONFIG_USER_ONLY */ 405 406 #define DUMP_CODE_BYTES_TOTAL 50 407 #define DUMP_CODE_BYTES_BACKWARD 20 408 409 void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags) 410 { 411 X86CPU *cpu = X86_CPU(cs); 412 CPUX86State *env = &cpu->env; 413 int eflags, i, nb; 414 char cc_op_name[32]; 415 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" }; 416 417 eflags = cpu_compute_eflags(env); 418 #ifdef TARGET_X86_64 419 if (env->hflags & HF_CS64_MASK) { 420 qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n" 421 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n" 422 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n" 423 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n" 424 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n", 425 env->regs[R_EAX], 426 env->regs[R_EBX], 427 env->regs[R_ECX], 428 env->regs[R_EDX], 429 env->regs[R_ESI], 430 env->regs[R_EDI], 431 env->regs[R_EBP], 432 env->regs[R_ESP], 433 env->regs[8], 434 env->regs[9], 435 env->regs[10], 436 env->regs[11], 437 env->regs[12], 438 env->regs[13], 439 env->regs[14], 440 env->regs[15], 441 env->eip, eflags, 442 eflags & DF_MASK ? 'D' : '-', 443 eflags & CC_O ? 'O' : '-', 444 eflags & CC_S ? 'S' : '-', 445 eflags & CC_Z ? 'Z' : '-', 446 eflags & CC_A ? 'A' : '-', 447 eflags & CC_P ? 'P' : '-', 448 eflags & CC_C ? 'C' : '-', 449 env->hflags & HF_CPL_MASK, 450 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1, 451 (env->a20_mask >> 20) & 1, 452 (env->hflags >> HF_SMM_SHIFT) & 1, 453 cs->halted); 454 } else 455 #endif 456 { 457 qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n" 458 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n" 459 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n", 460 (uint32_t)env->regs[R_EAX], 461 (uint32_t)env->regs[R_EBX], 462 (uint32_t)env->regs[R_ECX], 463 (uint32_t)env->regs[R_EDX], 464 (uint32_t)env->regs[R_ESI], 465 (uint32_t)env->regs[R_EDI], 466 (uint32_t)env->regs[R_EBP], 467 (uint32_t)env->regs[R_ESP], 468 (uint32_t)env->eip, eflags, 469 eflags & DF_MASK ? 'D' : '-', 470 eflags & CC_O ? 'O' : '-', 471 eflags & CC_S ? 'S' : '-', 472 eflags & CC_Z ? 'Z' : '-', 473 eflags & CC_A ? 'A' : '-', 474 eflags & CC_P ? 'P' : '-', 475 eflags & CC_C ? 'C' : '-', 476 env->hflags & HF_CPL_MASK, 477 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1, 478 (env->a20_mask >> 20) & 1, 479 (env->hflags >> HF_SMM_SHIFT) & 1, 480 cs->halted); 481 } 482 483 for(i = 0; i < 6; i++) { 484 cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]); 485 } 486 cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt); 487 cpu_x86_dump_seg_cache(env, f, "TR", &env->tr); 488 489 #ifdef TARGET_X86_64 490 if (env->hflags & HF_LMA_MASK) { 491 qemu_fprintf(f, "GDT= %016" PRIx64 " %08x\n", 492 env->gdt.base, env->gdt.limit); 493 qemu_fprintf(f, "IDT= %016" PRIx64 " %08x\n", 494 env->idt.base, env->idt.limit); 495 qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n", 496 (uint32_t)env->cr[0], 497 env->cr[2], 498 env->cr[3], 499 (uint32_t)env->cr[4]); 500 for(i = 0; i < 4; i++) 501 qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]); 502 qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n", 503 env->dr[6], env->dr[7]); 504 } else 505 #endif 506 { 507 qemu_fprintf(f, "GDT= %08x %08x\n", 508 (uint32_t)env->gdt.base, env->gdt.limit); 509 qemu_fprintf(f, "IDT= %08x %08x\n", 510 (uint32_t)env->idt.base, env->idt.limit); 511 qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n", 512 (uint32_t)env->cr[0], 513 (uint32_t)env->cr[2], 514 (uint32_t)env->cr[3], 515 (uint32_t)env->cr[4]); 516 for(i = 0; i < 4; i++) { 517 qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]); 518 } 519 qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n", 520 env->dr[6], env->dr[7]); 521 } 522 if (flags & CPU_DUMP_CCOP) { 523 if ((unsigned)env->cc_op < CC_OP_NB) 524 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]); 525 else 526 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op); 527 #ifdef TARGET_X86_64 528 if (env->hflags & HF_CS64_MASK) { 529 qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n", 530 env->cc_src, env->cc_dst, 531 cc_op_name); 532 } else 533 #endif 534 { 535 qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n", 536 (uint32_t)env->cc_src, (uint32_t)env->cc_dst, 537 cc_op_name); 538 } 539 } 540 qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer); 541 if (flags & CPU_DUMP_FPU) { 542 int fptag; 543 fptag = 0; 544 for(i = 0; i < 8; i++) { 545 fptag |= ((!env->fptags[i]) << i); 546 } 547 qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n", 548 env->fpuc, 549 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11, 550 env->fpstt, 551 fptag, 552 env->mxcsr); 553 for(i=0;i<8;i++) { 554 CPU_LDoubleU u; 555 u.d = env->fpregs[i].d; 556 qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x", 557 i, u.l.lower, u.l.upper); 558 if ((i & 1) == 1) 559 qemu_fprintf(f, "\n"); 560 else 561 qemu_fprintf(f, " "); 562 } 563 if (env->hflags & HF_CS64_MASK) 564 nb = 16; 565 else 566 nb = 8; 567 for(i=0;i<nb;i++) { 568 qemu_fprintf(f, "XMM%02d=%08x%08x%08x%08x", 569 i, 570 env->xmm_regs[i].ZMM_L(3), 571 env->xmm_regs[i].ZMM_L(2), 572 env->xmm_regs[i].ZMM_L(1), 573 env->xmm_regs[i].ZMM_L(0)); 574 if ((i & 1) == 1) 575 qemu_fprintf(f, "\n"); 576 else 577 qemu_fprintf(f, " "); 578 } 579 } 580 if (flags & CPU_DUMP_CODE) { 581 target_ulong base = env->segs[R_CS].base + env->eip; 582 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD); 583 uint8_t code; 584 char codestr[3]; 585 586 qemu_fprintf(f, "Code="); 587 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) { 588 if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) { 589 snprintf(codestr, sizeof(codestr), "%02x", code); 590 } else { 591 snprintf(codestr, sizeof(codestr), "??"); 592 } 593 qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "", 594 i == offs ? "<" : "", codestr, i == offs ? ">" : ""); 595 } 596 qemu_fprintf(f, "\n"); 597 } 598 } 599 600 /***********************************************************/ 601 /* x86 mmu */ 602 /* XXX: add PGE support */ 603 604 void x86_cpu_set_a20(X86CPU *cpu, int a20_state) 605 { 606 CPUX86State *env = &cpu->env; 607 608 a20_state = (a20_state != 0); 609 if (a20_state != ((env->a20_mask >> 20) & 1)) { 610 CPUState *cs = CPU(cpu); 611 612 qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state); 613 /* if the cpu is currently executing code, we must unlink it and 614 all the potentially executing TB */ 615 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); 616 617 /* when a20 is changed, all the MMU mappings are invalid, so 618 we must flush everything */ 619 tlb_flush(cs); 620 env->a20_mask = ~(1 << 20) | (a20_state << 20); 621 } 622 } 623 624 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0) 625 { 626 X86CPU *cpu = env_archcpu(env); 627 int pe_state; 628 629 qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0); 630 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) != 631 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) { 632 tlb_flush(CPU(cpu)); 633 } 634 635 #ifdef TARGET_X86_64 636 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) && 637 (env->efer & MSR_EFER_LME)) { 638 /* enter in long mode */ 639 /* XXX: generate an exception */ 640 if (!(env->cr[4] & CR4_PAE_MASK)) 641 return; 642 env->efer |= MSR_EFER_LMA; 643 env->hflags |= HF_LMA_MASK; 644 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) && 645 (env->efer & MSR_EFER_LMA)) { 646 /* exit long mode */ 647 env->efer &= ~MSR_EFER_LMA; 648 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK); 649 env->eip &= 0xffffffff; 650 } 651 #endif 652 env->cr[0] = new_cr0 | CR0_ET_MASK; 653 654 /* update PE flag in hidden flags */ 655 pe_state = (env->cr[0] & CR0_PE_MASK); 656 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT); 657 /* ensure that ADDSEG is always set in real mode */ 658 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT); 659 /* update FPU flags */ 660 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) | 661 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)); 662 } 663 664 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in 665 the PDPT */ 666 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3) 667 { 668 env->cr[3] = new_cr3; 669 if (env->cr[0] & CR0_PG_MASK) { 670 qemu_log_mask(CPU_LOG_MMU, 671 "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3); 672 tlb_flush(env_cpu(env)); 673 } 674 } 675 676 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) 677 { 678 uint32_t hflags; 679 680 #if defined(DEBUG_MMU) 681 printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4); 682 #endif 683 if ((new_cr4 ^ env->cr[4]) & 684 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK | 685 CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) { 686 tlb_flush(env_cpu(env)); 687 } 688 689 /* Clear bits we're going to recompute. */ 690 hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK); 691 692 /* SSE handling */ 693 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) { 694 new_cr4 &= ~CR4_OSFXSR_MASK; 695 } 696 if (new_cr4 & CR4_OSFXSR_MASK) { 697 hflags |= HF_OSFXSR_MASK; 698 } 699 700 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) { 701 new_cr4 &= ~CR4_SMAP_MASK; 702 } 703 if (new_cr4 & CR4_SMAP_MASK) { 704 hflags |= HF_SMAP_MASK; 705 } 706 707 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) { 708 new_cr4 &= ~CR4_PKE_MASK; 709 } 710 711 env->cr[4] = new_cr4; 712 env->hflags = hflags; 713 714 cpu_sync_bndcs_hflags(env); 715 } 716 717 #if !defined(CONFIG_USER_ONLY) 718 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) 719 { 720 X86CPU *cpu = X86_CPU(cs); 721 CPUX86State *env = &cpu->env; 722 target_ulong pde_addr, pte_addr; 723 uint64_t pte; 724 int32_t a20_mask; 725 uint32_t page_offset; 726 int page_size; 727 728 a20_mask = x86_get_a20_mask(env); 729 if (!(env->cr[0] & CR0_PG_MASK)) { 730 pte = addr & a20_mask; 731 page_size = 4096; 732 } else if (env->cr[4] & CR4_PAE_MASK) { 733 target_ulong pdpe_addr; 734 uint64_t pde, pdpe; 735 736 #ifdef TARGET_X86_64 737 if (env->hflags & HF_LMA_MASK) { 738 bool la57 = env->cr[4] & CR4_LA57_MASK; 739 uint64_t pml5e_addr, pml5e; 740 uint64_t pml4e_addr, pml4e; 741 int32_t sext; 742 743 /* test virtual address sign extension */ 744 sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; 745 if (sext != 0 && sext != -1) { 746 return -1; 747 } 748 749 if (la57) { 750 pml5e_addr = ((env->cr[3] & ~0xfff) + 751 (((addr >> 48) & 0x1ff) << 3)) & a20_mask; 752 pml5e = x86_ldq_phys(cs, pml5e_addr); 753 if (!(pml5e & PG_PRESENT_MASK)) { 754 return -1; 755 } 756 } else { 757 pml5e = env->cr[3]; 758 } 759 760 pml4e_addr = ((pml5e & PG_ADDRESS_MASK) + 761 (((addr >> 39) & 0x1ff) << 3)) & a20_mask; 762 pml4e = x86_ldq_phys(cs, pml4e_addr); 763 if (!(pml4e & PG_PRESENT_MASK)) { 764 return -1; 765 } 766 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + 767 (((addr >> 30) & 0x1ff) << 3)) & a20_mask; 768 pdpe = x86_ldq_phys(cs, pdpe_addr); 769 if (!(pdpe & PG_PRESENT_MASK)) { 770 return -1; 771 } 772 if (pdpe & PG_PSE_MASK) { 773 page_size = 1024 * 1024 * 1024; 774 pte = pdpe; 775 goto out; 776 } 777 778 } else 779 #endif 780 { 781 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & 782 a20_mask; 783 pdpe = x86_ldq_phys(cs, pdpe_addr); 784 if (!(pdpe & PG_PRESENT_MASK)) 785 return -1; 786 } 787 788 pde_addr = ((pdpe & PG_ADDRESS_MASK) + 789 (((addr >> 21) & 0x1ff) << 3)) & a20_mask; 790 pde = x86_ldq_phys(cs, pde_addr); 791 if (!(pde & PG_PRESENT_MASK)) { 792 return -1; 793 } 794 if (pde & PG_PSE_MASK) { 795 /* 2 MB page */ 796 page_size = 2048 * 1024; 797 pte = pde; 798 } else { 799 /* 4 KB page */ 800 pte_addr = ((pde & PG_ADDRESS_MASK) + 801 (((addr >> 12) & 0x1ff) << 3)) & a20_mask; 802 page_size = 4096; 803 pte = x86_ldq_phys(cs, pte_addr); 804 } 805 if (!(pte & PG_PRESENT_MASK)) { 806 return -1; 807 } 808 } else { 809 uint32_t pde; 810 811 /* page directory entry */ 812 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask; 813 pde = x86_ldl_phys(cs, pde_addr); 814 if (!(pde & PG_PRESENT_MASK)) 815 return -1; 816 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { 817 pte = pde | ((pde & 0x1fe000LL) << (32 - 13)); 818 page_size = 4096 * 1024; 819 } else { 820 /* page directory entry */ 821 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask; 822 pte = x86_ldl_phys(cs, pte_addr); 823 if (!(pte & PG_PRESENT_MASK)) { 824 return -1; 825 } 826 page_size = 4096; 827 } 828 pte = pte & a20_mask; 829 } 830 831 #ifdef TARGET_X86_64 832 out: 833 #endif 834 pte &= PG_ADDRESS_MASK & ~(page_size - 1); 835 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); 836 return pte | page_offset; 837 } 838 839 typedef struct MCEInjectionParams { 840 Monitor *mon; 841 int bank; 842 uint64_t status; 843 uint64_t mcg_status; 844 uint64_t addr; 845 uint64_t misc; 846 int flags; 847 } MCEInjectionParams; 848 849 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data) 850 { 851 MCEInjectionParams *params = data.host_ptr; 852 X86CPU *cpu = X86_CPU(cs); 853 CPUX86State *cenv = &cpu->env; 854 uint64_t *banks = cenv->mce_banks + 4 * params->bank; 855 856 cpu_synchronize_state(cs); 857 858 /* 859 * If there is an MCE exception being processed, ignore this SRAO MCE 860 * unless unconditional injection was requested. 861 */ 862 if (!(params->flags & MCE_INJECT_UNCOND_AO) 863 && !(params->status & MCI_STATUS_AR) 864 && (cenv->mcg_status & MCG_STATUS_MCIP)) { 865 return; 866 } 867 868 if (params->status & MCI_STATUS_UC) { 869 /* 870 * if MSR_MCG_CTL is not all 1s, the uncorrected error 871 * reporting is disabled 872 */ 873 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) { 874 monitor_printf(params->mon, 875 "CPU %d: Uncorrected error reporting disabled\n", 876 cs->cpu_index); 877 return; 878 } 879 880 /* 881 * if MSR_MCi_CTL is not all 1s, the uncorrected error 882 * reporting is disabled for the bank 883 */ 884 if (banks[0] != ~(uint64_t)0) { 885 monitor_printf(params->mon, 886 "CPU %d: Uncorrected error reporting disabled for" 887 " bank %d\n", 888 cs->cpu_index, params->bank); 889 return; 890 } 891 892 if ((cenv->mcg_status & MCG_STATUS_MCIP) || 893 !(cenv->cr[4] & CR4_MCE_MASK)) { 894 monitor_printf(params->mon, 895 "CPU %d: Previous MCE still in progress, raising" 896 " triple fault\n", 897 cs->cpu_index); 898 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n"); 899 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 900 return; 901 } 902 if (banks[1] & MCI_STATUS_VAL) { 903 params->status |= MCI_STATUS_OVER; 904 } 905 banks[2] = params->addr; 906 banks[3] = params->misc; 907 cenv->mcg_status = params->mcg_status; 908 banks[1] = params->status; 909 cpu_interrupt(cs, CPU_INTERRUPT_MCE); 910 } else if (!(banks[1] & MCI_STATUS_VAL) 911 || !(banks[1] & MCI_STATUS_UC)) { 912 if (banks[1] & MCI_STATUS_VAL) { 913 params->status |= MCI_STATUS_OVER; 914 } 915 banks[2] = params->addr; 916 banks[3] = params->misc; 917 banks[1] = params->status; 918 } else { 919 banks[1] |= MCI_STATUS_OVER; 920 } 921 } 922 923 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, 924 uint64_t status, uint64_t mcg_status, uint64_t addr, 925 uint64_t misc, int flags) 926 { 927 CPUState *cs = CPU(cpu); 928 CPUX86State *cenv = &cpu->env; 929 MCEInjectionParams params = { 930 .mon = mon, 931 .bank = bank, 932 .status = status, 933 .mcg_status = mcg_status, 934 .addr = addr, 935 .misc = misc, 936 .flags = flags, 937 }; 938 unsigned bank_num = cenv->mcg_cap & 0xff; 939 940 if (!cenv->mcg_cap) { 941 monitor_printf(mon, "MCE injection not supported\n"); 942 return; 943 } 944 if (bank >= bank_num) { 945 monitor_printf(mon, "Invalid MCE bank number\n"); 946 return; 947 } 948 if (!(status & MCI_STATUS_VAL)) { 949 monitor_printf(mon, "Invalid MCE status code\n"); 950 return; 951 } 952 if ((flags & MCE_INJECT_BROADCAST) 953 && !cpu_x86_support_mca_broadcast(cenv)) { 954 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n"); 955 return; 956 } 957 958 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms)); 959 if (flags & MCE_INJECT_BROADCAST) { 960 CPUState *other_cs; 961 962 params.bank = 1; 963 params.status = MCI_STATUS_VAL | MCI_STATUS_UC; 964 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; 965 params.addr = 0; 966 params.misc = 0; 967 CPU_FOREACH(other_cs) { 968 if (other_cs == cs) { 969 continue; 970 } 971 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms)); 972 } 973 } 974 } 975 976 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) 977 { 978 X86CPU *cpu = env_archcpu(env); 979 CPUState *cs = env_cpu(env); 980 981 if (kvm_enabled() || whpx_enabled()) { 982 env->tpr_access_type = access; 983 984 cpu_interrupt(cs, CPU_INTERRUPT_TPR); 985 } else if (tcg_enabled()) { 986 cpu_restore_state(cs, cs->mem_io_pc, false); 987 988 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); 989 } 990 } 991 #endif /* !CONFIG_USER_ONLY */ 992 993 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, 994 target_ulong *base, unsigned int *limit, 995 unsigned int *flags) 996 { 997 CPUState *cs = env_cpu(env); 998 SegmentCache *dt; 999 target_ulong ptr; 1000 uint32_t e1, e2; 1001 int index; 1002 1003 if (selector & 0x4) 1004 dt = &env->ldt; 1005 else 1006 dt = &env->gdt; 1007 index = selector & ~7; 1008 ptr = dt->base + index; 1009 if ((index + 7) > dt->limit 1010 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 1011 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) 1012 return 0; 1013 1014 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); 1015 *limit = (e1 & 0xffff) | (e2 & 0x000f0000); 1016 if (e2 & DESC_G_MASK) 1017 *limit = (*limit << 12) | 0xfff; 1018 *flags = e2; 1019 1020 return 1; 1021 } 1022 1023 #if !defined(CONFIG_USER_ONLY) 1024 void do_cpu_init(X86CPU *cpu) 1025 { 1026 CPUState *cs = CPU(cpu); 1027 CPUX86State *env = &cpu->env; 1028 CPUX86State *save = g_new(CPUX86State, 1); 1029 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI; 1030 1031 *save = *env; 1032 1033 cpu_reset(cs); 1034 cs->interrupt_request = sipi; 1035 memcpy(&env->start_init_save, &save->start_init_save, 1036 offsetof(CPUX86State, end_init_save) - 1037 offsetof(CPUX86State, start_init_save)); 1038 g_free(save); 1039 1040 if (kvm_enabled()) { 1041 kvm_arch_do_init_vcpu(cpu); 1042 } 1043 apic_init_reset(cpu->apic_state); 1044 } 1045 1046 void do_cpu_sipi(X86CPU *cpu) 1047 { 1048 apic_sipi(cpu->apic_state); 1049 } 1050 #else 1051 void do_cpu_init(X86CPU *cpu) 1052 { 1053 } 1054 void do_cpu_sipi(X86CPU *cpu) 1055 { 1056 } 1057 #endif 1058 1059 /* Frob eflags into and out of the CPU temporary format. */ 1060 1061 void x86_cpu_exec_enter(CPUState *cs) 1062 { 1063 X86CPU *cpu = X86_CPU(cs); 1064 CPUX86State *env = &cpu->env; 1065 1066 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 1067 env->df = 1 - (2 * ((env->eflags >> 10) & 1)); 1068 CC_OP = CC_OP_EFLAGS; 1069 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 1070 } 1071 1072 void x86_cpu_exec_exit(CPUState *cs) 1073 { 1074 X86CPU *cpu = X86_CPU(cs); 1075 CPUX86State *env = &cpu->env; 1076 1077 env->eflags = cpu_compute_eflags(env); 1078 } 1079 1080 #ifndef CONFIG_USER_ONLY 1081 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr) 1082 { 1083 X86CPU *cpu = X86_CPU(cs); 1084 CPUX86State *env = &cpu->env; 1085 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1086 AddressSpace *as = cpu_addressspace(cs, attrs); 1087 1088 return address_space_ldub(as, addr, attrs, NULL); 1089 } 1090 1091 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr) 1092 { 1093 X86CPU *cpu = X86_CPU(cs); 1094 CPUX86State *env = &cpu->env; 1095 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1096 AddressSpace *as = cpu_addressspace(cs, attrs); 1097 1098 return address_space_lduw(as, addr, attrs, NULL); 1099 } 1100 1101 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr) 1102 { 1103 X86CPU *cpu = X86_CPU(cs); 1104 CPUX86State *env = &cpu->env; 1105 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1106 AddressSpace *as = cpu_addressspace(cs, attrs); 1107 1108 return address_space_ldl(as, addr, attrs, NULL); 1109 } 1110 1111 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr) 1112 { 1113 X86CPU *cpu = X86_CPU(cs); 1114 CPUX86State *env = &cpu->env; 1115 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1116 AddressSpace *as = cpu_addressspace(cs, attrs); 1117 1118 return address_space_ldq(as, addr, attrs, NULL); 1119 } 1120 1121 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val) 1122 { 1123 X86CPU *cpu = X86_CPU(cs); 1124 CPUX86State *env = &cpu->env; 1125 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1126 AddressSpace *as = cpu_addressspace(cs, attrs); 1127 1128 address_space_stb(as, addr, val, attrs, NULL); 1129 } 1130 1131 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val) 1132 { 1133 X86CPU *cpu = X86_CPU(cs); 1134 CPUX86State *env = &cpu->env; 1135 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1136 AddressSpace *as = cpu_addressspace(cs, attrs); 1137 1138 address_space_stl_notdirty(as, addr, val, attrs, NULL); 1139 } 1140 1141 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val) 1142 { 1143 X86CPU *cpu = X86_CPU(cs); 1144 CPUX86State *env = &cpu->env; 1145 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1146 AddressSpace *as = cpu_addressspace(cs, attrs); 1147 1148 address_space_stw(as, addr, val, attrs, NULL); 1149 } 1150 1151 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val) 1152 { 1153 X86CPU *cpu = X86_CPU(cs); 1154 CPUX86State *env = &cpu->env; 1155 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1156 AddressSpace *as = cpu_addressspace(cs, attrs); 1157 1158 address_space_stl(as, addr, val, attrs, NULL); 1159 } 1160 1161 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val) 1162 { 1163 X86CPU *cpu = X86_CPU(cs); 1164 CPUX86State *env = &cpu->env; 1165 MemTxAttrs attrs = cpu_get_mem_attrs(env); 1166 AddressSpace *as = cpu_addressspace(cs, attrs); 1167 1168 address_space_stq(as, addr, val, attrs, NULL); 1169 } 1170 #endif 1171