xref: /qemu/target/i386/helper.c (revision 92eecfff)
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 "qemu/osdep.h"
21 #include "qapi/qapi-events-run-state.h"
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "qemu/qemu-print.h"
25 #include "sysemu/kvm.h"
26 #include "sysemu/runstate.h"
27 #include "kvm_i386.h"
28 #ifndef CONFIG_USER_ONLY
29 #include "sysemu/tcg.h"
30 #include "sysemu/hw_accel.h"
31 #include "monitor/monitor.h"
32 #include "hw/i386/apic_internal.h"
33 #endif
34 
35 void cpu_sync_bndcs_hflags(CPUX86State *env)
36 {
37     uint32_t hflags = env->hflags;
38     uint32_t hflags2 = env->hflags2;
39     uint32_t bndcsr;
40 
41     if ((hflags & HF_CPL_MASK) == 3) {
42         bndcsr = env->bndcs_regs.cfgu;
43     } else {
44         bndcsr = env->msr_bndcfgs;
45     }
46 
47     if ((env->cr[4] & CR4_OSXSAVE_MASK)
48         && (env->xcr0 & XSTATE_BNDCSR_MASK)
49         && (bndcsr & BNDCFG_ENABLE)) {
50         hflags |= HF_MPX_EN_MASK;
51     } else {
52         hflags &= ~HF_MPX_EN_MASK;
53     }
54 
55     if (bndcsr & BNDCFG_BNDPRESERVE) {
56         hflags2 |= HF2_MPX_PR_MASK;
57     } else {
58         hflags2 &= ~HF2_MPX_PR_MASK;
59     }
60 
61     env->hflags = hflags;
62     env->hflags2 = hflags2;
63 }
64 
65 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
66 {
67     int cpuver = env->cpuid_version;
68 
69     if (family == NULL || model == NULL) {
70         return;
71     }
72 
73     *family = (cpuver >> 8) & 0x0f;
74     *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
75 }
76 
77 /* Broadcast MCA signal for processor version 06H_EH and above */
78 int cpu_x86_support_mca_broadcast(CPUX86State *env)
79 {
80     int family = 0;
81     int model = 0;
82 
83     cpu_x86_version(env, &family, &model);
84     if ((family == 6 && model >= 14) || family > 6) {
85         return 1;
86     }
87 
88     return 0;
89 }
90 
91 /***********************************************************/
92 /* x86 debug */
93 
94 static const char *cc_op_str[CC_OP_NB] = {
95     "DYNAMIC",
96     "EFLAGS",
97 
98     "MULB",
99     "MULW",
100     "MULL",
101     "MULQ",
102 
103     "ADDB",
104     "ADDW",
105     "ADDL",
106     "ADDQ",
107 
108     "ADCB",
109     "ADCW",
110     "ADCL",
111     "ADCQ",
112 
113     "SUBB",
114     "SUBW",
115     "SUBL",
116     "SUBQ",
117 
118     "SBBB",
119     "SBBW",
120     "SBBL",
121     "SBBQ",
122 
123     "LOGICB",
124     "LOGICW",
125     "LOGICL",
126     "LOGICQ",
127 
128     "INCB",
129     "INCW",
130     "INCL",
131     "INCQ",
132 
133     "DECB",
134     "DECW",
135     "DECL",
136     "DECQ",
137 
138     "SHLB",
139     "SHLW",
140     "SHLL",
141     "SHLQ",
142 
143     "SARB",
144     "SARW",
145     "SARL",
146     "SARQ",
147 
148     "BMILGB",
149     "BMILGW",
150     "BMILGL",
151     "BMILGQ",
152 
153     "ADCX",
154     "ADOX",
155     "ADCOX",
156 
157     "CLR",
158 };
159 
160 static void
161 cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
162                        const char *name, struct SegmentCache *sc)
163 {
164 #ifdef TARGET_X86_64
165     if (env->hflags & HF_CS64_MASK) {
166         qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
167                      sc->selector, sc->base, sc->limit,
168                      sc->flags & 0x00ffff00);
169     } else
170 #endif
171     {
172         qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
173                      (uint32_t)sc->base, sc->limit,
174                      sc->flags & 0x00ffff00);
175     }
176 
177     if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
178         goto done;
179 
180     qemu_fprintf(f, " DPL=%d ",
181                  (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
182     if (sc->flags & DESC_S_MASK) {
183         if (sc->flags & DESC_CS_MASK) {
184             qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
185                          ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
186             qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
187                          (sc->flags & DESC_R_MASK) ? 'R' : '-');
188         } else {
189             qemu_fprintf(f, (sc->flags & DESC_B_MASK
190                              || env->hflags & HF_LMA_MASK)
191                          ? "DS  " : "DS16");
192             qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
193                          (sc->flags & DESC_W_MASK) ? 'W' : '-');
194         }
195         qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
196     } else {
197         static const char *sys_type_name[2][16] = {
198             { /* 32 bit mode */
199                 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
200                 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
201                 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
202                 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
203             },
204             { /* 64 bit mode */
205                 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
206                 "Reserved", "Reserved", "Reserved", "Reserved",
207                 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
208                 "Reserved", "IntGate64", "TrapGate64"
209             }
210         };
211         qemu_fprintf(f, "%s",
212                      sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
213                      [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]);
214     }
215 done:
216     qemu_fprintf(f, "\n");
217 }
218 
219 #ifndef CONFIG_USER_ONLY
220 
221 /* ARRAY_SIZE check is not required because
222  * DeliveryMode(dm) has a size of 3 bit.
223  */
224 static inline const char *dm2str(uint32_t dm)
225 {
226     static const char *str[] = {
227         "Fixed",
228         "...",
229         "SMI",
230         "...",
231         "NMI",
232         "INIT",
233         "...",
234         "ExtINT"
235     };
236     return str[dm];
237 }
238 
239 static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer)
240 {
241     uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
242     qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
243                 name, lvt,
244                 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
245                 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
246                 lvt & APIC_LVT_MASKED ? "masked" : "",
247                 lvt & APIC_LVT_DELIV_STS ? "pending" : "",
248                 !is_timer ?
249                     "" : lvt & APIC_LVT_TIMER_PERIODIC ?
250                             "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
251                                             "tsc-deadline" : "one-shot",
252                 dm2str(dm));
253     if (dm != APIC_DM_NMI) {
254         qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK);
255     } else {
256         qemu_printf("\n");
257     }
258 }
259 
260 /* ARRAY_SIZE check is not required because
261  * destination shorthand has a size of 2 bit.
262  */
263 static inline const char *shorthand2str(uint32_t shorthand)
264 {
265     const char *str[] = {
266         "no-shorthand", "self", "all-self", "all"
267     };
268     return str[shorthand];
269 }
270 
271 static inline uint8_t divider_conf(uint32_t divide_conf)
272 {
273     uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
274 
275     return divide_val == 7 ? 1 : 2 << divide_val;
276 }
277 
278 static inline void mask2str(char *str, uint32_t val, uint8_t size)
279 {
280     while (size--) {
281         *str++ = (val >> size) & 1 ? '1' : '0';
282     }
283     *str = 0;
284 }
285 
286 #define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
287 
288 static void dump_apic_icr(APICCommonState *s, CPUX86State *env)
289 {
290     uint32_t icr = s->icr[0], icr2 = s->icr[1];
291     uint8_t dest_shorthand = \
292         (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
293     bool logical_mod = icr & APIC_ICR_DEST_MOD;
294     char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
295     uint32_t dest_field;
296     bool x2apic;
297 
298     qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
299                 icr,
300                 logical_mod ? "logical" : "physical",
301                 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
302                 icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
303                 shorthand2str(dest_shorthand));
304 
305     qemu_printf("ICR2\t 0x%08x", icr2);
306     if (dest_shorthand != 0) {
307         qemu_printf("\n");
308         return;
309     }
310     x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
311     dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
312 
313     if (!logical_mod) {
314         if (x2apic) {
315             qemu_printf(" cpu %u (X2APIC ID)\n", dest_field);
316         } else {
317             qemu_printf(" cpu %u (APIC ID)\n",
318                         dest_field & APIC_LOGDEST_XAPIC_ID);
319         }
320         return;
321     }
322 
323     if (s->dest_mode == 0xf) { /* flat mode */
324         mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
325         qemu_printf(" mask %s (APIC ID)\n", apic_id_str);
326     } else if (s->dest_mode == 0) { /* cluster mode */
327         if (x2apic) {
328             mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
329             qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
330                         dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
331         } else {
332             mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
333             qemu_printf(" cluster %u mask %s (APIC ID)\n",
334                         dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
335         }
336     }
337 }
338 
339 static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab,
340                                 uint32_t *tmr_tab)
341 {
342     int i, empty = true;
343 
344     qemu_printf("%s\t ", name);
345     for (i = 0; i < 256; i++) {
346         if (apic_get_bit(ireg_tab, i)) {
347             qemu_printf("%u%s ", i,
348                         apic_get_bit(tmr_tab, i) ? "(level)" : "");
349             empty = false;
350         }
351     }
352     qemu_printf("%s\n", empty ? "(none)" : "");
353 }
354 
355 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
356 {
357     X86CPU *cpu = X86_CPU(cs);
358     APICCommonState *s = APIC_COMMON(cpu->apic_state);
359     if (!s) {
360         qemu_printf("local apic state not available\n");
361         return;
362     }
363     uint32_t *lvt = s->lvt;
364 
365     qemu_printf("dumping local APIC state for CPU %-2u\n\n",
366                 CPU(cpu)->cpu_index);
367     dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false);
368     dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false);
369     dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false);
370     dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false);
371     dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false);
372     dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true);
373 
374     qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
375                 " current_count = %u\n",
376                 s->divide_conf & APIC_DCR_MASK,
377                 divider_conf(s->divide_conf),
378                 s->initial_count, apic_get_current_count(s));
379 
380     qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
381                 s->spurious_vec,
382                 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
383                 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
384                 s->spurious_vec & APIC_VECTOR_MASK);
385 
386     dump_apic_icr(s, &cpu->env);
387 
388     qemu_printf("ESR\t 0x%08x\n", s->esr);
389 
390     dump_apic_interrupt("ISR", s->isr, s->tmr);
391     dump_apic_interrupt("IRR", s->irr, s->tmr);
392 
393     qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
394                 s->arb_id, s->tpr, s->dest_mode, s->log_dest);
395     if (s->dest_mode == 0) {
396         qemu_printf("(cluster %u: id %u)",
397                     s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
398                     s->log_dest & APIC_LOGDEST_XAPIC_ID);
399     }
400     qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s));
401 }
402 #else
403 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
404 {
405 }
406 #endif /* !CONFIG_USER_ONLY */
407 
408 #define DUMP_CODE_BYTES_TOTAL    50
409 #define DUMP_CODE_BYTES_BACKWARD 20
410 
411 void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
412 {
413     X86CPU *cpu = X86_CPU(cs);
414     CPUX86State *env = &cpu->env;
415     int eflags, i, nb;
416     char cc_op_name[32];
417     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
418 
419     eflags = cpu_compute_eflags(env);
420 #ifdef TARGET_X86_64
421     if (env->hflags & HF_CS64_MASK) {
422         qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
423                      "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
424                      "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
425                      "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
426                      "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
427                      env->regs[R_EAX],
428                      env->regs[R_EBX],
429                      env->regs[R_ECX],
430                      env->regs[R_EDX],
431                      env->regs[R_ESI],
432                      env->regs[R_EDI],
433                      env->regs[R_EBP],
434                      env->regs[R_ESP],
435                      env->regs[8],
436                      env->regs[9],
437                      env->regs[10],
438                      env->regs[11],
439                      env->regs[12],
440                      env->regs[13],
441                      env->regs[14],
442                      env->regs[15],
443                      env->eip, eflags,
444                      eflags & DF_MASK ? 'D' : '-',
445                      eflags & CC_O ? 'O' : '-',
446                      eflags & CC_S ? 'S' : '-',
447                      eflags & CC_Z ? 'Z' : '-',
448                      eflags & CC_A ? 'A' : '-',
449                      eflags & CC_P ? 'P' : '-',
450                      eflags & CC_C ? 'C' : '-',
451                      env->hflags & HF_CPL_MASK,
452                      (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
453                      (env->a20_mask >> 20) & 1,
454                      (env->hflags >> HF_SMM_SHIFT) & 1,
455                      cs->halted);
456     } else
457 #endif
458     {
459         qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
460                      "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
461                      "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
462                      (uint32_t)env->regs[R_EAX],
463                      (uint32_t)env->regs[R_EBX],
464                      (uint32_t)env->regs[R_ECX],
465                      (uint32_t)env->regs[R_EDX],
466                      (uint32_t)env->regs[R_ESI],
467                      (uint32_t)env->regs[R_EDI],
468                      (uint32_t)env->regs[R_EBP],
469                      (uint32_t)env->regs[R_ESP],
470                      (uint32_t)env->eip, eflags,
471                      eflags & DF_MASK ? 'D' : '-',
472                      eflags & CC_O ? 'O' : '-',
473                      eflags & CC_S ? 'S' : '-',
474                      eflags & CC_Z ? 'Z' : '-',
475                      eflags & CC_A ? 'A' : '-',
476                      eflags & CC_P ? 'P' : '-',
477                      eflags & CC_C ? 'C' : '-',
478                      env->hflags & HF_CPL_MASK,
479                      (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
480                      (env->a20_mask >> 20) & 1,
481                      (env->hflags >> HF_SMM_SHIFT) & 1,
482                      cs->halted);
483     }
484 
485     for(i = 0; i < 6; i++) {
486         cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]);
487     }
488     cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt);
489     cpu_x86_dump_seg_cache(env, f, "TR", &env->tr);
490 
491 #ifdef TARGET_X86_64
492     if (env->hflags & HF_LMA_MASK) {
493         qemu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
494                      env->gdt.base, env->gdt.limit);
495         qemu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
496                      env->idt.base, env->idt.limit);
497         qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
498                      (uint32_t)env->cr[0],
499                      env->cr[2],
500                      env->cr[3],
501                      (uint32_t)env->cr[4]);
502         for(i = 0; i < 4; i++)
503             qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
504         qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
505                      env->dr[6], env->dr[7]);
506     } else
507 #endif
508     {
509         qemu_fprintf(f, "GDT=     %08x %08x\n",
510                      (uint32_t)env->gdt.base, env->gdt.limit);
511         qemu_fprintf(f, "IDT=     %08x %08x\n",
512                      (uint32_t)env->idt.base, env->idt.limit);
513         qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
514                      (uint32_t)env->cr[0],
515                      (uint32_t)env->cr[2],
516                      (uint32_t)env->cr[3],
517                      (uint32_t)env->cr[4]);
518         for(i = 0; i < 4; i++) {
519             qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
520         }
521         qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
522                      env->dr[6], env->dr[7]);
523     }
524     if (flags & CPU_DUMP_CCOP) {
525         if ((unsigned)env->cc_op < CC_OP_NB)
526             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
527         else
528             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
529 #ifdef TARGET_X86_64
530         if (env->hflags & HF_CS64_MASK) {
531             qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
532                          env->cc_src, env->cc_dst,
533                          cc_op_name);
534         } else
535 #endif
536         {
537             qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
538                          (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
539                          cc_op_name);
540         }
541     }
542     qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
543     if (flags & CPU_DUMP_FPU) {
544         int fptag;
545         fptag = 0;
546         for(i = 0; i < 8; i++) {
547             fptag |= ((!env->fptags[i]) << i);
548         }
549         update_mxcsr_from_sse_status(env);
550         qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
551                      env->fpuc,
552                      (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
553                      env->fpstt,
554                      fptag,
555                      env->mxcsr);
556         for(i=0;i<8;i++) {
557             CPU_LDoubleU u;
558             u.d = env->fpregs[i].d;
559             qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
560                          i, u.l.lower, u.l.upper);
561             if ((i & 1) == 1)
562                 qemu_fprintf(f, "\n");
563             else
564                 qemu_fprintf(f, " ");
565         }
566         if (env->hflags & HF_CS64_MASK)
567             nb = 16;
568         else
569             nb = 8;
570         for(i=0;i<nb;i++) {
571             qemu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
572                          i,
573                          env->xmm_regs[i].ZMM_L(3),
574                          env->xmm_regs[i].ZMM_L(2),
575                          env->xmm_regs[i].ZMM_L(1),
576                          env->xmm_regs[i].ZMM_L(0));
577             if ((i & 1) == 1)
578                 qemu_fprintf(f, "\n");
579             else
580                 qemu_fprintf(f, " ");
581         }
582     }
583     if (flags & CPU_DUMP_CODE) {
584         target_ulong base = env->segs[R_CS].base + env->eip;
585         target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
586         uint8_t code;
587         char codestr[3];
588 
589         qemu_fprintf(f, "Code=");
590         for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
591             if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
592                 snprintf(codestr, sizeof(codestr), "%02x", code);
593             } else {
594                 snprintf(codestr, sizeof(codestr), "??");
595             }
596             qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
597                          i == offs ? "<" : "", codestr, i == offs ? ">" : "");
598         }
599         qemu_fprintf(f, "\n");
600     }
601 }
602 
603 /***********************************************************/
604 /* x86 mmu */
605 /* XXX: add PGE support */
606 
607 void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
608 {
609     CPUX86State *env = &cpu->env;
610 
611     a20_state = (a20_state != 0);
612     if (a20_state != ((env->a20_mask >> 20) & 1)) {
613         CPUState *cs = CPU(cpu);
614 
615         qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
616         /* if the cpu is currently executing code, we must unlink it and
617            all the potentially executing TB */
618         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
619 
620         /* when a20 is changed, all the MMU mappings are invalid, so
621            we must flush everything */
622         tlb_flush(cs);
623         env->a20_mask = ~(1 << 20) | (a20_state << 20);
624     }
625 }
626 
627 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
628 {
629     X86CPU *cpu = env_archcpu(env);
630     int pe_state;
631 
632     qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
633     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
634         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
635         tlb_flush(CPU(cpu));
636     }
637 
638 #ifdef TARGET_X86_64
639     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
640         (env->efer & MSR_EFER_LME)) {
641         /* enter in long mode */
642         /* XXX: generate an exception */
643         if (!(env->cr[4] & CR4_PAE_MASK))
644             return;
645         env->efer |= MSR_EFER_LMA;
646         env->hflags |= HF_LMA_MASK;
647     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
648                (env->efer & MSR_EFER_LMA)) {
649         /* exit long mode */
650         env->efer &= ~MSR_EFER_LMA;
651         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
652         env->eip &= 0xffffffff;
653     }
654 #endif
655     env->cr[0] = new_cr0 | CR0_ET_MASK;
656 
657     /* update PE flag in hidden flags */
658     pe_state = (env->cr[0] & CR0_PE_MASK);
659     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
660     /* ensure that ADDSEG is always set in real mode */
661     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
662     /* update FPU flags */
663     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
664         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
665 }
666 
667 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
668    the PDPT */
669 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
670 {
671     env->cr[3] = new_cr3;
672     if (env->cr[0] & CR0_PG_MASK) {
673         qemu_log_mask(CPU_LOG_MMU,
674                         "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
675         tlb_flush(env_cpu(env));
676     }
677 }
678 
679 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
680 {
681     uint32_t hflags;
682 
683 #if defined(DEBUG_MMU)
684     printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
685 #endif
686     if ((new_cr4 ^ env->cr[4]) &
687         (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
688          CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
689         tlb_flush(env_cpu(env));
690     }
691 
692     /* Clear bits we're going to recompute.  */
693     hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
694 
695     /* SSE handling */
696     if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
697         new_cr4 &= ~CR4_OSFXSR_MASK;
698     }
699     if (new_cr4 & CR4_OSFXSR_MASK) {
700         hflags |= HF_OSFXSR_MASK;
701     }
702 
703     if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
704         new_cr4 &= ~CR4_SMAP_MASK;
705     }
706     if (new_cr4 & CR4_SMAP_MASK) {
707         hflags |= HF_SMAP_MASK;
708     }
709 
710     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
711         new_cr4 &= ~CR4_PKE_MASK;
712     }
713 
714     env->cr[4] = new_cr4;
715     env->hflags = hflags;
716 
717     cpu_sync_bndcs_hflags(env);
718 }
719 
720 #if !defined(CONFIG_USER_ONLY)
721 hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
722                                          MemTxAttrs *attrs)
723 {
724     X86CPU *cpu = X86_CPU(cs);
725     CPUX86State *env = &cpu->env;
726     target_ulong pde_addr, pte_addr;
727     uint64_t pte;
728     int32_t a20_mask;
729     uint32_t page_offset;
730     int page_size;
731 
732     *attrs = cpu_get_mem_attrs(env);
733 
734     a20_mask = x86_get_a20_mask(env);
735     if (!(env->cr[0] & CR0_PG_MASK)) {
736         pte = addr & a20_mask;
737         page_size = 4096;
738     } else if (env->cr[4] & CR4_PAE_MASK) {
739         target_ulong pdpe_addr;
740         uint64_t pde, pdpe;
741 
742 #ifdef TARGET_X86_64
743         if (env->hflags & HF_LMA_MASK) {
744             bool la57 = env->cr[4] & CR4_LA57_MASK;
745             uint64_t pml5e_addr, pml5e;
746             uint64_t pml4e_addr, pml4e;
747             int32_t sext;
748 
749             /* test virtual address sign extension */
750             sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
751             if (sext != 0 && sext != -1) {
752                 return -1;
753             }
754 
755             if (la57) {
756                 pml5e_addr = ((env->cr[3] & ~0xfff) +
757                         (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
758                 pml5e = x86_ldq_phys(cs, pml5e_addr);
759                 if (!(pml5e & PG_PRESENT_MASK)) {
760                     return -1;
761                 }
762             } else {
763                 pml5e = env->cr[3];
764             }
765 
766             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
767                     (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
768             pml4e = x86_ldq_phys(cs, pml4e_addr);
769             if (!(pml4e & PG_PRESENT_MASK)) {
770                 return -1;
771             }
772             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
773                          (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
774             pdpe = x86_ldq_phys(cs, pdpe_addr);
775             if (!(pdpe & PG_PRESENT_MASK)) {
776                 return -1;
777             }
778             if (pdpe & PG_PSE_MASK) {
779                 page_size = 1024 * 1024 * 1024;
780                 pte = pdpe;
781                 goto out;
782             }
783 
784         } else
785 #endif
786         {
787             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
788                 a20_mask;
789             pdpe = x86_ldq_phys(cs, pdpe_addr);
790             if (!(pdpe & PG_PRESENT_MASK))
791                 return -1;
792         }
793 
794         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
795                     (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
796         pde = x86_ldq_phys(cs, pde_addr);
797         if (!(pde & PG_PRESENT_MASK)) {
798             return -1;
799         }
800         if (pde & PG_PSE_MASK) {
801             /* 2 MB page */
802             page_size = 2048 * 1024;
803             pte = pde;
804         } else {
805             /* 4 KB page */
806             pte_addr = ((pde & PG_ADDRESS_MASK) +
807                         (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
808             page_size = 4096;
809             pte = x86_ldq_phys(cs, pte_addr);
810         }
811         if (!(pte & PG_PRESENT_MASK)) {
812             return -1;
813         }
814     } else {
815         uint32_t pde;
816 
817         /* page directory entry */
818         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
819         pde = x86_ldl_phys(cs, pde_addr);
820         if (!(pde & PG_PRESENT_MASK))
821             return -1;
822         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
823             pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
824             page_size = 4096 * 1024;
825         } else {
826             /* page directory entry */
827             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
828             pte = x86_ldl_phys(cs, pte_addr);
829             if (!(pte & PG_PRESENT_MASK)) {
830                 return -1;
831             }
832             page_size = 4096;
833         }
834         pte = pte & a20_mask;
835     }
836 
837 #ifdef TARGET_X86_64
838 out:
839 #endif
840     pte &= PG_ADDRESS_MASK & ~(page_size - 1);
841     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
842     return pte | page_offset;
843 }
844 
845 typedef struct MCEInjectionParams {
846     Monitor *mon;
847     int bank;
848     uint64_t status;
849     uint64_t mcg_status;
850     uint64_t addr;
851     uint64_t misc;
852     int flags;
853 } MCEInjectionParams;
854 
855 static void emit_guest_memory_failure(MemoryFailureAction action, bool ar,
856                                       bool recursive)
857 {
858     MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive};
859 
860     qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action,
861                                    &mff);
862 }
863 
864 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
865 {
866     MCEInjectionParams *params = data.host_ptr;
867     X86CPU *cpu = X86_CPU(cs);
868     CPUX86State *cenv = &cpu->env;
869     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
870     g_autofree char *msg = NULL;
871     bool need_reset = false;
872     bool recursive;
873     bool ar = !!(params->status & MCI_STATUS_AR);
874 
875     cpu_synchronize_state(cs);
876     recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP);
877 
878     /*
879      * If there is an MCE exception being processed, ignore this SRAO MCE
880      * unless unconditional injection was requested.
881      */
882     if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) {
883         emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive);
884         return;
885     }
886 
887     if (params->status & MCI_STATUS_UC) {
888         /*
889          * if MSR_MCG_CTL is not all 1s, the uncorrected error
890          * reporting is disabled
891          */
892         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
893             monitor_printf(params->mon,
894                            "CPU %d: Uncorrected error reporting disabled\n",
895                            cs->cpu_index);
896             return;
897         }
898 
899         /*
900          * if MSR_MCi_CTL is not all 1s, the uncorrected error
901          * reporting is disabled for the bank
902          */
903         if (banks[0] != ~(uint64_t)0) {
904             monitor_printf(params->mon,
905                            "CPU %d: Uncorrected error reporting disabled for"
906                            " bank %d\n",
907                            cs->cpu_index, params->bank);
908             return;
909         }
910 
911         if (recursive) {
912             need_reset = true;
913             msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
914                                   "raising triple fault", cs->cpu_index);
915         }
916 
917         if (!(cenv->cr[4] & CR4_MCE_MASK)) {
918             need_reset = true;
919             msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
920                                   "raising triple fault", cs->cpu_index);
921         }
922 
923         if (need_reset) {
924             emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
925                                       recursive);
926             monitor_printf(params->mon, "%s", msg);
927             qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
928             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
929             return;
930         }
931 
932         if (banks[1] & MCI_STATUS_VAL) {
933             params->status |= MCI_STATUS_OVER;
934         }
935         banks[2] = params->addr;
936         banks[3] = params->misc;
937         cenv->mcg_status = params->mcg_status;
938         banks[1] = params->status;
939         cpu_interrupt(cs, CPU_INTERRUPT_MCE);
940     } else if (!(banks[1] & MCI_STATUS_VAL)
941                || !(banks[1] & MCI_STATUS_UC)) {
942         if (banks[1] & MCI_STATUS_VAL) {
943             params->status |= MCI_STATUS_OVER;
944         }
945         banks[2] = params->addr;
946         banks[3] = params->misc;
947         banks[1] = params->status;
948     } else {
949         banks[1] |= MCI_STATUS_OVER;
950     }
951 
952     emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
953 }
954 
955 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
956                         uint64_t status, uint64_t mcg_status, uint64_t addr,
957                         uint64_t misc, int flags)
958 {
959     CPUState *cs = CPU(cpu);
960     CPUX86State *cenv = &cpu->env;
961     MCEInjectionParams params = {
962         .mon = mon,
963         .bank = bank,
964         .status = status,
965         .mcg_status = mcg_status,
966         .addr = addr,
967         .misc = misc,
968         .flags = flags,
969     };
970     unsigned bank_num = cenv->mcg_cap & 0xff;
971 
972     if (!cenv->mcg_cap) {
973         monitor_printf(mon, "MCE injection not supported\n");
974         return;
975     }
976     if (bank >= bank_num) {
977         monitor_printf(mon, "Invalid MCE bank number\n");
978         return;
979     }
980     if (!(status & MCI_STATUS_VAL)) {
981         monitor_printf(mon, "Invalid MCE status code\n");
982         return;
983     }
984     if ((flags & MCE_INJECT_BROADCAST)
985         && !cpu_x86_support_mca_broadcast(cenv)) {
986         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
987         return;
988     }
989 
990     run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
991     if (flags & MCE_INJECT_BROADCAST) {
992         CPUState *other_cs;
993 
994         params.bank = 1;
995         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
996         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
997         params.addr = 0;
998         params.misc = 0;
999         CPU_FOREACH(other_cs) {
1000             if (other_cs == cs) {
1001                 continue;
1002             }
1003             run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1004         }
1005     }
1006 }
1007 
1008 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1009 {
1010     X86CPU *cpu = env_archcpu(env);
1011     CPUState *cs = env_cpu(env);
1012 
1013     if (kvm_enabled() || whpx_enabled()) {
1014         env->tpr_access_type = access;
1015 
1016         cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1017     } else if (tcg_enabled()) {
1018         cpu_restore_state(cs, cs->mem_io_pc, false);
1019 
1020         apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1021     }
1022 }
1023 #endif /* !CONFIG_USER_ONLY */
1024 
1025 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1026                             target_ulong *base, unsigned int *limit,
1027                             unsigned int *flags)
1028 {
1029     CPUState *cs = env_cpu(env);
1030     SegmentCache *dt;
1031     target_ulong ptr;
1032     uint32_t e1, e2;
1033     int index;
1034 
1035     if (selector & 0x4)
1036         dt = &env->ldt;
1037     else
1038         dt = &env->gdt;
1039     index = selector & ~7;
1040     ptr = dt->base + index;
1041     if ((index + 7) > dt->limit
1042         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1043         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1044         return 0;
1045 
1046     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1047     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1048     if (e2 & DESC_G_MASK)
1049         *limit = (*limit << 12) | 0xfff;
1050     *flags = e2;
1051 
1052     return 1;
1053 }
1054 
1055 #if !defined(CONFIG_USER_ONLY)
1056 void do_cpu_init(X86CPU *cpu)
1057 {
1058     CPUState *cs = CPU(cpu);
1059     CPUX86State *env = &cpu->env;
1060     CPUX86State *save = g_new(CPUX86State, 1);
1061     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1062 
1063     *save = *env;
1064 
1065     cpu_reset(cs);
1066     cs->interrupt_request = sipi;
1067     memcpy(&env->start_init_save, &save->start_init_save,
1068            offsetof(CPUX86State, end_init_save) -
1069            offsetof(CPUX86State, start_init_save));
1070     g_free(save);
1071 
1072     if (kvm_enabled()) {
1073         kvm_arch_do_init_vcpu(cpu);
1074     }
1075     apic_init_reset(cpu->apic_state);
1076 }
1077 
1078 void do_cpu_sipi(X86CPU *cpu)
1079 {
1080     apic_sipi(cpu->apic_state);
1081 }
1082 #else
1083 void do_cpu_init(X86CPU *cpu)
1084 {
1085 }
1086 void do_cpu_sipi(X86CPU *cpu)
1087 {
1088 }
1089 #endif
1090 
1091 /* Frob eflags into and out of the CPU temporary format.  */
1092 
1093 void x86_cpu_exec_enter(CPUState *cs)
1094 {
1095     X86CPU *cpu = X86_CPU(cs);
1096     CPUX86State *env = &cpu->env;
1097 
1098     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1099     env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1100     CC_OP = CC_OP_EFLAGS;
1101     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1102 }
1103 
1104 void x86_cpu_exec_exit(CPUState *cs)
1105 {
1106     X86CPU *cpu = X86_CPU(cs);
1107     CPUX86State *env = &cpu->env;
1108 
1109     env->eflags = cpu_compute_eflags(env);
1110 }
1111 
1112 #ifndef CONFIG_USER_ONLY
1113 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1114 {
1115     X86CPU *cpu = X86_CPU(cs);
1116     CPUX86State *env = &cpu->env;
1117     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1118     AddressSpace *as = cpu_addressspace(cs, attrs);
1119 
1120     return address_space_ldub(as, addr, attrs, NULL);
1121 }
1122 
1123 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1124 {
1125     X86CPU *cpu = X86_CPU(cs);
1126     CPUX86State *env = &cpu->env;
1127     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1128     AddressSpace *as = cpu_addressspace(cs, attrs);
1129 
1130     return address_space_lduw(as, addr, attrs, NULL);
1131 }
1132 
1133 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1134 {
1135     X86CPU *cpu = X86_CPU(cs);
1136     CPUX86State *env = &cpu->env;
1137     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1138     AddressSpace *as = cpu_addressspace(cs, attrs);
1139 
1140     return address_space_ldl(as, addr, attrs, NULL);
1141 }
1142 
1143 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1144 {
1145     X86CPU *cpu = X86_CPU(cs);
1146     CPUX86State *env = &cpu->env;
1147     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1148     AddressSpace *as = cpu_addressspace(cs, attrs);
1149 
1150     return address_space_ldq(as, addr, attrs, NULL);
1151 }
1152 
1153 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1154 {
1155     X86CPU *cpu = X86_CPU(cs);
1156     CPUX86State *env = &cpu->env;
1157     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1158     AddressSpace *as = cpu_addressspace(cs, attrs);
1159 
1160     address_space_stb(as, addr, val, attrs, NULL);
1161 }
1162 
1163 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1164 {
1165     X86CPU *cpu = X86_CPU(cs);
1166     CPUX86State *env = &cpu->env;
1167     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1168     AddressSpace *as = cpu_addressspace(cs, attrs);
1169 
1170     address_space_stl_notdirty(as, addr, val, attrs, NULL);
1171 }
1172 
1173 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1174 {
1175     X86CPU *cpu = X86_CPU(cs);
1176     CPUX86State *env = &cpu->env;
1177     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1178     AddressSpace *as = cpu_addressspace(cs, attrs);
1179 
1180     address_space_stw(as, addr, val, attrs, NULL);
1181 }
1182 
1183 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1184 {
1185     X86CPU *cpu = X86_CPU(cs);
1186     CPUX86State *env = &cpu->env;
1187     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1188     AddressSpace *as = cpu_addressspace(cs, attrs);
1189 
1190     address_space_stl(as, addr, val, attrs, NULL);
1191 }
1192 
1193 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1194 {
1195     X86CPU *cpu = X86_CPU(cs);
1196     CPUX86State *env = &cpu->env;
1197     MemTxAttrs attrs = cpu_get_mem_attrs(env);
1198     AddressSpace *as = cpu_addressspace(cs, attrs);
1199 
1200     address_space_stq(as, addr, val, attrs, NULL);
1201 }
1202 #endif
1203