Changeset 45821 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Apr 29, 2013 3:34:47 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/HM.cpp
r45804 r45821 2288 2288 2289 2289 /** 2290 * Checks if a code selector (CS) is suitable for execution 2291 * within VMX when unrestricted execution isn't available. 2292 * 2293 * @returns true if selector is suitable for VMX, otherwise 2294 * false. 2295 * @param pSel Pointer to the selector to check (CS). 2296 * uStackDpl The DPL of the stack segment. 2297 */ 2298 static bool hmR3IsCodeSelectorOkForVmx(PCPUMSELREG pSel, unsigned uStackDpl) 2299 { 2300 bool rc = false; 2301 2302 do 2303 { 2304 /* Segment must be accessed. */ 2305 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED)) 2306 break; 2307 /* Segment must be a code segment. */ 2308 if (!(pSel->Attr.u & X86_SEL_TYPE_CODE)) 2309 break; 2310 /* The S bit must be set. */ 2311 if (!pSel->Attr.n.u1DescType) 2312 break; 2313 if (pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF) 2314 { 2315 /* For conforming segments, CS.DPL must be <= SS.DPL. */ 2316 if (pSel->Attr.n.u2Dpl > uStackDpl) 2317 break; 2318 } 2319 else 2320 { 2321 /* For non-conforming segments, CS.DPL must equal SS.DPL. */ 2322 if (pSel->Attr.n.u2Dpl != uStackDpl) 2323 break; 2324 } 2325 /* Segment must be present. */ 2326 if (!pSel->Attr.n.u1Present) 2327 break; 2328 /* G bit must be set if any high limit bits are set. */ 2329 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2330 break; 2331 /* G bit must be clear if any low limit bits are clear. */ 2332 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2333 break; 2334 2335 rc = true; 2336 } while (0); 2337 return rc; 2338 } 2339 2340 2341 /** 2342 * Checks if a data selector (DS/ES/FS/GS) is suitable for 2343 * execution within VMX when unrestricted execution isn't 2344 * available. 2345 * 2346 * @returns true if selector is suitable for VMX, otherwise 2347 * false. 2348 * @param pSel Pointer to the selector to check 2349 * (DS/ES/FS/GS). 2350 */ 2351 static bool hmR3IsDataSelectorOkForVmx(PCPUMSELREG pSel) 2352 { 2353 bool rc = false; 2354 2355 /* If attributes are all zero, consider the segment unusable and therefore OK. 2356 * This logic must be in sync with HMVMXR0.cpp! 2357 */ 2358 if (!pSel->Attr.u) 2359 return true; 2360 2361 do 2362 { 2363 /* Segment must be accessed. */ 2364 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED)) 2365 break; 2366 /* Code segments must also be readable. */ 2367 if (pSel->Attr.u & X86_SEL_TYPE_CODE && !(pSel->Attr.u & X86_SEL_TYPE_READ)) 2368 break; 2369 /* The S bit must be set. */ 2370 if (!pSel->Attr.n.u1DescType) 2371 break; 2372 /* Except for conforming segments, DPL >= RPL. */ 2373 if (pSel->Attr.n.u4Type <= X86_SEL_TYPE_ER_ACC && pSel->Attr.n.u2Dpl < (pSel->Sel & X86_SEL_RPL)) 2374 break; 2375 /* Segment must be present. */ 2376 if (!pSel->Attr.n.u1Present) 2377 break; 2378 /* G bit must be set if any high limit bits are set. */ 2379 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2380 break; 2381 /* G bit must be clear if any low limit bits are clear. */ 2382 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2383 break; 2384 2385 rc = true; 2386 } while (0); 2387 return rc; 2388 } 2389 2390 2391 /** 2392 * Checks if the stack selector (SS) is suitable for execution 2393 * within VMX when unrestricted execution isn't available. 2394 * 2395 * @returns true if selector is suitable for VMX, otherwise 2396 * false. 2397 * @param pSel Pointer to the selector to check (SS). 2398 */ 2399 static bool hmR3IsStackSelectorOkForVmx(PCPUMSELREG pSel) 2400 { 2401 bool rc = false; 2402 2403 /* If attributes are all zero, consider the segment unusable and therefore OK. 2404 * This logic must be in sync with HMVMXR0.cpp! 2405 */ 2406 if (!pSel->Attr.u) 2407 return true; 2408 2409 do 2410 { 2411 /* Segment must be accessed. */ 2412 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED)) 2413 break; 2414 /* Segment must be writable. */ 2415 if (!(pSel->Attr.u & X86_SEL_TYPE_WRITE)) 2416 break; 2417 /* Segment must not be a code segment. */ 2418 if (pSel->Attr.u & X86_SEL_TYPE_CODE) 2419 break; 2420 /* The S bit must be set. */ 2421 if (!pSel->Attr.n.u1DescType) 2422 break; 2423 /* DPL must equal RPL. */ 2424 if (pSel->Attr.n.u2Dpl != (pSel->Sel & X86_SEL_RPL)) 2425 break; 2426 /* Segment must be present. */ 2427 if (!pSel->Attr.n.u1Present) 2428 break; 2429 /* G bit must be set if any high limit bits are set. */ 2430 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2431 break; 2432 /* G bit must be clear if any low limit bits are clear. */ 2433 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2434 break; 2435 2436 rc = true; 2437 } while (0); 2438 return rc; 2439 } 2440 2441 2442 /** 2290 2443 * Force execution of the current IO code in the recompiler. 2291 2444 * … … 2394 2547 #endif 2395 2548 { 2549 //@todo: If guest is in V86 mode, these checks should be different! 2550 #if VBOX_WITH_OLD_VTX_CODE 2396 2551 if ( (pCtx->cs.Sel & X86_SEL_RPL) 2397 2552 || (pCtx->ds.Sel & X86_SEL_RPL) … … 2400 2555 || (pCtx->gs.Sel & X86_SEL_RPL) 2401 2556 || (pCtx->ss.Sel & X86_SEL_RPL)) 2557 #else 2558 if ( ((pCtx->cs.Sel & X86_SEL_RPL) != (pCtx->ss.Sel & X86_SEL_RPL)) 2559 || !hmR3IsCodeSelectorOkForVmx(&pCtx->cs, pCtx->ss.Attr.n.u2Dpl) 2560 || !hmR3IsDataSelectorOkForVmx(&pCtx->ds) 2561 || !hmR3IsDataSelectorOkForVmx(&pCtx->es) 2562 || !hmR3IsDataSelectorOkForVmx(&pCtx->fs) 2563 || !hmR3IsDataSelectorOkForVmx(&pCtx->gs) 2564 || !hmR3IsStackSelectorOkForVmx(&pCtx->ss)) 2565 #endif 2402 2566 { 2403 2567 return false;
Note:
See TracChangeset
for help on using the changeset viewer.