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