1 /* 2 * x86 misc helpers 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 "qemu/main-loop.h" 22 #include "cpu.h" 23 #include "exec/helper-proto.h" 24 #include "exec/exec-all.h" 25 #include "exec/cpu_ldst.h" 26 #include "exec/address-spaces.h" 27 #include "helper-tcg.h" 28 29 /* 30 * NOTE: the translator must set DisasContext.cc_op to CC_OP_EFLAGS 31 * after generating a call to a helper that uses this. 32 */ 33 void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask) 34 { 35 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); 36 CC_OP = CC_OP_EFLAGS; 37 env->df = 1 - (2 * ((eflags >> 10) & 1)); 38 env->eflags = (env->eflags & ~update_mask) | 39 (eflags & update_mask) | 0x2; 40 } 41 42 void helper_outb(CPUX86State *env, uint32_t port, uint32_t data) 43 { 44 #ifdef CONFIG_USER_ONLY 45 fprintf(stderr, "outb: port=0x%04x, data=%02x\n", port, data); 46 #else 47 address_space_stb(&address_space_io, port, data, 48 cpu_get_mem_attrs(env), NULL); 49 #endif 50 } 51 52 target_ulong helper_inb(CPUX86State *env, uint32_t port) 53 { 54 #ifdef CONFIG_USER_ONLY 55 fprintf(stderr, "inb: port=0x%04x\n", port); 56 return 0; 57 #else 58 return address_space_ldub(&address_space_io, port, 59 cpu_get_mem_attrs(env), NULL); 60 #endif 61 } 62 63 void helper_outw(CPUX86State *env, uint32_t port, uint32_t data) 64 { 65 #ifdef CONFIG_USER_ONLY 66 fprintf(stderr, "outw: port=0x%04x, data=%04x\n", port, data); 67 #else 68 address_space_stw(&address_space_io, port, data, 69 cpu_get_mem_attrs(env), NULL); 70 #endif 71 } 72 73 target_ulong helper_inw(CPUX86State *env, uint32_t port) 74 { 75 #ifdef CONFIG_USER_ONLY 76 fprintf(stderr, "inw: port=0x%04x\n", port); 77 return 0; 78 #else 79 return address_space_lduw(&address_space_io, port, 80 cpu_get_mem_attrs(env), NULL); 81 #endif 82 } 83 84 void helper_outl(CPUX86State *env, uint32_t port, uint32_t data) 85 { 86 #ifdef CONFIG_USER_ONLY 87 fprintf(stderr, "outl: port=0x%04x, data=%08x\n", port, data); 88 #else 89 address_space_stl(&address_space_io, port, data, 90 cpu_get_mem_attrs(env), NULL); 91 #endif 92 } 93 94 target_ulong helper_inl(CPUX86State *env, uint32_t port) 95 { 96 #ifdef CONFIG_USER_ONLY 97 fprintf(stderr, "inl: port=0x%04x\n", port); 98 return 0; 99 #else 100 return address_space_ldl(&address_space_io, port, 101 cpu_get_mem_attrs(env), NULL); 102 #endif 103 } 104 105 void helper_into(CPUX86State *env, int next_eip_addend) 106 { 107 int eflags; 108 109 eflags = cpu_cc_compute_all(env, CC_OP); 110 if (eflags & CC_O) { 111 raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend); 112 } 113 } 114 115 void helper_cpuid(CPUX86State *env) 116 { 117 uint32_t eax, ebx, ecx, edx; 118 119 cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0, GETPC()); 120 121 cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX], 122 &eax, &ebx, &ecx, &edx); 123 env->regs[R_EAX] = eax; 124 env->regs[R_EBX] = ebx; 125 env->regs[R_ECX] = ecx; 126 env->regs[R_EDX] = edx; 127 } 128 129 #if defined(CONFIG_USER_ONLY) 130 target_ulong helper_read_crN(CPUX86State *env, int reg) 131 { 132 return 0; 133 } 134 135 void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) 136 { 137 } 138 #else 139 target_ulong helper_read_crN(CPUX86State *env, int reg) 140 { 141 target_ulong val; 142 143 cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC()); 144 switch (reg) { 145 default: 146 val = env->cr[reg]; 147 break; 148 case 8: 149 if (!(env->hflags2 & HF2_VINTR_MASK)) { 150 val = cpu_get_apic_tpr(env_archcpu(env)->apic_state); 151 } else { 152 val = env->v_tpr; 153 } 154 break; 155 } 156 return val; 157 } 158 159 void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) 160 { 161 cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC()); 162 switch (reg) { 163 case 0: 164 cpu_x86_update_cr0(env, t0); 165 break; 166 case 3: 167 cpu_x86_update_cr3(env, t0); 168 break; 169 case 4: 170 cpu_x86_update_cr4(env, t0); 171 break; 172 case 8: 173 if (!(env->hflags2 & HF2_VINTR_MASK)) { 174 qemu_mutex_lock_iothread(); 175 cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0); 176 qemu_mutex_unlock_iothread(); 177 } 178 env->v_tpr = t0 & 0x0f; 179 break; 180 default: 181 env->cr[reg] = t0; 182 break; 183 } 184 } 185 #endif 186 187 void helper_lmsw(CPUX86State *env, target_ulong t0) 188 { 189 /* only 4 lower bits of CR0 are modified. PE cannot be set to zero 190 if already set to one. */ 191 t0 = (env->cr[0] & ~0xe) | (t0 & 0xf); 192 helper_write_crN(env, 0, t0); 193 } 194 195 void helper_invlpg(CPUX86State *env, target_ulong addr) 196 { 197 X86CPU *cpu = env_archcpu(env); 198 199 cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC()); 200 tlb_flush_page(CPU(cpu), addr); 201 } 202 203 void helper_rdtsc(CPUX86State *env) 204 { 205 uint64_t val; 206 207 if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { 208 raise_exception_ra(env, EXCP0D_GPF, GETPC()); 209 } 210 cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0, GETPC()); 211 212 val = cpu_get_tsc(env) + env->tsc_offset; 213 env->regs[R_EAX] = (uint32_t)(val); 214 env->regs[R_EDX] = (uint32_t)(val >> 32); 215 } 216 217 void helper_rdtscp(CPUX86State *env) 218 { 219 helper_rdtsc(env); 220 env->regs[R_ECX] = (uint32_t)(env->tsc_aux); 221 } 222 223 void helper_rdpmc(CPUX86State *env) 224 { 225 if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) { 226 raise_exception_ra(env, EXCP0D_GPF, GETPC()); 227 } 228 cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC()); 229 230 /* currently unimplemented */ 231 qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n"); 232 raise_exception_err(env, EXCP06_ILLOP, 0); 233 } 234 235 #if defined(CONFIG_USER_ONLY) 236 void helper_wrmsr(CPUX86State *env) 237 { 238 } 239 240 void helper_rdmsr(CPUX86State *env) 241 { 242 } 243 #else 244 void helper_wrmsr(CPUX86State *env) 245 { 246 uint64_t val; 247 CPUState *cs = env_cpu(env); 248 249 cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC()); 250 251 val = ((uint32_t)env->regs[R_EAX]) | 252 ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); 253 254 switch ((uint32_t)env->regs[R_ECX]) { 255 case MSR_IA32_SYSENTER_CS: 256 env->sysenter_cs = val & 0xffff; 257 break; 258 case MSR_IA32_SYSENTER_ESP: 259 env->sysenter_esp = val; 260 break; 261 case MSR_IA32_SYSENTER_EIP: 262 env->sysenter_eip = val; 263 break; 264 case MSR_IA32_APICBASE: 265 cpu_set_apic_base(env_archcpu(env)->apic_state, val); 266 break; 267 case MSR_EFER: 268 { 269 uint64_t update_mask; 270 271 update_mask = 0; 272 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) { 273 update_mask |= MSR_EFER_SCE; 274 } 275 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { 276 update_mask |= MSR_EFER_LME; 277 } 278 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { 279 update_mask |= MSR_EFER_FFXSR; 280 } 281 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) { 282 update_mask |= MSR_EFER_NXE; 283 } 284 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { 285 update_mask |= MSR_EFER_SVME; 286 } 287 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { 288 update_mask |= MSR_EFER_FFXSR; 289 } 290 cpu_load_efer(env, (env->efer & ~update_mask) | 291 (val & update_mask)); 292 } 293 break; 294 case MSR_STAR: 295 env->star = val; 296 break; 297 case MSR_PAT: 298 env->pat = val; 299 break; 300 case MSR_IA32_PKRS: 301 if (val & 0xFFFFFFFF00000000ull) { 302 goto error; 303 } 304 env->pkrs = val; 305 tlb_flush(cs); 306 break; 307 case MSR_VM_HSAVE_PA: 308 env->vm_hsave = val; 309 break; 310 #ifdef TARGET_X86_64 311 case MSR_LSTAR: 312 env->lstar = val; 313 break; 314 case MSR_CSTAR: 315 env->cstar = val; 316 break; 317 case MSR_FMASK: 318 env->fmask = val; 319 break; 320 case MSR_FSBASE: 321 env->segs[R_FS].base = val; 322 break; 323 case MSR_GSBASE: 324 env->segs[R_GS].base = val; 325 break; 326 case MSR_KERNELGSBASE: 327 env->kernelgsbase = val; 328 break; 329 #endif 330 case MSR_MTRRphysBase(0): 331 case MSR_MTRRphysBase(1): 332 case MSR_MTRRphysBase(2): 333 case MSR_MTRRphysBase(3): 334 case MSR_MTRRphysBase(4): 335 case MSR_MTRRphysBase(5): 336 case MSR_MTRRphysBase(6): 337 case MSR_MTRRphysBase(7): 338 env->mtrr_var[((uint32_t)env->regs[R_ECX] - 339 MSR_MTRRphysBase(0)) / 2].base = val; 340 break; 341 case MSR_MTRRphysMask(0): 342 case MSR_MTRRphysMask(1): 343 case MSR_MTRRphysMask(2): 344 case MSR_MTRRphysMask(3): 345 case MSR_MTRRphysMask(4): 346 case MSR_MTRRphysMask(5): 347 case MSR_MTRRphysMask(6): 348 case MSR_MTRRphysMask(7): 349 env->mtrr_var[((uint32_t)env->regs[R_ECX] - 350 MSR_MTRRphysMask(0)) / 2].mask = val; 351 break; 352 case MSR_MTRRfix64K_00000: 353 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - 354 MSR_MTRRfix64K_00000] = val; 355 break; 356 case MSR_MTRRfix16K_80000: 357 case MSR_MTRRfix16K_A0000: 358 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - 359 MSR_MTRRfix16K_80000 + 1] = val; 360 break; 361 case MSR_MTRRfix4K_C0000: 362 case MSR_MTRRfix4K_C8000: 363 case MSR_MTRRfix4K_D0000: 364 case MSR_MTRRfix4K_D8000: 365 case MSR_MTRRfix4K_E0000: 366 case MSR_MTRRfix4K_E8000: 367 case MSR_MTRRfix4K_F0000: 368 case MSR_MTRRfix4K_F8000: 369 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - 370 MSR_MTRRfix4K_C0000 + 3] = val; 371 break; 372 case MSR_MTRRdefType: 373 env->mtrr_deftype = val; 374 break; 375 case MSR_MCG_STATUS: 376 env->mcg_status = val; 377 break; 378 case MSR_MCG_CTL: 379 if ((env->mcg_cap & MCG_CTL_P) 380 && (val == 0 || val == ~(uint64_t)0)) { 381 env->mcg_ctl = val; 382 } 383 break; 384 case MSR_TSC_AUX: 385 env->tsc_aux = val; 386 break; 387 case MSR_IA32_MISC_ENABLE: 388 env->msr_ia32_misc_enable = val; 389 break; 390 case MSR_IA32_BNDCFGS: 391 /* FIXME: #GP if reserved bits are set. */ 392 /* FIXME: Extend highest implemented bit of linear address. */ 393 env->msr_bndcfgs = val; 394 cpu_sync_bndcs_hflags(env); 395 break; 396 default: 397 if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL 398 && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + 399 (4 * env->mcg_cap & 0xff)) { 400 uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; 401 if ((offset & 0x3) != 0 402 || (val == 0 || val == ~(uint64_t)0)) { 403 env->mce_banks[offset] = val; 404 } 405 break; 406 } 407 /* XXX: exception? */ 408 break; 409 } 410 return; 411 error: 412 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 413 } 414 415 void helper_rdmsr(CPUX86State *env) 416 { 417 X86CPU *x86_cpu = env_archcpu(env); 418 uint64_t val; 419 420 cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC()); 421 422 switch ((uint32_t)env->regs[R_ECX]) { 423 case MSR_IA32_SYSENTER_CS: 424 val = env->sysenter_cs; 425 break; 426 case MSR_IA32_SYSENTER_ESP: 427 val = env->sysenter_esp; 428 break; 429 case MSR_IA32_SYSENTER_EIP: 430 val = env->sysenter_eip; 431 break; 432 case MSR_IA32_APICBASE: 433 val = cpu_get_apic_base(env_archcpu(env)->apic_state); 434 break; 435 case MSR_EFER: 436 val = env->efer; 437 break; 438 case MSR_STAR: 439 val = env->star; 440 break; 441 case MSR_PAT: 442 val = env->pat; 443 break; 444 case MSR_IA32_PKRS: 445 val = env->pkrs; 446 break; 447 case MSR_VM_HSAVE_PA: 448 val = env->vm_hsave; 449 break; 450 case MSR_IA32_PERF_STATUS: 451 /* tsc_increment_by_tick */ 452 val = 1000ULL; 453 /* CPU multiplier */ 454 val |= (((uint64_t)4ULL) << 40); 455 break; 456 #ifdef TARGET_X86_64 457 case MSR_LSTAR: 458 val = env->lstar; 459 break; 460 case MSR_CSTAR: 461 val = env->cstar; 462 break; 463 case MSR_FMASK: 464 val = env->fmask; 465 break; 466 case MSR_FSBASE: 467 val = env->segs[R_FS].base; 468 break; 469 case MSR_GSBASE: 470 val = env->segs[R_GS].base; 471 break; 472 case MSR_KERNELGSBASE: 473 val = env->kernelgsbase; 474 break; 475 case MSR_TSC_AUX: 476 val = env->tsc_aux; 477 break; 478 #endif 479 case MSR_SMI_COUNT: 480 val = env->msr_smi_count; 481 break; 482 case MSR_MTRRphysBase(0): 483 case MSR_MTRRphysBase(1): 484 case MSR_MTRRphysBase(2): 485 case MSR_MTRRphysBase(3): 486 case MSR_MTRRphysBase(4): 487 case MSR_MTRRphysBase(5): 488 case MSR_MTRRphysBase(6): 489 case MSR_MTRRphysBase(7): 490 val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - 491 MSR_MTRRphysBase(0)) / 2].base; 492 break; 493 case MSR_MTRRphysMask(0): 494 case MSR_MTRRphysMask(1): 495 case MSR_MTRRphysMask(2): 496 case MSR_MTRRphysMask(3): 497 case MSR_MTRRphysMask(4): 498 case MSR_MTRRphysMask(5): 499 case MSR_MTRRphysMask(6): 500 case MSR_MTRRphysMask(7): 501 val = env->mtrr_var[((uint32_t)env->regs[R_ECX] - 502 MSR_MTRRphysMask(0)) / 2].mask; 503 break; 504 case MSR_MTRRfix64K_00000: 505 val = env->mtrr_fixed[0]; 506 break; 507 case MSR_MTRRfix16K_80000: 508 case MSR_MTRRfix16K_A0000: 509 val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - 510 MSR_MTRRfix16K_80000 + 1]; 511 break; 512 case MSR_MTRRfix4K_C0000: 513 case MSR_MTRRfix4K_C8000: 514 case MSR_MTRRfix4K_D0000: 515 case MSR_MTRRfix4K_D8000: 516 case MSR_MTRRfix4K_E0000: 517 case MSR_MTRRfix4K_E8000: 518 case MSR_MTRRfix4K_F0000: 519 case MSR_MTRRfix4K_F8000: 520 val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - 521 MSR_MTRRfix4K_C0000 + 3]; 522 break; 523 case MSR_MTRRdefType: 524 val = env->mtrr_deftype; 525 break; 526 case MSR_MTRRcap: 527 if (env->features[FEAT_1_EDX] & CPUID_MTRR) { 528 val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | 529 MSR_MTRRcap_WC_SUPPORTED; 530 } else { 531 /* XXX: exception? */ 532 val = 0; 533 } 534 break; 535 case MSR_MCG_CAP: 536 val = env->mcg_cap; 537 break; 538 case MSR_MCG_CTL: 539 if (env->mcg_cap & MCG_CTL_P) { 540 val = env->mcg_ctl; 541 } else { 542 val = 0; 543 } 544 break; 545 case MSR_MCG_STATUS: 546 val = env->mcg_status; 547 break; 548 case MSR_IA32_MISC_ENABLE: 549 val = env->msr_ia32_misc_enable; 550 break; 551 case MSR_IA32_BNDCFGS: 552 val = env->msr_bndcfgs; 553 break; 554 case MSR_IA32_UCODE_REV: 555 val = x86_cpu->ucode_rev; 556 break; 557 default: 558 if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL 559 && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + 560 (4 * env->mcg_cap & 0xff)) { 561 uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; 562 val = env->mce_banks[offset]; 563 break; 564 } 565 /* XXX: exception? */ 566 val = 0; 567 break; 568 } 569 env->regs[R_EAX] = (uint32_t)(val); 570 env->regs[R_EDX] = (uint32_t)(val >> 32); 571 } 572 #endif 573 574 static void do_pause(X86CPU *cpu) 575 { 576 CPUState *cs = CPU(cpu); 577 578 /* Just let another CPU run. */ 579 cs->exception_index = EXCP_INTERRUPT; 580 cpu_loop_exit(cs); 581 } 582 583 static void do_hlt(X86CPU *cpu) 584 { 585 CPUState *cs = CPU(cpu); 586 CPUX86State *env = &cpu->env; 587 588 env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */ 589 cs->halted = 1; 590 cs->exception_index = EXCP_HLT; 591 cpu_loop_exit(cs); 592 } 593 594 void helper_hlt(CPUX86State *env, int next_eip_addend) 595 { 596 X86CPU *cpu = env_archcpu(env); 597 598 cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC()); 599 env->eip += next_eip_addend; 600 601 do_hlt(cpu); 602 } 603 604 void helper_monitor(CPUX86State *env, target_ulong ptr) 605 { 606 if ((uint32_t)env->regs[R_ECX] != 0) { 607 raise_exception_ra(env, EXCP0D_GPF, GETPC()); 608 } 609 /* XXX: store address? */ 610 cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC()); 611 } 612 613 void helper_mwait(CPUX86State *env, int next_eip_addend) 614 { 615 CPUState *cs = env_cpu(env); 616 X86CPU *cpu = env_archcpu(env); 617 618 if ((uint32_t)env->regs[R_ECX] != 0) { 619 raise_exception_ra(env, EXCP0D_GPF, GETPC()); 620 } 621 cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC()); 622 env->eip += next_eip_addend; 623 624 /* XXX: not complete but not completely erroneous */ 625 if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) { 626 do_pause(cpu); 627 } else { 628 do_hlt(cpu); 629 } 630 } 631 632 void helper_pause(CPUX86State *env, int next_eip_addend) 633 { 634 X86CPU *cpu = env_archcpu(env); 635 636 cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC()); 637 env->eip += next_eip_addend; 638 639 do_pause(cpu); 640 } 641 642 void helper_debug(CPUX86State *env) 643 { 644 CPUState *cs = env_cpu(env); 645 646 cs->exception_index = EXCP_DEBUG; 647 cpu_loop_exit(cs); 648 } 649 650 uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx) 651 { 652 if ((env->cr[4] & CR4_PKE_MASK) == 0) { 653 raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); 654 } 655 if (ecx != 0) { 656 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 657 } 658 659 return env->pkru; 660 } 661 662 void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val) 663 { 664 CPUState *cs = env_cpu(env); 665 666 if ((env->cr[4] & CR4_PKE_MASK) == 0) { 667 raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); 668 } 669 if (ecx != 0 || (val & 0xFFFFFFFF00000000ull)) { 670 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); 671 } 672 673 env->pkru = val; 674 tlb_flush(cs); 675 } 676