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