From nobody Fri Mar 29 00:32:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507819058475717.5192303525879; Thu, 12 Oct 2017 07:37:38 -0700 (PDT) Received: from localhost ([::1]:45872 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2ebw-0000rV-Jo for importer@patchew.org; Thu, 12 Oct 2017 10:37:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2eab-0000Ed-EI for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:36:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2eaX-0002G7-Om for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:35:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50564) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2eaX-0002Fi-Cf for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:35:53 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4CF3C7F403; Thu, 12 Oct 2017 14:35:52 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-116-77.ams2.redhat.com [10.36.116.77]) by smtp.corp.redhat.com (Postfix) with ESMTP id ECFCA5C88D; Thu, 12 Oct 2017 14:35:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 4CF3C7F403 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pbonzini@redhat.com From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 16:35:47 +0200 Message-Id: <20171012143548.18581-2-pbonzini@redhat.com> In-Reply-To: <20171012143548.18581-1-pbonzini@redhat.com> References: <20171012143548.18581-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 12 Oct 2017 14:35:52 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/2] target/i386: introduce x86_ld*_code X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard.henderson@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These take care of advancing s->pc, and will provide a unified point where to check for the 15-byte instruction length limit. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/translate.c | 228 ++++++++++++++++++++++++++------------------= ---- 1 file changed, 125 insertions(+), 103 deletions(-) diff --git a/target/i386/translate.c b/target/i386/translate.c index 5d61fa96ad..4a938c21a0 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -1863,6 +1863,41 @@ static void gen_shifti(DisasContext *s1, int op, TCG= MemOp ot, int d, int c) } } =20 +static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_byte= s) +{ + uint64_t pc =3D s->pc; + + s->pc +=3D num_bytes; + return pc; +} + +static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) +{ + return cpu_ldub_code(env, advance_pc(env, s, 1)); +} + +static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s) +{ + return cpu_ldsw_code(env, advance_pc(env, s, 2)); +} + +static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) +{ + return cpu_lduw_code(env, advance_pc(env, s, 2)); +} + +static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) +{ + return cpu_ldl_code(env, advance_pc(env, s, 4)); +} + +#ifdef TARGET_X86_64 +static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) +{ + return cpu_ldq_code(env, advance_pc(env, s, 8)); +} +#endif + /* Decompose an address. */ =20 typedef struct AddressParts { @@ -1900,7 +1935,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env,= DisasContext *s, case MO_32: havesib =3D 0; if (rm =3D=3D 4) { - int code =3D cpu_ldub_code(env, s->pc++); + int code =3D x86_ldub_code(env, s); scale =3D (code >> 6) & 3; index =3D ((code >> 3) & 7) | REX_X(s); if (index =3D=3D 4) { @@ -1914,8 +1949,7 @@ static AddressParts gen_lea_modrm_0(CPUX86State *env,= DisasContext *s, case 0: if ((base & 7) =3D=3D 5) { base =3D -1; - disp =3D (int32_t)cpu_ldl_code(env, s->pc); - s->pc +=3D 4; + disp =3D (int32_t)x86_ldl_code(env, s); if (CODE64(s) && !havesib) { base =3D -2; disp +=3D s->pc + s->rip_offset; @@ -1923,12 +1957,11 @@ static AddressParts gen_lea_modrm_0(CPUX86State *en= v, DisasContext *s, } break; case 1: - disp =3D (int8_t)cpu_ldub_code(env, s->pc++); + disp =3D (int8_t)x86_ldub_code(env, s); break; default: case 2: - disp =3D (int32_t)cpu_ldl_code(env, s->pc); - s->pc +=3D 4; + disp =3D (int32_t)x86_ldl_code(env, s); break; } =20 @@ -1945,15 +1978,13 @@ static AddressParts gen_lea_modrm_0(CPUX86State *en= v, DisasContext *s, if (mod =3D=3D 0) { if (rm =3D=3D 6) { base =3D -1; - disp =3D cpu_lduw_code(env, s->pc); - s->pc +=3D 2; + disp =3D x86_lduw_code(env, s); break; } } else if (mod =3D=3D 1) { - disp =3D (int8_t)cpu_ldub_code(env, s->pc++); + disp =3D (int8_t)x86_ldub_code(env, s); } else { - disp =3D (int16_t)cpu_lduw_code(env, s->pc); - s->pc +=3D 2; + disp =3D (int16_t)x86_lduw_code(env, s); } =20 switch (rm) { @@ -2103,19 +2134,16 @@ static inline uint32_t insn_get(CPUX86State *env, D= isasContext *s, TCGMemOp ot) =20 switch (ot) { case MO_8: - ret =3D cpu_ldub_code(env, s->pc); - s->pc++; + ret =3D x86_ldub_code(env, s); break; case MO_16: - ret =3D cpu_lduw_code(env, s->pc); - s->pc +=3D 2; + ret =3D x86_lduw_code(env, s); break; case MO_32: #ifdef TARGET_X86_64 case MO_64: #endif - ret =3D cpu_ldl_code(env, s->pc); - s->pc +=3D 4; + ret =3D x86_ldl_code(env, s); break; default: tcg_abort(); @@ -3041,7 +3069,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, gen_helper_enter_mmx(cpu_env); } =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7); if (is_xmm) reg |=3D rex_r; @@ -3250,8 +3278,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, =20 if (b1 =3D=3D 1 && reg !=3D 0) goto illegal_op; - field_length =3D cpu_ldub_code(env, s->pc++) & 0x3F; - bit_index =3D cpu_ldub_code(env, s->pc++) & 0x3F; + field_length =3D x86_ldub_code(env, s) & 0x3F; + bit_index =3D x86_ldub_code(env, s) & 0x3F; tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); if (b1 =3D=3D 1) @@ -3380,7 +3408,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, if (b1 >=3D 2) { goto unknown_op; } - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (is_xmm) { tcg_gen_movi_tl(cpu_T0, val); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_= t0.ZMM_L(0))); @@ -3537,7 +3565,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, case 0x1c4: s->rip_offset =3D 1; gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (b1) { val &=3D 7; tcg_gen_st16_tl(cpu_T0, cpu_env, @@ -3553,7 +3581,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, if (mod !=3D 3) goto illegal_op; ot =3D mo_64_32(s->dflag); - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (b1) { val &=3D 7; rm =3D (modrm & 7) | REX_B(s); @@ -3616,7 +3644,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, if ((b & 0xf0) =3D=3D 0xf0) { goto do_0f_38_fx; } - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); rm =3D modrm & 7; reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; @@ -3693,7 +3721,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, do_0f_38_fx: /* Various integer extensions at 0f 38 f[0-f]. */ b =3D modrm | (b1 << 8); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 switch (b) { @@ -4054,7 +4082,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, case 0x03a: case 0x13a: b =3D modrm; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); rm =3D modrm & 7; reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; @@ -4077,7 +4105,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, if (mod !=3D 3) gen_lea_modrm(env, s, modrm); reg =3D ((modrm >> 3) & 7) | rex_r; - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); switch (b) { case 0x14: /* pextrb */ tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, @@ -4225,7 +4253,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, gen_ldq_env_A0(s, op2_offset); } } - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); =20 if ((b & 0xfc) =3D=3D 0x60) { /* pcmpXstrX */ set_cc_op(s, CC_OP_EFLAGS); @@ -4244,7 +4272,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, case 0x33a: /* Various integer extensions at 0f 3a f[0-f]. */ b =3D modrm | (b1 << 8); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 switch (b) { @@ -4256,7 +4284,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, } ot =3D mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); - b =3D cpu_ldub_code(env, s->pc++); + b =3D x86_ldub_code(env, s); if (ot =3D=3D MO_64) { tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63); } else { @@ -4351,7 +4379,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, } switch(b) { case 0x0f: /* 3DNow! data insns */ - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); sse_fn_epp =3D sse_op_table5[val]; if (!sse_fn_epp) { goto unknown_op; @@ -4365,7 +4393,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, break; case 0x70: /* pshufx insn */ case 0xc6: /* pshufx insn */ - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); /* XXX: introduce a new table? */ @@ -4374,7 +4402,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s= , int b, break; case 0xc2: /* compare insns */ - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (val >=3D 8) goto unknown_op; sse_fn_epp =3D sse_op_table4[val][b1]; @@ -4443,8 +4471,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (s->pc - pc_start > 14) { goto illegal_op; } - b =3D cpu_ldub_code(env, s->pc); - s->pc++; + b =3D x86_ldub_code(env, s); /* Collect prefixes. */ switch (b) { case 0xf3: @@ -4501,7 +4528,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) static const int pp_prefix[4] =3D { 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ }; - int vex3, vex2 =3D cpu_ldub_code(env, s->pc); + int vex3, vex2 =3D x86_ldub_code(env, s); =20 if (!CODE64(s) && (vex2 & 0xc0) !=3D 0xc0) { /* 4.1.4.6: In 32-bit mode, bits [7:6] must be 11b, @@ -4523,17 +4550,17 @@ static target_ulong disas_insn(DisasContext *s, CPU= State *cpu) rex_r =3D (~vex2 >> 4) & 8; if (b =3D=3D 0xc5) { vex3 =3D vex2; - b =3D cpu_ldub_code(env, s->pc++); + b =3D x86_ldub_code(env, s); } else { #ifdef TARGET_X86_64 s->rex_x =3D (~vex2 >> 3) & 8; s->rex_b =3D (~vex2 >> 2) & 8; #endif - vex3 =3D cpu_ldub_code(env, s->pc++); + vex3 =3D x86_ldub_code(env, s); rex_w =3D (vex3 >> 7) & 1; switch (vex2 & 0x1f) { case 0x01: /* Implied 0f leading opcode bytes. */ - b =3D cpu_ldub_code(env, s->pc++) | 0x100; + b =3D x86_ldub_code(env, s) | 0x100; break; case 0x02: /* Implied 0f 38 leading opcode bytes. */ b =3D 0x138; @@ -4585,7 +4612,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x0f: /**************************/ /* extended op code */ - b =3D cpu_ldub_code(env, s->pc++) | 0x100; + b =3D x86_ldub_code(env, s) | 0x100; goto reswitch; =20 /**************************/ @@ -4607,7 +4634,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) =20 switch(f) { case 0: /* OP Ev, Gv */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); @@ -4628,7 +4655,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_op(s, op, ot, opreg); break; case 1: /* OP Gv, Ev */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; reg =3D ((modrm >> 3) & 7) | rex_r; rm =3D (modrm & 7) | REX_B(s); @@ -4662,7 +4689,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) =20 ot =3D mo_b_d(b, dflag); =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); op =3D (modrm >> 3) & 7; @@ -4708,7 +4735,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xf7: ot =3D mo_b_d(b, dflag); =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); op =3D (modrm >> 3) & 7; @@ -4940,7 +4967,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xff: /* GRP5 */ ot =3D mo_b_d(b, dflag); =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); op =3D (modrm >> 3) & 7; @@ -5048,7 +5075,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x85: ot =3D mo_b_d(b, dflag); =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); @@ -5120,7 +5147,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x69: /* imul Gv, Ev, I */ case 0x6b: ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; if (b =3D=3D 0x69) s->rip_offset =3D insn_const_size(ot); @@ -5172,7 +5199,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x1c0: case 0x1c1: /* xadd Ev, Gv */ ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; gen_op_mov_v_reg(ot, cpu_T0, reg); @@ -5204,7 +5231,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) TCGv oldv, newv, cmpv; =20 ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; oldv =3D tcg_temp_new(); @@ -5256,7 +5283,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) } break; case 0x1c7: /* cmpxchg8b */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; if ((mod =3D=3D 3) || ((modrm & 0x38) !=3D 0x8)) goto illegal_op; @@ -5318,7 +5345,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_push_v(s, cpu_T0); break; case 0x8f: /* pop Ev */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; ot =3D gen_pop_T0(s); if (mod =3D=3D 3) { @@ -5337,9 +5364,8 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xc8: /* enter */ { int level; - val =3D cpu_lduw_code(env, s->pc); - s->pc +=3D 2; - level =3D cpu_ldub_code(env, s->pc++); + val =3D x86_lduw_code(env, s); + level =3D x86_ldub_code(env, s); gen_enter(s, val, level); } break; @@ -5396,7 +5422,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x88: case 0x89: /* mov Gv, Ev */ ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 /* generate a generic store */ @@ -5405,7 +5431,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xc6: case 0xc7: /* mov Ev, Iv */ ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; if (mod !=3D 3) { s->rip_offset =3D insn_const_size(ot); @@ -5422,14 +5448,14 @@ static target_ulong disas_insn(DisasContext *s, CPU= State *cpu) case 0x8a: case 0x8b: /* mov Ev, Gv */ ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_op_mov_reg_v(ot, reg, cpu_T0); break; case 0x8e: /* mov seg, Gv */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D (modrm >> 3) & 7; if (reg >=3D 6 || reg =3D=3D R_CS) goto illegal_op; @@ -5447,7 +5473,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) } break; case 0x8c: /* mov Gv, seg */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D (modrm >> 3) & 7; mod =3D (modrm >> 6) & 3; if (reg >=3D 6) @@ -5472,7 +5498,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) /* s_ot is the sign+size of source */ s_ot =3D b & 8 ? MO_SIGN | ot : ot; =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); @@ -5508,7 +5534,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) break; =20 case 0x8d: /* lea */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) goto illegal_op; @@ -5532,8 +5558,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) switch (s->aflag) { #ifdef TARGET_X86_64 case MO_64: - offset_addr =3D cpu_ldq_code(env, s->pc); - s->pc +=3D 8; + offset_addr =3D x86_ldq_code(env, s); break; #endif default: @@ -5570,8 +5595,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (dflag =3D=3D MO_64) { uint64_t tmp; /* 64 bit case */ - tmp =3D cpu_ldq_code(env, s->pc); - s->pc +=3D 8; + tmp =3D x86_ldq_code(env, s); reg =3D (b & 7) | REX_B(s); tcg_gen_movi_tl(cpu_T0, tmp); gen_op_mov_reg_v(MO_64, reg, cpu_T0); @@ -5595,7 +5619,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x86: case 0x87: /* xchg Ev, Gv */ ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) { @@ -5632,7 +5656,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) op =3D R_GS; do_lxx: ot =3D dflag !=3D MO_16 ? MO_32 : MO_16; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) @@ -5660,7 +5684,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) grp2: { ot =3D mo_b_d(b, dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; op =3D (modrm >> 3) & 7; =20 @@ -5679,7 +5703,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_shift(s, op, ot, opreg, OR_ECX); } else { if (shift =3D=3D 2) { - shift =3D cpu_ldub_code(env, s->pc++); + shift =3D x86_ldub_code(env, s); } gen_shifti(s, op, ot, opreg, shift); } @@ -5713,7 +5737,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) shift =3D 0; do_shiftd: ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); reg =3D ((modrm >> 3) & 7) | rex_r; @@ -5726,7 +5750,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_op_mov_v_reg(ot, cpu_T1, reg); =20 if (shift) { - TCGv imm =3D tcg_const_tl(cpu_ldub_code(env, s->pc++)); + TCGv imm =3D tcg_const_tl(x86_ldub_code(env, s)); gen_shiftd_rm_T1(s, ot, opreg, op, imm); tcg_temp_free(imm); } else { @@ -5743,7 +5767,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; rm =3D modrm & 7; op =3D ((b & 7) << 3) | ((modrm >> 3) & 7); @@ -6328,7 +6352,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xe4: case 0xe5: ot =3D mo_b_d32(b, dflag); - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); tcg_gen_movi_tl(cpu_T0, val); gen_check_io(s, ot, pc_start - s->cs_base, SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes)); @@ -6347,7 +6371,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xe6: case 0xe7: ot =3D mo_b_d32(b, dflag); - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); tcg_gen_movi_tl(cpu_T0, val); gen_check_io(s, ot, pc_start - s->cs_base, svm_is_rep(prefixes)); @@ -6407,8 +6431,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) /************************/ /* control */ case 0xc2: /* ret im */ - val =3D cpu_ldsw_code(env, s->pc); - s->pc +=3D 2; + val =3D x86_ldsw_code(env, s); ot =3D gen_pop_T0(s); gen_stack_update(s, val + (1 << ot)); /* Note that gen_pop_T0 uses a zero-extending load. */ @@ -6425,8 +6448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_jr(s, cpu_T0); break; case 0xca: /* lret im */ - val =3D cpu_ldsw_code(env, s->pc); - s->pc +=3D 2; + val =3D x86_ldsw_code(env, s); do_lret: if (s->pe && !s->vm86) { gen_update_cc_op(s); @@ -6563,7 +6585,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) break; =20 case 0x190 ... 0x19f: /* setcc Gv */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); gen_setcc1(s, b, cpu_T0); gen_ldst_modrm(env, s, modrm, MO_8, OR_TMP0, 1); break; @@ -6572,7 +6594,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) goto illegal_op; } ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; gen_cmovcc1(env, s, ot, b, modrm, reg); break; @@ -6689,7 +6711,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) /* bit operations */ case 0x1ba: /* bt/bts/btr/btc Gv, im */ ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); op =3D (modrm >> 3) & 7; mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); @@ -6703,7 +6725,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_op_mov_v_reg(ot, cpu_T0, rm); } /* load shift */ - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); tcg_gen_movi_tl(cpu_T1, val); if (op < 4) goto unknown_op; @@ -6722,7 +6744,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) op =3D 3; do_btx: ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); @@ -6827,7 +6849,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x1bc: /* bsf / tzcnt */ case 0x1bd: /* bsr / lzcnt */ ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_extu(ot, cpu_T0); @@ -6907,7 +6929,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xd4: /* aam */ if (CODE64(s)) goto illegal_op; - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (val =3D=3D 0) { gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base); } else { @@ -6918,7 +6940,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0xd5: /* aad */ if (CODE64(s)) goto illegal_op; - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); gen_helper_aad(cpu_env, tcg_const_i32(val)); set_cc_op(s, CC_OP_LOGICB); break; @@ -6952,7 +6974,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs= _base); break; case 0xcd: /* int N */ - val =3D cpu_ldub_code(env, s->pc++); + val =3D x86_ldub_code(env, s); if (s->vm86 && s->iopl !=3D 3) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { @@ -7007,7 +7029,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (CODE64(s)) goto illegal_op; ot =3D dflag; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D (modrm >> 3) & 7; mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) @@ -7186,7 +7208,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) } break; case 0x100: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; op =3D (modrm >> 3) & 7; switch(op) { @@ -7251,7 +7273,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) break; =20 case 0x101: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); switch (modrm) { CASE_MODRM_MEM_OP(0): /* sgdt */ gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ); @@ -7596,7 +7618,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) /* d_ot is the size of destination */ d_ot =3D dflag; =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; mod =3D (modrm >> 6) & 3; rm =3D (modrm & 7) | REX_B(s); @@ -7625,7 +7647,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) t1 =3D tcg_temp_local_new(); t2 =3D tcg_temp_local_new(); ot =3D MO_16; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D (modrm >> 3) & 7; mod =3D (modrm >> 6) & 3; rm =3D modrm & 7; @@ -7670,7 +7692,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (!s->pe || s->vm86) goto illegal_op; ot =3D dflag !=3D MO_16 ? MO_32 : MO_16; - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); t0 =3D tcg_temp_local_new(); @@ -7690,7 +7712,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) } break; case 0x118: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; op =3D (modrm >> 3) & 7; switch(op) { @@ -7709,7 +7731,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) } break; case 0x11a: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); if (s->flags & HF_MPX_EN_MASK) { mod =3D (modrm >> 6) & 3; reg =3D ((modrm >> 3) & 7) | rex_r; @@ -7799,7 +7821,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_nop_modrm(env, s, modrm); break; case 0x11b: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); if (s->flags & HF_MPX_EN_MASK) { mod =3D (modrm >> 6) & 3; reg =3D ((modrm >> 3) & 7) | rex_r; @@ -7901,7 +7923,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_nop_modrm(env, s, modrm); break; case 0x119: case 0x11c ... 0x11f: /* nop (multi byte) */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); gen_nop_modrm(env, s, modrm); break; case 0x120: /* mov reg, crN */ @@ -7909,7 +7931,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (s->cpl !=3D 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); /* Ignore the mod bits (assume (modrm&0xc0)=3D=3D0xc0). * AMD documentation (24594.pdf) and testing of * intel 386 and 486 processors all show that the mod bits @@ -7966,7 +7988,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (s->cpl !=3D 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); /* Ignore the mod bits (assume (modrm&0xc0)=3D=3D0xc0). * AMD documentation (24594.pdf) and testing of * intel 386 and 486 processors all show that the mod bits @@ -8012,7 +8034,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (!(s->cpuid_features & CPUID_SSE2)) goto illegal_op; ot =3D mo_64_32(dflag); - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) goto illegal_op; @@ -8021,7 +8043,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_ldst_modrm(env, s, modrm, ot, reg, 1); break; case 0x1ae: - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); switch (modrm) { CASE_MODRM_MEM_OP(0): /* fxsave */ if (!(s->cpuid_features & CPUID_FXSR) @@ -8219,7 +8241,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) break; =20 case 0x10d: /* 3DNow! prefetch(w) */ - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); mod =3D (modrm >> 6) & 3; if (mod =3D=3D 3) goto illegal_op; @@ -8241,7 +8263,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) if (!(s->cpuid_ext_features & CPUID_EXT_POPCNT)) goto illegal_op; =20 - modrm =3D cpu_ldub_code(env, s->pc++); + modrm =3D x86_ldub_code(env, s); reg =3D ((modrm >> 3) & 7) | rex_r; =20 if (s->prefix & PREFIX_DATA) { --=20 2.14.2 From nobody Fri Mar 29 00:32:25 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1507819049198459.2213110549677; Thu, 12 Oct 2017 07:37:29 -0700 (PDT) Received: from localhost ([::1]:45870 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2ebp-0000n2-CC for importer@patchew.org; Thu, 12 Oct 2017 10:37:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43622) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e2eaZ-0000EW-ME for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:35:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e2eaY-0002GQ-Jj for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:35:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44232) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1e2eaY-0002GB-BT for qemu-devel@nongnu.org; Thu, 12 Oct 2017 10:35:54 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 69150C0828BA; Thu, 12 Oct 2017 14:35:53 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-116-77.ams2.redhat.com [10.36.116.77]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9EE5B5C88D; Thu, 12 Oct 2017 14:35:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 69150C0828BA Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=pbonzini@redhat.com From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 12 Oct 2017 16:35:48 +0200 Message-Id: <20171012143548.18581-3-pbonzini@redhat.com> In-Reply-To: <20171012143548.18581-1-pbonzini@redhat.com> References: <20171012143548.18581-1-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Thu, 12 Oct 2017 14:35:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/2] target/i386: trap on instructions longer than >15 bytes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard.henderson@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Besides being more correct, arbitrarily long instruction allow the generation of a translation block that spans three pages. This confuses the generator and even allows ring 3 code to poison the translation block cache and inject code into other processes that are in guest ring 3. This is an improved (and more invasive) fix for the bug fixed in commit 30663fd ("tcg/i386: Check the size of instruction being translated", 2017-03-24). In addition to being more precise (and generating the right exception, which is #GP rather than #UD), it distinguishes better between page faults and too long instructions, as shown by this test case: #include #include #include int main() { char *x =3D mmap(NULL, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, -1, 0); memset(x, 0x66, 4096); x[4096] =3D 0x90; x[4097] =3D 0xc3; char *i =3D x + 4096 - 15; mprotect(x + 4096, 4096, PROT_READ|PROT_WRITE); ((void(*)(void)) i) (); } ... which produces a #GP without the mprotect, and a #PF with it. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/translate.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/target/i386/translate.c b/target/i386/translate.c index 4a938c21a0..5f24a2de3c 100644 --- a/target/i386/translate.c +++ b/target/i386/translate.c @@ -136,6 +136,7 @@ typedef struct DisasContext { int cpuid_ext3_features; int cpuid_7_0_ebx_features; int cpuid_xsave_features; + sigjmp_buf jmpbuf; } DisasContext; =20 static void gen_eob(DisasContext *s); @@ -1863,11 +1864,27 @@ static void gen_shifti(DisasContext *s1, int op, TC= GMemOp ot, int d, int c) } } =20 +#define X86_MAX_INSN_LENGTH 15 + static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_byte= s) { uint64_t pc =3D s->pc; =20 s->pc +=3D num_bytes; + if (unlikely(s->pc - s->pc_start > X86_MAX_INSN_LENGTH)) { + /* If the instruction's 16th byte is on a different page than the = 1st, a + * page fault on the second page wins over the general protection = fault + * caused by the instruction being too long. + * This can happen even if the operand is only one byte long! + */ + if (((s->pc - 1) ^ (pc - 1)) & TARGET_PAGE_MASK) { + volatile uint8_t unused =3D + cpu_ldub_code(env, (s->pc - 1) & TARGET_PAGE_MASK); + (void) unused; + } + siglongjmp(s->jmpbuf, 1); + } + return pc; } =20 @@ -4463,14 +4480,12 @@ static target_ulong disas_insn(DisasContext *s, CPU= State *cpu) s->rip_offset =3D 0; /* for relative ip address */ s->vex_l =3D 0; s->vex_v =3D 0; - next_byte: - /* x86 has an upper limit of 15 bytes for an instruction. Since we - * do not want to decode and generate IR for an illegal - * instruction, the following check limits the instruction size to - * 25 bytes: 14 prefix + 1 opc + 6 (modrm+sib+ofs) + 4 imm */ - if (s->pc - pc_start > 14) { - goto illegal_op; + if (sigsetjmp(s->jmpbuf, 0) !=3D 0) { + gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); + return s->pc; } + + next_byte: b =3D x86_ldub_code(env, s); /* Collect prefixes. */ switch (b) { --=20 2.14.2