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/cputlb.h" 24 #include "exec/translation-block.h" 25 #include "system/runstate.h" 26 #ifndef CONFIG_USER_ONLY 27 #include "system/hw_accel.h" 28 #include "system/memory.h" 29 #include "monitor/monitor.h" 30 #include "kvm/kvm_i386.h" 31 #endif 32 #include "qemu/log.h" 33 #ifdef CONFIG_TCG 34 #include "tcg/insn-start-words.h" 35 #endif 36 37 void cpu_sync_avx_hflag(CPUX86State *env) 38 { 39 if ((env->cr[4] & CR4_OSXSAVE_MASK) 40 && (env->xcr0 & (XSTATE_SSE_MASK | XSTATE_YMM_MASK)) 41 == (XSTATE_SSE_MASK | XSTATE_YMM_MASK)) { 42 env->hflags |= HF_AVX_EN_MASK; 43 } else{ 44 env->hflags &= ~HF_AVX_EN_MASK; 45 } 46 } 47 48 void cpu_sync_bndcs_hflags(CPUX86State *env) 49 { 50 uint32_t hflags = env->hflags; 51 uint32_t hflags2 = env->hflags2; 52 uint32_t bndcsr; 53 54 if ((hflags & HF_CPL_MASK) == 3) { 55 bndcsr = env->bndcs_regs.cfgu; 56 } else { 57 bndcsr = env->msr_bndcfgs; 58 } 59 60 if ((env->cr[4] & CR4_OSXSAVE_MASK) 61 && (env->xcr0 & XSTATE_BNDCSR_MASK) 62 && (bndcsr & BNDCFG_ENABLE)) { 63 hflags |= HF_MPX_EN_MASK; 64 } else { 65 hflags &= ~HF_MPX_EN_MASK; 66 } 67 68 if (bndcsr & BNDCFG_BNDPRESERVE) { 69 hflags2 |= HF2_MPX_PR_MASK; 70 } else { 71 hflags2 &= ~HF2_MPX_PR_MASK; 72 } 73 74 env->hflags = hflags; 75 env->hflags2 = hflags2; 76 } 77 78 static void cpu_x86_version(CPUX86State *env, int *family, int *model) 79 { 80 int cpuver = env->cpuid_version; 81 82 if (family == NULL || model == NULL) { 83 return; 84 } 85 86 *family = (cpuver >> 8) & 0x0f; 87 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f); 88 } 89 90 /* Broadcast MCA signal for processor version 06H_EH and above */ 91 int cpu_x86_support_mca_broadcast(CPUX86State *env) 92 { 93 int family = 0; 94 int model = 0; 95 96 if (IS_AMD_CPU(env)) { 97 return 0; 98 } 99 100 cpu_x86_version(env, &family, &model); 101 if ((family == 6 && model >= 14) || family > 6) { 102 return 1; 103 } 104 105 return 0; 106 } 107 108 /***********************************************************/ 109 /* x86 mmu */ 110 /* XXX: add PGE support */ 111 112 void x86_cpu_set_a20(X86CPU *cpu, int a20_state) 113 { 114 CPUX86State *env = &cpu->env; 115 116 a20_state = (a20_state != 0); 117 if (a20_state != ((env->a20_mask >> 20) & 1)) { 118 CPUState *cs = CPU(cpu); 119 120 qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state); 121 /* if the cpu is currently executing code, we must unlink it and 122 all the potentially executing TB */ 123 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB); 124 125 /* when a20 is changed, all the MMU mappings are invalid, so 126 we must flush everything */ 127 tlb_flush(cs); 128 env->a20_mask = ~(1 << 20) | (a20_state << 20); 129 } 130 } 131 132 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0) 133 { 134 X86CPU *cpu = env_archcpu(env); 135 int pe_state; 136 137 qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0); 138 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) != 139 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) { 140 tlb_flush(CPU(cpu)); 141 } 142 143 #ifdef TARGET_X86_64 144 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) && 145 (env->efer & MSR_EFER_LME)) { 146 /* enter in long mode */ 147 /* XXX: generate an exception */ 148 if (!(env->cr[4] & CR4_PAE_MASK)) 149 return; 150 env->efer |= MSR_EFER_LMA; 151 env->hflags |= HF_LMA_MASK; 152 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) && 153 (env->efer & MSR_EFER_LMA)) { 154 /* exit long mode */ 155 env->efer &= ~MSR_EFER_LMA; 156 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK); 157 env->eip &= 0xffffffff; 158 } 159 #endif 160 env->cr[0] = new_cr0 | CR0_ET_MASK; 161 162 /* update PE flag in hidden flags */ 163 pe_state = (env->cr[0] & CR0_PE_MASK); 164 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT); 165 /* ensure that ADDSEG is always set in real mode */ 166 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT); 167 /* update FPU flags */ 168 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) | 169 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)); 170 } 171 172 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in 173 the PDPT */ 174 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3) 175 { 176 env->cr[3] = new_cr3; 177 if (env->cr[0] & CR0_PG_MASK) { 178 qemu_log_mask(CPU_LOG_MMU, 179 "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3); 180 tlb_flush(env_cpu(env)); 181 } 182 } 183 184 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4) 185 { 186 uint32_t hflags; 187 188 #if defined(DEBUG_MMU) 189 printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4); 190 #endif 191 if ((new_cr4 ^ env->cr[4]) & 192 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK | 193 CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) { 194 tlb_flush(env_cpu(env)); 195 } 196 197 /* Clear bits we're going to recompute. */ 198 hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK | HF_UMIP_MASK); 199 200 /* SSE handling */ 201 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) { 202 new_cr4 &= ~CR4_OSFXSR_MASK; 203 } 204 if (new_cr4 & CR4_OSFXSR_MASK) { 205 hflags |= HF_OSFXSR_MASK; 206 } 207 208 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) { 209 new_cr4 &= ~CR4_SMAP_MASK; 210 } 211 if (new_cr4 & CR4_SMAP_MASK) { 212 hflags |= HF_SMAP_MASK; 213 } 214 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_UMIP)) { 215 new_cr4 &= ~CR4_UMIP_MASK; 216 } 217 if (new_cr4 & CR4_UMIP_MASK) { 218 hflags |= HF_UMIP_MASK; 219 } 220 221 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) { 222 new_cr4 &= ~CR4_PKE_MASK; 223 } 224 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKS)) { 225 new_cr4 &= ~CR4_PKS_MASK; 226 } 227 228 if (!(env->features[FEAT_7_1_EAX] & CPUID_7_1_EAX_LAM)) { 229 new_cr4 &= ~CR4_LAM_SUP_MASK; 230 } 231 232 env->cr[4] = new_cr4; 233 env->hflags = hflags; 234 235 cpu_sync_bndcs_hflags(env); 236 cpu_sync_avx_hflag(env); 237 } 238 239 #if !defined(CONFIG_USER_ONLY) 240 hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr, 241 MemTxAttrs *attrs) 242 { 243 X86CPU *cpu = X86_CPU(cs); 244 CPUX86State *env = &cpu->env; 245 target_ulong pde_addr, pte_addr; 246 uint64_t pte; 247 int32_t a20_mask; 248 uint32_t page_offset; 249 int page_size; 250 251 *attrs = cpu_get_mem_attrs(env); 252 253 a20_mask = x86_get_a20_mask(env); 254 if (!(env->cr[0] & CR0_PG_MASK)) { 255 pte = addr & a20_mask; 256 page_size = 4096; 257 } else if (env->cr[4] & CR4_PAE_MASK) { 258 target_ulong pdpe_addr; 259 uint64_t pde, pdpe; 260 261 #ifdef TARGET_X86_64 262 if (env->hflags & HF_LMA_MASK) { 263 bool la57 = env->cr[4] & CR4_LA57_MASK; 264 uint64_t pml5e_addr, pml5e; 265 uint64_t pml4e_addr, pml4e; 266 int32_t sext; 267 268 /* test virtual address sign extension */ 269 sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; 270 if (sext != 0 && sext != -1) { 271 return -1; 272 } 273 274 if (la57) { 275 pml5e_addr = ((env->cr[3] & ~0xfff) + 276 (((addr >> 48) & 0x1ff) << 3)) & a20_mask; 277 pml5e = x86_ldq_phys(cs, pml5e_addr); 278 if (!(pml5e & PG_PRESENT_MASK)) { 279 return -1; 280 } 281 } else { 282 pml5e = env->cr[3]; 283 } 284 285 pml4e_addr = ((pml5e & PG_ADDRESS_MASK) + 286 (((addr >> 39) & 0x1ff) << 3)) & a20_mask; 287 pml4e = x86_ldq_phys(cs, pml4e_addr); 288 if (!(pml4e & PG_PRESENT_MASK)) { 289 return -1; 290 } 291 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + 292 (((addr >> 30) & 0x1ff) << 3)) & a20_mask; 293 pdpe = x86_ldq_phys(cs, pdpe_addr); 294 if (!(pdpe & PG_PRESENT_MASK)) { 295 return -1; 296 } 297 if (pdpe & PG_PSE_MASK) { 298 page_size = 1024 * 1024 * 1024; 299 pte = pdpe; 300 goto out; 301 } 302 303 } else 304 #endif 305 { 306 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & 307 a20_mask; 308 pdpe = x86_ldq_phys(cs, pdpe_addr); 309 if (!(pdpe & PG_PRESENT_MASK)) 310 return -1; 311 } 312 313 pde_addr = ((pdpe & PG_ADDRESS_MASK) + 314 (((addr >> 21) & 0x1ff) << 3)) & a20_mask; 315 pde = x86_ldq_phys(cs, pde_addr); 316 if (!(pde & PG_PRESENT_MASK)) { 317 return -1; 318 } 319 if (pde & PG_PSE_MASK) { 320 /* 2 MB page */ 321 page_size = 2048 * 1024; 322 pte = pde; 323 } else { 324 /* 4 KB page */ 325 pte_addr = ((pde & PG_ADDRESS_MASK) + 326 (((addr >> 12) & 0x1ff) << 3)) & a20_mask; 327 page_size = 4096; 328 pte = x86_ldq_phys(cs, pte_addr); 329 } 330 if (!(pte & PG_PRESENT_MASK)) { 331 return -1; 332 } 333 } else { 334 uint32_t pde; 335 336 /* page directory entry */ 337 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask; 338 pde = x86_ldl_phys(cs, pde_addr); 339 if (!(pde & PG_PRESENT_MASK)) 340 return -1; 341 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { 342 pte = pde | ((pde & 0x1fe000LL) << (32 - 13)); 343 page_size = 4096 * 1024; 344 } else { 345 /* page directory entry */ 346 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask; 347 pte = x86_ldl_phys(cs, pte_addr); 348 if (!(pte & PG_PRESENT_MASK)) { 349 return -1; 350 } 351 page_size = 4096; 352 } 353 pte = pte & a20_mask; 354 } 355 356 #ifdef TARGET_X86_64 357 out: 358 #endif 359 pte &= PG_ADDRESS_MASK & ~(page_size - 1); 360 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); 361 return pte | page_offset; 362 } 363 364 typedef struct MCEInjectionParams { 365 Monitor *mon; 366 int bank; 367 uint64_t status; 368 uint64_t mcg_status; 369 uint64_t addr; 370 uint64_t misc; 371 int flags; 372 } MCEInjectionParams; 373 374 static void emit_guest_memory_failure(MemoryFailureAction action, bool ar, 375 bool recursive) 376 { 377 MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive}; 378 379 qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action, 380 &mff); 381 } 382 383 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data) 384 { 385 MCEInjectionParams *params = data.host_ptr; 386 X86CPU *cpu = X86_CPU(cs); 387 CPUX86State *cenv = &cpu->env; 388 uint64_t *banks = cenv->mce_banks + 4 * params->bank; 389 g_autofree char *msg = NULL; 390 bool need_reset = false; 391 bool recursive; 392 bool ar = !!(params->status & MCI_STATUS_AR); 393 394 cpu_synchronize_state(cs); 395 recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP); 396 397 /* 398 * If there is an MCE exception being processed, ignore this SRAO MCE 399 * unless unconditional injection was requested. 400 */ 401 if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) { 402 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive); 403 return; 404 } 405 406 if (params->status & MCI_STATUS_UC) { 407 /* 408 * if MSR_MCG_CTL is not all 1s, the uncorrected error 409 * reporting is disabled 410 */ 411 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) { 412 monitor_printf(params->mon, 413 "CPU %d: Uncorrected error reporting disabled\n", 414 cs->cpu_index); 415 return; 416 } 417 418 /* 419 * if MSR_MCi_CTL is not all 1s, the uncorrected error 420 * reporting is disabled for the bank 421 */ 422 if (banks[0] != ~(uint64_t)0) { 423 monitor_printf(params->mon, 424 "CPU %d: Uncorrected error reporting disabled for" 425 " bank %d\n", 426 cs->cpu_index, params->bank); 427 return; 428 } 429 430 if (!(cenv->cr[4] & CR4_MCE_MASK)) { 431 need_reset = true; 432 msg = g_strdup_printf("CPU %d: MCE capability is not enabled, " 433 "raising triple fault", cs->cpu_index); 434 } else if (recursive) { 435 need_reset = true; 436 msg = g_strdup_printf("CPU %d: Previous MCE still in progress, " 437 "raising triple fault", cs->cpu_index); 438 } 439 440 if (need_reset) { 441 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar, 442 recursive); 443 monitor_printf(params->mon, "%s", msg); 444 qemu_log_mask(CPU_LOG_RESET, "%s\n", msg); 445 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); 446 return; 447 } 448 449 if (banks[1] & MCI_STATUS_VAL) { 450 params->status |= MCI_STATUS_OVER; 451 } 452 banks[2] = params->addr; 453 banks[3] = params->misc; 454 cenv->mcg_status = params->mcg_status; 455 banks[1] = params->status; 456 cpu_interrupt(cs, CPU_INTERRUPT_MCE); 457 } else if (!(banks[1] & MCI_STATUS_VAL) 458 || !(banks[1] & MCI_STATUS_UC)) { 459 if (banks[1] & MCI_STATUS_VAL) { 460 params->status |= MCI_STATUS_OVER; 461 } 462 banks[2] = params->addr; 463 banks[3] = params->misc; 464 banks[1] = params->status; 465 } else { 466 banks[1] |= MCI_STATUS_OVER; 467 } 468 469 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive); 470 } 471 472 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, 473 uint64_t status, uint64_t mcg_status, uint64_t addr, 474 uint64_t misc, int flags) 475 { 476 CPUState *cs = CPU(cpu); 477 CPUX86State *cenv = &cpu->env; 478 MCEInjectionParams params = { 479 .mon = mon, 480 .bank = bank, 481 .status = status, 482 .mcg_status = mcg_status, 483 .addr = addr, 484 .misc = misc, 485 .flags = flags, 486 }; 487 unsigned bank_num = cenv->mcg_cap & 0xff; 488 489 if (!cenv->mcg_cap) { 490 monitor_printf(mon, "MCE injection not supported\n"); 491 return; 492 } 493 if (bank >= bank_num) { 494 monitor_printf(mon, "Invalid MCE bank number\n"); 495 return; 496 } 497 if (!(status & MCI_STATUS_VAL)) { 498 monitor_printf(mon, "Invalid MCE status code\n"); 499 return; 500 } 501 if ((flags & MCE_INJECT_BROADCAST) 502 && !cpu_x86_support_mca_broadcast(cenv)) { 503 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n"); 504 return; 505 } 506 507 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms)); 508 if (flags & MCE_INJECT_BROADCAST) { 509 CPUState *other_cs; 510 511 params.bank = 1; 512 params.status = MCI_STATUS_VAL | MCI_STATUS_UC; 513 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; 514 params.addr = 0; 515 params.misc = 0; 516 CPU_FOREACH(other_cs) { 517 if (other_cs == cs) { 518 continue; 519 } 520 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(¶ms)); 521 } 522 } 523 } 524 525 static inline target_ulong get_memio_eip(CPUX86State *env) 526 { 527 #ifdef CONFIG_TCG 528 uint64_t data[TARGET_INSN_START_WORDS]; 529 CPUState *cs = env_cpu(env); 530 531 if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { 532 return env->eip; 533 } 534 535 /* Per x86_restore_state_to_opc. */ 536 if (tcg_cflags_has(cs, CF_PCREL)) { 537 return (env->eip & TARGET_PAGE_MASK) | data[0]; 538 } else { 539 return data[0] - env->segs[R_CS].base; 540 } 541 #else 542 qemu_build_not_reached(); 543 #endif 544 } 545 546 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) 547 { 548 X86CPU *cpu = env_archcpu(env); 549 CPUState *cs = env_cpu(env); 550 551 if (kvm_enabled() || whpx_enabled() || nvmm_enabled()) { 552 env->tpr_access_type = access; 553 554 cpu_interrupt(cs, CPU_INTERRUPT_TPR); 555 } else if (tcg_enabled()) { 556 target_ulong eip = get_memio_eip(env); 557 558 apic_handle_tpr_access_report(cpu->apic_state, eip, access); 559 } 560 } 561 #endif /* !CONFIG_USER_ONLY */ 562 563 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, 564 target_ulong *base, unsigned int *limit, 565 unsigned int *flags) 566 { 567 CPUState *cs = env_cpu(env); 568 SegmentCache *dt; 569 target_ulong ptr; 570 uint32_t e1, e2; 571 int index; 572 573 if (selector & 0x4) 574 dt = &env->ldt; 575 else 576 dt = &env->gdt; 577 index = selector & ~7; 578 ptr = dt->base + index; 579 if ((index + 7) > dt->limit 580 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0 581 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0) 582 return 0; 583 584 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000)); 585 *limit = (e1 & 0xffff) | (e2 & 0x000f0000); 586 if (e2 & DESC_G_MASK) 587 *limit = (*limit << 12) | 0xfff; 588 *flags = e2; 589 590 return 1; 591 } 592 593 void do_cpu_init(X86CPU *cpu) 594 { 595 #if !defined(CONFIG_USER_ONLY) 596 CPUState *cs = CPU(cpu); 597 CPUX86State *env = &cpu->env; 598 CPUX86State *save = g_new(CPUX86State, 1); 599 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI; 600 601 *save = *env; 602 603 cpu_reset(cs); 604 cs->interrupt_request = sipi; 605 memcpy(&env->start_init_save, &save->start_init_save, 606 offsetof(CPUX86State, end_init_save) - 607 offsetof(CPUX86State, start_init_save)); 608 g_free(save); 609 610 if (kvm_enabled()) { 611 kvm_arch_do_init_vcpu(cpu); 612 } 613 apic_init_reset(cpu->apic_state); 614 #endif /* CONFIG_USER_ONLY */ 615 } 616 617 #ifndef CONFIG_USER_ONLY 618 619 void do_cpu_sipi(X86CPU *cpu) 620 { 621 apic_sipi(cpu->apic_state); 622 } 623 624 void cpu_load_efer(CPUX86State *env, uint64_t val) 625 { 626 env->efer = val; 627 env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); 628 if (env->efer & MSR_EFER_LMA) { 629 env->hflags |= HF_LMA_MASK; 630 } 631 if (env->efer & MSR_EFER_SVME) { 632 env->hflags |= HF_SVME_MASK; 633 } 634 } 635 636 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr) 637 { 638 X86CPU *cpu = X86_CPU(cs); 639 CPUX86State *env = &cpu->env; 640 MemTxAttrs attrs = cpu_get_mem_attrs(env); 641 AddressSpace *as = cpu_addressspace(cs, attrs); 642 643 return address_space_ldub(as, addr, attrs, NULL); 644 } 645 646 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr) 647 { 648 X86CPU *cpu = X86_CPU(cs); 649 CPUX86State *env = &cpu->env; 650 MemTxAttrs attrs = cpu_get_mem_attrs(env); 651 AddressSpace *as = cpu_addressspace(cs, attrs); 652 653 return address_space_lduw(as, addr, attrs, NULL); 654 } 655 656 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr) 657 { 658 X86CPU *cpu = X86_CPU(cs); 659 CPUX86State *env = &cpu->env; 660 MemTxAttrs attrs = cpu_get_mem_attrs(env); 661 AddressSpace *as = cpu_addressspace(cs, attrs); 662 663 return address_space_ldl(as, addr, attrs, NULL); 664 } 665 666 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr) 667 { 668 X86CPU *cpu = X86_CPU(cs); 669 CPUX86State *env = &cpu->env; 670 MemTxAttrs attrs = cpu_get_mem_attrs(env); 671 AddressSpace *as = cpu_addressspace(cs, attrs); 672 673 return address_space_ldq(as, addr, attrs, NULL); 674 } 675 676 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val) 677 { 678 X86CPU *cpu = X86_CPU(cs); 679 CPUX86State *env = &cpu->env; 680 MemTxAttrs attrs = cpu_get_mem_attrs(env); 681 AddressSpace *as = cpu_addressspace(cs, attrs); 682 683 address_space_stb(as, addr, val, attrs, NULL); 684 } 685 686 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val) 687 { 688 X86CPU *cpu = X86_CPU(cs); 689 CPUX86State *env = &cpu->env; 690 MemTxAttrs attrs = cpu_get_mem_attrs(env); 691 AddressSpace *as = cpu_addressspace(cs, attrs); 692 693 address_space_stl_notdirty(as, addr, val, attrs, NULL); 694 } 695 696 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val) 697 { 698 X86CPU *cpu = X86_CPU(cs); 699 CPUX86State *env = &cpu->env; 700 MemTxAttrs attrs = cpu_get_mem_attrs(env); 701 AddressSpace *as = cpu_addressspace(cs, attrs); 702 703 address_space_stw(as, addr, val, attrs, NULL); 704 } 705 706 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val) 707 { 708 X86CPU *cpu = X86_CPU(cs); 709 CPUX86State *env = &cpu->env; 710 MemTxAttrs attrs = cpu_get_mem_attrs(env); 711 AddressSpace *as = cpu_addressspace(cs, attrs); 712 713 address_space_stl(as, addr, val, attrs, NULL); 714 } 715 716 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val) 717 { 718 X86CPU *cpu = X86_CPU(cs); 719 CPUX86State *env = &cpu->env; 720 MemTxAttrs attrs = cpu_get_mem_attrs(env); 721 AddressSpace *as = cpu_addressspace(cs, attrs); 722 723 address_space_stq(as, addr, val, attrs, NULL); 724 } 725 #endif 726