qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet?
@ 2015-03-09 22:02 Bill Paul
  2015-03-09 22:23 ` Stefan Weil
  0 siblings, 1 reply; 7+ messages in thread
From: Bill Paul @ 2015-03-09 22:02 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2750 bytes --]

Nobody has commented on this yet. 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.

Can someone confirm that this is in fact a real bug? The Intel architecture 
manual seems quite clear about the SYSRET behavior. The bug seems to have been 
around as far back as QEMU 0.10.5.

I am using QEMU 2.2.0 on FreeBSD/amd64 9.1-RELEASE.

-Bill

Signed-off-by: Bill Paul <wpaul@windriver.com>

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -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) |
@@ -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) |
-- 
1.8.0

-- 
=============================================================================
-Bill Paul            (510) 749-2329 | Senior Member of Technical Staff,
                 wpaul@windriver.com | Master of Unix-Fu - Wind River Systems
=============================================================================
   "I put a dollar in a change machine. Nothing changed." - George Carlin
=============================================================================

[-- Attachment #2: Type: text/html, Size: 10873 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread
* [Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet?
@ 2015-03-09 22:48 Bill Paul
  2015-03-10  8:29 ` Fam Zheng
  2015-03-10  9:38 ` Paolo Bonzini
  0 siblings, 2 replies; 7+ messages in thread
From: Bill Paul @ 2015-03-09 22:48 UTC (permalink / raw)
  To: qemu-devel

I'm certain I'm sending this in plain text mode this time. 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.

Can someone confirm that this is in fact a real bug? The Intel architecture 
manual seems quite clear about the SYSRET behavior. The bug seems to have been 
around as far back as QEMU 0.10.5.

I am using QEMU 2.2.0 on FreeBSD/amd64 9.1-RELEASE.

-Bill

Signed-off-by: Bill Paul <wpaul@windriver.com>

---
 target-i386/seg_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index fa374d0..2bc757a 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -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) |
@@ -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) |
-- 
1.8.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-03-10  9:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-03-09 22:02 [Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet? Bill Paul
2015-03-09 22:23 ` Stefan Weil
2015-03-09 22:46   ` Bill Paul
2015-03-10  5:46     ` Stefan Weil
  -- strict thread matches above, loose matches on Subject: below --
2015-03-09 22:48 Bill Paul
2015-03-10  8:29 ` Fam Zheng
2015-03-10  9:38 ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).