Skip to content

Commit

Permalink
x86: fix SS selector in SYSRET
Browse files Browse the repository at this point in the history
According to my reading of the Intel documentation, the SYSRET instruction
is supposed to force the RPL bits of the %ss register to 3 when returning
to user mode. The actual sequence is:

SS.Selector <-- (IA32_STAR[63:48]+8) OR 3; (* RPL forced to 3 *)

However, the code in helper_sysret() leaves them at 0 (in other words, the "OR
3" part of the above sequence is missing). It does set the privilege level
bits of %cs correctly though.

This has caused me trouble with some of my VxWorks development: code that runs
okay on real hardware will crash on QEMU, unless I apply the patch below.

Signed-off-by: Bill Paul <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Bill-Paul authored and bonzini committed Mar 10, 2015
1 parent ae071cc commit ac57622
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions target-i386/seg_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
env->eip = (uint32_t)env->regs[R_ECX];
}
cpu_x86_load_seg_cache(env, R_SS, selector + 8,
cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
Expand All @@ -1056,7 +1056,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
env->eip = (uint32_t)env->regs[R_ECX];
cpu_x86_load_seg_cache(env, R_SS, selector + 8,
cpu_x86_load_seg_cache(env, R_SS, (selector + 8) | 3,
0, 0xffffffff,
DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
DESC_S_MASK | (3 << DESC_DPL_SHIFT) |
Expand Down

0 comments on commit ac57622

Please sign in to comment.