]> Git Repo - qemu.git/blob - target-i386/helper.c
Merge remote-tracking branch 'remotes/alon/pull-libcacard.glusterfs' into staging
[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 cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
489                              int is_write, int mmu_idx)
490 {
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;
498 }
499
500 #else
501
502 /* XXX: This value should match the one returned by CPUID
503  * and in exec.c */
504 # if defined(TARGET_X86_64)
505 # define PHYS_ADDR_MASK 0xfffffff000LL
506 # else
507 # define PHYS_ADDR_MASK 0xffffff000LL
508 # endif
509
510 /* return value:
511    -1 = cannot handle fault
512    0  = nothing more to do
513    1  = generate PF fault
514 */
515 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
516                              int is_write1, int mmu_idx)
517 {
518     CPUState *cs = ENV_GET_CPU(env);
519     uint64_t ptep, pte;
520     target_ulong pde_addr, pte_addr;
521     int error_code, is_dirty, prot, page_size, is_write, is_user;
522     hwaddr paddr;
523     uint32_t page_offset;
524     target_ulong vaddr, virt_addr;
525
526     is_user = mmu_idx == MMU_USER_IDX;
527 #if defined(DEBUG_MMU)
528     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
529            addr, is_write1, is_user, env->eip);
530 #endif
531     is_write = is_write1 & 1;
532
533     if (!(env->cr[0] & CR0_PG_MASK)) {
534         pte = addr;
535 #ifdef TARGET_X86_64
536         if (!(env->hflags & HF_LMA_MASK)) {
537             /* Without long mode we can only address 32bits in real mode */
538             pte = (uint32_t)pte;
539         }
540 #endif
541         virt_addr = addr & TARGET_PAGE_MASK;
542         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
543         page_size = 4096;
544         goto do_mapping;
545     }
546
547     if (env->cr[4] & CR4_PAE_MASK) {
548         uint64_t pde, pdpe;
549         target_ulong pdpe_addr;
550
551 #ifdef TARGET_X86_64
552         if (env->hflags & HF_LMA_MASK) {
553             uint64_t pml4e_addr, pml4e;
554             int32_t sext;
555
556             /* test virtual address sign extension */
557             sext = (int64_t)addr >> 47;
558             if (sext != 0 && sext != -1) {
559                 env->error_code = 0;
560                 env->exception_index = EXCP0D_GPF;
561                 return 1;
562             }
563
564             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
565                 env->a20_mask;
566             pml4e = ldq_phys(cs->as, pml4e_addr);
567             if (!(pml4e & PG_PRESENT_MASK)) {
568                 error_code = 0;
569                 goto do_fault;
570             }
571             if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
572                 error_code = PG_ERROR_RSVD_MASK;
573                 goto do_fault;
574             }
575             if (!(pml4e & PG_ACCESSED_MASK)) {
576                 pml4e |= PG_ACCESSED_MASK;
577                 stl_phys_notdirty(cs->as, pml4e_addr, pml4e);
578             }
579             ptep = pml4e ^ PG_NX_MASK;
580             pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
581                 env->a20_mask;
582             pdpe = ldq_phys(cs->as, pdpe_addr);
583             if (!(pdpe & PG_PRESENT_MASK)) {
584                 error_code = 0;
585                 goto do_fault;
586             }
587             if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
588                 error_code = PG_ERROR_RSVD_MASK;
589                 goto do_fault;
590             }
591             ptep &= pdpe ^ PG_NX_MASK;
592             if (!(pdpe & PG_ACCESSED_MASK)) {
593                 pdpe |= PG_ACCESSED_MASK;
594                 stl_phys_notdirty(cs->as, pdpe_addr, pdpe);
595             }
596         } else
597 #endif
598         {
599             /* XXX: load them when cr3 is loaded ? */
600             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
601                 env->a20_mask;
602             pdpe = ldq_phys(cs->as, pdpe_addr);
603             if (!(pdpe & PG_PRESENT_MASK)) {
604                 error_code = 0;
605                 goto do_fault;
606             }
607             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
608         }
609
610         pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
611             env->a20_mask;
612         pde = ldq_phys(cs->as, pde_addr);
613         if (!(pde & PG_PRESENT_MASK)) {
614             error_code = 0;
615             goto do_fault;
616         }
617         if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
618             error_code = PG_ERROR_RSVD_MASK;
619             goto do_fault;
620         }
621         ptep &= pde ^ PG_NX_MASK;
622         if (pde & PG_PSE_MASK) {
623             /* 2 MB page */
624             page_size = 2048 * 1024;
625             ptep ^= PG_NX_MASK;
626             if ((ptep & PG_NX_MASK) && is_write1 == 2) {
627                 goto do_fault_protect;
628             }
629             switch (mmu_idx) {
630             case MMU_USER_IDX:
631                 if (!(ptep & PG_USER_MASK)) {
632                     goto do_fault_protect;
633                 }
634                 if (is_write && !(ptep & PG_RW_MASK)) {
635                     goto do_fault_protect;
636                 }
637                 break;
638
639             case MMU_KERNEL_IDX:
640                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
641                     (ptep & PG_USER_MASK)) {
642                     goto do_fault_protect;
643                 }
644                 /* fall through */
645             case MMU_KSMAP_IDX:
646                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
647                     (ptep & PG_USER_MASK)) {
648                     goto do_fault_protect;
649                 }
650                 if ((env->cr[0] & CR0_WP_MASK) &&
651                     is_write && !(ptep & PG_RW_MASK)) {
652                     goto do_fault_protect;
653                 }
654                 break;
655
656             default: /* cannot happen */
657                 break;
658             }
659             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
660             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
661                 pde |= PG_ACCESSED_MASK;
662                 if (is_dirty)
663                     pde |= PG_DIRTY_MASK;
664                 stl_phys_notdirty(cs->as, pde_addr, pde);
665             }
666             /* align to page_size */
667             pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
668             virt_addr = addr & ~(page_size - 1);
669         } else {
670             /* 4 KB page */
671             if (!(pde & PG_ACCESSED_MASK)) {
672                 pde |= PG_ACCESSED_MASK;
673                 stl_phys_notdirty(cs->as, pde_addr, pde);
674             }
675             pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
676                 env->a20_mask;
677             pte = ldq_phys(cs->as, pte_addr);
678             if (!(pte & PG_PRESENT_MASK)) {
679                 error_code = 0;
680                 goto do_fault;
681             }
682             if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
683                 error_code = PG_ERROR_RSVD_MASK;
684                 goto do_fault;
685             }
686             /* combine pde and pte nx, user and rw protections */
687             ptep &= pte ^ PG_NX_MASK;
688             ptep ^= PG_NX_MASK;
689             if ((ptep & PG_NX_MASK) && is_write1 == 2)
690                 goto do_fault_protect;
691             switch (mmu_idx) {
692             case MMU_USER_IDX:
693                 if (!(ptep & PG_USER_MASK)) {
694                     goto do_fault_protect;
695                 }
696                 if (is_write && !(ptep & PG_RW_MASK)) {
697                     goto do_fault_protect;
698                 }
699                 break;
700
701             case MMU_KERNEL_IDX:
702                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
703                     (ptep & PG_USER_MASK)) {
704                     goto do_fault_protect;
705                 }
706                 /* fall through */
707             case MMU_KSMAP_IDX:
708                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
709                     (ptep & PG_USER_MASK)) {
710                     goto do_fault_protect;
711                 }
712                 if ((env->cr[0] & CR0_WP_MASK) &&
713                     is_write && !(ptep & PG_RW_MASK)) {
714                     goto do_fault_protect;
715                 }
716                 break;
717
718             default: /* cannot happen */
719                 break;
720             }
721             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
722             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
723                 pte |= PG_ACCESSED_MASK;
724                 if (is_dirty)
725                     pte |= PG_DIRTY_MASK;
726                 stl_phys_notdirty(cs->as, pte_addr, pte);
727             }
728             page_size = 4096;
729             virt_addr = addr & ~0xfff;
730             pte = pte & (PHYS_ADDR_MASK | 0xfff);
731         }
732     } else {
733         uint32_t pde;
734
735         /* page directory entry */
736         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
737             env->a20_mask;
738         pde = ldl_phys(cs->as, pde_addr);
739         if (!(pde & PG_PRESENT_MASK)) {
740             error_code = 0;
741             goto do_fault;
742         }
743         /* if PSE bit is set, then we use a 4MB page */
744         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
745             page_size = 4096 * 1024;
746             switch (mmu_idx) {
747             case MMU_USER_IDX:
748                 if (!(pde & PG_USER_MASK)) {
749                     goto do_fault_protect;
750                 }
751                 if (is_write && !(pde & PG_RW_MASK)) {
752                     goto do_fault_protect;
753                 }
754                 break;
755
756             case MMU_KERNEL_IDX:
757                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
758                     (pde & PG_USER_MASK)) {
759                     goto do_fault_protect;
760                 }
761                 /* fall through */
762             case MMU_KSMAP_IDX:
763                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
764                     (pde & PG_USER_MASK)) {
765                     goto do_fault_protect;
766                 }
767                 if ((env->cr[0] & CR0_WP_MASK) &&
768                     is_write && !(pde & PG_RW_MASK)) {
769                     goto do_fault_protect;
770                 }
771                 break;
772
773             default: /* cannot happen */
774                 break;
775             }
776             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
777             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
778                 pde |= PG_ACCESSED_MASK;
779                 if (is_dirty)
780                     pde |= PG_DIRTY_MASK;
781                 stl_phys_notdirty(cs->as, pde_addr, pde);
782             }
783
784             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
785             ptep = pte;
786             virt_addr = addr & ~(page_size - 1);
787         } else {
788             if (!(pde & PG_ACCESSED_MASK)) {
789                 pde |= PG_ACCESSED_MASK;
790                 stl_phys_notdirty(cs->as, pde_addr, pde);
791             }
792
793             /* page directory entry */
794             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
795                 env->a20_mask;
796             pte = ldl_phys(cs->as, pte_addr);
797             if (!(pte & PG_PRESENT_MASK)) {
798                 error_code = 0;
799                 goto do_fault;
800             }
801             /* combine pde and pte user and rw protections */
802             ptep = pte & pde;
803             switch (mmu_idx) {
804             case MMU_USER_IDX:
805                 if (!(ptep & PG_USER_MASK)) {
806                     goto do_fault_protect;
807                 }
808                 if (is_write && !(ptep & PG_RW_MASK)) {
809                     goto do_fault_protect;
810                 }
811                 break;
812
813             case MMU_KERNEL_IDX:
814                 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
815                     (ptep & PG_USER_MASK)) {
816                     goto do_fault_protect;
817                 }
818                 /* fall through */
819             case MMU_KSMAP_IDX:
820                 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
821                     (ptep & PG_USER_MASK)) {
822                     goto do_fault_protect;
823                 }
824                 if ((env->cr[0] & CR0_WP_MASK) &&
825                     is_write && !(ptep & PG_RW_MASK)) {
826                     goto do_fault_protect;
827                 }
828                 break;
829
830             default: /* cannot happen */
831                 break;
832             }
833             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
834             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
835                 pte |= PG_ACCESSED_MASK;
836                 if (is_dirty)
837                     pte |= PG_DIRTY_MASK;
838                 stl_phys_notdirty(cs->as, pte_addr, pte);
839             }
840             page_size = 4096;
841             virt_addr = addr & ~0xfff;
842         }
843     }
844     /* the page can be put in the TLB */
845     prot = PAGE_READ;
846     if (!(ptep & PG_NX_MASK))
847         prot |= PAGE_EXEC;
848     if (pte & PG_DIRTY_MASK) {
849         /* only set write access if already dirty... otherwise wait
850            for dirty access */
851         if (is_user) {
852             if (ptep & PG_RW_MASK)
853                 prot |= PAGE_WRITE;
854         } else {
855             if (!(env->cr[0] & CR0_WP_MASK) ||
856                 (ptep & PG_RW_MASK))
857                 prot |= PAGE_WRITE;
858         }
859     }
860  do_mapping:
861     pte = pte & env->a20_mask;
862
863     /* Even if 4MB pages, we map only one 4KB page in the cache to
864        avoid filling it too fast */
865     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
866     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
867     vaddr = virt_addr + page_offset;
868
869     tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
870     return 0;
871  do_fault_protect:
872     error_code = PG_ERROR_P_MASK;
873  do_fault:
874     error_code |= (is_write << PG_ERROR_W_BIT);
875     if (is_user)
876         error_code |= PG_ERROR_U_MASK;
877     if (is_write1 == 2 &&
878         (((env->efer & MSR_EFER_NXE) &&
879           (env->cr[4] & CR4_PAE_MASK)) ||
880          (env->cr[4] & CR4_SMEP_MASK)))
881         error_code |= PG_ERROR_I_D_MASK;
882     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
883         /* cr2 is not modified in case of exceptions */
884         stq_phys(cs->as,
885                  env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
886                  addr);
887     } else {
888         env->cr[2] = addr;
889     }
890     env->error_code = error_code;
891     env->exception_index = EXCP0E_PAGE;
892     return 1;
893 }
894
895 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
896 {
897     X86CPU *cpu = X86_CPU(cs);
898     CPUX86State *env = &cpu->env;
899     target_ulong pde_addr, pte_addr;
900     uint64_t pte;
901     hwaddr paddr;
902     uint32_t page_offset;
903     int page_size;
904
905     if (!(env->cr[0] & CR0_PG_MASK)) {
906         pte = addr & env->a20_mask;
907         page_size = 4096;
908     } else if (env->cr[4] & CR4_PAE_MASK) {
909         target_ulong pdpe_addr;
910         uint64_t pde, pdpe;
911
912 #ifdef TARGET_X86_64
913         if (env->hflags & HF_LMA_MASK) {
914             uint64_t pml4e_addr, pml4e;
915             int32_t sext;
916
917             /* test virtual address sign extension */
918             sext = (int64_t)addr >> 47;
919             if (sext != 0 && sext != -1)
920                 return -1;
921
922             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
923                 env->a20_mask;
924             pml4e = ldq_phys(cs->as, pml4e_addr);
925             if (!(pml4e & PG_PRESENT_MASK))
926                 return -1;
927
928             pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
929                          (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
930             pdpe = ldq_phys(cs->as, pdpe_addr);
931             if (!(pdpe & PG_PRESENT_MASK))
932                 return -1;
933         } else
934 #endif
935         {
936             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
937                 env->a20_mask;
938             pdpe = ldq_phys(cs->as, pdpe_addr);
939             if (!(pdpe & PG_PRESENT_MASK))
940                 return -1;
941         }
942
943         pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
944                     (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
945         pde = ldq_phys(cs->as, pde_addr);
946         if (!(pde & PG_PRESENT_MASK)) {
947             return -1;
948         }
949         if (pde & PG_PSE_MASK) {
950             /* 2 MB page */
951             page_size = 2048 * 1024;
952             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
953         } else {
954             /* 4 KB page */
955             pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
956                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
957             page_size = 4096;
958             pte = ldq_phys(cs->as, pte_addr);
959         }
960         pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
961         if (!(pte & PG_PRESENT_MASK))
962             return -1;
963     } else {
964         uint32_t pde;
965
966         /* page directory entry */
967         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
968         pde = ldl_phys(cs->as, pde_addr);
969         if (!(pde & PG_PRESENT_MASK))
970             return -1;
971         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
972             pte = pde & ~0x003ff000; /* align to 4MB */
973             page_size = 4096 * 1024;
974         } else {
975             /* page directory entry */
976             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
977             pte = ldl_phys(cs->as, pte_addr);
978             if (!(pte & PG_PRESENT_MASK))
979                 return -1;
980             page_size = 4096;
981         }
982         pte = pte & env->a20_mask;
983     }
984
985     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
986     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
987     return paddr;
988 }
989
990 void hw_breakpoint_insert(CPUX86State *env, int index)
991 {
992     int type = 0, err = 0;
993
994     switch (hw_breakpoint_type(env->dr[7], index)) {
995     case DR7_TYPE_BP_INST:
996         if (hw_breakpoint_enabled(env->dr[7], index)) {
997             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
998                                         &env->cpu_breakpoint[index]);
999         }
1000         break;
1001     case DR7_TYPE_DATA_WR:
1002         type = BP_CPU | BP_MEM_WRITE;
1003         break;
1004     case DR7_TYPE_IO_RW:
1005         /* No support for I/O watchpoints yet */
1006         break;
1007     case DR7_TYPE_DATA_RW:
1008         type = BP_CPU | BP_MEM_ACCESS;
1009         break;
1010     }
1011
1012     if (type != 0) {
1013         err = cpu_watchpoint_insert(env, env->dr[index],
1014                                     hw_breakpoint_len(env->dr[7], index),
1015                                     type, &env->cpu_watchpoint[index]);
1016     }
1017
1018     if (err) {
1019         env->cpu_breakpoint[index] = NULL;
1020     }
1021 }
1022
1023 void hw_breakpoint_remove(CPUX86State *env, int index)
1024 {
1025     if (!env->cpu_breakpoint[index])
1026         return;
1027     switch (hw_breakpoint_type(env->dr[7], index)) {
1028     case DR7_TYPE_BP_INST:
1029         if (hw_breakpoint_enabled(env->dr[7], index)) {
1030             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1031         }
1032         break;
1033     case DR7_TYPE_DATA_WR:
1034     case DR7_TYPE_DATA_RW:
1035         cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1036         break;
1037     case DR7_TYPE_IO_RW:
1038         /* No support for I/O watchpoints yet */
1039         break;
1040     }
1041 }
1042
1043 bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
1044 {
1045     target_ulong dr6;
1046     int reg;
1047     bool hit_enabled = false;
1048
1049     dr6 = env->dr[6] & ~0xf;
1050     for (reg = 0; reg < DR7_MAX_BP; reg++) {
1051         bool bp_match = false;
1052         bool wp_match = false;
1053
1054         switch (hw_breakpoint_type(env->dr[7], reg)) {
1055         case DR7_TYPE_BP_INST:
1056             if (env->dr[reg] == env->eip) {
1057                 bp_match = true;
1058             }
1059             break;
1060         case DR7_TYPE_DATA_WR:
1061         case DR7_TYPE_DATA_RW:
1062             if (env->cpu_watchpoint[reg] &&
1063                 env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
1064                 wp_match = true;
1065             }
1066             break;
1067         case DR7_TYPE_IO_RW:
1068             break;
1069         }
1070         if (bp_match || wp_match) {
1071             dr6 |= 1 << reg;
1072             if (hw_breakpoint_enabled(env->dr[7], reg)) {
1073                 hit_enabled = true;
1074             }
1075         }
1076     }
1077
1078     if (hit_enabled || force_dr6_update) {
1079         env->dr[6] = dr6;
1080     }
1081
1082     return hit_enabled;
1083 }
1084
1085 void breakpoint_handler(CPUX86State *env)
1086 {
1087     CPUBreakpoint *bp;
1088
1089     if (env->watchpoint_hit) {
1090         if (env->watchpoint_hit->flags & BP_CPU) {
1091             env->watchpoint_hit = NULL;
1092             if (check_hw_breakpoints(env, false)) {
1093                 raise_exception(env, EXCP01_DB);
1094             } else {
1095                 cpu_resume_from_signal(env, NULL);
1096             }
1097         }
1098     } else {
1099         QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1100             if (bp->pc == env->eip) {
1101                 if (bp->flags & BP_CPU) {
1102                     check_hw_breakpoints(env, true);
1103                     raise_exception(env, EXCP01_DB);
1104                 }
1105                 break;
1106             }
1107     }
1108 }
1109
1110 typedef struct MCEInjectionParams {
1111     Monitor *mon;
1112     X86CPU *cpu;
1113     int bank;
1114     uint64_t status;
1115     uint64_t mcg_status;
1116     uint64_t addr;
1117     uint64_t misc;
1118     int flags;
1119 } MCEInjectionParams;
1120
1121 static void do_inject_x86_mce(void *data)
1122 {
1123     MCEInjectionParams *params = data;
1124     CPUX86State *cenv = &params->cpu->env;
1125     CPUState *cpu = CPU(params->cpu);
1126     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1127
1128     cpu_synchronize_state(cpu);
1129
1130     /*
1131      * If there is an MCE exception being processed, ignore this SRAO MCE
1132      * unless unconditional injection was requested.
1133      */
1134     if (!(params->flags & MCE_INJECT_UNCOND_AO)
1135         && !(params->status & MCI_STATUS_AR)
1136         && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1137         return;
1138     }
1139
1140     if (params->status & MCI_STATUS_UC) {
1141         /*
1142          * if MSR_MCG_CTL is not all 1s, the uncorrected error
1143          * reporting is disabled
1144          */
1145         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1146             monitor_printf(params->mon,
1147                            "CPU %d: Uncorrected error reporting disabled\n",
1148                            cpu->cpu_index);
1149             return;
1150         }
1151
1152         /*
1153          * if MSR_MCi_CTL is not all 1s, the uncorrected error
1154          * reporting is disabled for the bank
1155          */
1156         if (banks[0] != ~(uint64_t)0) {
1157             monitor_printf(params->mon,
1158                            "CPU %d: Uncorrected error reporting disabled for"
1159                            " bank %d\n",
1160                            cpu->cpu_index, params->bank);
1161             return;
1162         }
1163
1164         if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1165             !(cenv->cr[4] & CR4_MCE_MASK)) {
1166             monitor_printf(params->mon,
1167                            "CPU %d: Previous MCE still in progress, raising"
1168                            " triple fault\n",
1169                            cpu->cpu_index);
1170             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1171             qemu_system_reset_request();
1172             return;
1173         }
1174         if (banks[1] & MCI_STATUS_VAL) {
1175             params->status |= MCI_STATUS_OVER;
1176         }
1177         banks[2] = params->addr;
1178         banks[3] = params->misc;
1179         cenv->mcg_status = params->mcg_status;
1180         banks[1] = params->status;
1181         cpu_interrupt(cpu, CPU_INTERRUPT_MCE);
1182     } else if (!(banks[1] & MCI_STATUS_VAL)
1183                || !(banks[1] & MCI_STATUS_UC)) {
1184         if (banks[1] & MCI_STATUS_VAL) {
1185             params->status |= MCI_STATUS_OVER;
1186         }
1187         banks[2] = params->addr;
1188         banks[3] = params->misc;
1189         banks[1] = params->status;
1190     } else {
1191         banks[1] |= MCI_STATUS_OVER;
1192     }
1193 }
1194
1195 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
1196                         uint64_t status, uint64_t mcg_status, uint64_t addr,
1197                         uint64_t misc, int flags)
1198 {
1199     CPUState *cs = CPU(cpu);
1200     CPUX86State *cenv = &cpu->env;
1201     MCEInjectionParams params = {
1202         .mon = mon,
1203         .cpu = cpu,
1204         .bank = bank,
1205         .status = status,
1206         .mcg_status = mcg_status,
1207         .addr = addr,
1208         .misc = misc,
1209         .flags = flags,
1210     };
1211     unsigned bank_num = cenv->mcg_cap & 0xff;
1212
1213     if (!cenv->mcg_cap) {
1214         monitor_printf(mon, "MCE injection not supported\n");
1215         return;
1216     }
1217     if (bank >= bank_num) {
1218         monitor_printf(mon, "Invalid MCE bank number\n");
1219         return;
1220     }
1221     if (!(status & MCI_STATUS_VAL)) {
1222         monitor_printf(mon, "Invalid MCE status code\n");
1223         return;
1224     }
1225     if ((flags & MCE_INJECT_BROADCAST)
1226         && !cpu_x86_support_mca_broadcast(cenv)) {
1227         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1228         return;
1229     }
1230
1231     run_on_cpu(cs, do_inject_x86_mce, &params);
1232     if (flags & MCE_INJECT_BROADCAST) {
1233         CPUState *other_cs;
1234
1235         params.bank = 1;
1236         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1237         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1238         params.addr = 0;
1239         params.misc = 0;
1240         CPU_FOREACH(other_cs) {
1241             if (other_cs == cs) {
1242                 continue;
1243             }
1244             params.cpu = X86_CPU(other_cs);
1245             run_on_cpu(other_cs, do_inject_x86_mce, &params);
1246         }
1247     }
1248 }
1249
1250 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1251 {
1252     X86CPU *cpu = x86_env_get_cpu(env);
1253
1254     if (kvm_enabled()) {
1255         env->tpr_access_type = access;
1256
1257         cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TPR);
1258     } else {
1259         cpu_restore_state(env, env->mem_io_pc);
1260
1261         apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1262     }
1263 }
1264 #endif /* !CONFIG_USER_ONLY */
1265
1266 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1267                             target_ulong *base, unsigned int *limit,
1268                             unsigned int *flags)
1269 {
1270     X86CPU *cpu = x86_env_get_cpu(env);
1271     CPUState *cs = CPU(cpu);
1272     SegmentCache *dt;
1273     target_ulong ptr;
1274     uint32_t e1, e2;
1275     int index;
1276
1277     if (selector & 0x4)
1278         dt = &env->ldt;
1279     else
1280         dt = &env->gdt;
1281     index = selector & ~7;
1282     ptr = dt->base + index;
1283     if ((index + 7) > dt->limit
1284         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1285         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1286         return 0;
1287
1288     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1289     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1290     if (e2 & DESC_G_MASK)
1291         *limit = (*limit << 12) | 0xfff;
1292     *flags = e2;
1293
1294     return 1;
1295 }
1296
1297 #if !defined(CONFIG_USER_ONLY)
1298 void do_cpu_init(X86CPU *cpu)
1299 {
1300     CPUState *cs = CPU(cpu);
1301     CPUX86State *env = &cpu->env;
1302     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1303     uint64_t pat = env->pat;
1304
1305     cpu_reset(cs);
1306     cs->interrupt_request = sipi;
1307     env->pat = pat;
1308     apic_init_reset(cpu->apic_state);
1309 }
1310
1311 void do_cpu_sipi(X86CPU *cpu)
1312 {
1313     apic_sipi(cpu->apic_state);
1314 }
1315 #else
1316 void do_cpu_init(X86CPU *cpu)
1317 {
1318 }
1319 void do_cpu_sipi(X86CPU *cpu)
1320 {
1321 }
1322 #endif
This page took 0.102915 seconds and 4 git commands to generate.