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,13 +2335,13 @@ void helper_rdmsr(void)
2335 void helper_lsl(void) 2335 void helper_lsl(void)
2336 { 2336 {
2337 unsigned int selector, limit; 2337 unsigned int selector, limit;
2338 - uint32_t e1, e2; 2338 + uint32_t e1, e2, eflags;
2339 int rpl, dpl, cpl, type; 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 selector = T0 & 0xffff; 2342 selector = T0 & 0xffff;
2343 if (load_segment(&e1, &e2, selector) != 0) 2343 if (load_segment(&e1, &e2, selector) != 0)
2344 - return; 2344 + goto fail;
2345 rpl = selector & 3; 2345 rpl = selector & 3;
2346 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2346 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2347 cpl = env->hflags & HF_CPL_MASK; 2347 cpl = env->hflags & HF_CPL_MASK;
@@ -2350,7 +2350,7 @@ void helper_lsl(void) @@ -2350,7 +2350,7 @@ void helper_lsl(void)
2350 /* conforming */ 2350 /* conforming */
2351 } else { 2351 } else {
2352 if (dpl < cpl || dpl < rpl) 2352 if (dpl < cpl || dpl < rpl)
2353 - return; 2353 + goto fail;
2354 } 2354 }
2355 } else { 2355 } else {
2356 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 2356 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
@@ -2362,28 +2362,31 @@ void helper_lsl(void) @@ -2362,28 +2362,31 @@ void helper_lsl(void)
2362 case 11: 2362 case 11:
2363 break; 2363 break;
2364 default: 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 return; 2370 return;
  2371 + }
2369 } 2372 }
2370 limit = get_seg_limit(e1, e2); 2373 limit = get_seg_limit(e1, e2);
2371 T1 = limit; 2374 T1 = limit;
2372 - CC_SRC |= CC_Z; 2375 + CC_SRC = eflags | CC_Z;
2373 } 2376 }
2374 2377
2375 void helper_lar(void) 2378 void helper_lar(void)
2376 { 2379 {
2377 unsigned int selector; 2380 unsigned int selector;
2378 - uint32_t e1, e2; 2381 + uint32_t e1, e2, eflags;
2379 int rpl, dpl, cpl, type; 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 selector = T0 & 0xffff; 2385 selector = T0 & 0xffff;
2383 if ((selector & 0xfffc) == 0) 2386 if ((selector & 0xfffc) == 0)
2384 - return; 2387 + goto fail;
2385 if (load_segment(&e1, &e2, selector) != 0) 2388 if (load_segment(&e1, &e2, selector) != 0)
2386 - return; 2389 + goto fail;
2387 rpl = selector & 3; 2390 rpl = selector & 3;
2388 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2391 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2389 cpl = env->hflags & HF_CPL_MASK; 2392 cpl = env->hflags & HF_CPL_MASK;
@@ -2392,7 +2395,7 @@ void helper_lar(void) @@ -2392,7 +2395,7 @@ void helper_lar(void)
2392 /* conforming */ 2395 /* conforming */
2393 } else { 2396 } else {
2394 if (dpl < cpl || dpl < rpl) 2397 if (dpl < cpl || dpl < rpl)
2395 - return; 2398 + goto fail;
2396 } 2399 }
2397 } else { 2400 } else {
2398 type = (e2 >> DESC_TYPE_SHIFT) & 0xf; 2401 type = (e2 >> DESC_TYPE_SHIFT) & 0xf;
@@ -2407,72 +2410,81 @@ void helper_lar(void) @@ -2407,72 +2410,81 @@ void helper_lar(void)
2407 case 12: 2410 case 12:
2408 break; 2411 break;
2409 default: 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 return; 2418 return;
  2419 + }
