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