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