Commit 5516d670f69dafc77c936a02ff9916a9fba9fcd0
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 */ | ... | ... |