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