qemu/target/i386/helper.c
<<
>>
Prefs
   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.1 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
  35void 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
  65static 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 */
  78int 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
  94static 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
 160static void
 161cpu_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    }
 215done:
 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 */
 224static 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
 239static 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 */
 263static 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
 271static 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
 278static 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
 288static 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
 339static 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
 355void 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
 403void 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
 411void 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
 607void 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
 627void 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 */
 669void 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
 679void 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)
 721hwaddr 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
 838out:
 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
 845typedef 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
 855static 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
 864static 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 (!(cenv->cr[4] & CR4_MCE_MASK)) {
 912            need_reset = true;
 913            msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
 914                                  "raising triple fault", cs->cpu_index);
 915        } else if (recursive) {
 916            need_reset = true;
 917            msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
 918                                  "raising triple fault", cs->cpu_index);
 919        }
 920
 921        if (need_reset) {
 922            emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
 923                                      recursive);
 924            monitor_printf(params->mon, "%s", msg);
 925            qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
 926            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 927            return;
 928        }
 929
 930        if (banks[1] & MCI_STATUS_VAL) {
 931            params->status |= MCI_STATUS_OVER;
 932        }
 933        banks[2] = params->addr;
 934        banks[3] = params->misc;
 935        cenv->mcg_status = params->mcg_status;
 936        banks[1] = params->status;
 937        cpu_interrupt(cs, CPU_INTERRUPT_MCE);
 938    } else if (!(banks[1] & MCI_STATUS_VAL)
 939               || !(banks[1] & MCI_STATUS_UC)) {
 940        if (banks[1] & MCI_STATUS_VAL) {
 941            params->status |= MCI_STATUS_OVER;
 942        }
 943        banks[2] = params->addr;
 944        banks[3] = params->misc;
 945        banks[1] = params->status;
 946    } else {
 947        banks[1] |= MCI_STATUS_OVER;
 948    }
 949
 950    emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
 951}
 952
 953void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
 954                        uint64_t status, uint64_t mcg_status, uint64_t addr,
 955                        uint64_t misc, int flags)
 956{
 957    CPUState *cs = CPU(cpu);
 958    CPUX86State *cenv = &cpu->env;
 959    MCEInjectionParams params = {
 960        .mon = mon,
 961        .bank = bank,
 962        .status = status,
 963        .mcg_status = mcg_status,
 964        .addr = addr,
 965        .misc = misc,
 966        .flags = flags,
 967    };
 968    unsigned bank_num = cenv->mcg_cap & 0xff;
 969
 970    if (!cenv->mcg_cap) {
 971        monitor_printf(mon, "MCE injection not supported\n");
 972        return;
 973    }
 974    if (bank >= bank_num) {
 975        monitor_printf(mon, "Invalid MCE bank number\n");
 976        return;
 977    }
 978    if (!(status & MCI_STATUS_VAL)) {
 979        monitor_printf(mon, "Invalid MCE status code\n");
 980        return;
 981    }
 982    if ((flags & MCE_INJECT_BROADCAST)
 983        && !cpu_x86_support_mca_broadcast(cenv)) {
 984        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
 985        return;
 986    }
 987
 988    run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
 989    if (flags & MCE_INJECT_BROADCAST) {
 990        CPUState *other_cs;
 991
 992        params.bank = 1;
 993        params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
 994        params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
 995        params.addr = 0;
 996        params.misc = 0;
 997        CPU_FOREACH(other_cs) {
 998            if (other_cs == cs) {
 999                continue;
1000            }
1001            run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1002        }
1003    }
1004}
1005
1006void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1007{
1008    X86CPU *cpu = env_archcpu(env);
1009    CPUState *cs = env_cpu(env);
1010
1011    if (kvm_enabled() || whpx_enabled()) {
1012        env->tpr_access_type = access;
1013
1014        cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1015    } else if (tcg_enabled()) {
1016        cpu_restore_state(cs, cs->mem_io_pc, false);
1017
1018        apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1019    }
1020}
1021#endif /* !CONFIG_USER_ONLY */
1022
1023int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1024                            target_ulong *base, unsigned int *limit,
1025                            unsigned int *flags)
1026{
1027    CPUState *cs = env_cpu(env);
1028    SegmentCache *dt;
1029    target_ulong ptr;
1030    uint32_t e1, e2;
1031    int index;
1032
1033    if (selector & 0x4)
1034        dt = &env->ldt;
1035    else
1036        dt = &env->gdt;
1037    index = selector & ~7;
1038    ptr = dt->base + index;
1039    if ((index + 7) > dt->limit
1040        || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1041        || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1042        return 0;
1043
1044    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1045    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1046    if (e2 & DESC_G_MASK)
1047        *limit = (*limit << 12) | 0xfff;
1048    *flags = e2;
1049
1050    return 1;
1051}
1052
1053#if !defined(CONFIG_USER_ONLY)
1054void do_cpu_init(X86CPU *cpu)
1055{
1056    CPUState *cs = CPU(cpu);
1057    CPUX86State *env = &cpu->env;
1058    CPUX86State *save = g_new(CPUX86State, 1);
1059    int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1060
1061    *save = *env;
1062
1063    cpu_reset(cs);
1064    cs->interrupt_request = sipi;
1065    memcpy(&env->start_init_save, &save->start_init_save,
1066           offsetof(CPUX86State, end_init_save) -
1067           offsetof(CPUX86State, start_init_save));
1068    g_free(save);
1069
1070    if (kvm_enabled()) {
1071        kvm_arch_do_init_vcpu(cpu);
1072    }
1073    apic_init_reset(cpu->apic_state);
1074}
1075
1076void do_cpu_sipi(X86CPU *cpu)
1077{
1078    apic_sipi(cpu->apic_state);
1079}
1080#else
1081void do_cpu_init(X86CPU *cpu)
1082{
1083}
1084void do_cpu_sipi(X86CPU *cpu)
1085{
1086}
1087#endif
1088
1089/* Frob eflags into and out of the CPU temporary format.  */
1090
1091void x86_cpu_exec_enter(CPUState *cs)
1092{
1093    X86CPU *cpu = X86_CPU(cs);
1094    CPUX86State *env = &cpu->env;
1095
1096    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1097    env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1098    CC_OP = CC_OP_EFLAGS;
1099    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1100}
1101
1102void x86_cpu_exec_exit(CPUState *cs)
1103{
1104    X86CPU *cpu = X86_CPU(cs);
1105    CPUX86State *env = &cpu->env;
1106
1107    env->eflags = cpu_compute_eflags(env);
1108}
1109
1110#ifndef CONFIG_USER_ONLY
1111uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1112{
1113    X86CPU *cpu = X86_CPU(cs);
1114    CPUX86State *env = &cpu->env;
1115    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1116    AddressSpace *as = cpu_addressspace(cs, attrs);
1117
1118    return address_space_ldub(as, addr, attrs, NULL);
1119}
1120
1121uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1122{
1123    X86CPU *cpu = X86_CPU(cs);
1124    CPUX86State *env = &cpu->env;
1125    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1126    AddressSpace *as = cpu_addressspace(cs, attrs);
1127
1128    return address_space_lduw(as, addr, attrs, NULL);
1129}
1130
1131uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1132{
1133    X86CPU *cpu = X86_CPU(cs);
1134    CPUX86State *env = &cpu->env;
1135    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1136    AddressSpace *as = cpu_addressspace(cs, attrs);
1137
1138    return address_space_ldl(as, addr, attrs, NULL);
1139}
1140
1141uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1142{
1143    X86CPU *cpu = X86_CPU(cs);
1144    CPUX86State *env = &cpu->env;
1145    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1146    AddressSpace *as = cpu_addressspace(cs, attrs);
1147
1148    return address_space_ldq(as, addr, attrs, NULL);
1149}
1150
1151void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1152{
1153    X86CPU *cpu = X86_CPU(cs);
1154    CPUX86State *env = &cpu->env;
1155    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1156    AddressSpace *as = cpu_addressspace(cs, attrs);
1157
1158    address_space_stb(as, addr, val, attrs, NULL);
1159}
1160
1161void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1162{
1163    X86CPU *cpu = X86_CPU(cs);
1164    CPUX86State *env = &cpu->env;
1165    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1166    AddressSpace *as = cpu_addressspace(cs, attrs);
1167
1168    address_space_stl_notdirty(as, addr, val, attrs, NULL);
1169}
1170
1171void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1172{
1173    X86CPU *cpu = X86_CPU(cs);
1174    CPUX86State *env = &cpu->env;
1175    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1176    AddressSpace *as = cpu_addressspace(cs, attrs);
1177
1178    address_space_stw(as, addr, val, attrs, NULL);
1179}
1180
1181void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1182{
1183    X86CPU *cpu = X86_CPU(cs);
1184    CPUX86State *env = &cpu->env;
1185    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1186    AddressSpace *as = cpu_addressspace(cs, attrs);
1187
1188    address_space_stl(as, addr, val, attrs, NULL);
1189}
1190
1191void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1192{
1193    X86CPU *cpu = X86_CPU(cs);
1194    CPUX86State *env = &cpu->env;
1195    MemTxAttrs attrs = cpu_get_mem_attrs(env);
1196    AddressSpace *as = cpu_addressspace(cs, attrs);
1197
1198    address_space_stq(as, addr, val, attrs, NULL);
1199}
1200#endif
1201