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