Commit b359d4e7e44d643d25e3ead1dba31e6559f4eb72

Authored by bellard
1 parent c45b3c0e

fixed zero ss selector case in x86_64 emulation


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1394 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 16 additions and 9 deletions
target-i386/helper.c
... ... @@ -1494,11 +1494,12 @@ void load_seg(int seg_reg, int selector)
1494 1494 target_ulong ptr;
1495 1495  
1496 1496 selector &= 0xffff;
  1497 + cpl = env->hflags & HF_CPL_MASK;
1497 1498 if ((selector & 0xfffc) == 0) {
1498 1499 /* null selector case */
1499 1500 if (seg_reg == R_SS
1500 1501 #ifdef TARGET_X86_64
1501   - && !(env->hflags & HF_CS64_MASK)
  1502 + && (!(env->hflags & HF_CS64_MASK) || cpl == 3)
1502 1503 #endif
1503 1504 )
1504 1505 raise_exception_err(EXCP0D_GPF, 0);
... ... @@ -1520,7 +1521,6 @@ void load_seg(int seg_reg, int selector)
1520 1521 raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
1521 1522 rpl = selector & 3;
1522 1523 dpl = (e2 >> DESC_DPL_SHIFT) & 3;
1523   - cpl = env->hflags & HF_CPL_MASK;
1524 1524 if (seg_reg == R_SS) {
1525 1525 /* must be writable segment */
1526 1526 if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK))
... ... @@ -2054,13 +2054,20 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend)
2054 2054 new_ss, new_esp);
2055 2055 }
2056 2056 #endif
2057   - if ((env->hflags & HF_LMA_MASK) && (new_ss & 0xfffc) == 0) {
2058   - /* NULL ss is allowed in long mode */
2059   - cpu_x86_load_seg_cache(env, R_SS, new_ss,
2060   - 0, 0xffffffff,
2061   - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
2062   - DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
2063   - DESC_W_MASK | DESC_A_MASK);
  2057 + if ((new_ss & 0xfffc) == 0) {
  2058 +#ifdef TARGET_X86_64
  2059 + /* NULL ss is allowed in long mode if cpl != 3*/
  2060 + if ((env->hflags & HF_LMA_MASK) && rpl != 3) {
  2061 + cpu_x86_load_seg_cache(env, R_SS, new_ss,
  2062 + 0, 0xffffffff,
  2063 + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
  2064 + DESC_S_MASK | (rpl << DESC_DPL_SHIFT) |
  2065 + DESC_W_MASK | DESC_A_MASK);
  2066 + } else
  2067 +#endif
  2068 + {
  2069 + raise_exception_err(EXCP0D_GPF, 0);
  2070 + }
2064 2071 } else {
2065 2072 if ((new_ss & 3) != rpl)
2066 2073 raise_exception_err(EXCP0D_GPF, new_ss & 0xfffc);
... ...