Changeset 47309 in vbox for trunk/src/recompiler
- Timestamp:
- Jul 22, 2013 2:42:08 PM (11 years ago)
- Location:
- trunk/src/recompiler
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/VBoxRecompiler.c
r46493 r47309 83 83 /** How remR3RunLoggingStep operates. */ 84 84 #define REM_USE_QEMU_SINGLE_STEP_FOR_LOGGING 85 86 87 /** Selector flag shift between qemu and VBox. 88 * VBox shifts the qemu bits to the right. */ 89 #define SEL_FLAGS_SHIFT (8) 90 /** Mask applied to the shifted qemu selector flags to get the attributes VBox 91 * (VT-x) needs. */ 92 #define SEL_FLAGS_SMASK UINT32_C(0x1F0FF) 85 93 86 94 … … 1403 1411 Ctx.tr.u64Base = env->tr.base; 1404 1412 Ctx.tr.u32Limit = env->tr.limit; 1405 Ctx.tr.Attr.u = (env->tr.flags >> 8) & 0xF0FF;1413 Ctx.tr.Attr.u = (env->tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1406 1414 1407 1415 Ctx.ldtr.Sel = env->ldt.selector; … … 1410 1418 Ctx.ldtr.u64Base = env->ldt.base; 1411 1419 Ctx.ldtr.u32Limit = env->ldt.limit; 1412 Ctx.ldtr.Attr.u = (env->ldt.flags >> 8) & 0xF0FF;1420 Ctx.ldtr.Attr.u = (env->ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1413 1421 1414 1422 Ctx.idtr.cbIdt = env->idt.limit; … … 1428 1436 Ctx.cs.u64Base = env->segs[R_CS].base; 1429 1437 Ctx.cs.u32Limit = env->segs[R_CS].limit; 1430 Ctx.cs.Attr.u = (env->segs[R_CS].flags >> 8) & 0xF0FF;1438 Ctx.cs.Attr.u = (env->segs[R_CS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1431 1439 1432 1440 Ctx.ds.Sel = env->segs[R_DS].selector; … … 1435 1443 Ctx.ds.u64Base = env->segs[R_DS].base; 1436 1444 Ctx.ds.u32Limit = env->segs[R_DS].limit; 1437 Ctx.ds.Attr.u = (env->segs[R_DS].flags >> 8) & 0xF0FF;1445 Ctx.ds.Attr.u = (env->segs[R_DS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1438 1446 1439 1447 Ctx.es.Sel = env->segs[R_ES].selector; … … 1442 1450 Ctx.es.u64Base = env->segs[R_ES].base; 1443 1451 Ctx.es.u32Limit = env->segs[R_ES].limit; 1444 Ctx.es.Attr.u = (env->segs[R_ES].flags >> 8) & 0xF0FF;1452 Ctx.es.Attr.u = (env->segs[R_ES].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1445 1453 1446 1454 Ctx.fs.Sel = env->segs[R_FS].selector; … … 1449 1457 Ctx.fs.u64Base = env->segs[R_FS].base; 1450 1458 Ctx.fs.u32Limit = env->segs[R_FS].limit; 1451 Ctx.fs.Attr.u = (env->segs[R_FS].flags >> 8) & 0xF0FF;1459 Ctx.fs.Attr.u = (env->segs[R_FS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1452 1460 1453 1461 Ctx.gs.Sel = env->segs[R_GS].selector; … … 1456 1464 Ctx.gs.u64Base = env->segs[R_GS].base; 1457 1465 Ctx.gs.u32Limit = env->segs[R_GS].limit; 1458 Ctx.gs.Attr.u = (env->segs[R_GS].flags >> 8) & 0xF0FF;1466 Ctx.gs.Attr.u = (env->segs[R_GS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1459 1467 1460 1468 Ctx.ss.Sel = env->segs[R_SS].selector; … … 1463 1471 Ctx.ss.u64Base = env->segs[R_SS].base; 1464 1472 Ctx.ss.u32Limit = env->segs[R_SS].limit; 1465 Ctx.ss.Attr.u = (env->segs[R_SS].flags >> 8) & 0xF0FF;1473 Ctx.ss.Attr.u = (env->segs[R_SS].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 1466 1474 1467 1475 Ctx.msrEFER = env->efer; … … 2317 2325 pVM->rem.s.Env.ldt.base = pCtx->ldtr.u64Base; 2318 2326 pVM->rem.s.Env.ldt.limit = pCtx->ldtr.u32Limit; 2319 pVM->rem.s.Env.ldt.flags = (pCtx->ldtr.Attr.u << 8) & 0xFFFFFF;2327 pVM->rem.s.Env.ldt.flags = (pCtx->ldtr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT; 2320 2328 } 2321 2329 else … … 2350 2358 pVM->rem.s.Env.tr.base = pCtx->tr.u64Base; 2351 2359 pVM->rem.s.Env.tr.limit = pCtx->tr.u32Limit; 2352 pVM->rem.s.Env.tr.flags = (pCtx->tr.Attr.u << 8) & 0xFFFFFF;2353 /* Note! do_interrupt will fault if the busy flag is still set... */ 2360 pVM->rem.s.Env.tr.flags = (pCtx->tr.Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT; 2361 /* Note! do_interrupt will fault if the busy flag is still set... */ /** @todo so fix do_interrupt then! */ 2354 2362 pVM->rem.s.Env.tr.flags &= ~DESC_TSS_BUSY_MASK; 2355 2363 … … 2375 2383 (a_pVBoxSReg)->u64Base, \ 2376 2384 (a_pVBoxSReg)->u32Limit, \ 2377 ((a_pVBoxSReg)->Attr.u << 8) & 0xFFFFFF); \2385 ((a_pVBoxSReg)->Attr.u & SEL_FLAGS_SMASK) << SEL_FLAGS_SHIFT); \ 2378 2386 (a_pRemSReg)->fVBoxFlags = (a_pVBoxSReg)->fFlags; \ 2379 2387 } \ … … 2574 2582 pCtx->a_sreg.u64Base = pVM->rem.s.Env.segs[R_##a_SREG].base; \ 2575 2583 pCtx->a_sreg.u32Limit = pVM->rem.s.Env.segs[R_##a_SREG].limit; \ 2576 /* Note! QEmu saves the 2nd dword of the descriptor; we should store the attribute word only! */ \2577 pCtx->a_sreg.Attr.u = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> 8) & 0xF0FF; \2584 /* Note! QEmu saves the 2nd dword of the descriptor; we (VT-x/AMD-V) keep only the attributes! */ \ 2585 pCtx->a_sreg.Attr.u = (pVM->rem.s.Env.segs[R_##a_SREG].flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; \ 2578 2586 } \ 2579 2587 else \ … … 2637 2645 || pCtx->ldtr.u64Base != pVM->rem.s.Env.ldt.base 2638 2646 || pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit 2639 || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)2647 || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK) 2640 2648 || !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID) 2641 2649 ) … … 2646 2654 pCtx->ldtr.u64Base = pVM->rem.s.Env.ldt.base; 2647 2655 pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit; 2648 pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;2656 pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 2649 2657 STAM_COUNTER_INC(&gStatREMLDTRChange); 2650 2658 #ifdef VBOX_WITH_RAW_MODE … … 2658 2666 || pCtx->tr.u64Base != pVM->rem.s.Env.tr.base 2659 2667 || pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit 2660 /* Qemu and AMD/Intel have different ideas about the busy flag ... */ 2661 || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF2662 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 82668 /* Qemu and AMD/Intel have different ideas about the busy flag ... */ /** @todo just fix qemu! */ 2669 || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE) 2670 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT 2663 2671 : 0) 2664 2672 || !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID) … … 2668 2676 pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u, 2669 2677 pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit, 2670 (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0)); 2678 (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE) 2679 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0)); 2671 2680 pCtx->tr.Sel = pVM->rem.s.Env.tr.selector; 2672 2681 pCtx->tr.ValidSel = pVM->rem.s.Env.tr.selector; … … 2674 2683 pCtx->tr.u64Base = pVM->rem.s.Env.tr.base; 2675 2684 pCtx->tr.u32Limit = pVM->rem.s.Env.tr.limit; 2676 pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;2677 if (pCtx->tr.Attr.u )2678 pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;2685 pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 2686 if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE) 2687 pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT; 2679 2688 STAM_COUNTER_INC(&gStatREMTRChange); 2680 2689 #ifdef VBOX_WITH_RAW_MODE … … 2877 2886 || pCtx->ldtr.u64Base != pVM->rem.s.Env.ldt.base 2878 2887 || pCtx->ldtr.u32Limit != pVM->rem.s.Env.ldt.limit 2879 || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF)2888 || pCtx->ldtr.Attr.u != ((pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK) 2880 2889 || !(pCtx->ldtr.fFlags & CPUMSELREG_FLAGS_VALID) 2881 2890 ) … … 2886 2895 pCtx->ldtr.u64Base = pVM->rem.s.Env.ldt.base; 2887 2896 pCtx->ldtr.u32Limit = pVM->rem.s.Env.ldt.limit; 2888 pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> 8) & 0xF0FF;2897 pCtx->ldtr.Attr.u = (pVM->rem.s.Env.ldt.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 2889 2898 STAM_COUNTER_INC(&gStatREMLDTRChange); 2890 2899 #ifdef VBOX_WITH_RAW_MODE … … 2899 2908 || pCtx->tr.u32Limit != pVM->rem.s.Env.tr.limit 2900 2909 /* Qemu and AMD/Intel have different ideas about the busy flag ... */ 2901 || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF2902 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 82910 || pCtx->tr.Attr.u != ( (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE) 2911 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT 2903 2912 : 0) 2904 2913 || !(pCtx->tr.fFlags & CPUMSELREG_FLAGS_VALID) … … 2908 2917 pCtx->tr.Sel, pCtx->tr.u64Base, pCtx->tr.u32Limit, pCtx->tr.Attr.u, 2909 2918 pVM->rem.s.Env.tr.selector, (uint64_t)pVM->rem.s.Env.tr.base, pVM->rem.s.Env.tr.limit, 2910 (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> 8 : 0)); 2919 (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & (SEL_FLAGS_SMASK & ~DESC_INTEL_UNUSABLE) 2920 ? (pVM->rem.s.Env.tr.flags | DESC_TSS_BUSY_MASK) >> SEL_FLAGS_SHIFT : 0)); 2911 2921 pCtx->tr.Sel = pVM->rem.s.Env.tr.selector; 2912 2922 pCtx->tr.ValidSel = pVM->rem.s.Env.tr.selector; … … 2914 2924 pCtx->tr.u64Base = pVM->rem.s.Env.tr.base; 2915 2925 pCtx->tr.u32Limit = pVM->rem.s.Env.tr.limit; 2916 pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> 8) & 0xF0FF;2917 if (pCtx->tr.Attr.u )2918 pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> 8;2926 pCtx->tr.Attr.u = (pVM->rem.s.Env.tr.flags >> SEL_FLAGS_SHIFT) & SEL_FLAGS_SMASK; 2927 if (pCtx->tr.Attr.u & ~DESC_INTEL_UNUSABLE) 2928 pCtx->tr.Attr.u |= DESC_TSS_BUSY_MASK >> SEL_FLAGS_SHIFT; 2919 2929 STAM_COUNTER_INC(&gStatREMTRChange); 2920 2930 #ifdef VBOX_WITH_RAW_MODE -
trunk/src/recompiler/target-i386/cpu.h
r43394 r47309 116 116 117 117 #define DESC_TSS_BUSY_MASK (1 << 9) 118 #ifdef VBOX 119 # define DESC_INTEL_UNUSABLE RT_BIT_32(16+8) /**< Internal VT-x bit for NULL sectors. */ 120 #endif 118 121 119 122 /* eflags masks */ … … 949 952 if (flags & DESC_P_MASK) 950 953 flags |= DESC_A_MASK; /* Make sure the A bit is set to avoid trouble. */ 954 if (selector < 4U && (env->hflags & HF_CS64_MASK)) 955 flags |= DESC_INTEL_UNUSABLE; 956 else 957 flags &= ~DESC_INTEL_UNUSABLE; 951 958 sc->flags = flags; 952 959 sc->newselector = 0; -
trunk/src/recompiler/target-i386/op_helper.c
r45494 r47309 274 274 sc->flags = e2; 275 275 #ifdef VBOX 276 sc->flags &= ~DESC_INTEL_UNUSABLE; 276 277 sc->newselector = 0; 277 278 sc->fVBoxFlags = CPUMSELREG_FLAGS_VALID; … … 624 625 env->ldt.flags = 0; 625 626 #ifdef VBOX 627 env->ldt.flags = DESC_INTEL_UNUSABLE; 626 628 env->ldt.fVBoxFlags = CPUMSELREG_FLAGS_VALID; 627 629 env->ldt.newselector = 0; … … 1326 1328 if (new_stack) { 1327 1329 ss = 0 | dpl; 1330 #ifndef VBOX 1328 1331 cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, 0); 1332 #else 1333 cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT); 1334 #endif 1329 1335 } 1330 1336 ESP = esp; … … 2503 2509 env->ldt.limit = 0; 2504 2510 #ifdef VBOX 2511 env->ldt.flags = DESC_INTEL_UNUSABLE; 2505 2512 env->ldt.fVBoxFlags = CPUMSELREG_FLAGS_VALID; 2506 2513 env->ldt.newselector = 0; … … 2569 2576 env->tr.flags = 0; 2570 2577 #ifdef VBOX 2578 env->tr.flags = DESC_INTEL_UNUSABLE; 2571 2579 env->tr.fVBoxFlags = CPUMSELREG_FLAGS_VALID; 2572 2580 env->tr.newselector = 0; … … 2645 2653 if ((selector & 0xfffc) == 0) { 2646 2654 /* null selector case */ 2655 #ifndef VBOX 2647 2656 if (seg_reg == R_SS 2648 2657 #ifdef TARGET_X86_64 … … 2652 2661 raise_exception_err(EXCP0D_GPF, 0); 2653 2662 cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0); 2663 #else 2664 if (seg_reg == R_SS) { 2665 if (!(env->hflags & HF_CS64_MASK) || cpl == 3) 2666 raise_exception_err(EXCP0D_GPF, 0); 2667 e2 = (cpl << DESC_DPL_SHIFT) | DESC_INTEL_UNUSABLE; 2668 } else { 2669 e2 = DESC_INTEL_UNUSABLE; 2670 } 2671 cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, e2); 2672 #endif 2654 2673 } else { 2655 2674 … … 3321 3340 #endif 3322 3341 { 3342 #if defined(VBOX) && defined(DEBUG) 3343 Log(("NULL ss, rpl=%d\n", rpl)); 3344 #endif 3323 3345 raise_exception_err(EXCP0D_GPF, 0); 3324 3346 } 3325 3347 } else { 3326 3348 if ((new_ss & 3) != rpl) 3349 { 3350 #if defined(VBOX) && defined(DEBUG) 3351 Log(("new_ss=%x != rpl=%d\n", new_ss, rpl)); 3352 #endif 3327 3353 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); 3354 } 3328 3355 if (load_segment(&ss_e1, &ss_e2, new_ss) != 0) 3356 { 3357 #if defined(VBOX) && defined(DEBUG) 3358 Log(("new_ss=%x load error\n", new_ss)); 3359 #endif 3329 3360 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); 3361 } 3330 3362 if (!(ss_e2 & DESC_S_MASK) || 3331 3363 (ss_e2 & DESC_CS_MASK) || 3332 3364 !(ss_e2 & DESC_W_MASK)) 3365 { 3366 #if defined(VBOX) && defined(DEBUG) 3367 Log(("new_ss=%x ss_e2=%#x bad type\n", new_ss, ss_e2)); 3368 #endif 3333 3369 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); 3370 } 3334 3371 dpl = (ss_e2 >> DESC_DPL_SHIFT) & 3; 3335 3372 if (dpl != rpl) 3373 { 3374 #if defined(VBOX) && defined(DEBUG) 3375 Log(("SS.dpl=%u != rpl=%u\n", dpl, rpl)); 3376 #endif 3336 3377 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc); 3378 } 3337 3379 if (!(ss_e2 & DESC_P_MASK)) 3380 { 3381 #if defined(VBOX) && defined(DEBUG) 3382 Log(("new_ss=%#x #NP\n", new_ss)); 3383 #endif 3338 3384 raise_exception_err(EXCP0B_NOSEG, new_ss & 0xfffc); 3385 } 3339 3386 #ifdef VBOX 3340 3387 if (!(e2 & DESC_A_MASK)) … … 3419 3466 3420 3467 #ifdef VBOX 3468 Log(("iret (shift=%d new_eip=%#x)\n", shift, next_eip)); 3421 3469 e1 = e2 = 0; /** @todo Why do we do this? */ 3422 3470 remR3TrapClear(env->pVM); … … 3427 3475 #ifdef TARGET_X86_64 3428 3476 if (env->hflags & HF_LMA_MASK) 3477 { 3478 #if defined(VBOX) && defined(DEBUG) 3479 Log(("eflags.NT=1 on iret in long mode\n")); 3480 #endif 3429 3481 raise_exception_err(EXCP0D_GPF, 0); 3482 } 3430 3483 #endif 3431 3484 tss_selector = lduw_kernel(env->tr.base + 0); … … 3597 3650 env->dr[reg] = t0; 3598 3651 hw_breakpoint_insert(env, reg); 3652 # ifndef VBOX 3599 3653 } else if (reg == 7) { 3654 # else 3655 } else if (reg == 7 || reg == 5) { 3656 # endif 3600 3657 for (i = 0; i < 4; i++) 3601 3658 hw_breakpoint_remove(env, i); … … 3604 3661 hw_breakpoint_insert(env, i); 3605 3662 } else 3663 # ifndef VBOX 3606 3664 env->dr[reg] = t0; 3665 # else 3666 env->dr[6] = (t0 & ~RT_BIT_32(12)) | UINT32_C(0xffff0ff0); /* 4 is an alias for 6. */ 3667 # endif 3607 3668 } 3608 3669 #endif
Note:
See TracChangeset
for help on using the changeset viewer.