From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56278) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ws9FC-0004wO-QW for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:20:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Ws9F4-0005ol-3n for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:20:34 -0400 Received: from mail-we0-x230.google.com ([2a00:1450:400c:c03::230]:51386) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Ws9F3-0005oU-QK for qemu-devel@nongnu.org; Wed, 04 Jun 2014 07:20:26 -0400 Received: by mail-we0-f176.google.com with SMTP id q59so8095332wes.21 for ; Wed, 04 Jun 2014 04:20:25 -0700 (PDT) Received: from playground.station (net-37-117-132-7.cust.vodafonedsl.it. [37.117.132.7]) by mx.google.com with ESMTPSA id ci54sm5075943eeb.19.2014.06.04.04.20.23 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Jun 2014 04:20:24 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Wed, 4 Jun 2014 13:20:06 +0200 Message-Id: <1401880812-818-6-git-send-email-pbonzini@redhat.com> In-Reply-To: <1401880812-818-1-git-send-email-pbonzini@redhat.com> References: <1401880812-818-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 05/11] target-i386: rework CPL checks during task switch, preparing for next patch List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org During task switch, all of CS.DPL, CS.RPL, SS.DPL must match (in addition to all the other requirements) and will be the new CPL. So far this worked by carefully setting the CS selector and flags before doing the task switch; but this will not work once we get the CPL from SS.DPL. Temporarily assume that the CPL comes from CS.RPL during task switch to a protected-mode task, until the descriptor of SS is loaded. Tested-by: Kevin O'Connor Signed-off-by: Paolo Bonzini --- target-i386/seg_helper.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 6f7efee..0f00aed 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -135,11 +135,10 @@ static inline void get_ss_esp_from_tss(CPUX86State *env, uint32_t *ss_ptr, } } -/* XXX: merge with load_seg() */ -static void tss_load_seg(CPUX86State *env, int seg_reg, int selector) +static void tss_load_seg(CPUX86State *env, int seg_reg, int selector, int cpl) { uint32_t e1, e2; - int rpl, dpl, cpl; + int rpl, dpl; if ((selector & 0xfffc) != 0) { if (load_segment(env, &e1, &e2, selector) != 0) { @@ -150,18 +149,13 @@ static void tss_load_seg(CPUX86State *env, int seg_reg, int selector) } rpl = selector & 3; dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; if (seg_reg == R_CS) { if (!(e2 & DESC_CS_MASK)) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); } - /* XXX: is it correct? */ if (dpl != rpl) { raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); } - if ((e2 & DESC_C_MASK) && dpl > rpl) { - raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc); - } } else if (seg_reg == R_SS) { /* SS must be writable data */ if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) { @@ -448,12 +442,13 @@ static void switch_tss(CPUX86State *env, int tss_selector, /* load the segments */ if (!(new_eflags & VM_MASK)) { - tss_load_seg(env, R_CS, new_segs[R_CS]); - tss_load_seg(env, R_SS, new_segs[R_SS]); - tss_load_seg(env, R_ES, new_segs[R_ES]); - tss_load_seg(env, R_DS, new_segs[R_DS]); - tss_load_seg(env, R_FS, new_segs[R_FS]); - tss_load_seg(env, R_GS, new_segs[R_GS]); + int cpl = new_segs[R_CS] & 3; + tss_load_seg(env, R_CS, new_segs[R_CS], cpl); + tss_load_seg(env, R_SS, new_segs[R_SS], cpl); + tss_load_seg(env, R_ES, new_segs[R_ES], cpl); + tss_load_seg(env, R_DS, new_segs[R_DS], cpl); + tss_load_seg(env, R_FS, new_segs[R_FS], cpl); + tss_load_seg(env, R_GS, new_segs[R_GS], cpl); } /* check that env->eip is in the CS segment limits */ -- 1.8.3.1