From patchwork Mon May 6 05:55:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: liguang X-Patchwork-Id: 241556 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 628D62C00E6 for ; Mon, 6 May 2013 15:58:17 +1000 (EST) Received: from localhost ([::1]:38916 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZERD-0007Z6-8J for incoming@patchwork.ozlabs.org; Mon, 06 May 2013 01:58:15 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49592) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZEQs-0007Yt-SV for qemu-devel@nongnu.org; Mon, 06 May 2013 01:57:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UZEQr-0003wQ-Ge for qemu-devel@nongnu.org; Mon, 06 May 2013 01:57:54 -0400 Received: from [222.73.24.84] (port=37736 helo=song.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZEQq-0003sf-Jn for qemu-devel@nongnu.org; Mon, 06 May 2013 01:57:53 -0400 X-IronPort-AV: E=Sophos;i="4.87,619,1363104000"; d="scan'208";a="7194209" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 06 May 2013 13:54:54 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id r465vfLe009720; Mon, 6 May 2013 13:57:41 +0800 Received: from liguang.fnst.cn.fujitsu.com ([10.167.233.147]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013050613554958-1006049 ; Mon, 6 May 2013 13:55:49 +0800 From: liguang To: qemu-devel@nongnu.org Date: Mon, 6 May 2013 13:55:06 +0800 Message-Id: <1367819707-11978-1-git-send-email-lig.fnst@cn.fujitsu.com> X-Mailer: git-send-email 1.7.2.5 X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/06 13:55:49, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/06 13:55:50, Serialize complete at 2013/05/06 13:55:50 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 222.73.24.84 Cc: Blue Swirl , Peter Maydell , liguang Subject: [Qemu-devel] [PATCH v2 1/2] target-i386/seg_helper: refactor 4 helper functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org for helper_{lsl, lar, verr, verw}, there are common parts, so move them outside, and then call this new helper-helper function. Signed-off-by: liguang --- v2: change misc_check_helper to privilege_check --- target-i386/seg_helper.c | 179 ++++++++++++++------------------------------- 1 files changed, 56 insertions(+), 123 deletions(-) diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index ff93374..eb9dc04 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -2288,9 +2288,10 @@ void helper_sysexit(CPUX86State *env, int dflag) EIP = EDX; } -target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) + +static target_ulong privilege_check(CPUX86State *env, target_ulong selector1, + int inst) { - unsigned int limit; uint32_t e1, e2, eflags, selector; int rpl, dpl, cpl, type; @@ -2302,14 +2303,30 @@ target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) if (load_segment(env, &e1, &e2, selector) != 0) { goto fail; } + + CC_SRC = eflags & ~CC_Z; + rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; cpl = env->hflags & HF_CPL_MASK; + if (e2 & DESC_S_MASK) { - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { - /* conforming */ - } else { - if (dpl < cpl || dpl < rpl) { + if (e2 & DESC_CS_MASK) { + switch (inst) { + case 1: + goto fail; + case 2: + if (!(e2 & (DESC_R_MASK | DESC_C_MASK))) { + goto fail; + } + break; + case 3: + case 4: + if (!(e2 & DESC_C_MASK)) { + goto check_pl; + } + break; + default: goto fail; } } @@ -2321,140 +2338,56 @@ target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) case 3: case 9: case 11: - break; + if (inst == 3) { + break; + } + case 5: + case 12: + if (inst == 4) { + break; + } default: goto fail; } - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return 0; - } + goto check_pl; + } + + if (inst == 3) { + e2 &= 0x00f0ff00; } - limit = get_seg_limit(e1, e2); + if (inst == 4) { + e2 = get_seg_limit(e1, e2); + } + CC_SRC = eflags | CC_Z; - return limit; + +check_pl: + if (dpl < cpl || dpl < rpl) { + goto fail; + } + +fail: + return e2; } -target_ulong helper_lar(CPUX86State *env, target_ulong selector1) +target_ulong helper_lsl(CPUX86State *env, target_ulong selector1) { - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl, type; + return privilege_check(env, selector1, 4); +} - selector = selector1 & 0xffff; - eflags = cpu_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) { - goto fail; - } - if (load_segment(env, &e1, &e2, selector) != 0) { - goto fail; - } - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_S_MASK) { - if ((e2 & DESC_CS_MASK) && (e2 & DESC_C_MASK)) { - /* conforming */ - } else { - if (dpl < cpl || dpl < rpl) { - goto fail; - } - } - } else { - type = (e2 >> DESC_TYPE_SHIFT) & 0xf; - switch (type) { - case 1: - case 2: - case 3: - case 4: - case 5: - case 9: - case 11: - case 12: - break; - default: - goto fail; - } - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return 0; - } - } - CC_SRC = eflags | CC_Z; - return e2 & 0x00f0ff00; +target_ulong helper_lar(CPUX86State *env, target_ulong selector1) +{ + return privilege_check(env, selector1, 3); } void helper_verr(CPUX86State *env, target_ulong selector1) { - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl; - - selector = selector1 & 0xffff; - eflags = cpu_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) { - goto fail; - } - if (load_segment(env, &e1, &e2, selector) != 0) { - goto fail; - } - if (!(e2 & DESC_S_MASK)) { - goto fail; - } - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_CS_MASK) { - if (!(e2 & DESC_R_MASK)) { - goto fail; - } - if (!(e2 & DESC_C_MASK)) { - if (dpl < cpl || dpl < rpl) { - goto fail; - } - } - } else { - if (dpl < cpl || dpl < rpl) { - fail: - CC_SRC = eflags & ~CC_Z; - return; - } - } - CC_SRC = eflags | CC_Z; + privilege_check(env, selector1, 2); } void helper_verw(CPUX86State *env, target_ulong selector1) { - uint32_t e1, e2, eflags, selector; - int rpl, dpl, cpl; - - selector = selector1 & 0xffff; - eflags = cpu_cc_compute_all(env, CC_OP); - if ((selector & 0xfffc) == 0) { - goto fail; - } - if (load_segment(env, &e1, &e2, selector) != 0) { - goto fail; - } - if (!(e2 & DESC_S_MASK)) { - goto fail; - } - rpl = selector & 3; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - if (e2 & DESC_CS_MASK) { - goto fail; - } else { - if (dpl < cpl || dpl < rpl) { - goto fail; - } - if (!(e2 & DESC_W_MASK)) { - fail: - CC_SRC = eflags & ~CC_Z; - return; - } - } - CC_SRC = eflags | CC_Z; + privilege_check(env, selector1, 1); } #if defined(CONFIG_USER_ONLY)