Commit 5516d670f69dafc77c936a02ff9916a9fba9fcd0

Authored by bellard
1 parent cc6f538b

make lsl, lar verr and verw exception safe


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1369 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 45 additions and 33 deletions
target-i386/helper.c
... ... @@ -2335,13 +2335,13 @@ void helper_rdmsr(void)
2335 2335 void helper_lsl(void)
2336 2336 {
2337 2337 unsigned int selector, limit;
2338   - uint32_t e1, e2;
  2338 + uint32_t e1, e2, eflags;
2339 2339 int rpl, dpl, cpl, type;
2340 2340  
2341   - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  2341 + eflags = cc_table[CC_OP].compute_all();
2342 2342 selector = T0 & 0xffff;
2343 2343 if (load_segment(&e1, &e2, selector) != 0)
2344   - return;
  2344 + goto fail;
2345 2345 rpl = selector & 3;
2346 2346 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2347 2347 cpl = env->hflags & HF_CPL_MASK;
... ... @@ -2350,7 +2350,7 @@ void helper_lsl(void)
2350 2350 /* conforming */
2351 2351 } else {
2352 2352 if (dpl < cpl || dpl < rpl)
2353   - return;
  2353 + goto fail;
2354 2354 }
2355 2355 } else {
2356 2356 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
... ... @@ -2362,28 +2362,31 @@ void helper_lsl(void)
2362 2362 case 11:
2363 2363 break;
2364 2364 default:
2365   - return;
  2365 + goto fail;
2366 2366 }
2367   - if (dpl < cpl || dpl < rpl)
  2367 + if (dpl < cpl || dpl < rpl) {
  2368 + fail:
  2369 + CC_SRC = eflags & ~CC_Z;
2368 2370 return;
  2371 + }
2369 2372 }
2370 2373 limit = get_seg_limit(e1, e2);
2371 2374 T1 = limit;
2372   - CC_SRC |= CC_Z;
  2375 + CC_SRC = eflags | CC_Z;
2373 2376 }
2374 2377  
2375 2378 void helper_lar(void)
2376 2379 {
2377 2380 unsigned int selector;
2378   - uint32_t e1, e2;
  2381 + uint32_t e1, e2, eflags;
2379 2382 int rpl, dpl, cpl, type;
2380 2383  
2381   - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  2384 + eflags = cc_table[CC_OP].compute_all();
2382 2385 selector = T0 & 0xffff;
2383 2386 if ((selector & 0xfffc) == 0)
2384   - return;
  2387 + goto fail;
2385 2388 if (load_segment(&e1, &e2, selector) != 0)
2386   - return;
  2389 + goto fail;
2387 2390 rpl = selector & 3;
2388 2391 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2389 2392 cpl = env->hflags & HF_CPL_MASK;
... ... @@ -2392,7 +2395,7 @@ void helper_lar(void)
2392 2395 /* conforming */
2393 2396 } else {
2394 2397 if (dpl < cpl || dpl < rpl)
2395   - return;
  2398 + goto fail;
2396 2399 }
2397 2400 } else {
2398 2401 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
... ... @@ -2407,72 +2410,81 @@ void helper_lar(void)
2407 2410 case 12:
2408 2411 break;
2409 2412 default:
2410   - return;
  2413 + goto fail;
2411 2414 }
2412   - if (dpl < cpl || dpl < rpl)
  2415 + if (dpl < cpl || dpl < rpl) {
  2416 + fail:
  2417 + CC_SRC = eflags & ~CC_Z;
2413 2418 return;
  2419 + }
2414 2420 }
2415 2421 T1 = e2 & 0x00f0ff00;
2416   - CC_SRC |= CC_Z;
  2422 + CC_SRC = eflags | CC_Z;
2417 2423 }
2418 2424  
2419 2425 void helper_verr(void)
2420 2426 {
2421 2427 unsigned int selector;
2422   - uint32_t e1, e2;
  2428 + uint32_t e1, e2, eflags;
2423 2429 int rpl, dpl, cpl;
2424 2430  
2425   - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  2431 + eflags = cc_table[CC_OP].compute_all();
2426 2432 selector = T0 & 0xffff;
2427 2433 if ((selector & 0xfffc) == 0)
2428   - return;
  2434 + goto fail;
2429 2435 if (load_segment(&e1, &e2, selector) != 0)
2430   - return;
  2436 + goto fail;
2431 2437 if (!(e2 & DESC_S_MASK))
2432   - return;
  2438 + goto fail;
2433 2439 rpl = selector & 3;
2434 2440 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2435 2441 cpl = env->hflags & HF_CPL_MASK;
2436 2442 if (e2 & DESC_CS_MASK) {
2437 2443 if (!(e2 & DESC_R_MASK))
2438   - return;
  2444 + goto fail;
2439 2445 if (!(e2 & DESC_C_MASK)) {
2440 2446 if (dpl < cpl || dpl < rpl)
2441   - return;
  2447 + goto fail;
2442 2448 }
2443 2449 } else {
2444   - if (dpl < cpl || dpl < rpl)
  2450 + if (dpl < cpl || dpl < rpl) {
  2451 + fail:
  2452 + CC_SRC = eflags & ~CC_Z;
2445 2453 return;
  2454 + }
2446 2455 }
2447   - CC_SRC |= CC_Z;
  2456 + CC_SRC = eflags | CC_Z;
2448 2457 }
2449 2458  
2450 2459 void helper_verw(void)
2451 2460 {
2452 2461 unsigned int selector;
2453   - uint32_t e1, e2;
  2462 + uint32_t e1, e2, eflags;
2454 2463 int rpl, dpl, cpl;
2455 2464  
2456   - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  2465 + eflags = cc_table[CC_OP].compute_all();
2457 2466 selector = T0 & 0xffff;
2458 2467 if ((selector & 0xfffc) == 0)
2459   - return;
  2468 + goto fail;
2460 2469 if (load_segment(&e1, &e2, selector) != 0)
2461   - return;
  2470 + goto fail;
2462 2471 if (!(e2 & DESC_S_MASK))
2463   - return;
  2472 + goto fail;
2464 2473 rpl = selector & 3;
2465 2474 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2466 2475 cpl = env->hflags & HF_CPL_MASK;
2467 2476 if (e2 & DESC_CS_MASK) {
2468   - return;
  2477 + goto fail;
2469 2478 } else {
2470 2479 if (dpl < cpl || dpl < rpl)
  2480 + goto fail;
  2481 + if (!(e2 & DESC_W_MASK)) {
  2482 + fail:
  2483 + CC_SRC = eflags & ~CC_Z;
2471 2484 return;
2472   - if (!(e2 & DESC_W_MASK))
2473   - return;
  2485 + }
2474 2486 }
2475   - CC_SRC |= CC_Z;
  2487 + CC_SRC = eflags | CC_Z;
2476 2488 }
2477 2489  
2478 2490 /* FPU helpers */
... ...