]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/helper.c
target-i386: Use cpu_exec_enter/exit qom hooks
[mirror_qemu.git] / target-i386 / helper.c
CommitLineData
2c0262af 1/*
eaa728ee 2 * i386 helpers (without register variable usage)
5fafdf24 3 *
2c0262af
FB
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
2c0262af 18 */
2c0262af 19
eaa728ee 20#include "cpu.h"
9c17d615 21#include "sysemu/kvm.h"
e0723c45 22#include "kvm_i386.h"
2fa11da0 23#ifndef CONFIG_USER_ONLY
9c17d615 24#include "sysemu/sysemu.h"
83c9089e 25#include "monitor/monitor.h"
2fa11da0 26#endif
f3f2d9be 27
eaa728ee 28//#define DEBUG_MMU
b5ec5ce0 29
317ac620 30static void cpu_x86_version(CPUX86State *env, int *family, int *model)
2bd3e04c
JD
31{
32 int cpuver = env->cpuid_version;
33
34 if (family == NULL || model == NULL) {
35 return;
36 }
37
38 *family = (cpuver >> 8) & 0x0f;
39 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
40}
41
42/* Broadcast MCA signal for processor version 06H_EH and above */
317ac620 43int cpu_x86_support_mca_broadcast(CPUX86State *env)
2bd3e04c
JD
44{
45 int family = 0;
46 int model = 0;
47
48 cpu_x86_version(env, &family, &model);
49 if ((family == 6 && model >= 14) || family > 6) {
50 return 1;
51 }
52
53 return 0;
54}
55
eaa728ee
FB
56/***********************************************************/
57/* x86 debug */
3b46e624 58
bc4b43dc 59static const char *cc_op_str[CC_OP_NB] = {
eaa728ee
FB
60 "DYNAMIC",
61 "EFLAGS",
7e84c249 62
eaa728ee
FB
63 "MULB",
64 "MULW",
65 "MULL",
66 "MULQ",
3b46e624 67
eaa728ee
FB
68 "ADDB",
69 "ADDW",
70 "ADDL",
71 "ADDQ",
3b46e624 72
eaa728ee
FB
73 "ADCB",
74 "ADCW",
75 "ADCL",
76 "ADCQ",
3b46e624 77
eaa728ee
FB
78 "SUBB",
79 "SUBW",
80 "SUBL",
81 "SUBQ",
7e84c249 82
eaa728ee
FB
83 "SBBB",
84 "SBBW",
85 "SBBL",
86 "SBBQ",
7e84c249 87
eaa728ee
FB
88 "LOGICB",
89 "LOGICW",
90 "LOGICL",
91 "LOGICQ",
7e84c249 92
eaa728ee
FB
93 "INCB",
94 "INCW",
95 "INCL",
96 "INCQ",
3b46e624 97
eaa728ee
FB
98 "DECB",
99 "DECW",
100 "DECL",
101 "DECQ",
3b46e624 102
eaa728ee
FB
103 "SHLB",
104 "SHLW",
105 "SHLL",
106 "SHLQ",
3b46e624 107
eaa728ee
FB
108 "SARB",
109 "SARW",
110 "SARL",
111 "SARQ",
bc4b43dc
RH
112
113 "BMILGB",
114 "BMILGW",
115 "BMILGL",
116 "BMILGQ",
cd7f97ca
RH
117
118 "ADCX",
119 "ADOX",
120 "ADCOX",
436ff2d2
RH
121
122 "CLR",
eaa728ee 123};
7e84c249 124
a3867ed2 125static void
317ac620 126cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
a3867ed2
AL
127 const char *name, struct SegmentCache *sc)
128{
129#ifdef TARGET_X86_64
130 if (env->hflags & HF_CS64_MASK) {
131 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
4058fd98 132 sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
133 } else
134#endif
135 {
136 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
4058fd98 137 (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
138 }
139
140 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
141 goto done;
142
143 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
144 if (sc->flags & DESC_S_MASK) {
145 if (sc->flags & DESC_CS_MASK) {
146 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
147 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
148 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
149 (sc->flags & DESC_R_MASK) ? 'R' : '-');
150 } else {
469936ae
TM
151 cpu_fprintf(f,
152 (sc->flags & DESC_B_MASK || env->hflags & HF_LMA_MASK)
153 ? "DS " : "DS16");
a3867ed2
AL
154 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
155 (sc->flags & DESC_W_MASK) ? 'W' : '-');
156 }
157 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
158 } else {
159 static const char *sys_type_name[2][16] = {
160 { /* 32 bit mode */
161 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
162 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
163 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
164 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
165 },
166 { /* 64 bit mode */
167 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
168 "Reserved", "Reserved", "Reserved", "Reserved",
169 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
170 "Reserved", "IntGate64", "TrapGate64"
171 }
172 };
e5c15eff
SW
173 cpu_fprintf(f, "%s",
174 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
175 [(sc->flags & DESC_TYPE_MASK)
176 >> DESC_TYPE_SHIFT]);
a3867ed2
AL
177 }
178done:
179 cpu_fprintf(f, "\n");
180}
181
f5c848ee
JK
182#define DUMP_CODE_BYTES_TOTAL 50
183#define DUMP_CODE_BYTES_BACKWARD 20
184
878096ee
AF
185void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
186 int flags)
eaa728ee 187{
878096ee
AF
188 X86CPU *cpu = X86_CPU(cs);
189 CPUX86State *env = &cpu->env;
eaa728ee
FB
190 int eflags, i, nb;
191 char cc_op_name[32];
192 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
7e84c249 193
4980ef9e 194 eflags = cpu_compute_eflags(env);
eaa728ee
FB
195#ifdef TARGET_X86_64
196 if (env->hflags & HF_CS64_MASK) {
197 cpu_fprintf(f,
198 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
199 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
200 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
201 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
202 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
203 env->regs[R_EAX],
204 env->regs[R_EBX],
205 env->regs[R_ECX],
206 env->regs[R_EDX],
207 env->regs[R_ESI],
208 env->regs[R_EDI],
209 env->regs[R_EBP],
210 env->regs[R_ESP],
211 env->regs[8],
212 env->regs[9],
213 env->regs[10],
214 env->regs[11],
215 env->regs[12],
216 env->regs[13],
217 env->regs[14],
218 env->regs[15],
219 env->eip, eflags,
220 eflags & DF_MASK ? 'D' : '-',
221 eflags & CC_O ? 'O' : '-',
222 eflags & CC_S ? 'S' : '-',
223 eflags & CC_Z ? 'Z' : '-',
224 eflags & CC_A ? 'A' : '-',
225 eflags & CC_P ? 'P' : '-',
226 eflags & CC_C ? 'C' : '-',
227 env->hflags & HF_CPL_MASK,
228 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 229 (env->a20_mask >> 20) & 1,
eaa728ee 230 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 231 cs->halted);
eaa728ee
FB
232 } else
233#endif
234 {
235 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
236 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
237 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
238 (uint32_t)env->regs[R_EAX],
239 (uint32_t)env->regs[R_EBX],
240 (uint32_t)env->regs[R_ECX],
241 (uint32_t)env->regs[R_EDX],
242 (uint32_t)env->regs[R_ESI],
243 (uint32_t)env->regs[R_EDI],
244 (uint32_t)env->regs[R_EBP],
245 (uint32_t)env->regs[R_ESP],
246 (uint32_t)env->eip, eflags,
247 eflags & DF_MASK ? 'D' : '-',
248 eflags & CC_O ? 'O' : '-',
249 eflags & CC_S ? 'S' : '-',
250 eflags & CC_Z ? 'Z' : '-',
251 eflags & CC_A ? 'A' : '-',
252 eflags & CC_P ? 'P' : '-',
253 eflags & CC_C ? 'C' : '-',
254 env->hflags & HF_CPL_MASK,
255 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 256 (env->a20_mask >> 20) & 1,
eaa728ee 257 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 258 cs->halted);
8145122b 259 }
3b46e624 260
a3867ed2
AL
261 for(i = 0; i < 6; i++) {
262 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
263 &env->segs[i]);
264 }
265 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
266 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
267
eaa728ee
FB
268#ifdef TARGET_X86_64
269 if (env->hflags & HF_LMA_MASK) {
eaa728ee
FB
270 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
271 env->gdt.base, env->gdt.limit);
272 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
273 env->idt.base, env->idt.limit);
274 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
275 (uint32_t)env->cr[0],
276 env->cr[2],
277 env->cr[3],
278 (uint32_t)env->cr[4]);
a59cb4e0
AL
279 for(i = 0; i < 4; i++)
280 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
281 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
d4b55be5 282 env->dr[6], env->dr[7]);
eaa728ee
FB
283 } else
284#endif
285 {
eaa728ee
FB
286 cpu_fprintf(f, "GDT= %08x %08x\n",
287 (uint32_t)env->gdt.base, env->gdt.limit);
288 cpu_fprintf(f, "IDT= %08x %08x\n",
289 (uint32_t)env->idt.base, env->idt.limit);
290 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
291 (uint32_t)env->cr[0],
292 (uint32_t)env->cr[2],
293 (uint32_t)env->cr[3],
294 (uint32_t)env->cr[4]);
9a78eead
SW
295 for(i = 0; i < 4; i++) {
296 cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
297 }
298 cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
299 env->dr[6], env->dr[7]);
eaa728ee 300 }
6fd2a026 301 if (flags & CPU_DUMP_CCOP) {
eaa728ee
FB
302 if ((unsigned)env->cc_op < CC_OP_NB)
303 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
304 else
305 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
306#ifdef TARGET_X86_64
307 if (env->hflags & HF_CS64_MASK) {
308 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
309 env->cc_src, env->cc_dst,
310 cc_op_name);
311 } else
312#endif
313 {
314 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
315 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
316 cc_op_name);
317 }
7e84c249 318 }
b5e5a934 319 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
6fd2a026 320 if (flags & CPU_DUMP_FPU) {
eaa728ee
FB
321 int fptag;
322 fptag = 0;
323 for(i = 0; i < 8; i++) {
324 fptag |= ((!env->fptags[i]) << i);
325 }
326 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
327 env->fpuc,
328 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
329 env->fpstt,
330 fptag,
331 env->mxcsr);
332 for(i=0;i<8;i++) {
1ffd41ee
AJ
333 CPU_LDoubleU u;
334 u.d = env->fpregs[i].d;
eaa728ee 335 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
1ffd41ee 336 i, u.l.lower, u.l.upper);
eaa728ee
FB
337 if ((i & 1) == 1)
338 cpu_fprintf(f, "\n");
339 else
340 cpu_fprintf(f, " ");
341 }
342 if (env->hflags & HF_CS64_MASK)
343 nb = 16;
344 else
345 nb = 8;
346 for(i=0;i<nb;i++) {
347 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
348 i,
349 env->xmm_regs[i].XMM_L(3),
350 env->xmm_regs[i].XMM_L(2),
351 env->xmm_regs[i].XMM_L(1),
352 env->xmm_regs[i].XMM_L(0));
353 if ((i & 1) == 1)
354 cpu_fprintf(f, "\n");
355 else
356 cpu_fprintf(f, " ");
357 }
7e84c249 358 }
f5c848ee
JK
359 if (flags & CPU_DUMP_CODE) {
360 target_ulong base = env->segs[R_CS].base + env->eip;
361 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
362 uint8_t code;
363 char codestr[3];
364
365 cpu_fprintf(f, "Code=");
366 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
f17ec444 367 if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
f5c848ee
JK
368 snprintf(codestr, sizeof(codestr), "%02x", code);
369 } else {
370 snprintf(codestr, sizeof(codestr), "??");
371 }
372 cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
373 i == offs ? "<" : "", codestr, i == offs ? ">" : "");
374 }
375 cpu_fprintf(f, "\n");
376 }
2c0262af 377}
7e84c249 378
eaa728ee
FB
379/***********************************************************/
380/* x86 mmu */
381/* XXX: add PGE support */
382
cc36a7a2 383void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
2c0262af 384{
cc36a7a2
AF
385 CPUX86State *env = &cpu->env;
386
eaa728ee
FB
387 a20_state = (a20_state != 0);
388 if (a20_state != ((env->a20_mask >> 20) & 1)) {
00c8cb0a
AF
389 CPUState *cs = CPU(cpu);
390
eaa728ee
FB
391#if defined(DEBUG_MMU)
392 printf("A20 update: a20=%d\n", a20_state);
393#endif
394 /* if the cpu is currently executing code, we must unlink it and
395 all the potentially executing TB */
00c8cb0a 396 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
3b46e624 397
eaa728ee
FB
398 /* when a20 is changed, all the MMU mappings are invalid, so
399 we must flush everything */
00c8cb0a 400 tlb_flush(cs, 1);
5ee0ffaa 401 env->a20_mask = ~(1 << 20) | (a20_state << 20);
7e84c249 402 }
2c0262af
FB
403}
404
eaa728ee 405void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 406{
00c8cb0a 407 X86CPU *cpu = x86_env_get_cpu(env);
eaa728ee 408 int pe_state;
2c0262af 409
eaa728ee
FB
410#if defined(DEBUG_MMU)
411 printf("CR0 update: CR0=0x%08x\n", new_cr0);
412#endif
413 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
414 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
00c8cb0a 415 tlb_flush(CPU(cpu), 1);
eaa728ee 416 }
2c0262af 417
eaa728ee
FB
418#ifdef TARGET_X86_64
419 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
420 (env->efer & MSR_EFER_LME)) {
421 /* enter in long mode */
422 /* XXX: generate an exception */
423 if (!(env->cr[4] & CR4_PAE_MASK))
424 return;
425 env->efer |= MSR_EFER_LMA;
426 env->hflags |= HF_LMA_MASK;
427 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
428 (env->efer & MSR_EFER_LMA)) {
429 /* exit long mode */
430 env->efer &= ~MSR_EFER_LMA;
431 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
432 env->eip &= 0xffffffff;
433 }
434#endif
435 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 436
eaa728ee
FB
437 /* update PE flag in hidden flags */
438 pe_state = (env->cr[0] & CR0_PE_MASK);
439 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
440 /* ensure that ADDSEG is always set in real mode */
441 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
442 /* update FPU flags */
443 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
444 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
445}
446
eaa728ee
FB
447/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
448 the PDPT */
449void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 450{
00c8cb0a
AF
451 X86CPU *cpu = x86_env_get_cpu(env);
452
eaa728ee
FB
453 env->cr[3] = new_cr3;
454 if (env->cr[0] & CR0_PG_MASK) {
455#if defined(DEBUG_MMU)
456 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
457#endif
00c8cb0a 458 tlb_flush(CPU(cpu), 0);
eaa728ee 459 }
7e84c249
FB
460}
461
eaa728ee 462void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 463{
00c8cb0a
AF
464 X86CPU *cpu = x86_env_get_cpu(env);
465
eaa728ee
FB
466#if defined(DEBUG_MMU)
467 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
468#endif
a9321a4d
PA
469 if ((new_cr4 ^ env->cr[4]) &
470 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
471 CR4_SMEP_MASK | CR4_SMAP_MASK)) {
00c8cb0a 472 tlb_flush(CPU(cpu), 1);
eaa728ee
FB
473 }
474 /* SSE handling */
0514ef2f 475 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
eaa728ee 476 new_cr4 &= ~CR4_OSFXSR_MASK;
a9321a4d
PA
477 }
478 env->hflags &= ~HF_OSFXSR_MASK;
479 if (new_cr4 & CR4_OSFXSR_MASK) {
eaa728ee 480 env->hflags |= HF_OSFXSR_MASK;
a9321a4d
PA
481 }
482
0514ef2f 483 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
a9321a4d
PA
484 new_cr4 &= ~CR4_SMAP_MASK;
485 }
486 env->hflags &= ~HF_SMAP_MASK;
487 if (new_cr4 & CR4_SMAP_MASK) {
488 env->hflags |= HF_SMAP_MASK;
489 }
b8b6a50b 490
eaa728ee 491 env->cr[4] = new_cr4;
b8b6a50b
FB
492}
493
eaa728ee
FB
494#if defined(CONFIG_USER_ONLY)
495
7510454e 496int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 497 int is_write, int mmu_idx)
b8b6a50b 498{
7510454e
AF
499 X86CPU *cpu = X86_CPU(cs);
500 CPUX86State *env = &cpu->env;
501
eaa728ee
FB
502 /* user mode only emulation */
503 is_write &= 1;
504 env->cr[2] = addr;
505 env->error_code = (is_write << PG_ERROR_W_BIT);
506 env->error_code |= PG_ERROR_U_MASK;
27103424 507 cs->exception_index = EXCP0E_PAGE;
eaa728ee 508 return 1;
2c0262af
FB
509}
510
8d7b0fbb 511#else
891b38e4 512
eaa728ee 513/* return value:
7510454e
AF
514 * -1 = cannot handle fault
515 * 0 = nothing more to do
516 * 1 = generate PF fault
517 */
518int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 519 int is_write1, int mmu_idx)
eaa728ee 520{
7510454e
AF
521 X86CPU *cpu = X86_CPU(cs);
522 CPUX86State *env = &cpu->env;
eaa728ee
FB
523 uint64_t ptep, pte;
524 target_ulong pde_addr, pte_addr;
c1eb2fa3
PB
525 int error_code = 0;
526 int is_dirty, prot, page_size, is_write, is_user;
a8170e5e 527 hwaddr paddr;
e8f6d00c 528 uint64_t rsvd_mask = PG_HI_RSVD_MASK;
eaa728ee 529 uint32_t page_offset;
e7e898a7 530 target_ulong vaddr;
eaa728ee
FB
531
532 is_user = mmu_idx == MMU_USER_IDX;
533#if defined(DEBUG_MMU)
7510454e 534 printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
eaa728ee
FB
535 addr, is_write1, is_user, env->eip);
536#endif
537 is_write = is_write1 & 1;
538
539 if (!(env->cr[0] & CR0_PG_MASK)) {
540 pte = addr;
33dfdb56
AG
541#ifdef TARGET_X86_64
542 if (!(env->hflags & HF_LMA_MASK)) {
543 /* Without long mode we can only address 32bits in real mode */
544 pte = (uint32_t)pte;
545 }
546#endif
eaa728ee
FB
547 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
548 page_size = 4096;
549 goto do_mapping;
550 }
551
e2a32ebb
PB
552 if (!(env->efer & MSR_EFER_NXE)) {
553 rsvd_mask |= PG_NX_MASK;
554 }
555
eaa728ee
FB
556 if (env->cr[4] & CR4_PAE_MASK) {
557 uint64_t pde, pdpe;
558 target_ulong pdpe_addr;
2c0262af 559
eaa728ee
FB
560#ifdef TARGET_X86_64
561 if (env->hflags & HF_LMA_MASK) {
562 uint64_t pml4e_addr, pml4e;
563 int32_t sext;
564
565 /* test virtual address sign extension */
566 sext = (int64_t)addr >> 47;
567 if (sext != 0 && sext != -1) {
568 env->error_code = 0;
27103424 569 cs->exception_index = EXCP0D_GPF;
eaa728ee
FB
570 return 1;
571 }
0573fbfc 572
eaa728ee
FB
573 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
574 env->a20_mask;
2c17449b 575 pml4e = ldq_phys(cs->as, pml4e_addr);
eaa728ee 576 if (!(pml4e & PG_PRESENT_MASK)) {
eaa728ee
FB
577 goto do_fault;
578 }
e8f6d00c 579 if (pml4e & (rsvd_mask | PG_PSE_MASK)) {
b728464a
PB
580 goto do_fault_rsvd;
581 }
eaa728ee
FB
582 if (!(pml4e & PG_ACCESSED_MASK)) {
583 pml4e |= PG_ACCESSED_MASK;
2198a121 584 stl_phys_notdirty(cs->as, pml4e_addr, pml4e);
eaa728ee
FB
585 }
586 ptep = pml4e ^ PG_NX_MASK;
e8f6d00c 587 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
eaa728ee 588 env->a20_mask;
2c17449b 589 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee 590 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee
FB
591 goto do_fault;
592 }
e8f6d00c
PB
593 if (pdpe & rsvd_mask) {
594 goto do_fault_rsvd;
595 }
eaa728ee
FB
596 ptep &= pdpe ^ PG_NX_MASK;
597 if (!(pdpe & PG_ACCESSED_MASK)) {
598 pdpe |= PG_ACCESSED_MASK;
2198a121 599 stl_phys_notdirty(cs->as, pdpe_addr, pdpe);
eaa728ee 600 }
77549a78
PB
601 if (pdpe & PG_PSE_MASK) {
602 /* 1 GB page */
603 page_size = 1024 * 1024 * 1024;
604 pte_addr = pdpe_addr;
605 pte = pdpe;
606 goto do_check_protect;
607 }
eaa728ee
FB
608 } else
609#endif
610 {
611 /* XXX: load them when cr3 is loaded ? */
612 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
613 env->a20_mask;
2c17449b 614 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee 615 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee
FB
616 goto do_fault;
617 }
1844e68e
WG
618 rsvd_mask |= PG_HI_USER_MASK;
619 if (pdpe & (rsvd_mask | PG_NX_MASK)) {
e8f6d00c
PB
620 goto do_fault_rsvd;
621 }
eaa728ee 622 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
7e84c249 623 }
7e84c249 624
e8f6d00c 625 pde_addr = ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
eaa728ee 626 env->a20_mask;
2c17449b 627 pde = ldq_phys(cs->as, pde_addr);
eaa728ee 628 if (!(pde & PG_PRESENT_MASK)) {
eaa728ee
FB
629 goto do_fault;
630 }
e8f6d00c
PB
631 if (pde & rsvd_mask) {
632 goto do_fault_rsvd;
633 }
eaa728ee
FB
634 ptep &= pde ^ PG_NX_MASK;
635 if (pde & PG_PSE_MASK) {
636 /* 2 MB page */
637 page_size = 2048 * 1024;
00cc3e1d
PB
638 pte_addr = pde_addr;
639 pte = pde;
b052e450
PB
640 goto do_check_protect;
641 }
642 /* 4 KB page */
643 if (!(pde & PG_ACCESSED_MASK)) {
644 pde |= PG_ACCESSED_MASK;
645 stl_phys_notdirty(cs->as, pde_addr, pde);
646 }
e8f6d00c 647 pte_addr = ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
b052e450
PB
648 env->a20_mask;
649 pte = ldq_phys(cs->as, pte_addr);
650 if (!(pte & PG_PRESENT_MASK)) {
b052e450
PB
651 goto do_fault;
652 }
e8f6d00c
PB
653 if (pte & rsvd_mask) {
654 goto do_fault_rsvd;
655 }
b052e450
PB
656 /* combine pde and pte nx, user and rw protections */
657 ptep &= pte ^ PG_NX_MASK;
658 page_size = 4096;
2c0262af 659 } else {
eaa728ee
FB
660 uint32_t pde;
661
662 /* page directory entry */
663 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
664 env->a20_mask;
fdfba1a2 665 pde = ldl_phys(cs->as, pde_addr);
eaa728ee 666 if (!(pde & PG_PRESENT_MASK)) {
eaa728ee
FB
667 goto do_fault;
668 }
870a7067
PB
669 ptep = pde | PG_NX_MASK;
670
eaa728ee
FB
671 /* if PSE bit is set, then we use a 4MB page */
672 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
673 page_size = 4096 * 1024;
487cad88 674 pte_addr = pde_addr;
de431a65
PB
675
676 /* Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
677 * Leave bits 20-13 in place for setting accessed/dirty bits below.
678 */
679 pte = pde | ((pde & 0x1fe000) << (32 - 13));
680 rsvd_mask = 0x200000;
681 goto do_check_protect_pse36;
b052e450 682 }
891b38e4 683
b052e450
PB
684 if (!(pde & PG_ACCESSED_MASK)) {
685 pde |= PG_ACCESSED_MASK;
686 stl_phys_notdirty(cs->as, pde_addr, pde);
687 }
688
689 /* page directory entry */
690 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
691 env->a20_mask;
692 pte = ldl_phys(cs->as, pte_addr);
693 if (!(pte & PG_PRESENT_MASK)) {
b052e450 694 goto do_fault;
487cad88 695 }
b052e450
PB
696 /* combine pde and pte user and rw protections */
697 ptep &= pte | PG_NX_MASK;
698 page_size = 4096;
e8f6d00c 699 rsvd_mask = 0;
7c822560 700 }
487cad88 701
b052e450 702do_check_protect:
eaad03e4 703 rsvd_mask |= (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK;
de431a65 704do_check_protect_pse36:
e8f6d00c
PB
705 if (pte & rsvd_mask) {
706 goto do_fault_rsvd;
707 }
870a7067 708 ptep ^= PG_NX_MASK;
7c822560
PB
709 if ((ptep & PG_NX_MASK) && is_write1 == 2) {
710 goto do_fault_protect;
711 }
712 switch (mmu_idx) {
713 case MMU_USER_IDX:
714 if (!(ptep & PG_USER_MASK)) {
715 goto do_fault_protect;
716 }
717 if (is_write && !(ptep & PG_RW_MASK)) {
718 goto do_fault_protect;
719 }
720 break;
487cad88 721
7c822560
PB
722 case MMU_KSMAP_IDX:
723 if (is_write1 != 2 && (ptep & PG_USER_MASK)) {
724 goto do_fault_protect;
2c0262af 725 }
7c822560
PB
726 /* fall through */
727 case MMU_KNOSMAP_IDX:
728 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
729 (ptep & PG_USER_MASK)) {
730 goto do_fault_protect;
731 }
732 if ((env->cr[0] & CR0_WP_MASK) &&
733 is_write && !(ptep & PG_RW_MASK)) {
734 goto do_fault_protect;
487cad88 735 }
7c822560
PB
736 break;
737
738 default: /* cannot happen */
739 break;
740 }
741 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
742 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
743 pte |= PG_ACCESSED_MASK;
744 if (is_dirty) {
745 pte |= PG_DIRTY_MASK;
746 }
747 stl_phys_notdirty(cs->as, pte_addr, pte);
2c0262af 748 }
7c822560 749
eaa728ee
FB
750 /* the page can be put in the TLB */
751 prot = PAGE_READ;
b09481de 752 if (!(ptep & PG_NX_MASK) &&
b4bda1ae
RZ
753 (mmu_idx == MMU_USER_IDX ||
754 !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
eaa728ee 755 prot |= PAGE_EXEC;
b09481de 756 }
eaa728ee
FB
757 if (pte & PG_DIRTY_MASK) {
758 /* only set write access if already dirty... otherwise wait
759 for dirty access */
760 if (is_user) {
761 if (ptep & PG_RW_MASK)
762 prot |= PAGE_WRITE;
763 } else {
764 if (!(env->cr[0] & CR0_WP_MASK) ||
765 (ptep & PG_RW_MASK))
766 prot |= PAGE_WRITE;
8e682019 767 }
891b38e4 768 }
eaa728ee
FB
769 do_mapping:
770 pte = pte & env->a20_mask;
771
e7e898a7
PB
772 /* align to page_size */
773 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
774
eaa728ee
FB
775 /* Even if 4MB pages, we map only one 4KB page in the cache to
776 avoid filling it too fast */
e7e898a7
PB
777 vaddr = addr & TARGET_PAGE_MASK;
778 page_offset = vaddr & (page_size - 1);
779 paddr = pte + page_offset;
eaa728ee 780
0c591eb0 781 tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
d4c430a8 782 return 0;
c1eb2fa3
PB
783 do_fault_rsvd:
784 error_code |= PG_ERROR_RSVD_MASK;
eaa728ee 785 do_fault_protect:
c1eb2fa3 786 error_code |= PG_ERROR_P_MASK;
eaa728ee
FB
787 do_fault:
788 error_code |= (is_write << PG_ERROR_W_BIT);
789 if (is_user)
790 error_code |= PG_ERROR_U_MASK;
791 if (is_write1 == 2 &&
a9321a4d
PA
792 (((env->efer & MSR_EFER_NXE) &&
793 (env->cr[4] & CR4_PAE_MASK)) ||
794 (env->cr[4] & CR4_SMEP_MASK)))
eaa728ee 795 error_code |= PG_ERROR_I_D_MASK;
872929aa
FB
796 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
797 /* cr2 is not modified in case of exceptions */
f606604f
EI
798 stq_phys(cs->as,
799 env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
872929aa 800 addr);
eaa728ee
FB
801 } else {
802 env->cr[2] = addr;
2c0262af 803 }
eaa728ee 804 env->error_code = error_code;
27103424 805 cs->exception_index = EXCP0E_PAGE;
eaa728ee 806 return 1;
14ce26e7
FB
807}
808
00b941e5 809hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
14ce26e7 810{
00b941e5
AF
811 X86CPU *cpu = X86_CPU(cs);
812 CPUX86State *env = &cpu->env;
eaa728ee
FB
813 target_ulong pde_addr, pte_addr;
814 uint64_t pte;
eaa728ee
FB
815 uint32_t page_offset;
816 int page_size;
14ce26e7 817
f2f8560c
PB
818 if (!(env->cr[0] & CR0_PG_MASK)) {
819 pte = addr & env->a20_mask;
820 page_size = 4096;
821 } else if (env->cr[4] & CR4_PAE_MASK) {
eaa728ee
FB
822 target_ulong pdpe_addr;
823 uint64_t pde, pdpe;
14ce26e7 824
eaa728ee
FB
825#ifdef TARGET_X86_64
826 if (env->hflags & HF_LMA_MASK) {
827 uint64_t pml4e_addr, pml4e;
828 int32_t sext;
829
830 /* test virtual address sign extension */
831 sext = (int64_t)addr >> 47;
16b96f82 832 if (sext != 0 && sext != -1) {
eaa728ee 833 return -1;
16b96f82 834 }
eaa728ee
FB
835 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
836 env->a20_mask;
2c17449b 837 pml4e = ldq_phys(cs->as, pml4e_addr);
16b96f82 838 if (!(pml4e & PG_PRESENT_MASK)) {
eaa728ee 839 return -1;
16b96f82
PB
840 }
841 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
3f2cbf0d 842 (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
2c17449b 843 pdpe = ldq_phys(cs->as, pdpe_addr);
16b96f82 844 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee 845 return -1;
16b96f82 846 }
c8c14bcb
LC
847 if (pdpe & PG_PSE_MASK) {
848 page_size = 1024 * 1024 * 1024;
16b96f82 849 pte = pdpe;
c8c14bcb
LC
850 goto out;
851 }
852
eaa728ee
FB
853 } else
854#endif
855 {
856 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
857 env->a20_mask;
2c17449b 858 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee
FB
859 if (!(pdpe & PG_PRESENT_MASK))
860 return -1;
14ce26e7 861 }
14ce26e7 862
16b96f82 863 pde_addr = ((pdpe & PG_ADDRESS_MASK) +
3f2cbf0d 864 (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
2c17449b 865 pde = ldq_phys(cs->as, pde_addr);
eaa728ee
FB
866 if (!(pde & PG_PRESENT_MASK)) {
867 return -1;
868 }
869 if (pde & PG_PSE_MASK) {
870 /* 2 MB page */
871 page_size = 2048 * 1024;
16b96f82 872 pte = pde;
eaa728ee
FB
873 } else {
874 /* 4 KB page */
16b96f82 875 pte_addr = ((pde & PG_ADDRESS_MASK) +
3f2cbf0d 876 (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
eaa728ee 877 page_size = 4096;
2c17449b 878 pte = ldq_phys(cs->as, pte_addr);
eaa728ee 879 }
16b96f82 880 if (!(pte & PG_PRESENT_MASK)) {
ca1c9e15 881 return -1;
16b96f82 882 }
14ce26e7 883 } else {
eaa728ee 884 uint32_t pde;
3b46e624 885
f2f8560c
PB
886 /* page directory entry */
887 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
fdfba1a2 888 pde = ldl_phys(cs->as, pde_addr);
f2f8560c
PB
889 if (!(pde & PG_PRESENT_MASK))
890 return -1;
891 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
de431a65 892 pte = pde | ((pde & 0x1fe000) << (32 - 13));
f2f8560c 893 page_size = 4096 * 1024;
eaa728ee
FB
894 } else {
895 /* page directory entry */
f2f8560c 896 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
fdfba1a2 897 pte = ldl_phys(cs->as, pte_addr);
16b96f82 898 if (!(pte & PG_PRESENT_MASK)) {
eaa728ee 899 return -1;
16b96f82 900 }
f2f8560c 901 page_size = 4096;
eaa728ee
FB
902 }
903 pte = pte & env->a20_mask;
14ce26e7 904 }
14ce26e7 905
c8c14bcb
LC
906#ifdef TARGET_X86_64
907out:
908#endif
16b96f82 909 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
eaa728ee 910 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
16b96f82 911 return pte | page_offset;
3b21e03e 912}
01df040b 913
317ac620 914void hw_breakpoint_insert(CPUX86State *env, int index)
01df040b 915{
75a34036 916 CPUState *cs = CPU(x86_env_get_cpu(env));
1cc21a18 917 int type = 0, err = 0;
01df040b
AL
918
919 switch (hw_breakpoint_type(env->dr[7], index)) {
428065ce 920 case DR7_TYPE_BP_INST:
5902564a 921 if (hw_breakpoint_enabled(env->dr[7], index)) {
b3310ab3 922 err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
01df040b 923 &env->cpu_breakpoint[index]);
5902564a 924 }
01df040b 925 break;
428065ce 926 case DR7_TYPE_DATA_WR:
01df040b 927 type = BP_CPU | BP_MEM_WRITE;
1cc21a18 928 break;
428065ce 929 case DR7_TYPE_IO_RW:
1cc21a18 930 /* No support for I/O watchpoints yet */
01df040b 931 break;
428065ce 932 case DR7_TYPE_DATA_RW:
01df040b 933 type = BP_CPU | BP_MEM_ACCESS;
1cc21a18
LG
934 break;
935 }
936
937 if (type != 0) {
75a34036 938 err = cpu_watchpoint_insert(cs, env->dr[index],
01df040b
AL
939 hw_breakpoint_len(env->dr[7], index),
940 type, &env->cpu_watchpoint[index]);
01df040b 941 }
1cc21a18
LG
942
943 if (err) {
01df040b 944 env->cpu_breakpoint[index] = NULL;
1cc21a18 945 }
01df040b
AL
946}
947
317ac620 948void hw_breakpoint_remove(CPUX86State *env, int index)
01df040b 949{
75a34036
AF
950 CPUState *cs;
951
952 if (!env->cpu_breakpoint[index]) {
01df040b 953 return;
75a34036
AF
954 }
955 cs = CPU(x86_env_get_cpu(env));
01df040b 956 switch (hw_breakpoint_type(env->dr[7], index)) {
428065ce 957 case DR7_TYPE_BP_INST:
5902564a 958 if (hw_breakpoint_enabled(env->dr[7], index)) {
b3310ab3 959 cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
5902564a 960 }
01df040b 961 break;
428065ce
LG
962 case DR7_TYPE_DATA_WR:
963 case DR7_TYPE_DATA_RW:
75a34036 964 cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
01df040b 965 break;
428065ce 966 case DR7_TYPE_IO_RW:
01df040b
AL
967 /* No support for I/O watchpoints yet */
968 break;
969 }
970}
971
e175bce5 972bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
01df040b
AL
973{
974 target_ulong dr6;
e175bce5
LG
975 int reg;
976 bool hit_enabled = false;
01df040b
AL
977
978 dr6 = env->dr[6] & ~0xf;
428065ce 979 for (reg = 0; reg < DR7_MAX_BP; reg++) {
e175bce5
LG
980 bool bp_match = false;
981 bool wp_match = false;
982
983 switch (hw_breakpoint_type(env->dr[7], reg)) {
984 case DR7_TYPE_BP_INST:
985 if (env->dr[reg] == env->eip) {
986 bp_match = true;
987 }
988 break;
989 case DR7_TYPE_DATA_WR:
990 case DR7_TYPE_DATA_RW:
991 if (env->cpu_watchpoint[reg] &&
992 env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
993 wp_match = true;
994 }
995 break;
996 case DR7_TYPE_IO_RW:
997 break;
998 }
999 if (bp_match || wp_match) {
01df040b 1000 dr6 |= 1 << reg;
5902564a 1001 if (hw_breakpoint_enabled(env->dr[7], reg)) {
e175bce5 1002 hit_enabled = true;
5902564a 1003 }
01df040b
AL
1004 }
1005 }
e175bce5
LG
1006
1007 if (hit_enabled || force_dr6_update) {
01df040b 1008 env->dr[6] = dr6;
e175bce5
LG
1009 }
1010
01df040b
AL
1011 return hit_enabled;
1012}
1013
86025ee4 1014void breakpoint_handler(CPUState *cs)
01df040b 1015{
86025ee4
PM
1016 X86CPU *cpu = X86_CPU(cs);
1017 CPUX86State *env = &cpu->env;
01df040b
AL
1018 CPUBreakpoint *bp;
1019
ff4700b0
AF
1020 if (cs->watchpoint_hit) {
1021 if (cs->watchpoint_hit->flags & BP_CPU) {
1022 cs->watchpoint_hit = NULL;
e175bce5 1023 if (check_hw_breakpoints(env, false)) {
77b2bc2c 1024 raise_exception(env, EXCP01_DB);
e175bce5 1025 } else {
0ea8cb88 1026 cpu_resume_from_signal(cs, NULL);
e175bce5 1027 }
01df040b
AL
1028 }
1029 } else {
f0c3c505 1030 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
01df040b
AL
1031 if (bp->pc == env->eip) {
1032 if (bp->flags & BP_CPU) {
e175bce5 1033 check_hw_breakpoints(env, true);
77b2bc2c 1034 raise_exception(env, EXCP01_DB);
01df040b
AL
1035 }
1036 break;
1037 }
f0c3c505 1038 }
01df040b 1039 }
01df040b 1040}
79c4f6b0 1041
d5bfda33
JK
1042typedef struct MCEInjectionParams {
1043 Monitor *mon;
55e5c285 1044 X86CPU *cpu;
d5bfda33
JK
1045 int bank;
1046 uint64_t status;
1047 uint64_t mcg_status;
1048 uint64_t addr;
1049 uint64_t misc;
1050 int flags;
1051} MCEInjectionParams;
1052
1053static void do_inject_x86_mce(void *data)
79c4f6b0 1054{
d5bfda33 1055 MCEInjectionParams *params = data;
55e5c285
AF
1056 CPUX86State *cenv = &params->cpu->env;
1057 CPUState *cpu = CPU(params->cpu);
d5bfda33
JK
1058 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1059
cb446eca 1060 cpu_synchronize_state(cpu);
316378e4 1061
747461c7
JK
1062 /*
1063 * If there is an MCE exception being processed, ignore this SRAO MCE
1064 * unless unconditional injection was requested.
1065 */
d5bfda33
JK
1066 if (!(params->flags & MCE_INJECT_UNCOND_AO)
1067 && !(params->status & MCI_STATUS_AR)
747461c7
JK
1068 && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1069 return;
1070 }
d5bfda33
JK
1071
1072 if (params->status & MCI_STATUS_UC) {
316378e4
JK
1073 /*
1074 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1075 * reporting is disabled
1076 */
d5bfda33
JK
1077 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1078 monitor_printf(params->mon,
316378e4 1079 "CPU %d: Uncorrected error reporting disabled\n",
55e5c285 1080 cpu->cpu_index);
316378e4
JK
1081 return;
1082 }
1083
1084 /*
1085 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1086 * reporting is disabled for the bank
1087 */
1088 if (banks[0] != ~(uint64_t)0) {
d5bfda33
JK
1089 monitor_printf(params->mon,
1090 "CPU %d: Uncorrected error reporting disabled for"
1091 " bank %d\n",
55e5c285 1092 cpu->cpu_index, params->bank);
316378e4
JK
1093 return;
1094 }
1095
79c4f6b0
HY
1096 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1097 !(cenv->cr[4] & CR4_MCE_MASK)) {
d5bfda33
JK
1098 monitor_printf(params->mon,
1099 "CPU %d: Previous MCE still in progress, raising"
1100 " triple fault\n",
55e5c285 1101 cpu->cpu_index);
79c4f6b0
HY
1102 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1103 qemu_system_reset_request();
1104 return;
1105 }
2fa11da0 1106 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1107 params->status |= MCI_STATUS_OVER;
2fa11da0 1108 }
d5bfda33
JK
1109 banks[2] = params->addr;
1110 banks[3] = params->misc;
1111 cenv->mcg_status = params->mcg_status;
1112 banks[1] = params->status;
c3affe56 1113 cpu_interrupt(cpu, CPU_INTERRUPT_MCE);
79c4f6b0
HY
1114 } else if (!(banks[1] & MCI_STATUS_VAL)
1115 || !(banks[1] & MCI_STATUS_UC)) {
2fa11da0 1116 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1117 params->status |= MCI_STATUS_OVER;
2fa11da0 1118 }
d5bfda33
JK
1119 banks[2] = params->addr;
1120 banks[3] = params->misc;
1121 banks[1] = params->status;
2fa11da0 1122 } else {
79c4f6b0 1123 banks[1] |= MCI_STATUS_OVER;
2fa11da0 1124 }
79c4f6b0 1125}
b3cd24e0 1126
8c5cf3b6 1127void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
316378e4 1128 uint64_t status, uint64_t mcg_status, uint64_t addr,
747461c7 1129 uint64_t misc, int flags)
b3cd24e0 1130{
182735ef 1131 CPUState *cs = CPU(cpu);
8c5cf3b6 1132 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
1133 MCEInjectionParams params = {
1134 .mon = mon,
55e5c285 1135 .cpu = cpu,
d5bfda33
JK
1136 .bank = bank,
1137 .status = status,
1138 .mcg_status = mcg_status,
1139 .addr = addr,
1140 .misc = misc,
1141 .flags = flags,
1142 };
b3cd24e0
JD
1143 unsigned bank_num = cenv->mcg_cap & 0xff;
1144
316378e4
JK
1145 if (!cenv->mcg_cap) {
1146 monitor_printf(mon, "MCE injection not supported\n");
b3cd24e0
JD
1147 return;
1148 }
316378e4
JK
1149 if (bank >= bank_num) {
1150 monitor_printf(mon, "Invalid MCE bank number\n");
1151 return;
1152 }
1153 if (!(status & MCI_STATUS_VAL)) {
1154 monitor_printf(mon, "Invalid MCE status code\n");
1155 return;
1156 }
747461c7
JK
1157 if ((flags & MCE_INJECT_BROADCAST)
1158 && !cpu_x86_support_mca_broadcast(cenv)) {
316378e4
JK
1159 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1160 return;
2bd3e04c
JD
1161 }
1162
182735ef 1163 run_on_cpu(cs, do_inject_x86_mce, &params);
c34d440a 1164 if (flags & MCE_INJECT_BROADCAST) {
182735ef
AF
1165 CPUState *other_cs;
1166
c34d440a
JK
1167 params.bank = 1;
1168 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1169 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1170 params.addr = 0;
1171 params.misc = 0;
bdc44640 1172 CPU_FOREACH(other_cs) {
182735ef 1173 if (other_cs == cs) {
c34d440a 1174 continue;
31ce5e0c 1175 }
182735ef
AF
1176 params.cpu = X86_CPU(other_cs);
1177 run_on_cpu(other_cs, do_inject_x86_mce, &params);
31ce5e0c 1178 }
b3cd24e0
JD
1179 }
1180}
d362e757 1181
317ac620 1182void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
d362e757 1183{
02e51483 1184 X86CPU *cpu = x86_env_get_cpu(env);
93afeade 1185 CPUState *cs = CPU(cpu);
02e51483 1186
d362e757
JK
1187 if (kvm_enabled()) {
1188 env->tpr_access_type = access;
1189
93afeade 1190 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
d362e757 1191 } else {
3f38f309 1192 cpu_restore_state(cs, cs->mem_io_pc);
d362e757 1193
02e51483 1194 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
d362e757
JK
1195 }
1196}
74ce674f 1197#endif /* !CONFIG_USER_ONLY */
6fd805e1 1198
84273177
JK
1199int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1200 target_ulong *base, unsigned int *limit,
1201 unsigned int *flags)
1202{
f17ec444
AF
1203 X86CPU *cpu = x86_env_get_cpu(env);
1204 CPUState *cs = CPU(cpu);
84273177
JK
1205 SegmentCache *dt;
1206 target_ulong ptr;
1207 uint32_t e1, e2;
1208 int index;
1209
1210 if (selector & 0x4)
1211 dt = &env->ldt;
1212 else
1213 dt = &env->gdt;
1214 index = selector & ~7;
1215 ptr = dt->base + index;
1216 if ((index + 7) > dt->limit
f17ec444
AF
1217 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1218 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
84273177
JK
1219 return 0;
1220
1221 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1222 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1223 if (e2 & DESC_G_MASK)
1224 *limit = (*limit << 12) | 0xfff;
1225 *flags = e2;
1226
1227 return 1;
1228}
1229
b09ea7d5 1230#if !defined(CONFIG_USER_ONLY)
232fc23b 1231void do_cpu_init(X86CPU *cpu)
b09ea7d5 1232{
259186a7 1233 CPUState *cs = CPU(cpu);
232fc23b 1234 CPUX86State *env = &cpu->env;
43175fa9 1235 CPUX86State *save = g_new(CPUX86State, 1);
259186a7 1236 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
43175fa9
PB
1237
1238 *save = *env;
ebda377f 1239
259186a7
AF
1240 cpu_reset(cs);
1241 cs->interrupt_request = sipi;
43175fa9
PB
1242 memcpy(&env->start_init_save, &save->start_init_save,
1243 offsetof(CPUX86State, end_init_save) -
1244 offsetof(CPUX86State, start_init_save));
1245 g_free(save);
1246
e0723c45
PB
1247 if (kvm_enabled()) {
1248 kvm_arch_do_init_vcpu(cpu);
1249 }
02e51483 1250 apic_init_reset(cpu->apic_state);
b09ea7d5
GN
1251}
1252
232fc23b 1253void do_cpu_sipi(X86CPU *cpu)
b09ea7d5 1254{
02e51483 1255 apic_sipi(cpu->apic_state);
b09ea7d5
GN
1256}
1257#else
232fc23b 1258void do_cpu_init(X86CPU *cpu)
b09ea7d5
GN
1259{
1260}
232fc23b 1261void do_cpu_sipi(X86CPU *cpu)
b09ea7d5
GN
1262{
1263}
1264#endif
374e0cd4
RH
1265
1266/* Frob eflags into and out of the CPU temporary format. */
1267
1268void x86_cpu_exec_enter(CPUState *cs)
1269{
1270 X86CPU *cpu = X86_CPU(cs);
1271 CPUX86State *env = &cpu->env;
1272
1273 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1274 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1275 CC_OP = CC_OP_EFLAGS;
1276 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1277}
1278
1279void x86_cpu_exec_exit(CPUState *cs)
1280{
1281 X86CPU *cpu = X86_CPU(cs);
1282 CPUX86State *env = &cpu->env;
1283
1284 env->eflags = cpu_compute_eflags(env);
1285}