Changeset 48450 in vbox
- Timestamp:
- Sep 12, 2013 3:00:15 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 88906
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/HM.cpp
r48433 r48450 2254 2254 * false. 2255 2255 * @param pSel Pointer to the selector to check (CS). 2256 * uStackDpl The DPL of the stack segment.2256 * uStackDpl The CPL, aka the DPL of the stack segment. 2257 2257 */ 2258 2258 static bool hmR3IsCodeSelectorOkForVmx(PCPUMSELREG pSel, unsigned uStackDpl) 2259 2259 { 2260 bool rc = false; 2261 2262 do 2263 { 2264 /* Segment must be accessed. */ 2265 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED)) 2266 break; 2267 /* Segment must be a code segment. */ 2268 if (!(pSel->Attr.u & X86_SEL_TYPE_CODE)) 2269 break; 2270 /* The S bit must be set. */ 2271 if (!pSel->Attr.n.u1DescType) 2272 break; 2273 if (pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF) 2274 { 2275 /* For conforming segments, CS.DPL must be <= SS.DPL. */ 2276 if (pSel->Attr.n.u2Dpl > uStackDpl) 2277 break; 2278 } 2279 else 2280 { 2281 /* For non-conforming segments, CS.DPL must equal SS.DPL. */ 2282 if (pSel->Attr.n.u2Dpl != uStackDpl) 2283 break; 2284 } 2285 /* Segment must be present. */ 2286 if (!pSel->Attr.n.u1Present) 2287 break; 2288 /* G bit must be set if any high limit bits are set. */ 2289 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2290 break; 2291 /* G bit must be clear if any low limit bits are clear. */ 2292 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2293 break; 2294 2295 rc = true; 2296 } while (0); 2297 return rc; 2260 /* 2261 * Segment must be an accessed code segment, it must be present and it must 2262 * be usable. 2263 * Note! These are all standard requirements and if CS holds anything else 2264 * we've got buggy code somewhere! 2265 */ 2266 AssertCompile(X86DESCATTR_TYPE == 0xf); 2267 AssertMsgReturn( (pSel->Attr.u & (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_CODE | X86DESCATTR_DT | X86DESCATTR_P | X86DESCATTR_UNUSABLE)) 2268 == (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_CODE | X86DESCATTR_DT | X86DESCATTR_P), 2269 ("%#x\n", pSel->Attr.u), 2270 false); 2271 2272 /* For conforming segments, CS.DPL must be <= SS.DPL, while CS.DPL 2273 must equal SS.DPL for non-confroming segments. 2274 Note! This is also a hard requirement like above. */ 2275 AssertMsgReturn( pSel->Attr.n.u4Type & X86_SEL_TYPE_CONF 2276 ? pSel->Attr.n.u2Dpl <= uStackDpl 2277 : pSel->Attr.n.u2Dpl == uStackDpl, 2278 ("u4Type=%#x u2Dpl=%u uStackDpl=%u\n", pSel->Attr.n.u4Type, pSel->Attr.n.u2Dpl, uStackDpl), 2279 false); 2280 2281 /* 2282 * The following two requirements are VT-x specific: 2283 * - G bit must be set if any high limit bits are set. 2284 * - G bit must be clear if any low limit bits are clear. 2285 */ 2286 if ( ((pSel->u32Limit & 0xfff00000) == 0x00000000 || pSel->Attr.n.u1Granularity) 2287 && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) ) 2288 return true; 2289 return false; 2298 2290 } 2299 2291 … … 2311 2303 static bool hmR3IsDataSelectorOkForVmx(PCPUMSELREG pSel) 2312 2304 { 2313 bool rc = false;2314 2315 /* If attributes are all zero, consider the segment unusable and therefore OK.2316 * This logic must be in sync with HMVMXR0.cpp!2317 */ 2318 if ( !pSel->Attr.u)2305 /* 2306 * Unusable segments are OK. These days they should be marked as such, as 2307 * but as an alternative we for old saved states and AMD<->VT-x migration 2308 * we also treat segments with all the attributes cleared as unusable. 2309 */ 2310 if (pSel->Attr.n.u1Unusable || !pSel->Attr.u) 2319 2311 return true; 2320 2312 2321 do2322 { 2323 2324 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED))2325 break;2313 /** @todo tighten these checks. Will require CPUM load adjusting. */ 2314 2315 /* Segment must be accessed. */ 2316 if (pSel->Attr.u & X86_SEL_TYPE_ACCESSED) 2317 { 2326 2318 /* Code segments must also be readable. */ 2327 if (pSel->Attr.u & X86_SEL_TYPE_CODE && !(pSel->Attr.u & X86_SEL_TYPE_READ)) 2328 break; 2329 /* The S bit must be set. */ 2330 if (!pSel->Attr.n.u1DescType) 2331 break; 2332 /* Except for conforming segments, DPL >= RPL. */ 2333 if (pSel->Attr.n.u4Type <= X86_SEL_TYPE_ER_ACC && pSel->Attr.n.u2Dpl < (pSel->Sel & X86_SEL_RPL)) 2334 break; 2335 /* Segment must be present. */ 2336 if (!pSel->Attr.n.u1Present) 2337 break; 2338 /* G bit must be set if any high limit bits are set. */ 2339 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2340 break; 2341 /* G bit must be clear if any low limit bits are clear. */ 2342 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2343 break; 2344 2345 rc = true; 2346 } while (0); 2347 return rc; 2319 if ( !(pSel->Attr.u & X86_SEL_TYPE_CODE) 2320 || (pSel->Attr.u & X86_SEL_TYPE_READ)) 2321 { 2322 /* The S bit must be set. */ 2323 if (pSel->Attr.n.u1DescType) 2324 { 2325 /* Except for conforming segments, DPL >= RPL. */ 2326 if ( pSel->Attr.n.u2Dpl >= (pSel->Sel & X86_SEL_RPL) 2327 || pSel->Attr.n.u4Type >= X86_SEL_TYPE_ER_ACC) 2328 { 2329 /* Segment must be present. */ 2330 if (pSel->Attr.n.u1Present) 2331 { 2332 /* 2333 * The following two requirements are VT-x specific: 2334 * - G bit must be set if any high limit bits are set. 2335 * - G bit must be clear if any low limit bits are clear. 2336 */ 2337 if ( ((pSel->u32Limit & 0xfff00000) == 0x00000000 || pSel->Attr.n.u1Granularity) 2338 && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) ) 2339 return true; 2340 } 2341 } 2342 } 2343 } 2344 } 2345 2346 return false; 2348 2347 } 2349 2348 … … 2359 2358 static bool hmR3IsStackSelectorOkForVmx(PCPUMSELREG pSel) 2360 2359 { 2361 bool rc = false; 2362 2363 /* If attributes are all zero, consider the segment unusable and therefore OK. 2364 * This logic must be in sync with HMVMXR0.cpp! 2365 */ 2366 if (!pSel->Attr.u) 2360 /* 2361 * Unusable segments are OK. These days they should be marked as such, as 2362 * but as an alternative we for old saved states and AMD<->VT-x migration 2363 * we also treat segments with all the attributes cleared as unusable. 2364 */ 2365 /** @todo r=bird: actually all zeros isn't gonna cut it... SS.DPL == CPL. */ 2366 if (pSel->Attr.n.u1Unusable || !pSel->Attr.u) 2367 2367 return true; 2368 2368 2369 do 2370 { 2371 /* Segment must be accessed. */ 2372 if (!(pSel->Attr.u & X86_SEL_TYPE_ACCESSED)) 2373 break; 2374 /* Segment must be writable. */ 2375 if (!(pSel->Attr.u & X86_SEL_TYPE_WRITE)) 2376 break; 2377 /* Segment must not be a code segment. */ 2378 if (pSel->Attr.u & X86_SEL_TYPE_CODE) 2379 break; 2380 /* The S bit must be set. */ 2381 if (!pSel->Attr.n.u1DescType) 2382 break; 2383 /* DPL must equal RPL. */ 2384 if (pSel->Attr.n.u2Dpl != (pSel->Sel & X86_SEL_RPL)) 2385 break; 2386 /* Segment must be present. */ 2387 if (!pSel->Attr.n.u1Present) 2388 break; 2389 /* G bit must be set if any high limit bits are set. */ 2390 if ((pSel->u32Limit & 0xfff00000) && !pSel->Attr.n.u1Granularity) 2391 break; 2392 /* G bit must be clear if any low limit bits are clear. */ 2393 if ((pSel->u32Limit & 0x0fff) != 0x0fff && pSel->Attr.n.u1Granularity) 2394 break; 2395 2396 rc = true; 2397 } while (0); 2398 return rc; 2369 /* 2370 * Segment must be an accessed writable segment, it must be present. 2371 * Note! These are all standard requirements and if SS holds anything else 2372 * we've got buggy code somewhere! 2373 */ 2374 AssertCompile(X86DESCATTR_TYPE == 0xf); 2375 AssertMsgReturn( (pSel->Attr.u & (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_WRITE | X86DESCATTR_DT | X86DESCATTR_P | X86_SEL_TYPE_CODE)) 2376 == (X86_SEL_TYPE_ACCESSED | X86_SEL_TYPE_WRITE | X86DESCATTR_DT | X86DESCATTR_P), 2377 ("%#x\n", pSel->Attr.u), 2378 false); 2379 2380 /* DPL must equal RPL. 2381 Note! This is also a hard requirement like above. */ 2382 AssertMsgReturn(pSel->Attr.n.u2Dpl == (pSel->Sel & X86_SEL_RPL), 2383 ("u2Dpl=%u Sel=%#x\n", pSel->Attr.n.u2Dpl, pSel->Sel), 2384 false); 2385 2386 /* 2387 * The following two requirements are VT-x specific: 2388 * - G bit must be set if any high limit bits are set. 2389 * - G bit must be clear if any low limit bits are clear. 2390 */ 2391 if ( ((pSel->u32Limit & 0xfff00000) == 0x00000000 || pSel->Attr.n.u1Granularity) 2392 && ((pSel->u32Limit & 0x00000fff) == 0x00000fff || !pSel->Attr.n.u1Granularity) ) 2393 return true; 2394 return false; 2399 2395 } 2400 2396
Note:
See TracChangeset
for help on using the changeset viewer.