2414 } 2420 }
2415 T1 = e2 & 0x00f0ff00; 2421 T1 = e2 & 0x00f0ff00;
2416 - CC_SRC |= CC_Z; 2422 + CC_SRC = eflags | CC_Z;
2417 } 2423 }
2418 2424
2419 void helper_verr(void) 2425 void helper_verr(void)
2420 { 2426 {
2421 unsigned int selector; 2427 unsigned int selector;
2422 - uint32_t e1, e2; 2428 + uint32_t e1, e2, eflags;
2423 int rpl, dpl, cpl; 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 selector = T0 & 0xffff; 2432 selector = T0 & 0xffff;
2427 if ((selector & 0xfffc) == 0) 2433 if ((selector & 0xfffc) == 0)
2428 - return; 2434 + goto fail;
2429 if (load_segment(&e1, &e2, selector) != 0) 2435 if (load_segment(&e1, &e2, selector) != 0)
2430 - return; 2436 + goto fail;
2431 if (!(e2 & DESC_S_MASK)) 2437 if (!(e2 & DESC_S_MASK))
2432 - return; 2438 + goto fail;
2433 rpl = selector & 3; 2439 rpl = selector & 3;
2434 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2440 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2435 cpl = env->hflags & HF_CPL_MASK; 2441 cpl = env->hflags & HF_CPL_MASK;
2436 if (e2 & DESC_CS_MASK) { 2442 if (e2 & DESC_CS_MASK) {
2437 if (!(e2 & DESC_R_MASK)) 2443 if (!(e2 & DESC_R_MASK))
2438 - return; 2444 + goto fail;
2439 if (!(e2 & DESC_C_MASK)) { 2445 if (!(e2 & DESC_C_MASK)) {
2440 if (dpl < cpl || dpl < rpl) 2446 if (dpl < cpl || dpl < rpl)
2441 - return; 2447 + goto fail;
2442 } 2448 }
2443 } else { 2449 } else {
2444 - if (dpl < cpl || dpl < rpl) 2450 + if (dpl < cpl || dpl < rpl) {
  2451 + fail:
  2452 + CC_SRC = eflags & ~CC_Z;
2445 return; 2453 return;
  2454 + }
2446 } 2455 }
2447 - CC_SRC |= CC_Z; 2456 + CC_SRC = eflags | CC_Z;
2448 } 2457 }
2449 2458
2450 void helper_verw(void) 2459 void helper_verw(void)
2451 { 2460 {
2452 unsigned int selector; 2461 unsigned int selector;
2453 - uint32_t e1, e2; 2462 + uint32_t e1, e2, eflags;
2454 int rpl, dpl, cpl; 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 selector = T0 & 0xffff; 2466 selector = T0 & 0xffff;
2458 if ((selector & 0xfffc) == 0) 2467 if ((selector & 0xfffc) == 0)
2459 - return; 2468 + goto fail;
2460 if (load_segment(&e1, &e2, selector) != 0) 2469 if (load_segment(&e1, &e2, selector) != 0)
2461 - return; 2470 + goto fail;
2462 if (!(e2 & DESC_S_MASK)) 2471 if (!(e2 & DESC_S_MASK))
2463 - return; 2472 + goto fail;
2464 rpl = selector & 3; 2473 rpl = selector & 3;
2465 dpl = (e2 >> DESC_DPL_SHIFT) & 3; 2474 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
2466 cpl = env->hflags & HF_CPL_MASK; 2475 cpl = env->hflags & HF_CPL_MASK;
2467 if (e2 & DESC_CS_MASK) { 2476 if (e2 & DESC_CS_MASK) {
2468 - return; 2477 + goto fail;
2469 } else { 2478 } else {
2470 if (dpl < cpl || dpl < rpl) 2479 if (dpl < cpl || dpl < rpl)
  2480 + goto fail;
  2481 + if (!(e2 & DESC_W_MASK)) {
  2482 + fail:
  2483 + CC_SRC = eflags & ~CC_Z;
2471 return; 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 /* FPU helpers */ 2490 /* FPU helpers */