]> Git Repo - qemu.git/blob - target-i386/helper.c
cpu-exec: Change cpu_resume_from_signal() argument to CPUState
[qemu.git] / target-i386 / helper.c
1 /*
2  *  i386 helpers (without register variable usage)
3  *
4  *  Copyright (c) 2003 Fabrice Bellard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "cpu.h"
21 #include "sysemu/kvm.h"
22 #ifndef CONFIG_USER_ONLY
23 #include "sysemu/sysemu.h"
24 #include "monitor/monitor.h"
25 #endif
26
27 //#define DEBUG_MMU
28
29 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
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 */
42 int cpu_x86_support_mca_broadcast(CPUX86State *env)
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
55 /***********************************************************/
56 /* x86 debug */
57
58 static const char *cc_op_str[CC_OP_NB] = {
59     "DYNAMIC",
60     "EFLAGS",
61
62     "MULB",
63     "MULW",
64     "MULL",
65     "MULQ",
66
67     "ADDB",
68     "ADDW",
69     "ADDL",
70     "ADDQ",
71
72     "ADCB",
73     "ADCW",
74     "ADCL",
75     "ADCQ",
76
77     "SUBB",
78     "SUBW",
79     "SUBL",
80     "SUBQ",
81
82     "SBBB",
83     "SBBW",
84     "SBBL",
85     "SBBQ",
86
87     "LOGICB",
88     "LOGICW",
89     "LOGICL",
90     "LOGICQ",
91
92     "INCB",
93     "INCW",
94     "INCL",
95     "INCQ",
96
97     "DECB",
98     "DECW",
99     "DECL",
100     "DECQ",
101
102     "SHLB",
103     "SHLW",
104     "SHLL",
105     "SHLQ",
106
107     "SARB",
108     "SARW",
109     "SARL",
110     "SARQ",
111
112     "BMILGB",
113     "BMILGW",
114     "BMILGL",
115     "BMILGQ",
116
117     "ADCX",
118     "ADOX",
119     "ADCOX",
120
121     "CLR",
122 };
123
124 static void
125 cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
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,
131                     sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
132     } else
133 #endif
134     {
135         cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
136                     (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
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 {
150             cpu_fprintf(f,
151                         (sc->flags & DESC_B_MASK || env->hflags & HF_LMA_MASK)
152                         ? "DS  " : "DS16");
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         };
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]);
176     }
177 done:
178     cpu_fprintf(f, "\n");
179 }
180
181 #define DUMP_CODE_BYTES_TOTAL    50
182 #define DUMP_CODE_BYTES_BACKWARD 20
183
184 void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
185                         int flags)
186 {
187     X86CPU *cpu = X86_CPU(cs);
188     CPUX86State *env = &cpu->env;
189     int eflags, i, nb;
190     char cc_op_name[32];
191     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
192
193     eflags = cpu_compute_eflags(env);
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,
228                     (env->a20_mask >> 20) & 1,
229                     (env->hflags >> HF_SMM_SHIFT) & 1,
230                     cs->halted);
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,
255                     (env->a20_mask >> 20) & 1,
256                     (env->hflags >> HF_SMM_SHIFT) & 1,
257                     cs->halted);
258     }
259
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
267 #ifdef TARGET_X86_64
268     if (env->hflags & HF_LMA_MASK) {
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]);
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",
281                     env->dr[6], env->dr[7]);
282     } else
283 #endif
284     {
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]);
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]);
299     }
300     if (flags & CPU_DUMP_CCOP) {
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         }
317     }
318     cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
319     if (flags & CPU_DUMP_FPU) {
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++) {
332             CPU_LDoubleU u;
333             u.d = env->fpregs[i].d;
334             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
335                         i, u.l.lower, u.l.upper);
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         }
357     }
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++) {
366             if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
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     }
376 }
377
378 /***********************************************************/
379 /* x86 mmu */
380 /* XXX: add PGE support */
381
382 void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
383 {
384     CPUX86State *env = &cpu->env;
385
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 */
393         cpu_interrupt(CPU(cpu), CPU_INTERRUPT_EXITTB);
394
395         /* when a20 is changed, all the MMU mappings are invalid, so
396            we must flush everything */
397         tlb_flush(env, 1);
398         env->a20_mask = ~(1 << 20) | (a20_state << 20);
399     }
400 }
401
402 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
403 {
404     int pe_state;
405
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     }
413
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;
432
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));
441 }
442
443 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
444    the PDPT */
445 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
446 {
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     }
454 }
455
456 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
457 {
458 #if defined(DEBUG_MMU)
459     printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
460 #endif
461     if ((new_cr4 ^ env->cr[4]) &
462         (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
463          CR4_SMEP_MASK | CR4_SMAP_MASK)) {
464         tlb_flush(env, 1);
465     }
466     /* SSE handling */
467     if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
468         new_cr4 &= ~CR4_OSFXSR_MASK;
469     }
470     env->hflags &= ~HF_OSFXSR_MASK;
471     if (new_cr4 & CR4_OSFXSR_MASK) {
472         env->hflags |= HF_OSFXSR_MASK;
473     }
474
475     if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
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     }
482
483     env->cr[4] = new_cr4;
484 }
485
486 #if defined(CONFIG_USER_ONLY)
487
488 int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
489                              int is_write, int mmu_idx)
490 {
491     X86CPU *cpu = X86_CPU(cs);
492     CPUX86State *env = &cpu->env;
493
494     /* user mode only emulation */
495     is_write &= 1;
496     env->cr[2] = addr;
497     env->error_code = (is_write << PG_ERROR_W_BIT);
498     env->error_code |= PG_ERROR_U_MASK;
499     cs->exception_index = EXCP0E_PAGE;
500     return 1;
501 }
502
503 #else
504
505 /* XXX: This value should match the one returned by CPUID
506  * and in exec.c */
507 # if defined(TARGET_X86_64)
508 # define PHYS_ADDR_MASK 0xfffffff000LL
509 # else
510 # define PHYS_ADDR_MASK 0xffffff000LL
511 # endif
512
513 /* return value:
514  * -1 = cannot handle fault
515  * 0  = nothing more to do
516  * 1  = generate PF fault
517  */
518 int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
519                              int is_write1, int mmu_idx)
520 {
521     X86CPU *cpu = X86_CPU(cs);
522     CPUX86State *env = &cpu->env;
523     uint64_t ptep, pte;
524     target_ulong pde_addr, pte_addr;
525     int error_code, is_dirty, prot, page_size, is_write, is_user;
526     hwaddr paddr;
527     uint32_t page_offset;
528     target_ulong vaddr, virt_addr;
529
530     is_user = mmu_idx == MMU_USER_IDX;
531 #if defined(DEBUG_MMU)
532     printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
533            addr, is_write1, is_user, env->eip);
534 #endif
535     is_write = is_write1 & 1;
536
537     if (!(env->cr[0] & CR0_PG_MASK)) {
538         pte = addr;
539 #ifdef TARGET_X86_64
540         if (!(env->hflags & HF_LMA_MASK)) {
541             /* Without long mode we can only address 32bits in real mode */
542             pte = (uint32_t)pte;
543         }
544 #endif
545         virt_addr = addr & TARGET_PAGE_MASK;
546         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
547         page_size = 4096;
548         goto do_mapping;
549     }
550
551     if (env->cr[4] & CR4_PAE_MASK) {
552         uint64_t pde, pdpe;
553         target_ulong pdpe_addr;
554
555 #ifdef TARGET_X86_64
556         if (env->hflags & HF_LMA_MASK) {
557             uint64_t pml4e_addr, pml4e;
558             int32_t sext;
559
560             /* test virtual address sign extension */
561             sext = (int64_t)addr >> 47;
562             if (sext != 0 && sext != -1) {
563                 env->error_code = 0;
564                 cs->exception_index = EXCP0D_GPF;
565                 return 1;
566             }
567
568             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
569                 env->a20_mask;
570             pml4e = ldq_phys(cs->as, pml4e_addr);
571             if (!(pml4e & PG_PRESENT_MASK)) {
572                 error_code = 0;
573                 goto do_fault;
574             }
575             if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
576                 error_code = PG_ERROR_RSVD_MASK;
577                 goto do_fault;
578             }
579             if (!(pml4e & PG_ACCESSED_MASK)) {
580                 pml4e |= PG_ACCESSED_MASK;
581                 stl_phys_notdirty(cs->as, pml4e_addr, pml4e);
582             }
583             ptep = pml4e ^ PG_NX_MASK;
584             pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
585                 env->a20_mask;
586             pdpe = ldq_phys(cs->as, pdpe_addr);
587             if (!(pdpe & PG_PRESENT_MASK)) {
588                 error_code = 0;
589                 goto do_fault;
590             }
591             if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
592                 error_code = PG_ERROR_RSVD_MASK;
593                 goto do_fault;
594             }
595             ptep &= pdpe ^ PG_NX_MASK;
596             if (!(pdpe & PG_ACCESSED_MASK)) {
597                 pdpe |= PG_ACCESSED_MASK;
598                 stl_phys_notdirty(cs->as, pdpe_addr, pdpe);
599             }
600         } else
601 #endif
602         {
603             /* XXX: load them when cr3 is loaded ? */
604             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
605                 env->a20_mask;
606             pdpe = ldq_phys(cs->as, pdpe_addr);
607             if (!(pdpe & PG_PRESENT_MASK)) {
608                 error_code = 0;
609                 goto do_fault;
610             }
611             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
612         }
613
614         pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
615             env->a20_mask;
616         pde = ldq_phys(cs->as, pde_addr);
617         if (!(pde & PG_PRESENT_MASK)) {
618             error_code = 0;
619             goto do_fault;
620         }
621         if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
622             error_code = PG_ERROR_RSVD_MASK;
623             goto do_fault;
624         }
625         ptep &= pde ^ PG_NX_MASK;
626         if (pde & PG_PSE_MASK) {
627             /* 2 MB page */
628             page_size = 2048 * 1024;
629             ptep ^= PG_NX_MASK;
630             if ((ptep & PG_NX_MASK) && is_write1 == 2) {
631                 goto do_fault_protect;
632             }
633             switch (mmu_idx) {
634             case MMU_USER_IDX:
635                 if (!(ptep & PG_USER_MASK)) {
636                     goto do_fault_protect;
637                 }
638                 if (is_write && !(ptep & PG_RW_MASK)) {
639                     goto do_fault_protect;
640                 }
641                 break;
642
643             case MMU_KERNEL_IDX:
644                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
645                     (ptep & PG_USER_MASK)) {
646                     goto do_fault_protect;
647                 }
648                 /* fall through */
649             case MMU_KSMAP_IDX:
650                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
651                     (ptep & PG_USER_MASK)) {
652                     goto do_fault_protect;
653                 }
654                 if ((env->cr[0] & CR0_WP_MASK) &&
655                     is_write && !(ptep & PG_RW_MASK)) {
656                     goto do_fault_protect;
657                 }
658                 break;
659
660             default: /* cannot happen */
661                 break;
662             }
663             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
664             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
665                 pde |= PG_ACCESSED_MASK;
666                 if (is_dirty)
667                     pde |= PG_DIRTY_MASK;
668                 stl_phys_notdirty(cs->as, pde_addr, pde);
669             }
670             /* align to page_size */
671             pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
672             virt_addr = addr & ~(page_size - 1);
673         } else {
674             /* 4 KB page */
675             if (!(pde & PG_ACCESSED_MASK)) {
676                 pde |= PG_ACCESSED_MASK;
677                 stl_phys_notdirty(cs->as, pde_addr, pde);
678             }
679             pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
680                 env->a20_mask;
681             pte = ldq_phys(cs->as, pte_addr);
682             if (!(pte & PG_PRESENT_MASK)) {
683                 error_code = 0;
684                 goto do_fault;
685             }
686             if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
687                 error_code = PG_ERROR_RSVD_MASK;
688                 goto do_fault;
689             }
690             /* combine pde and pte nx, user and rw protections */
691             ptep &= pte ^ PG_NX_MASK;
692             ptep ^= PG_NX_MASK;
693             if ((ptep & PG_NX_MASK) && is_write1 == 2)
694                 goto do_fault_protect;
695             switch (mmu_idx) {
696             case MMU_USER_IDX:
697                 if (!(ptep & PG_USER_MASK)) {
698                     goto do_fault_protect;
699                 }
700                 if (is_write && !(ptep & PG_RW_MASK)) {
701                     goto do_fault_protect;
702                 }
703                 break;
704
705             case MMU_KERNEL_IDX:
706                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
707                     (ptep & PG_USER_MASK)) {
708                     goto do_fault_protect;
709                 }
710                 /* fall through */
711             case MMU_KSMAP_IDX:
712                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
713                     (ptep & PG_USER_MASK)) {
714                     goto do_fault_protect;
715                 }
716                 if ((env->cr[0] & CR0_WP_MASK) &&
717                     is_write && !(ptep & PG_RW_MASK)) {
718                     goto do_fault_protect;
719                 }
720                 break;
721
722             default: /* cannot happen */
723                 break;
724             }
725             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
726             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
727                 pte |= PG_ACCESSED_MASK;
728                 if (is_dirty)
729                     pte |= PG_DIRTY_MASK;
730                 stl_phys_notdirty(cs->as, pte_addr, pte);
731             }
732             page_size = 4096;
733             virt_addr = addr & ~0xfff;
734             pte = pte & (PHYS_ADDR_MASK | 0xfff);
735         }
736     } else {
737         uint32_t pde;
738
739         /* page directory entry */
740         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
741             env->a20_mask;
742         pde = ldl_phys(cs->as, pde_addr);
743         if (!(pde & PG_PRESENT_MASK)) {
744             error_code = 0;
745             goto do_fault;
746         }
747         /* if PSE bit is set, then we use a 4MB page */
748         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
749             page_size = 4096 * 1024;
750             switch (mmu_idx) {
751             case MMU_USER_IDX:
752                 if (!(pde & PG_USER_MASK)) {
753                     goto do_fault_protect;
754                 }
755                 if (is_write && !(pde & PG_RW_MASK)) {
756                     goto do_fault_protect;
757                 }
758                 break;
759
760             case MMU_KERNEL_IDX:
761                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
762                     (pde & PG_USER_MASK)) {
763                     goto do_fault_protect;
764                 }
765                 /* fall through */
766             case MMU_KSMAP_IDX:
767                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
768                     (pde & PG_USER_MASK)) {
769                     goto do_fault_protect;
770                 }
771                 if ((env->cr[0] & CR0_WP_MASK) &&
772                     is_write && !(pde & PG_RW_MASK)) {
773                     goto do_fault_protect;
774                 }
775                 break;
776
777             default: /* cannot happen */
778                 break;
779             }
780             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
781             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
782                 pde |= PG_ACCESSED_MASK;
783                 if (is_dirty)
784                     pde |= PG_DIRTY_MASK;
785                 stl_phys_notdirty(cs->as, pde_addr, pde);
786             }
787
788             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
789             ptep = pte;
790             virt_addr = addr & ~(page_size - 1);
791         } else {
792             if (!(pde & PG_ACCESSED_MASK)) {
793                 pde |= PG_ACCESSED_MASK;
794                 stl_phys_notdirty(cs->as, pde_addr, pde);
795             }
796
797             /* page directory entry */
798             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
799                 env->a20_mask;
800             pte = ldl_phys(cs->as, pte_addr);
801             if (!(pte & PG_PRESENT_MASK)) {
802                 error_code = 0;
803                 goto do_fault;
804             }
805             /* combine pde and pte user and rw protections */
806             ptep = pte & pde;
807             switch (mmu_idx) {
808             case MMU_USER_IDX:
809                 if (!(ptep & PG_USER_MASK)) {
810                     goto do_fault_protect;
811                 }
812                 if (is_write && !(ptep & PG_RW_MASK)) {
813                     goto do_fault_protect;
814                 }
815                 break;
816
817             case MMU_KERNEL_IDX:
818                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
819                     (ptep & PG_USER_MASK)) {
820                     goto do_fault_protect;
821                 }
822                 /* fall through */
823             case MMU_KSMAP_IDX:
824                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
825                     (ptep & PG_USER_MASK)) {
826                     goto do_fault_protect;
827                 }
828                 if ((env->cr[0] & CR0_WP_MASK) &&
829                     is_write && !(ptep & PG_RW_MASK)) {
830                     goto do_fault_protect;
831                 }
832                 break;
833
834             default: /* cannot happen */
835                 break;
836             }
837             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
838             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
839                 pte |= PG_ACCESSED_MASK;
840                 if (is_dirty)
841                     pte |= PG_DIRTY_MASK;
842                 stl_phys_notdirty(cs->as, pte_addr, pte);
843             }
844             page_size = 4096;
845             virt_addr = addr & ~0xfff;
846         }
847     }
848     /* the page can be put in the TLB */
849     prot = PAGE_READ;
850     if (!(ptep & PG_NX_MASK))
851         prot |= PAGE_EXEC;
852     if (pte & PG_DIRTY_MASK) {
853         /* only set write access if already dirty... otherwise wait
854            for dirty access */
855         if (is_user) {
856             if (ptep & PG_RW_MASK)
857                 prot |= PAGE_WRITE;
858         } else {
859             if (!(env->cr[0] & CR0_WP_MASK) ||
860                 (ptep & PG_RW_MASK))
861                 prot |= PAGE_WRITE;
862         }
863     }
864  do_mapping:
865     pte = pte & env->a20_mask;
866
867     /* Even if 4MB pages, we map only one 4KB page in the cache to
868        avoid filling it too fast */
869     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
870     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
871     vaddr = virt_addr + page_offset;
872
873     tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
874     return 0;
875  do_fault_protect:
876     error_code = PG_ERROR_P_MASK;
877  do_fault:
878     error_code |= (is_write << PG_ERROR_W_BIT);
879     if (is_user)
880         error_code |= PG_ERROR_U_MASK;
881     if (is_write1 == 2 &&
882         (((env->efer & MSR_EFER_NXE) &&
883           (env->cr[4] & CR4_PAE_MASK)) ||
884          (env->cr[4] & CR4_SMEP_MASK)))
885         error_code |= PG_ERROR_I_D_MASK;
886     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
887         /* cr2 is not modified in case of exceptions */
888         stq_phys(cs->as,
889                  env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
890                  addr);
891     } else {
892         env->cr[2] = addr;
893     }
894     env->error_code = error_code;
895     cs->exception_index = EXCP0E_PAGE;
896     return 1;
897 }
898
899 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
900 {
901     X86CPU *cpu = X86_CPU(cs);
902     CPUX86State *env = &cpu->env;
903     target_ulong pde_addr, pte_addr;
904     uint64_t pte;
905     hwaddr paddr;
906     uint32_t page_offset;
907     int page_size;
908
909     if (!(env->cr[0] & CR0_PG_MASK)) {
910         pte = addr & env->a20_mask;
911         page_size = 4096;
912     } else if (env->cr[4] & CR4_PAE_MASK) {
913         target_ulong pdpe_addr;
914         uint64_t pde, pdpe;
915
916 #ifdef TARGET_X86_64
917         if (env->hflags & HF_LMA_MASK) {
918             uint64_t pml4e_addr, pml4e;
919             int32_t sext;
920
921             /* test virtual address sign extension */
922             sext = (int64_t)addr >> 47;
923             if (sext != 0 && sext != -1)
924                 return -1;
925
926             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
927                 env->a20_mask;
928             pml4e = ldq_phys(cs->as, pml4e_addr);
929             if (!(pml4e & PG_PRESENT_MASK))
930                 return -1;
931
932             pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
933                          (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
934             pdpe = ldq_phys(cs->as, pdpe_addr);
935             if (!(pdpe & PG_PRESENT_MASK))
936                 return -1;
937         } else
938 #endif
939         {
940             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
941                 env->a20_mask;
942             pdpe = ldq_phys(cs->as, pdpe_addr);
943             if (!(pdpe & PG_PRESENT_MASK))
944                 return -1;
945         }
946
947         pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
948                     (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
949         pde = ldq_phys(cs->as, pde_addr);
950         if (!(pde & PG_PRESENT_MASK)) {
951             return -1;
952         }
953         if (pde & PG_PSE_MASK) {
954             /* 2 MB page */
955             page_size = 2048 * 1024;
956             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
957         } else {
958             /* 4 KB page */
959             pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
960                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
961             page_size = 4096;
962             pte = ldq_phys(cs->as, pte_addr);
963         }
964         pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
965         if (!(pte & PG_PRESENT_MASK))
966             return -1;
967     } else {
968         uint32_t pde;
969
970         /* page directory entry */
971         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
972         pde = ldl_phys(cs->as, pde_addr);
973         if (!(pde & PG_PRESENT_MASK))
974             return -1;
975         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
976             pte = pde & ~0x003ff000; /* align to 4MB */
977             page_size = 4096 * 1024;
978         } else {
979             /* page directory entry */
980             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
981             pte = ldl_phys(cs->as, pte_addr);
982             if (!(pte & PG_PRESENT_MASK))
983                 return -1;
984             page_size = 4096;
985         }
986         pte = pte & env->a20_mask;
987     }
988
989     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
990     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
991     return paddr;
992 }
993
994 void hw_breakpoint_insert(CPUX86State *env, int index)
995 {
996     CPUState *cs = CPU(x86_env_get_cpu(env));
997     int type = 0, err = 0;
998
999     switch (hw_breakpoint_type(env->dr[7], index)) {
1000     case DR7_TYPE_BP_INST:
1001         if (hw_breakpoint_enabled(env->dr[7], index)) {
1002             err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
1003                                         &env->cpu_breakpoint[index]);
1004         }
1005         break;
1006     case DR7_TYPE_DATA_WR:
1007         type = BP_CPU | BP_MEM_WRITE;
1008         break;
1009     case DR7_TYPE_IO_RW:
1010         /* No support for I/O watchpoints yet */
1011         break;
1012     case DR7_TYPE_DATA_RW:
1013         type = BP_CPU | BP_MEM_ACCESS;
1014         break;
1015     }
1016
1017     if (type != 0) {
1018         err = cpu_watchpoint_insert(cs, env->dr[index],
1019                                     hw_breakpoint_len(env->dr[7], index),
1020                                     type, &env->cpu_watchpoint[index]);
1021     }
1022
1023     if (err) {
1024         env->cpu_breakpoint[index] = NULL;
1025     }
1026 }
1027
1028 void hw_breakpoint_remove(CPUX86State *env, int index)
1029 {
1030     CPUState *cs;
1031
1032     if (!env->cpu_breakpoint[index]) {
1033         return;
1034     }
1035     cs = CPU(x86_env_get_cpu(env));
1036     switch (hw_breakpoint_type(env->dr[7], index)) {
1037     case DR7_TYPE_BP_INST:
1038         if (hw_breakpoint_enabled(env->dr[7], index)) {
1039             cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
1040         }
1041         break;
1042     case DR7_TYPE_DATA_WR:
1043     case DR7_TYPE_DATA_RW:
1044         cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
1045         break;
1046     case DR7_TYPE_IO_RW:
1047         /* No support for I/O watchpoints yet */
1048         break;
1049     }
1050 }
1051
1052 bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
1053 {
1054     target_ulong dr6;
1055     int reg;
1056     bool hit_enabled = false;
1057
1058     dr6 = env->dr[6] & ~0xf;
1059     for (reg = 0; reg < DR7_MAX_BP; reg++) {
1060         bool bp_match = false;
1061         bool wp_match = false;
1062
1063         switch (hw_breakpoint_type(env->dr[7], reg)) {
1064         case DR7_TYPE_BP_INST:
1065             if (env->dr[reg] == env->eip) {
1066                 bp_match = true;
1067             }
1068             break;
1069         case DR7_TYPE_DATA_WR:
1070         case DR7_TYPE_DATA_RW:
1071             if (env->cpu_watchpoint[reg] &&
1072                 env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
1073                 wp_match = true;
1074             }
1075             break;
1076         case DR7_TYPE_IO_RW:
1077             break;
1078         }
1079         if (bp_match || wp_match) {
1080             dr6 |= 1 << reg;
1081             if (hw_breakpoint_enabled(env->dr[7], reg)) {
1082                 hit_enabled = true;
1083             }
1084         }
1085     }
1086
1087     if (hit_enabled || force_dr6_update) {
1088         env->dr[6] = dr6;
1089     }
1090
1091     return hit_enabled;
1092 }
1093
1094 void breakpoint_handler(CPUX86State *env)
1095 {
1096     CPUState *cs = CPU(x86_env_get_cpu(env));
1097     CPUBreakpoint *bp;
1098
1099     if (cs->watchpoint_hit) {
1100         if (cs->watchpoint_hit->flags & BP_CPU) {
1101             cs->watchpoint_hit = NULL;
1102             if (check_hw_breakpoints(env, false)) {
1103                 raise_exception(env, EXCP01_DB);
1104             } else {
1105                 cpu_resume_from_signal(cs, NULL);
1106             }
1107         }
1108     } else {
1109         QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
1110             if (bp->pc == env->eip) {
1111                 if (bp->flags & BP_CPU) {
1112                     check_hw_breakpoints(env, true);
1113                     raise_exception(env, EXCP01_DB);
1114                 }
1115                 break;
1116             }
1117         }
1118     }
1119 }
1120
1121 typedef struct MCEInjectionParams {
1122     Monitor *mon;
1123     X86CPU *cpu;
1124     int bank;
1125     uint64_t status;
1126     uint64_t mcg_status;
1127     uint64_t addr;
1128     uint64_t misc;
1129     int flags;
1130 } MCEInjectionParams;
1131
1132 static void do_inject_x86_mce(void *data)
1133 {
1134     MCEInjectionParams *params = data;
1135     CPUX86State *cenv = &params->cpu->env;
1136     CPUState *cpu = CPU(params->cpu);
1137     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1138
1139     cpu_synchronize_state(cpu);
1140
1141     /*
1142      * If there is an MCE exception being processed, ignore this SRAO MCE
1143      * unless unconditional injection was requested.
1144      */
1145     if (!(params->flags & MCE_INJECT_UNCOND_AO)
1146         && !(params->status & MCI_STATUS_AR)
1147         && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1148         return;
1149     }
1150
1151     if (params->status & MCI_STATUS_UC) {
1152         /*
1153          * if MSR_MCG_CTL is not all 1s, the uncorrected error
1154          * reporting is disabled
1155          */
1156         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1157             monitor_printf(params->mon,
1158                            "CPU %d: Uncorrected error reporting disabled\n",
1159                            cpu->cpu_index);
1160             return;
1161         }
1162
1163         /*
1164          * if MSR_MCi_CTL is not all 1s, the uncorrected error
1165          * reporting is disabled for the bank
1166          */
1167         if (banks[0] != ~(uint64_t)0) {
1168             monitor_printf(params->mon,
1169                            "CPU %d: Uncorrected error reporting disabled for"
1170                            " bank %d\n",
1171                            cpu->cpu_index, params->bank);
1172             return;
1173         }
1174
1175         if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1176             !(cenv->cr[4] & CR4_MCE_MASK)) {
1177             monitor_printf(params->mon,
1178                            "CPU %d: Previous MCE still in progress, raising"
1179                            " triple fault\n",
1180                            cpu->cpu_index);
1181             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1182             qemu_system_reset_request();
1183             return;
1184         }
1185         if (banks[1] & MCI_STATUS_VAL) {
1186             params->status |= MCI_STATUS_OVER;
1187         }
1188         banks[2] = params->addr;
1189         banks[3] = params->misc;
1190         cenv->mcg_status = params->mcg_status;
1191         banks[1] = params->status;
1192         cpu_interrupt(cpu, CPU_INTERRUPT_MCE);
1193     } else if (!(banks[1] & MCI_STATUS_VAL)
1194                || !(banks[1] & MCI_STATUS_UC)) {
1195         if (banks[1] & MCI_STATUS_VAL) {
1196             params->status |= MCI_STATUS_OVER;
1197         }
1198         banks[2] = params->addr;
1199         banks[3] = params->misc;
1200         banks[1] = params->status;
1201     } else {
1202         banks[1] |= MCI_STATUS_OVER;
1203     }
1204 }
1205
1206 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
1207                         uint64_t status, uint64_t mcg_status, uint64_t addr,
1208                         uint64_t misc, int flags)
1209 {
1210     CPUState *cs = CPU(cpu);
1211     CPUX86State *cenv = &cpu->env;
1212     MCEInjectionParams params = {
1213         .mon = mon,
1214         .cpu = cpu,
1215         .bank = bank,
1216         .status = status,
1217         .mcg_status = mcg_status,
1218         .addr = addr,
1219         .misc = misc,
1220         .flags = flags,
1221     };
1222     unsigned bank_num = cenv->mcg_cap & 0xff;
1223
1224     if (!cenv->mcg_cap) {
1225         monitor_printf(mon, "MCE injection not supported\n");
1226         return;
1227     }
1228     if (bank >= bank_num) {
1229         monitor_printf(mon, "Invalid MCE bank number\n");
1230         return;
1231     }
1232     if (!(status & MCI_STATUS_VAL)) {
1233         monitor_printf(mon, "Invalid MCE status code\n");
1234         return;
1235     }
1236     if ((flags & MCE_INJECT_BROADCAST)
1237         && !cpu_x86_support_mca_broadcast(cenv)) {
1238         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1239         return;
1240     }
1241
1242     run_on_cpu(cs, do_inject_x86_mce, &params);
1243     if (flags & MCE_INJECT_BROADCAST) {
1244         CPUState *other_cs;
1245
1246         params.bank = 1;
1247         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1248         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1249         params.addr = 0;
1250         params.misc = 0;
1251         CPU_FOREACH(other_cs) {
1252             if (other_cs == cs) {
1253                 continue;
1254             }
1255             params.cpu = X86_CPU(other_cs);
1256             run_on_cpu(other_cs, do_inject_x86_mce, &params);
1257         }
1258     }
1259 }
1260
1261 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1262 {
1263     X86CPU *cpu = x86_env_get_cpu(env);
1264     CPUState *cs = CPU(cpu);
1265
1266     if (kvm_enabled()) {
1267         env->tpr_access_type = access;
1268
1269         cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1270     } else {
1271         cpu_restore_state(cs, cs->mem_io_pc);
1272
1273         apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1274     }
1275 }
1276 #endif /* !CONFIG_USER_ONLY */
1277
1278 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1279                             target_ulong *base, unsigned int *limit,
1280                             unsigned int *flags)
1281 {
1282     X86CPU *cpu = x86_env_get_cpu(env);
1283     CPUState *cs = CPU(cpu);
1284     SegmentCache *dt;
1285     target_ulong ptr;
1286     uint32_t e1, e2;
1287     int index;
1288
1289     if (selector & 0x4)
1290         dt = &env->ldt;
1291     else
1292         dt = &env->gdt;
1293     index = selector & ~7;
1294     ptr = dt->base + index;
1295     if ((index + 7) > dt->limit
1296         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1297         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1298         return 0;
1299
1300     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1301     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1302     if (e2 & DESC_G_MASK)
1303         *limit = (*limit << 12) | 0xfff;
1304     *flags = e2;
1305
1306     return 1;
1307 }
1308
1309 #if !defined(CONFIG_USER_ONLY)
1310 void do_cpu_init(X86CPU *cpu)
1311 {
1312     CPUState *cs = CPU(cpu);
1313     CPUX86State *env = &cpu->env;
1314     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1315     uint64_t pat = env->pat;
1316
1317     cpu_reset(cs);
1318     cs->interrupt_request = sipi;
1319     env->pat = pat;
1320     apic_init_reset(cpu->apic_state);
1321 }
1322
1323 void do_cpu_sipi(X86CPU *cpu)
1324 {
1325     apic_sipi(cpu->apic_state);
1326 }
1327 #else
1328 void do_cpu_init(X86CPU *cpu)
1329 {
1330 }
1331 void do_cpu_sipi(X86CPU *cpu)
1332 {
1333 }
1334 #endif
This page took 0.099648 seconds and 4 git commands to generate.