From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36081) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YV6Vm-0003dH-Ty for qemu-devel@nongnu.org; Mon, 09 Mar 2015 18:50:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YV6Vh-0005sc-Tl for qemu-devel@nongnu.org; Mon, 09 Mar 2015 18:50:58 -0400 Received: from mail.windriver.com ([147.11.1.11]:36428) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YV6Vh-0005sW-Jw for qemu-devel@nongnu.org; Mon, 09 Mar 2015 18:50:53 -0400 Received: from huisne.wrs.com (huisne.wrs.com [147.11.217.26]) by mail.windriver.com (8.14.9/8.14.5) with ESMTP id t29MoqNf022377 for ; Mon, 9 Mar 2015 15:50:52 -0700 (PDT) Received: from ala-wpaul-lx1.wrs.com (ala-wpaul-lx1.corp.ad.wrs.com [147.11.157.242]) by huisne.wrs.com (8.9.1/8.9.1) with ESMTP id PAA08045 for ; Mon, 9 Mar 2015 15:50:52 -0700 (PDT) From: Bill Paul Date: Mon, 9 Mar 2015 15:48:01 -0700 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201503091548.01462.wpaul@windriver.com> Subject: [Qemu-devel] Fix for incorrect SYSRET instruction implementation -- anyone looked at this yet? List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 --- 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