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 */ | ... | ... |