All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/50] target/i386 translate cleanups
@ 2021-05-14 15:12 Richard Henderson
  2021-05-14 15:12 ` [PATCH v2 01/50] target/i386: Split out gen_exception_gpf Richard Henderson
                   ` (51 more replies)
  0 siblings, 52 replies; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Supercedes: 20210228232321.322053-1-richard.henderson@linaro.org
("i386 cleanup part 3")

Claudio's prerequite patch set ("i386 cleanup part 2"), is now merged.
Version 2 here fixes some minor rebase conflicts that crept in.
Only 4 of the 50 patches have been reviewed.

Blurb from v1:
This started out to address a fixme in Claudio's patch set, then
wandered a bit, with cleanups and bug fixes in the code that I was
touching.  I stopped when I reached my original goal of removing
target/i386/tcg/user/*_stubs.c.

There are a lot of patches, but hopefully they're all small
enough to be obvious.


r~


Richard Henderson (50):
  target/i386: Split out gen_exception_gpf
  target/i386: Split out check_cpl0
  target/i386: Unify code paths for IRET
  target/i386: Split out check_vm86_iopl
  target/i386: Split out check_iopl
  target/i386: Assert PE is set for user-only
  target/i386: Assert CPL is 3 for user-only
  target/i386: Assert IOPL is 0 for user-only
  target/i386: Assert !VM86 for x86_64 user-only
  target/i386: Assert CODE32 for x86_64 user-only
  target/i386: Assert SS32 for x86_64 user-only
  target/i386: Assert CODE64 for x86_64 user-only
  target/i386: Assert LMA for x86_64 user-only
  target/i386: Assert !ADDSEG for x86_64 user-only
  target/i386: Introduce REX_PREFIX
  target/i386: Tidy REX_B, REX_X definition
  target/i386: Move rex_r into DisasContext
  target/i386: Move rex_w into DisasContext
  target/i386: Remove DisasContext.f_st as unused
  target/i386: Reduce DisasContext.flags to uint32_t
  target/i386: Reduce DisasContext.override to int8_t
  target/i386: Reduce DisasContext.prefix to uint8_t
  target/i386: Reduce DisasContext.vex_[lv] to uint8_t
  target/i386: Reduce DisasContext popl_esp_hack and rip_offset to
    uint8_t
  target/i386: Leave TF in DisasContext.flags
  target/i386: Reduce DisasContext jmp_opt, repz_opt to bool
  target/i386: Fix the comment for repz_opt
  target/i386: Reorder DisasContext members
  target/i386: Add stub generator for helper_set_dr
  target/i386: Assert !SVME for user-only
  target/i386: Assert !GUEST for user-only
  target/i386: Implement skinit in translate.c
  target/i386: Eliminate SVM helpers for user-only
  target/i386: Mark some helpers as noreturn
  target/i386: Simplify gen_debug usage
  target/i386: Tidy svm_check_intercept from tcg
  target/i386: Remove pc_start argument to gen_svm_check_intercept
  target/i386: Remove user stub for cpu_vmexit
  target/i386: Cleanup read_crN, write_crN, lmsw
  target/i386: Pass env to do_pause and do_hlt
  target/i386: Move invlpg, hlt, monitor, mwait to sysemu
  target/i386: Unify invlpg, invlpga
  target/i386: Inline user cpu_svm_check_intercept_param
  target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr
  target/i386: Exit tb after wrmsr
  target/i386: Tidy gen_check_io
  target/i386: Pass in port to gen_check_io
  target/i386: Create helper_check_io
  target/i386: Move helper_check_io to sysemu
  target/i386: Remove user-only i/o stubs

 target/i386/cpu.h                    |   8 +
 target/i386/helper.h                 |  43 +-
 target/i386/tcg/helper-tcg.h         |   5 +-
 target/i386/tcg/bpt_helper.c         |   2 +-
 target/i386/tcg/excp_helper.c        |  18 +-
 target/i386/tcg/misc_helper.c        |  79 +--
 target/i386/tcg/seg_helper.c         |  43 --
 target/i386/tcg/sysemu/misc_helper.c |  52 +-
 target/i386/tcg/sysemu/seg_helper.c  |  29 +
 target/i386/tcg/sysemu/svm_helper.c  |  30 +-
 target/i386/tcg/translate.c          | 891 ++++++++++++++-------------
 target/i386/tcg/user/misc_stubs.c    |  75 ---
 target/i386/tcg/user/svm_stubs.c     |  76 ---
 target/i386/tcg/user/meson.build     |   2 -
 14 files changed, 600 insertions(+), 753 deletions(-)
 delete mode 100644 target/i386/tcg/user/misc_stubs.c
 delete mode 100644 target/i386/tcg/user/svm_stubs.c

-- 
2.25.1



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

* [PATCH v2 01/50] target/i386: Split out gen_exception_gpf
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:08   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 02/50] target/i386: Split out check_cpl0 Richard Henderson
                   ` (50 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 68 ++++++++++++++++++++-----------------
 1 file changed, 37 insertions(+), 31 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index db56a48343..2672e08197 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1276,6 +1276,12 @@ static void gen_illegal_opcode(DisasContext *s)
     gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
 }
 
+/* Generate #GP for the current instruction. */
+static void gen_exception_gpf(DisasContext *s)
+{
+    gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
+}
+
 /* if d == OR_TMP0, it means memory operand (address in A0) */
 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
 {
@@ -4502,7 +4508,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     s->vex_l = 0;
     s->vex_v = 0;
     if (sigsetjmp(s->jmpbuf, 0) != 0) {
-        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+        gen_exception_gpf(s);
         return s->pc;
     }
 
@@ -6567,7 +6573,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             set_cc_op(s, CC_OP_EFLAGS);
         } else if (s->vm86) {
             if (s->iopl != 3) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
             } else {
                 gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
                 set_cc_op(s, CC_OP_EFLAGS);
@@ -6689,7 +6695,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x9c: /* pushf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_update_cc_op(s);
             gen_helper_read_eflags(s->T0, cpu_env);
@@ -6699,7 +6705,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x9d: /* popf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             ot = gen_pop_T0(s);
             if (s->cpl == 0) {
@@ -7061,7 +7067,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xcd: /* int N */
         val = x86_ldub_code(env, s);
         if (s->vm86 && s->iopl != 3) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
         }
@@ -7084,13 +7090,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (s->cpl <= s->iopl) {
                 gen_helper_cli(cpu_env);
             } else {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
             }
         } else {
             if (s->iopl == 3) {
                 gen_helper_cli(cpu_env);
             } else {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
             }
         }
         break;
@@ -7101,7 +7107,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_jmp_im(s, s->pc - s->cs_base);
             gen_eob_inhibit_irq(s, true);
         } else {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         }
         break;
     case 0x62: /* bound */
@@ -7194,7 +7200,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x130: /* wrmsr */
     case 0x132: /* rdmsr */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
@@ -7226,7 +7232,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_helper_sysenter(cpu_env);
             gen_eob(s);
@@ -7237,7 +7243,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
             gen_eob(s);
@@ -7256,7 +7262,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x107: /* sysret */
         if (!s->pe) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
             /* condition codes are modified only in long mode */
@@ -7278,7 +7284,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xf4: /* hlt */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
@@ -7304,7 +7310,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!s->pe || s->vm86)
                 goto illegal_op;
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
@@ -7325,7 +7331,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!s->pe || s->vm86)
                 goto illegal_op;
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
@@ -7441,7 +7447,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
@@ -7458,7 +7464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7483,7 +7489,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7496,7 +7502,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7511,7 +7517,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7525,7 +7531,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7549,7 +7555,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7559,7 +7565,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(2): /* lgdt */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
@@ -7576,7 +7582,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(3): /* lidt */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
@@ -7622,7 +7628,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
         CASE_MODRM_OP(6): /* lmsw */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
@@ -7634,7 +7640,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         CASE_MODRM_MEM_OP(7): /* invlpg */
             if (s->cpl != 0) {
-                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                gen_exception_gpf(s);
                 break;
             }
             gen_update_cc_op(s);
@@ -7649,7 +7655,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #ifdef TARGET_X86_64
             if (CODE64(s)) {
                 if (s->cpl != 0) {
-                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+                    gen_exception_gpf(s);
                 } else {
                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
@@ -7685,7 +7691,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x108: /* invd */
     case 0x109: /* wbinvd */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
             /* nothing to do */
@@ -8009,7 +8015,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x120: /* mov reg, crN */
     case 0x122: /* mov crN, reg */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
@@ -8063,7 +8069,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x121: /* mov reg, drN */
     case 0x123: /* mov drN, reg */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
 #ifndef CONFIG_USER_ONLY
             modrm = x86_ldub_code(env, s);
@@ -8099,7 +8105,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x106: /* clts */
         if (s->cpl != 0) {
-            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+            gen_exception_gpf(s);
         } else {
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
             gen_helper_clts(cpu_env);
-- 
2.25.1



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

* [PATCH v2 02/50] target/i386: Split out check_cpl0
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
  2021-05-14 15:12 ` [PATCH v2 01/50] target/i386: Split out gen_exception_gpf Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:10   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 03/50] target/i386: Unify code paths for IRET Richard Henderson
                   ` (49 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Split out the check for CPL != 0 and the raising of #GP.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 79 ++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 49 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 2672e08197..61b30117a3 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1282,6 +1282,16 @@ static void gen_exception_gpf(DisasContext *s)
     gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
 }
 
+/* Check for cpl == 0; if not, raise #GP and return false. */
+static bool check_cpl0(DisasContext *s)
+{
+    if (s->cpl == 0) {
+        return true;
+    }
+    gen_exception_gpf(s);
+    return false;
+}
+
 /* if d == OR_TMP0, it means memory operand (address in A0) */
 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
 {
@@ -7199,9 +7209,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x130: /* wrmsr */
     case 0x132: /* rdmsr */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             if (b & 2) {
@@ -7283,9 +7291,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_helper_cpuid(cpu_env);
         break;
     case 0xf4: /* hlt */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
@@ -7309,9 +7315,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 2: /* lldt */
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
-            } else {
+            if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
@@ -7330,9 +7334,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 3: /* ltr */
             if (!s->pe || s->vm86)
                 goto illegal_op;
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
-            } else {
+            if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
@@ -7446,8 +7448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                                  | PREFIX_REPZ | PREFIX_REPNZ))) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
@@ -7463,8 +7464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7488,8 +7488,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7501,8 +7500,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7516,8 +7514,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7530,8 +7527,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7554,8 +7550,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!(s->flags & HF_SVME_MASK) || !s->pe) {
                 goto illegal_op;
             }
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7564,8 +7559,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(2): /* lgdt */
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
@@ -7581,8 +7575,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(3): /* lidt */
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
@@ -7627,8 +7620,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
             break;
         CASE_MODRM_OP(6): /* lmsw */
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
@@ -7639,8 +7631,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(7): /* invlpg */
-            if (s->cpl != 0) {
-                gen_exception_gpf(s);
+            if (!check_cpl0(s)) {
                 break;
             }
             gen_update_cc_op(s);
@@ -7654,9 +7645,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0xf8: /* swapgs */
 #ifdef TARGET_X86_64
             if (CODE64(s)) {
-                if (s->cpl != 0) {
-                    gen_exception_gpf(s);
-                } else {
+                if (check_cpl0(s)) {
                     tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
                     tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
                                   offsetof(CPUX86State, kernelgsbase));
@@ -7690,9 +7679,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     case 0x108: /* invd */
     case 0x109: /* wbinvd */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
             gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
             /* nothing to do */
         }
@@ -8014,9 +8001,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x120: /* mov reg, crN */
     case 0x122: /* mov crN, reg */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
              * AMD documentation (24594.pdf) and testing of
@@ -8068,9 +8053,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x121: /* mov reg, drN */
     case 0x123: /* mov drN, reg */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
 #ifndef CONFIG_USER_ONLY
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
@@ -8104,9 +8087,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         break;
     case 0x106: /* clts */
-        if (s->cpl != 0) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_cpl0(s)) {
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
             gen_helper_clts(cpu_env);
             /* abort block because static cpu state changed */
-- 
2.25.1



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

* [PATCH v2 03/50] target/i386: Unify code paths for IRET
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
  2021-05-14 15:12 ` [PATCH v2 01/50] target/i386: Split out gen_exception_gpf Richard Henderson
  2021-05-14 15:12 ` [PATCH v2 02/50] target/i386: Split out check_cpl0 Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:11   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 04/50] target/i386: Split out check_vm86_iopl Richard Henderson
                   ` (48 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

In vm86 mode, we use the same helper as real-mode, but with
an extra check for IOPL.  All non-exceptional paths set EFLAGS.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 61b30117a3..0a15662949 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -6577,22 +6577,18 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         goto do_lret;
     case 0xcf: /* iret */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
-        if (!s->pe) {
-            /* real mode */
-            gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
-            set_cc_op(s, CC_OP_EFLAGS);
-        } else if (s->vm86) {
-            if (s->iopl != 3) {
+        if (!s->pe || s->vm86) {
+            /* real mode or vm86 mode */
+            if (s->vm86 && s->iopl != 3) {
                 gen_exception_gpf(s);
-            } else {
-                gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
-                set_cc_op(s, CC_OP_EFLAGS);
+                break;
             }
+            gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
         } else {
             gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
                                       tcg_const_i32(s->pc - s->cs_base));
-            set_cc_op(s, CC_OP_EFLAGS);
         }
+        set_cc_op(s, CC_OP_EFLAGS);
         gen_eob(s);
         break;
     case 0xe8: /* call im */
-- 
2.25.1



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

* [PATCH v2 04/50] target/i386: Split out check_vm86_iopl
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (2 preceding siblings ...)
  2021-05-14 15:12 ` [PATCH v2 03/50] target/i386: Unify code paths for IRET Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:48   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 05/50] target/i386: Split out check_iopl Richard Henderson
                   ` (47 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 0a15662949..74f6024f82 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1292,6 +1292,16 @@ static bool check_cpl0(DisasContext *s)
     return false;
 }
 
+/* If vm86, check for iopl == 3; if not, raise #GP and return false. */
+static bool check_vm86_iopl(DisasContext *s)
+{
+    if (!s->vm86 || s->iopl == 3) {
+        return true;
+    }
+    gen_exception_gpf(s);
+    return false;
+}
+
 /* if d == OR_TMP0, it means memory operand (address in A0) */
 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
 {
@@ -6579,8 +6589,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
         if (!s->pe || s->vm86) {
             /* real mode or vm86 mode */
-            if (s->vm86 && s->iopl != 3) {
-                gen_exception_gpf(s);
+            if (!check_vm86_iopl(s)) {
                 break;
             }
             gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
@@ -6700,9 +6709,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* flags */
     case 0x9c: /* pushf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
-        if (s->vm86 && s->iopl != 3) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_vm86_iopl(s)) {
             gen_update_cc_op(s);
             gen_helper_read_eflags(s->T0, cpu_env);
             gen_push_v(s, s->T0);
@@ -6710,9 +6717,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x9d: /* popf */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
-        if (s->vm86 && s->iopl != 3) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_vm86_iopl(s)) {
             ot = gen_pop_T0(s);
             if (s->cpl == 0) {
                 if (dflag != MO_16) {
@@ -7072,9 +7077,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0xcd: /* int N */
         val = x86_ldub_code(env, s);
-        if (s->vm86 && s->iopl != 3) {
-            gen_exception_gpf(s);
-        } else {
+        if (check_vm86_iopl(s)) {
             gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
         }
         break;
-- 
2.25.1



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

* [PATCH v2 05/50] target/i386: Split out check_iopl
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (3 preceding siblings ...)
  2021-05-14 15:12 ` [PATCH v2 04/50] target/i386: Split out check_vm86_iopl Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:14   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 06/50] target/i386: Assert PE is set for user-only Richard Henderson
                   ` (46 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 74f6024f82..873ed00975 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -1302,6 +1302,16 @@ static bool check_vm86_iopl(DisasContext *s)
     return false;
 }
 
+/* Check for iopl allowing access; if not, raise #GP and return false. */
+static bool check_iopl(DisasContext *s)
+{
+    if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
+        return true;
+    }
+    gen_exception_gpf(s);
+    return false;
+}
+
 /* if d == OR_TMP0, it means memory operand (address in A0) */
 static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
 {
@@ -7095,28 +7105,16 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
 #endif
     case 0xfa: /* cli */
-        if (!s->vm86) {
-            if (s->cpl <= s->iopl) {
-                gen_helper_cli(cpu_env);
-            } else {
-                gen_exception_gpf(s);
-            }
-        } else {
-            if (s->iopl == 3) {
-                gen_helper_cli(cpu_env);
-            } else {
-                gen_exception_gpf(s);
-            }
+        if (check_iopl(s)) {
+            gen_helper_cli(cpu_env);
         }
         break;
     case 0xfb: /* sti */
-        if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
+        if (check_iopl(s)) {
             gen_helper_sti(cpu_env);
             /* interruptions are enabled only the first insn after sti */
             gen_jmp_im(s, s->pc - s->cs_base);
             gen_eob_inhibit_irq(s, true);
-        } else {
-            gen_exception_gpf(s);
         }
         break;
     case 0x62: /* bound */
-- 
2.25.1



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

* [PATCH v2 06/50] target/i386: Assert PE is set for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (4 preceding siblings ...)
  2021-05-14 15:12 ` [PATCH v2 05/50] target/i386: Split out check_iopl Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:15   ` Paolo Bonzini
  2021-05-14 15:12 ` [PATCH v2 07/50] target/i386: Assert CPL is 3 " Richard Henderson
                   ` (45 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

A user-mode executable is never in real-mode.  Since we're adding
an accessor macro, pull the value directly out of flags for sysemu.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 69 +++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 33 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 873ed00975..7f3993fccb 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -94,7 +94,6 @@ typedef struct DisasContext {
     target_ulong pc; /* pc = eip + cs_base */
     /* current block context */
     target_ulong cs_base; /* base of CS segment */
-    int pe;     /* protected mode */
     int code32; /* 32 bit code segment */
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
@@ -146,6 +145,13 @@ typedef struct DisasContext {
     sigjmp_buf jmpbuf;
 } DisasContext;
 
+/* The environment in which user-only runs is constrained. */
+#ifdef CONFIG_USER_ONLY
+#define PE(S)     true
+#else
+#define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
+#endif
+
 static void gen_eob(DisasContext *s);
 static void gen_jr(DisasContext *s, TCGv dest);
 static void gen_jmp(DisasContext *s, target_ulong eip);
@@ -617,7 +623,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
 {
     target_ulong next_eip;
 
-    if (s->pe && (s->cpl > s->iopl || s->vm86)) {
+    if (PE(s) && (s->cpl > s->iopl || s->vm86)) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         switch (ot) {
         case MO_8:
@@ -2345,7 +2351,7 @@ static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
    call this function with seg_reg == R_CS */
 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
 {
-    if (s->pe && !s->vm86) {
+    if (PE(s) && !s->vm86) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32);
         /* abort translation because the addseg value may change or
@@ -5108,7 +5114,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_add_A0_im(s, 1 << ot);
             gen_op_ld_v(s, MO_16, s->T0, s->A0);
         do_lcall:
-            if (s->pe && !s->vm86) {
+            if (PE(s) && !s->vm86) {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
                                            tcg_const_i32(dflag - 1),
@@ -5138,7 +5144,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_add_A0_im(s, 1 << ot);
             gen_op_ld_v(s, MO_16, s->T0, s->A0);
         do_ljmp:
-            if (s->pe && !s->vm86) {
+            if (PE(s) && !s->vm86) {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
                                           tcg_const_tl(s->pc - s->cs_base));
@@ -6571,7 +6577,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xca: /* lret im */
         val = x86_ldsw_code(env, s);
     do_lret:
-        if (s->pe && !s->vm86) {
+        if (PE(s) && !s->vm86) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
@@ -6597,7 +6603,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         goto do_lret;
     case 0xcf: /* iret */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
-        if (!s->pe || s->vm86) {
+        if (!PE(s) || s->vm86) {
             /* real mode or vm86 mode */
             if (!check_vm86_iopl(s)) {
                 break;
@@ -7236,7 +7242,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* For Intel SYSENTER is valid on 64-bit */
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
-        if (!s->pe) {
+        if (!PE(s)) {
             gen_exception_gpf(s);
         } else {
             gen_helper_sysenter(cpu_env);
@@ -7247,7 +7253,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* For Intel SYSEXIT is valid on 64-bit */
         if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
             goto illegal_op;
-        if (!s->pe) {
+        if (!PE(s)) {
             gen_exception_gpf(s);
         } else {
             gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
@@ -7266,7 +7272,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_eob_worker(s, false, true);
         break;
     case 0x107: /* sysret */
-        if (!s->pe) {
+        if (!PE(s)) {
             gen_exception_gpf(s);
         } else {
             gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
@@ -7301,7 +7307,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         op = (modrm >> 3) & 7;
         switch(op) {
         case 0: /* sldt */
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
@@ -7310,7 +7316,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 2: /* lldt */
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
@@ -7320,7 +7326,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             }
             break;
         case 1: /* str */
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
@@ -7329,7 +7335,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 3: /* ltr */
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
@@ -7340,7 +7346,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
         case 4: /* verr */
         case 5: /* verw */
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             gen_update_cc_op(s);
@@ -7458,7 +7464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xd8: /* VMRUN */
-            if (!(s->flags & HF_SVME_MASK) || !s->pe) {
+            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7482,7 +7488,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xda: /* VMLOAD */
-            if (!(s->flags & HF_SVME_MASK) || !s->pe) {
+            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7494,7 +7500,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdb: /* VMSAVE */
-            if (!(s->flags & HF_SVME_MASK) || !s->pe) {
+            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7508,7 +7514,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0xdc: /* STGI */
             if ((!(s->flags & HF_SVME_MASK)
                    && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
-                || !s->pe) {
+                || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7521,7 +7527,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdd: /* CLGI */
-            if (!(s->flags & HF_SVME_MASK) || !s->pe) {
+            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7535,7 +7541,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0xde: /* SKINIT */
             if ((!(s->flags & HF_SVME_MASK)
                  && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
-                || !s->pe) {
+                || !PE(s)) {
                 goto illegal_op;
             }
             gen_update_cc_op(s);
@@ -7544,7 +7550,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdf: /* INVLPGA */
-            if (!(s->flags & HF_SVME_MASK) || !s->pe) {
+            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7711,7 +7717,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             TCGLabel *label1;
             TCGv t0, t1, t2, a0;
 
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             t0 = tcg_temp_local_new();
             t1 = tcg_temp_local_new();
@@ -7759,7 +7765,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         {
             TCGLabel *label1;
             TCGv t0;
-            if (!s->pe || s->vm86)
+            if (!PE(s) || s->vm86)
                 goto illegal_op;
             ot = dflag != MO_16 ? MO_32 : MO_16;
             modrm = x86_ldub_code(env, s);
@@ -8461,9 +8467,13 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     DisasContext *dc = container_of(dcbase, DisasContext, base);
     CPUX86State *env = cpu->env_ptr;
     uint32_t flags = dc->base.tb->flags;
-    target_ulong cs_base = dc->base.tb->cs_base;
 
-    dc->pe = (flags >> HF_PE_SHIFT) & 1;
+    dc->cs_base = dc->base.tb->cs_base;
+    dc->flags = flags;
+
+    /* We make some simplifying assumptions; validate they're correct. */
+    g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
+
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
@@ -8474,7 +8484,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-    dc->cs_base = cs_base;
     dc->popl_esp_hack = 0;
     /* select memory access functions */
     dc->mem_index = 0;
@@ -8491,7 +8500,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
     dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
-    dc->flags = flags;
     dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK));
     /* Do not optimize repz jumps at all in icount mode, because
@@ -8505,11 +8513,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
        additional step for ecx=0 when icount is enabled.
      */
     dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
-#if 0
-    /* check addseg logic */
-    if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
-        printf("ERROR addseg\n");
-#endif
 
     dc->T0 = tcg_temp_new();
     dc->T1 = tcg_temp_new();
-- 
2.25.1



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

* [PATCH v2 07/50] target/i386: Assert CPL is 3 for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (5 preceding siblings ...)
  2021-05-14 15:12 ` [PATCH v2 06/50] target/i386: Assert PE is set for user-only Richard Henderson
@ 2021-05-14 15:12 ` Richard Henderson
  2021-05-18  9:17   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 08/50] target/i386: Assert IOPL is 0 " Richard Henderson
                   ` (44 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

A user-mode executable always runs in ring 3.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7f3993fccb..4c9194416d 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -94,6 +94,11 @@ typedef struct DisasContext {
     target_ulong pc; /* pc = eip + cs_base */
     /* current block context */
     target_ulong cs_base; /* base of CS segment */
+
+#ifndef CONFIG_USER_ONLY
+    uint8_t cpl;   /* code priv level */
+#endif
+
     int code32; /* 32 bit code segment */
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
@@ -111,7 +116,6 @@ typedef struct DisasContext {
     int addseg; /* non zero if either DS/ES/SS have a non zero base */
     int f_st;   /* currently unused */
     int vm86;   /* vm86 mode */
-    int cpl;
     int iopl;
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
@@ -148,8 +152,10 @@ typedef struct DisasContext {
 /* The environment in which user-only runs is constrained. */
 #ifdef CONFIG_USER_ONLY
 #define PE(S)     true
+#define CPL(S)    3
 #else
 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
+#define CPL(S)    ((S)->cpl)
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -623,7 +629,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
 {
     target_ulong next_eip;
 
-    if (PE(s) && (s->cpl > s->iopl || s->vm86)) {
+    if (PE(s) && (CPL(s) > s->iopl || s->vm86)) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         switch (ot) {
         case MO_8:
@@ -1291,7 +1297,7 @@ static void gen_exception_gpf(DisasContext *s)
 /* Check for cpl == 0; if not, raise #GP and return false. */
 static bool check_cpl0(DisasContext *s)
 {
-    if (s->cpl == 0) {
+    if (CPL(s) == 0) {
         return true;
     }
     gen_exception_gpf(s);
@@ -1311,7 +1317,7 @@ static bool check_vm86_iopl(DisasContext *s)
 /* Check for iopl allowing access; if not, raise #GP and return false. */
 static bool check_iopl(DisasContext *s)
 {
-    if (s->vm86 ? s->iopl == 3 : s->cpl <= s->iopl) {
+    if (s->vm86 ? s->iopl == 3 : CPL(s) <= s->iopl) {
         return true;
     }
     gen_exception_gpf(s);
@@ -6735,7 +6741,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
         if (check_vm86_iopl(s)) {
             ot = gen_pop_T0(s);
-            if (s->cpl == 0) {
+            if (CPL(s) == 0) {
                 if (dflag != MO_16) {
                     gen_helper_write_eflags(cpu_env, s->T0,
                                             tcg_const_i32((TF_MASK | AC_MASK |
@@ -6750,7 +6756,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                                                           & 0xffff));
                 }
             } else {
-                if (s->cpl <= s->iopl) {
+                if (CPL(s) <= s->iopl) {
                     if (dflag != MO_16) {
                         gen_helper_write_eflags(cpu_env, s->T0,
                                                 tcg_const_i32((TF_MASK |
@@ -7380,7 +7386,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xc8: /* monitor */
-            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
+            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
                 goto illegal_op;
             }
             gen_update_cc_op(s);
@@ -7392,7 +7398,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xc9: /* mwait */
-            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || s->cpl != 0) {
+            if (!(s->cpuid_ext_features & CPUID_EXT_MONITOR) || CPL(s) != 0) {
                 goto illegal_op;
             }
             gen_update_cc_op(s);
@@ -7403,7 +7409,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         case 0xca: /* clac */
             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
-                || s->cpl != 0) {
+                || CPL(s) != 0) {
                 goto illegal_op;
             }
             gen_helper_clac(cpu_env);
@@ -7413,7 +7419,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
         case 0xcb: /* stac */
             if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_SMAP)
-                || s->cpl != 0) {
+                || CPL(s) != 0) {
                 goto illegal_op;
             }
             gen_helper_stac(cpu_env);
@@ -8467,19 +8473,23 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     DisasContext *dc = container_of(dcbase, DisasContext, base);
     CPUX86State *env = cpu->env_ptr;
     uint32_t flags = dc->base.tb->flags;
+    int cpl = (flags >> HF_CPL_SHIFT) & 3;
 
     dc->cs_base = dc->base.tb->cs_base;
     dc->flags = flags;
+#ifndef CONFIG_USER_ONLY
+    dc->cpl = cpl;
+#endif
 
     /* We make some simplifying assumptions; validate they're correct. */
     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
+    g_assert(CPL(dc) == cpl);
 
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
     dc->vm86 = (flags >> VM_SHIFT) & 1;
-    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
     dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
-- 
2.25.1



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

* [PATCH v2 08/50] target/i386: Assert IOPL is 0 for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (6 preceding siblings ...)
  2021-05-14 15:12 ` [PATCH v2 07/50] target/i386: Assert CPL is 3 " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:18   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only Richard Henderson
                   ` (43 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

On real hardware, the linux kernel has the iopl(2) syscall which
can set IOPL to 3, to allow e.g. the xserver to briefly disable
interrupts while programming the graphics card.

However, QEMU cannot and does not implement this syscall, so the
IOPL is never changed from 0.  Which means that all of the checks
vs CPL <= IOPL are false for user-only.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 4c9194416d..b8cb7163ee 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -97,6 +97,7 @@ typedef struct DisasContext {
 
 #ifndef CONFIG_USER_ONLY
     uint8_t cpl;   /* code priv level */
+    uint8_t iopl;  /* i/o priv level */
 #endif
 
     int code32; /* 32 bit code segment */
@@ -116,7 +117,6 @@ typedef struct DisasContext {
     int addseg; /* non zero if either DS/ES/SS have a non zero base */
     int f_st;   /* currently unused */
     int vm86;   /* vm86 mode */
-    int iopl;
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
@@ -153,9 +153,11 @@ typedef struct DisasContext {
 #ifdef CONFIG_USER_ONLY
 #define PE(S)     true
 #define CPL(S)    3
+#define IOPL(S)   0
 #else
 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
 #define CPL(S)    ((S)->cpl)
+#define IOPL(S)   ((S)->iopl)
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -629,7 +631,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
 {
     target_ulong next_eip;
 
-    if (PE(s) && (CPL(s) > s->iopl || s->vm86)) {
+    if (PE(s) && (CPL(s) > IOPL(s) || s->vm86)) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         switch (ot) {
         case MO_8:
@@ -1307,7 +1309,7 @@ static bool check_cpl0(DisasContext *s)
 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
 static bool check_vm86_iopl(DisasContext *s)
 {
-    if (!s->vm86 || s->iopl == 3) {
+    if (!s->vm86 || IOPL(s) == 3) {
         return true;
     }
     gen_exception_gpf(s);
@@ -1317,7 +1319,7 @@ static bool check_vm86_iopl(DisasContext *s)
 /* Check for iopl allowing access; if not, raise #GP and return false. */
 static bool check_iopl(DisasContext *s)
 {
-    if (s->vm86 ? s->iopl == 3 : CPL(s) <= s->iopl) {
+    if (s->vm86 ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
         return true;
     }
     gen_exception_gpf(s);
@@ -6756,7 +6758,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                                                           & 0xffff));
                 }
             } else {
-                if (CPL(s) <= s->iopl) {
+                if (CPL(s) <= IOPL(s)) {
                     if (dflag != MO_16) {
                         gen_helper_write_eflags(cpu_env, s->T0,
                                                 tcg_const_i32((TF_MASK |
@@ -8474,23 +8476,25 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     CPUX86State *env = cpu->env_ptr;
     uint32_t flags = dc->base.tb->flags;
     int cpl = (flags >> HF_CPL_SHIFT) & 3;
+    int iopl = (flags >> IOPL_SHIFT) & 3;
 
     dc->cs_base = dc->base.tb->cs_base;
     dc->flags = flags;
 #ifndef CONFIG_USER_ONLY
     dc->cpl = cpl;
+    dc->iopl = iopl;
 #endif
 
     /* We make some simplifying assumptions; validate they're correct. */
     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
     g_assert(CPL(dc) == cpl);
+    g_assert(IOPL(dc) == iopl);
 
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
     dc->vm86 = (flags >> VM_SHIFT) & 1;
-    dc->iopl = (flags >> IOPL_SHIFT) & 3;
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-- 
2.25.1



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

* [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (7 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 08/50] target/i386: Assert IOPL is 0 " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:19   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 10/50] target/i386: Assert CODE32 " Richard Henderson
                   ` (42 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

For i386-linux-user, we can enter vm86 mode via the vm86(2) syscall.
That syscall explicitly returns to 32-bit mode, and the syscall does
not exist for a 64-bit x86_64 executable.

Since we're adding an accessor macro, pull the value directly out of
flags otherwise.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 40 ++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index b8cb7163ee..27806f35f9 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -116,7 +116,6 @@ typedef struct DisasContext {
 #endif
     int addseg; /* non zero if either DS/ES/SS have a non zero base */
     int f_st;   /* currently unused */
-    int vm86;   /* vm86 mode */
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
@@ -159,6 +158,11 @@ typedef struct DisasContext {
 #define CPL(S)    ((S)->cpl)
 #define IOPL(S)   ((S)->iopl)
 #endif
+#if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
+#define VM86(S)   false
+#else
+#define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
+#endif
 
 static void gen_eob(DisasContext *s);
 static void gen_jr(DisasContext *s, TCGv dest);
@@ -631,7 +635,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
 {
     target_ulong next_eip;
 
-    if (PE(s) && (CPL(s) > IOPL(s) || s->vm86)) {
+    if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         switch (ot) {
         case MO_8:
@@ -1309,7 +1313,7 @@ static bool check_cpl0(DisasContext *s)
 /* If vm86, check for iopl == 3; if not, raise #GP and return false. */
 static bool check_vm86_iopl(DisasContext *s)
 {
-    if (!s->vm86 || IOPL(s) == 3) {
+    if (!VM86(s) || IOPL(s) == 3) {
         return true;
     }
     gen_exception_gpf(s);
@@ -1319,7 +1323,7 @@ static bool check_vm86_iopl(DisasContext *s)
 /* Check for iopl allowing access; if not, raise #GP and return false. */
 static bool check_iopl(DisasContext *s)
 {
-    if (s->vm86 ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
+    if (VM86(s) ? IOPL(s) == 3 : CPL(s) <= IOPL(s)) {
         return true;
     }
     gen_exception_gpf(s);
@@ -2359,7 +2363,7 @@ static inline void gen_op_movl_seg_T0_vm(DisasContext *s, X86Seg seg_reg)
    call this function with seg_reg == R_CS */
 static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
 {
-    if (PE(s) && !s->vm86) {
+    if (PE(s) && !VM86(s)) {
         tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), s->tmp2_i32);
         /* abort translation because the addseg value may change or
@@ -4615,7 +4619,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xc4: /* 3-byte VEX */
         /* VEX prefixes cannot be used except in 32-bit mode.
            Otherwise the instruction is LES or LDS.  */
-        if (s->code32 && !s->vm86) {
+        if (s->code32 && !VM86(s)) {
             static const int pp_prefix[4] = {
                 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
             };
@@ -5122,7 +5126,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_add_A0_im(s, 1 << ot);
             gen_op_ld_v(s, MO_16, s->T0, s->A0);
         do_lcall:
-            if (PE(s) && !s->vm86) {
+            if (PE(s) && !VM86(s)) {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
                                            tcg_const_i32(dflag - 1),
@@ -5152,7 +5156,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_add_A0_im(s, 1 << ot);
             gen_op_ld_v(s, MO_16, s->T0, s->A0);
         do_ljmp:
-            if (PE(s) && !s->vm86) {
+            if (PE(s) && !VM86(s)) {
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
                                           tcg_const_tl(s->pc - s->cs_base));
@@ -6585,7 +6589,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xca: /* lret im */
         val = x86_ldsw_code(env, s);
     do_lret:
-        if (PE(s) && !s->vm86) {
+        if (PE(s) && !VM86(s)) {
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             gen_helper_lret_protected(cpu_env, tcg_const_i32(dflag - 1),
@@ -6611,7 +6615,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         goto do_lret;
     case 0xcf: /* iret */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
-        if (!PE(s) || s->vm86) {
+        if (!PE(s) || VM86(s)) {
             /* real mode or vm86 mode */
             if (!check_vm86_iopl(s)) {
                 break;
@@ -7315,7 +7319,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         op = (modrm >> 3) & 7;
         switch(op) {
         case 0: /* sldt */
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
@@ -7324,7 +7328,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 2: /* lldt */
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
@@ -7334,7 +7338,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             }
             break;
         case 1: /* str */
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
@@ -7343,7 +7347,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
             break;
         case 3: /* ltr */
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             if (check_cpl0(s)) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
@@ -7354,7 +7358,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
         case 4: /* verr */
         case 5: /* verw */
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             gen_update_cc_op(s);
@@ -7725,7 +7729,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             TCGLabel *label1;
             TCGv t0, t1, t2, a0;
 
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             t0 = tcg_temp_local_new();
             t1 = tcg_temp_local_new();
@@ -7773,7 +7777,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         {
             TCGLabel *label1;
             TCGv t0;
-            if (!PE(s) || s->vm86)
+            if (!PE(s) || VM86(s))
                 goto illegal_op;
             ot = dflag != MO_16 ? MO_32 : MO_16;
             modrm = x86_ldub_code(env, s);
@@ -8489,12 +8493,12 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(PE(dc) == ((flags & HF_PE_MASK) != 0));
     g_assert(CPL(dc) == cpl);
     g_assert(IOPL(dc) == iopl);
+    g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
 
     dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
-    dc->vm86 = (flags >> VM_SHIFT) & 1;
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-- 
2.25.1



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

* [PATCH v2 10/50] target/i386: Assert CODE32 for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (8 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:20   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 11/50] target/i386: Assert SS32 " Richard Henderson
                   ` (41 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

For user-only, CODE32 == !VM86, because we are never in real-mode.
Since we cannot enter vm86 mode for x86_64 user-only, CODE32 is
always set.

Since we're adding an accessor macro, pull the value directly out
of flags otherwise.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 27806f35f9..b570921410 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -100,7 +100,6 @@ typedef struct DisasContext {
     uint8_t iopl;  /* i/o priv level */
 #endif
 
-    int code32; /* 32 bit code segment */
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
     int code64; /* 64 bit code segment */
@@ -160,8 +159,10 @@ typedef struct DisasContext {
 #endif
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
 #define VM86(S)   false
+#define CODE32(S) true
 #else
 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
+#define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -2370,7 +2371,7 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
            because ss32 may change. For R_SS, translation must always
            stop as a special handling must be done to disable hardware
            interrupts for the next instruction */
-        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS)) {
+        if (seg_reg == R_SS || (CODE32(s) && seg_reg < R_FS)) {
             s->base.is_jmp = DISAS_TOO_MANY;
         }
     } else {
@@ -4619,7 +4620,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xc4: /* 3-byte VEX */
         /* VEX prefixes cannot be used except in 32-bit mode.
            Otherwise the instruction is LES or LDS.  */
-        if (s->code32 && !VM86(s)) {
+        if (CODE32(s) && !VM86(s)) {
             static const int pp_prefix[4] = {
                 0, PREFIX_DATA, PREFIX_REPZ, PREFIX_REPNZ
             };
@@ -4686,13 +4687,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
     } else {
         /* In 16/32-bit mode, 0x66 selects the opposite data size.  */
-        if (s->code32 ^ ((prefixes & PREFIX_DATA) != 0)) {
+        if (CODE32(s) ^ ((prefixes & PREFIX_DATA) != 0)) {
             dflag = MO_32;
         } else {
             dflag = MO_16;
         }
         /* In 16/32-bit mode, 0x67 selects the opposite addressing.  */
-        if (s->code32 ^ ((prefixes & PREFIX_ADR) != 0)) {
+        if (CODE32(s) ^ ((prefixes & PREFIX_ADR) != 0)) {
             aflag = MO_32;
         }  else {
             aflag = MO_16;
@@ -8494,8 +8495,8 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(CPL(dc) == cpl);
     g_assert(IOPL(dc) == iopl);
     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
+    g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
 
-    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
     dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
-- 
2.25.1



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

* [PATCH v2 11/50] target/i386: Assert SS32 for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (9 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 10/50] target/i386: Assert CODE32 " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:20   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 12/50] target/i386: Assert CODE64 " Richard Henderson
                   ` (40 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

For user-only, SS32 == !VM86, because we are never in
real-mode.  Since we cannot enter vm86 mode for x86_64
user-only, SS32 is always set.

Since we're adding an accessor macro, pull the value
directly out of flags otherwise.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index b570921410..7b5031f647 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -107,7 +107,6 @@ typedef struct DisasContext {
 #endif
     int vex_l;  /* vex vector length */
     int vex_v;  /* vex vvvv register, without 1's complement.  */
-    int ss32;   /* 32 bit stack segment */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
 #ifdef TARGET_X86_64
@@ -160,9 +159,11 @@ typedef struct DisasContext {
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
 #define VM86(S)   false
 #define CODE32(S) true
+#define SS32(S)   true
 #else
 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
+#define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -352,7 +353,7 @@ static inline MemOp mo_pushpop(DisasContext *s, MemOp ot)
 /* Select the size of the stack pointer.  */
 static inline MemOp mo_stacksize(DisasContext *s)
 {
-    return CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
+    return CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
 }
 
 /* Select only size 64 else 32.  Used for SSE operand sizes.  */
@@ -2451,12 +2452,12 @@ static inline void gen_pop_update(DisasContext *s, MemOp ot)
 
 static inline void gen_stack_A0(DisasContext *s)
 {
-    gen_lea_v_seg(s, s->ss32 ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
+    gen_lea_v_seg(s, SS32(s) ? MO_32 : MO_16, cpu_regs[R_ESP], R_SS, -1);
 }
 
 static void gen_pusha(DisasContext *s)
 {
-    MemOp s_ot = s->ss32 ? MO_32 : MO_16;
+    MemOp s_ot = SS32(s) ? MO_32 : MO_16;
     MemOp d_ot = s->dflag;
     int size = 1 << d_ot;
     int i;
@@ -2472,7 +2473,7 @@ static void gen_pusha(DisasContext *s)
 
 static void gen_popa(DisasContext *s)
 {
-    MemOp s_ot = s->ss32 ? MO_32 : MO_16;
+    MemOp s_ot = SS32(s) ? MO_32 : MO_16;
     MemOp d_ot = s->dflag;
     int size = 1 << d_ot;
     int i;
@@ -2494,7 +2495,7 @@ static void gen_popa(DisasContext *s)
 static void gen_enter(DisasContext *s, int esp_addend, int level)
 {
     MemOp d_ot = mo_pushpop(s, s->dflag);
-    MemOp a_ot = CODE64(s) ? MO_64 : s->ss32 ? MO_32 : MO_16;
+    MemOp a_ot = CODE64(s) ? MO_64 : SS32(s) ? MO_32 : MO_16;
     int size = 1 << d_ot;
 
     /* Push BP; compute FrameTemp into T1.  */
@@ -8496,8 +8497,8 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(IOPL(dc) == iopl);
     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
+    g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
 
-    dc->ss32 = (flags >> HF_SS32_SHIFT) & 1;
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
     dc->tf = (flags >> TF_SHIFT) & 1;
-- 
2.25.1



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

* [PATCH v2 12/50] target/i386: Assert CODE64 for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (10 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 11/50] target/i386: Assert SS32 " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:21   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 13/50] target/i386: Assert LMA " Richard Henderson
                   ` (39 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

For x86_64 user-only, there is no way to leave 64-bit mode.

Without x86_64, there is no way to enter 64-bit mode.  There is
an existing macro to aid with that; simply place it in the right
place in the ifdef chain.

Since we're adding an accessor macro, pull the value directly out
of flags when we're not assuming a constant.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7b5031f647..e3907f9066 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -41,11 +41,9 @@
 #define PREFIX_VEX    0x20
 
 #ifdef TARGET_X86_64
-#define CODE64(s) ((s)->code64)
 #define REX_X(s) ((s)->rex_x)
 #define REX_B(s) ((s)->rex_b)
 #else
-#define CODE64(s) 0
 #define REX_X(s) 0
 #define REX_B(s) 0
 #endif
@@ -102,7 +100,6 @@ typedef struct DisasContext {
 
 #ifdef TARGET_X86_64
     int lma;    /* long mode active */
-    int code64; /* 64 bit code segment */
     int rex_x, rex_b;
 #endif
     int vex_l;  /* vex vector length */
@@ -165,6 +162,13 @@ typedef struct DisasContext {
 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
 #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
 #endif
+#if !defined(TARGET_X86_64)
+#define CODE64(S) false
+#elif defined(CONFIG_USER_ONLY)
+#define CODE64(S) true
+#else
+#define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
+#endif
 
 static void gen_eob(DisasContext *s);
 static void gen_jr(DisasContext *s, TCGv dest);
@@ -8497,6 +8501,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(IOPL(dc) == iopl);
     g_assert(VM86(dc) == ((flags & HF_VM_MASK) != 0));
     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
+    g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
 
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
@@ -8518,7 +8523,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
 #ifdef TARGET_X86_64
     dc->lma = (flags >> HF_LMA_SHIFT) & 1;
-    dc->code64 = (flags >> HF_CS64_SHIFT) & 1;
 #endif
     dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK));
-- 
2.25.1



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

* [PATCH v2 13/50] target/i386: Assert LMA for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (11 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 12/50] target/i386: Assert CODE64 " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:21   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 14/50] target/i386: Assert !ADDSEG " Richard Henderson
                   ` (38 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

LMA is a pre-requisite for CODE64, so there is no way to disable it
for x86_64-linux-user, and there is no way to enable it for i386.

Since we're adding an accessor macro, pull the value directly out
of flags when we're not assuming a constant.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index e3907f9066..9c8a405694 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -99,7 +99,6 @@ typedef struct DisasContext {
 #endif
 
 #ifdef TARGET_X86_64
-    int lma;    /* long mode active */
     int rex_x, rex_b;
 #endif
     int vex_l;  /* vex vector length */
@@ -164,10 +163,13 @@ typedef struct DisasContext {
 #endif
 #if !defined(TARGET_X86_64)
 #define CODE64(S) false
+#define LMA(S)    false
 #elif defined(CONFIG_USER_ONLY)
 #define CODE64(S) true
+#define LMA(S)    true
 #else
 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
+#define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -7295,7 +7297,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         } else {
             gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
             /* condition codes are modified only in long mode */
-            if (s->lma) {
+            if (LMA(s)) {
                 set_cc_op(s, CC_OP_EFLAGS);
             }
             /* TF handling for the sysret insn is different. The TF bit is
@@ -8503,6 +8505,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(CODE32(dc) == ((flags & HF_CS32_MASK) != 0));
     g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
+    g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
 
     dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
@@ -8521,9 +8524,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
-#ifdef TARGET_X86_64
-    dc->lma = (flags >> HF_LMA_SHIFT) & 1;
-#endif
     dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK));
     /* Do not optimize repz jumps at all in icount mode, because
-- 
2.25.1



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

* [PATCH v2 14/50] target/i386: Assert !ADDSEG for x86_64 user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (12 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 13/50] target/i386: Assert LMA " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:23   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 15/50] target/i386: Introduce REX_PREFIX Richard Henderson
                   ` (37 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

LMA disables traditional segmentation, exposing a flat address space.
This means that ADDSEG is off.

Since we're adding an accessor macro, pull the value directly out
of flags otherwise.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 9c8a405694..7d7ab3e03d 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -108,7 +108,6 @@ typedef struct DisasContext {
 #ifdef TARGET_X86_64
     bool x86_64_hregs;
 #endif
-    int addseg; /* non zero if either DS/ES/SS have a non zero base */
     int f_st;   /* currently unused */
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
@@ -156,10 +155,12 @@ typedef struct DisasContext {
 #define VM86(S)   false
 #define CODE32(S) true
 #define SS32(S)   true
+#define ADDSEG(S) false
 #else
 #define VM86(S)   (((S)->flags & HF_VM_MASK) != 0)
 #define CODE32(S) (((S)->flags & HF_CS32_MASK) != 0)
 #define SS32(S)   (((S)->flags & HF_SS32_MASK) != 0)
+#define ADDSEG(S) (((S)->flags & HF_ADDSEG_MASK) != 0)
 #endif
 #if !defined(TARGET_X86_64)
 #define CODE64(S) false
@@ -492,7 +493,7 @@ static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
 #endif
     case MO_32:
         /* 32 bit address */
-        if (ovr_seg < 0 && s->addseg) {
+        if (ovr_seg < 0 && ADDSEG(s)) {
             ovr_seg = def_seg;
         }
         if (ovr_seg < 0) {
@@ -505,7 +506,7 @@ static void gen_lea_v_seg(DisasContext *s, MemOp aflag, TCGv a0,
         tcg_gen_ext16u_tl(s->A0, a0);
         a0 = s->A0;
         if (ovr_seg < 0) {
-            if (s->addseg) {
+            if (ADDSEG(s)) {
                 ovr_seg = def_seg;
             } else {
                 return;
@@ -2429,7 +2430,7 @@ static void gen_push_v(DisasContext *s, TCGv val)
     tcg_gen_subi_tl(s->A0, cpu_regs[R_ESP], size);
 
     if (!CODE64(s)) {
-        if (s->addseg) {
+        if (ADDSEG(s)) {
             new_esp = s->tmp4;
             tcg_gen_mov_tl(new_esp, s->A0);
         }
@@ -8506,8 +8507,8 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(CODE64(dc) == ((flags & HF_CS64_MASK) != 0));
     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
+    g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
 
-    dc->addseg = (flags >> HF_ADDSEG_SHIFT) & 1;
     dc->f_st = 0;
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
-- 
2.25.1



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

* [PATCH v2 15/50] target/i386: Introduce REX_PREFIX
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (13 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 14/50] target/i386: Assert !ADDSEG " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:26   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition Richard Henderson
                   ` (36 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The existing flag, x86_64_hregs, does not accurately describe
its setting.  It is true if and only if a REX prefix has been
seen.  Yes, that affects the "h" regs, but that's secondary.

Add PREFIX_REX and include this bit in s->prefix.  Add REX_PREFIX
so that the check folds away when x86_64 is compiled out.

Fold away the reg >= 8 check, because bit 3 of the register
number comes from the REX prefix in the first place.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 29 +++++++++++------------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7d7ab3e03d..79a37fb1a7 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -39,6 +39,7 @@
 #define PREFIX_DATA   0x08
 #define PREFIX_ADR    0x10
 #define PREFIX_VEX    0x20
+#define PREFIX_REX    0x40
 
 #ifdef TARGET_X86_64
 #define REX_X(s) ((s)->rex_x)
@@ -105,9 +106,6 @@ typedef struct DisasContext {
     int vex_v;  /* vex vvvv register, without 1's complement.  */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
-#ifdef TARGET_X86_64
-    bool x86_64_hregs;
-#endif
     int f_st;   /* currently unused */
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
@@ -173,6 +171,12 @@ typedef struct DisasContext {
 #define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
 #endif
 
+#ifdef TARGET_X86_64
+#define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
+#else
+#define REX_PREFIX(S)  false
+#endif
+
 static void gen_eob(DisasContext *s);
 static void gen_jr(DisasContext *s, TCGv dest);
 static void gen_jmp(DisasContext *s, target_ulong eip);
@@ -336,14 +340,10 @@ static void gen_update_cc_op(DisasContext *s)
  */
 static inline bool byte_reg_is_xH(DisasContext *s, int reg)
 {
-    if (reg < 4) {
+    /* Any time the REX prefix is present, byte registers are uniform */
+    if (reg < 4 || REX_PREFIX(s)) {
         return false;
     }
-#ifdef TARGET_X86_64
-    if (reg >= 8 || s->x86_64_hregs) {
-        return false;
-    }
-#endif
     return true;
 }
 
@@ -4559,7 +4559,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #ifdef TARGET_X86_64
     s->rex_x = 0;
     s->rex_b = 0;
-    s->x86_64_hregs = false;
 #endif
     s->rip_offset = 0; /* for relative ip address */
     s->vex_l = 0;
@@ -4614,12 +4613,11 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x40 ... 0x4f:
         if (CODE64(s)) {
             /* REX prefix */
+            prefixes |= PREFIX_REX;
             rex_w = (b >> 3) & 1;
             rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
             REX_B(s) = (b & 0x1) << 3;
-            /* select uniform byte register addressing */
-            s->x86_64_hregs = true;
             goto next_byte;
         }
         break;
@@ -4643,14 +4641,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
             /* 4.1.1-4.1.3: No preceding lock, 66, f2, f3, or rex prefixes. */
             if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ
-                            | PREFIX_LOCK | PREFIX_DATA)) {
+                            | PREFIX_LOCK | PREFIX_DATA | PREFIX_REX)) {
                 goto illegal_op;
             }
-#ifdef TARGET_X86_64
-            if (s->x86_64_hregs) {
-                goto illegal_op;
-            }
-#endif
             rex_r = (~vex2 >> 4) & 8;
             if (b == 0xc5) {
                 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
-- 
2.25.1



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

* [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (14 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 15/50] target/i386: Introduce REX_PREFIX Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:28   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 17/50] target/i386: Move rex_r into DisasContext Richard Henderson
                   ` (35 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Change the storage from int to uint8_t since the value is in {0,8}.
For x86_64 add 0 in the macros to (1) promote the type back to int,
and (2) make the macro an rvalue.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 79a37fb1a7..9bb37215d8 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -41,14 +41,6 @@
 #define PREFIX_VEX    0x20
 #define PREFIX_REX    0x40
 
-#ifdef TARGET_X86_64
-#define REX_X(s) ((s)->rex_x)
-#define REX_B(s) ((s)->rex_b)
-#else
-#define REX_X(s) 0
-#define REX_B(s) 0
-#endif
-
 #ifdef TARGET_X86_64
 # define ctztl  ctz64
 # define clztl  clz64
@@ -100,7 +92,8 @@ typedef struct DisasContext {
 #endif
 
 #ifdef TARGET_X86_64
-    int rex_x, rex_b;
+    uint8_t rex_x;
+    uint8_t rex_b;
 #endif
     int vex_l;  /* vex vector length */
     int vex_v;  /* vex vvvv register, without 1's complement.  */
@@ -173,8 +166,12 @@ typedef struct DisasContext {
 
 #ifdef TARGET_X86_64
 #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
+#define REX_X(S)       ((S)->rex_x + 0)
+#define REX_B(S)       ((S)->rex_b + 0)
 #else
 #define REX_PREFIX(S)  false
+#define REX_X(S)       0
+#define REX_B(S)       0
 #endif
 
 static void gen_eob(DisasContext *s);
@@ -4617,7 +4614,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             rex_w = (b >> 3) & 1;
             rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
-            REX_B(s) = (b & 0x1) << 3;
+            s->rex_b = (b & 0x1) << 3;
             goto next_byte;
         }
         break;
-- 
2.25.1



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

* [PATCH v2 17/50] target/i386: Move rex_r into DisasContext
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (15 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:28   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 18/50] target/i386: Move rex_w " Richard Henderson
                   ` (34 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Treat this flag exactly like we treat rex_b and rex_x.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 84 ++++++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 39 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 9bb37215d8..22175c6628 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -92,6 +92,7 @@ typedef struct DisasContext {
 #endif
 
 #ifdef TARGET_X86_64
+    uint8_t rex_r;
     uint8_t rex_x;
     uint8_t rex_b;
 #endif
@@ -166,10 +167,12 @@ typedef struct DisasContext {
 
 #ifdef TARGET_X86_64
 #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
+#define REX_R(S)       ((S)->rex_r + 0)
 #define REX_X(S)       ((S)->rex_x + 0)
 #define REX_B(S)       ((S)->rex_b + 0)
 #else
 #define REX_PREFIX(S)  false
+#define REX_R(S)       0
 #define REX_X(S)       0
 #define REX_B(S)       0
 #endif
@@ -3094,7 +3097,7 @@ static const struct SSEOpHelper_eppi sse_op_table7[256] = {
 };
 
 static void gen_sse(CPUX86State *env, DisasContext *s, int b,
-                    target_ulong pc_start, int rex_r)
+                    target_ulong pc_start)
 {
     int b1, op1_offset, op2_offset, is_xmm, val;
     int modrm, mod, rm, reg;
@@ -3164,8 +3167,9 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
 
     modrm = x86_ldub_code(env, s);
     reg = ((modrm >> 3) & 7);
-    if (is_xmm)
-        reg |= rex_r;
+    if (is_xmm) {
+        reg |= REX_R(s);
+    }
     mod = (modrm >> 6) & 3;
     if (sse_fn_epp == SSE_SPECIAL) {
         b |= (b1 << 8);
@@ -3699,7 +3703,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                 tcg_gen_ld16u_tl(s->T0, cpu_env,
                                 offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val)));
             }
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             gen_op_mov_reg_v(s, ot, reg, s->T0);
             break;
         case 0x1d6: /* movq ea, xmm */
@@ -3743,7 +3747,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                                  offsetof(CPUX86State, fpregs[rm].mmx));
                 gen_helper_pmovmskb_mmx(s->tmp2_i32, cpu_env, s->ptr0);
             }
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             tcg_gen_extu_i32_tl(cpu_regs[reg], s->tmp2_i32);
             break;
 
@@ -3755,7 +3759,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             }
             modrm = x86_ldub_code(env, s);
             rm = modrm & 7;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             if (b1 >= 2) {
                 goto unknown_op;
@@ -3831,7 +3835,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             /* Various integer extensions at 0f 38 f[0-f].  */
             b = modrm | (b1 << 8);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
 
             switch (b) {
             case 0x3f0: /* crc32 Gd,Eb */
@@ -4185,7 +4189,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             b = modrm;
             modrm = x86_ldub_code(env, s);
             rm = modrm & 7;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             if (b1 >= 2) {
                 goto unknown_op;
@@ -4205,7 +4209,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3)
                     gen_lea_modrm(env, s, modrm);
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 val = x86_ldub_code(env, s);
                 switch (b) {
                 case 0x14: /* pextrb */
@@ -4374,7 +4378,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
             /* Various integer extensions at 0f 3a f[0-f].  */
             b = modrm | (b1 << 8);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
 
             switch (b) {
             case 0x3f0: /* rorx Gy,Ey, Ib */
@@ -4548,12 +4552,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     MemOp ot, aflag, dflag;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
-    int rex_w, rex_r;
+    int rex_w;
     target_ulong pc_start = s->base.pc_next;
 
     s->pc_start = s->pc = pc_start;
     s->override = -1;
 #ifdef TARGET_X86_64
+    s->rex_r = 0;
     s->rex_x = 0;
     s->rex_b = 0;
 #endif
@@ -4567,7 +4572,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
     prefixes = 0;
     rex_w = -1;
-    rex_r = 0;
 
  next_byte:
     b = x86_ldub_code(env, s);
@@ -4612,7 +4616,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             /* REX prefix */
             prefixes |= PREFIX_REX;
             rex_w = (b >> 3) & 1;
-            rex_r = (b & 0x4) << 1;
+            s->rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
             s->rex_b = (b & 0x1) << 3;
             goto next_byte;
@@ -4641,7 +4645,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                             | PREFIX_LOCK | PREFIX_DATA | PREFIX_REX)) {
                 goto illegal_op;
             }
-            rex_r = (~vex2 >> 4) & 8;
+#ifdef TARGET_X86_64
+            s->rex_r = (~vex2 >> 4) & 8;
+#endif
             if (b == 0xc5) {
                 /* 2-byte VEX prefix: RVVVVlpp, implied 0f leading opcode byte */
                 vex3 = vex2;
@@ -4731,7 +4737,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             switch(f) {
             case 0: /* OP Ev, Gv */
                 modrm = x86_ldub_code(env, s);
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 mod = (modrm >> 6) & 3;
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
@@ -4753,7 +4759,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             case 1: /* OP Gv, Ev */
                 modrm = x86_ldub_code(env, s);
                 mod = (modrm >> 6) & 3;
-                reg = ((modrm >> 3) & 7) | rex_r;
+                reg = ((modrm >> 3) & 7) | REX_R(s);
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
                     gen_lea_modrm(env, s, modrm);
@@ -5179,7 +5185,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d(b, dflag);
 
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_op_mov_v_reg(s, ot, s->T1, reg);
@@ -5251,7 +5257,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6b:
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         if (b == 0x69)
             s->rip_offset = insn_const_size(ot);
         else if (b == 0x6b)
@@ -5303,7 +5309,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c1: /* xadd Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         gen_op_mov_v_reg(s, ot, s->T0, reg);
         if (mod == 3) {
@@ -5335,7 +5341,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 
             ot = mo_b_d(b, dflag);
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             oldv = tcg_temp_new();
             newv = tcg_temp_new();
@@ -5557,7 +5563,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x89: /* mov Gv, Ev */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         /* generate a generic store */
         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
@@ -5583,7 +5589,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x8b: /* mov Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_op_mov_reg_v(s, ot, reg, s->T0);
@@ -5633,7 +5639,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             s_ot = b & 8 ? MO_SIGN | ot : ot;
 
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             rm = (modrm & 7) | REX_B(s);
 
@@ -5672,7 +5678,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         {
             AddressParts a = gen_lea_modrm_0(env, s, modrm);
             TCGv ea = gen_lea_modrm_1(s, a);
@@ -5754,7 +5760,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x87: /* xchg Ev, Gv */
         ot = mo_b_d(b, dflag);
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
@@ -5791,7 +5797,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_lxx:
         ot = dflag != MO_16 ? MO_32 : MO_16;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
@@ -5874,7 +5880,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         if (mod != 3) {
             gen_lea_modrm(env, s, modrm);
             opreg = OR_TMP0;
@@ -6728,7 +6734,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_cmovcc1(env, s, ot, b, modrm, reg);
         break;
 
@@ -6874,7 +6880,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     do_btx:
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
         gen_op_mov_v_reg(s, MO_32, s->T1, reg);
@@ -6979,7 +6985,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1bd: /* bsr / lzcnt */
         ot = dflag;
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
         gen_extu(ot, s->T0);
 
@@ -7706,7 +7712,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             d_ot = dflag;
 
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             mod = (modrm >> 6) & 3;
             rm = (modrm & 7) | REX_B(s);
 
@@ -7780,7 +7786,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             ot = dflag != MO_16 ? MO_32 : MO_16;
             modrm = x86_ldub_code(env, s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             t0 = tcg_temp_local_new();
             gen_update_cc_op(s);
@@ -7821,7 +7827,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (prefixes & PREFIX_REPZ) {
                 /* bndcl */
                 if (reg >= 4
@@ -7911,7 +7917,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         if (s->flags & HF_MPX_EN_MASK) {
             mod = (modrm >> 6) & 3;
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (mod != 3 && (prefixes & PREFIX_REPZ)) {
                 /* bndmk */
                 if (reg >= 4
@@ -8023,7 +8029,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
              * are assumed to be 1's, regardless of actual values.
              */
             rm = (modrm & 7) | REX_B(s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (CODE64(s))
                 ot = MO_64;
             else
@@ -8076,7 +8082,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
              * are assumed to be 1's, regardless of actual values.
              */
             rm = (modrm & 7) | REX_B(s);
-            reg = ((modrm >> 3) & 7) | rex_r;
+            reg = ((modrm >> 3) & 7) | REX_R(s);
             if (CODE64(s))
                 ot = MO_64;
             else
@@ -8118,7 +8124,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
         /* generate a generic store */
         gen_ldst_modrm(env, s, modrm, ot, reg, 1);
         break;
@@ -8350,7 +8356,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             goto illegal_op;
 
         modrm = x86_ldub_code(env, s);
-        reg = ((modrm >> 3) & 7) | rex_r;
+        reg = ((modrm >> 3) & 7) | REX_R(s);
 
         if (s->prefix & PREFIX_DATA) {
             ot = MO_16;
@@ -8378,7 +8384,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x1c2:
     case 0x1c4 ... 0x1c6:
     case 0x1d0 ... 0x1fe:
-        gen_sse(env, s, b, pc_start, rex_r);
+        gen_sse(env, s, b, pc_start);
         break;
     default:
         goto unknown_op;
-- 
2.25.1



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

* [PATCH v2 18/50] target/i386: Move rex_w into DisasContext
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (16 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 17/50] target/i386: Move rex_r into DisasContext Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:30   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused Richard Henderson
                   ` (33 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Treat this flag exactly like we treat the other rex bits.
The -1 initialization is unused; the two tests are > 0 and == 1,
so the value can be reduced to a bool.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 22175c6628..4222f09b6f 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -95,6 +95,7 @@ typedef struct DisasContext {
     uint8_t rex_r;
     uint8_t rex_x;
     uint8_t rex_b;
+    bool rex_w;
 #endif
     int vex_l;  /* vex vector length */
     int vex_v;  /* vex vvvv register, without 1's complement.  */
@@ -167,11 +168,13 @@ typedef struct DisasContext {
 
 #ifdef TARGET_X86_64
 #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
+#define REX_W(S)       ((S)->rex_w)
 #define REX_R(S)       ((S)->rex_r + 0)
 #define REX_X(S)       ((S)->rex_x + 0)
 #define REX_B(S)       ((S)->rex_b + 0)
 #else
 #define REX_PREFIX(S)  false
+#define REX_W(S)       false
 #define REX_R(S)       0
 #define REX_X(S)       0
 #define REX_B(S)       0
@@ -4552,12 +4555,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     MemOp ot, aflag, dflag;
     int modrm, reg, rm, mod, op, opreg, val;
     target_ulong next_eip, tval;
-    int rex_w;
     target_ulong pc_start = s->base.pc_next;
 
     s->pc_start = s->pc = pc_start;
     s->override = -1;
 #ifdef TARGET_X86_64
+    s->rex_w = false;
     s->rex_r = 0;
     s->rex_x = 0;
     s->rex_b = 0;
@@ -4571,7 +4574,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     }
 
     prefixes = 0;
-    rex_w = -1;
 
  next_byte:
     b = x86_ldub_code(env, s);
@@ -4615,7 +4617,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (CODE64(s)) {
             /* REX prefix */
             prefixes |= PREFIX_REX;
-            rex_w = (b >> 3) & 1;
+            s->rex_w = (b >> 3) & 1;
             s->rex_r = (b & 0x4) << 1;
             s->rex_x = (b & 0x2) << 2;
             s->rex_b = (b & 0x1) << 3;
@@ -4654,12 +4656,12 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 b = x86_ldub_code(env, s) | 0x100;
             } else {
                 /* 3-byte VEX prefix: RXBmmmmm wVVVVlpp */
+                vex3 = x86_ldub_code(env, s);
 #ifdef TARGET_X86_64
                 s->rex_x = (~vex2 >> 3) & 8;
                 s->rex_b = (~vex2 >> 2) & 8;
+                s->rex_w = (vex3 >> 7) & 1;
 #endif
-                vex3 = x86_ldub_code(env, s);
-                rex_w = (vex3 >> 7) & 1;
                 switch (vex2 & 0x1f) {
                 case 0x01: /* Implied 0f leading opcode bytes.  */
                     b = x86_ldub_code(env, s) | 0x100;
@@ -4686,7 +4688,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /* In 64-bit mode, the default data size is 32-bit.  Select 64-bit
            data with rex_w, and 16-bit data with 0x66; rex_w takes precedence
            over 0x66 if both are present.  */
-        dflag = (rex_w > 0 ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
+        dflag = (REX_W(s) ? MO_64 : prefixes & PREFIX_DATA ? MO_16 : MO_32);
         /* In 64-bit mode, 0x67 selects 32-bit addressing.  */
         aflag = (prefixes & PREFIX_ADR ? MO_32 : MO_64);
     } else {
@@ -5082,7 +5084,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 /* operand size for jumps is 64 bit */
                 ot = MO_64;
             } else if (op == 3 || op == 5) {
-                ot = dflag != MO_16 ? MO_32 + (rex_w == 1) : MO_16;
+                ot = dflag != MO_16 ? MO_32 + REX_W(s) : MO_16;
             } else if (op == 6) {
                 /* default push size is 64 bit */
                 ot = mo_pushpop(s, dflag);
-- 
2.25.1



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

* [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (17 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 18/50] target/i386: Move rex_w " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:30   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t Richard Henderson
                   ` (32 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 4222f09b6f..7e296b39f5 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -101,7 +101,6 @@ typedef struct DisasContext {
     int vex_v;  /* vex vvvv register, without 1's complement.  */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
-    int f_st;   /* currently unused */
     int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
@@ -8507,7 +8506,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
 
-    dc->f_st = 0;
     dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-- 
2.25.1



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

* [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (18 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:30   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t Richard Henderson
                   ` (31 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The value comes from tb->flags, which is uint32_t.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 7e296b39f5..ca7f0a8cf4 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -105,7 +105,7 @@ typedef struct DisasContext {
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
     int mem_index; /* select memory access functions */
-    uint64_t flags; /* all execution flags */
+    uint32_t flags; /* all execution flags */
     int popl_esp_hack; /* for correct popl with esp base handling */
     int rip_offset; /* only used in x86_64, but left for simplicity */
     int cpuid_features;
-- 
2.25.1



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

* [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (19 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:31   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t Richard Henderson
                   ` (30 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The range of values is -1 (none) to 5 (R_GS).

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index ca7f0a8cf4..44a28858aa 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -77,7 +77,7 @@ typedef struct DisasContext {
     DisasContextBase base;
 
     /* current insn context */
-    int override; /* -1 if no override */
+    int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
     int prefix;
     MemOp aflag;
     MemOp dflag;
-- 
2.25.1



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

* [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (20 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:31   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] " Richard Henderson
                   ` (29 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The highest bit in this set is 0x40 (PREFIX_REX).

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 44a28858aa..61c0573c2f 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -78,7 +78,7 @@ typedef struct DisasContext {
 
     /* current insn context */
     int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
-    int prefix;
+    uint8_t prefix;
     MemOp aflag;
     MemOp dflag;
     target_ulong pc_start;
-- 
2.25.1



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

* [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] to uint8_t
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (21 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:32   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset " Richard Henderson
                   ` (28 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Currently, vex_l is either {0,1}; if in the future we implement
AVX-512, the max value will be 2.  In vex_v we store a register
number.  This is 0-15 for SSE, and 0-31 for AVX-512.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 61c0573c2f..1367e53e4e 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -97,8 +97,8 @@ typedef struct DisasContext {
     uint8_t rex_b;
     bool rex_w;
 #endif
-    int vex_l;  /* vex vector length */
-    int vex_v;  /* vex vvvv register, without 1's complement.  */
+    uint8_t vex_l;  /* vex vector length */
+    uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
     int tf;     /* TF cpu flag */
-- 
2.25.1



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

* [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset to uint8_t
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (22 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:34   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags Richard Henderson
                   ` (27 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Both of these fields store the size of a single memory access,
so the range of values is 0-8.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 1367e53e4e..847502046f 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -106,8 +106,8 @@ typedef struct DisasContext {
     int repz_opt; /* optimize jumps within repz instructions */
     int mem_index; /* select memory access functions */
     uint32_t flags; /* all execution flags */
-    int popl_esp_hack; /* for correct popl with esp base handling */
-    int rip_offset; /* only used in x86_64, but left for simplicity */
+    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
+    uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
     int cpuid_features;
     int cpuid_ext_features;
     int cpuid_ext2_features;
-- 
2.25.1



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

* [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (23 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:36   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool Richard Henderson
                   ` (26 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

It's just as easy to clear the flag with AND than assignment.
In two cases the test for the bit can be folded together with
the test for HF_INHIBIT_IRQ_MASK.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 847502046f..3f6214c624 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -101,7 +101,6 @@ typedef struct DisasContext {
     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
-    int tf;     /* TF cpu flag */
     int jmp_opt; /* use direct block chaining for direct jumps */
     int repz_opt; /* optimize jumps within repz instructions */
     int mem_index; /* select memory access functions */
@@ -2656,7 +2655,7 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
     } else if (recheck_tf) {
         gen_helper_rechecking_single_step(cpu_env);
         tcg_gen_exit_tb(NULL, 0);
-    } else if (s->tf) {
+    } else if (s->flags & HF_TF_MASK) {
         gen_helper_single_step(cpu_env);
     } else if (jr) {
         tcg_gen_lookup_and_goto_ptr();
@@ -5540,7 +5539,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->base.is_jmp) {
             gen_jmp_im(s, s->pc - s->cs_base);
             if (reg == R_SS) {
-                s->tf = 0;
+                s->flags &= ~HF_TF_MASK;
                 gen_eob_inhibit_irq(s, true);
             } else {
                 gen_eob(s);
@@ -5606,7 +5605,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         if (s->base.is_jmp) {
             gen_jmp_im(s, s->pc - s->cs_base);
             if (reg == R_SS) {
-                s->tf = 0;
+                s->flags &= ~HF_TF_MASK;
                 gen_eob_inhibit_irq(s, true);
             } else {
                 gen_eob(s);
@@ -8506,7 +8505,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
 
-    dc->tf = (flags >> TF_SHIFT) & 1;
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
     dc->popl_esp_hack = 0;
@@ -8521,8 +8519,8 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->cpuid_ext3_features = env->features[FEAT_8000_0001_ECX];
     dc->cpuid_7_0_ebx_features = env->features[FEAT_7_0_EBX];
     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
-    dc->jmp_opt = !(dc->tf || dc->base.singlestep_enabled ||
-                    (flags & HF_INHIBIT_IRQ_MASK));
+    dc->jmp_opt = !(dc->base.singlestep_enabled ||
+                    (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
     /* Do not optimize repz jumps at all in icount mode, because
        rep movsS instructions are execured with different paths
        in !repz_opt and repz_opt modes. The first one was used
@@ -8597,7 +8595,7 @@ static void i386_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
 
     pc_next = disas_insn(dc, cpu);
 
-    if (dc->tf || (dc->base.tb->flags & HF_INHIBIT_IRQ_MASK)) {
+    if (dc->flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)) {
         /* if single step mode, we generate only one instruction and
            generate an exception */
         /* if irq were inhibited with HF_INHIBIT_IRQ_MASK, we clear
-- 
2.25.1



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

* [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (24 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:36   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 27/50] target/i386: Fix the comment for repz_opt Richard Henderson
                   ` (25 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 3f6214c624..b9b94f0625 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -101,8 +101,8 @@ typedef struct DisasContext {
     uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
     CCOp cc_op;  /* current CC operation */
     bool cc_op_dirty;
-    int jmp_opt; /* use direct block chaining for direct jumps */
-    int repz_opt; /* optimize jumps within repz instructions */
+    bool jmp_opt; /* use direct block chaining for direct jumps */
+    bool repz_opt; /* optimize jumps within repz instructions */
     int mem_index; /* select memory access functions */
     uint32_t flags; /* all execution flags */
     uint8_t popl_esp_hack; /* for correct popl with esp base handling */
-- 
2.25.1



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

* [PATCH v2 27/50] target/i386: Fix the comment for repz_opt
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (25 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:48   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 28/50] target/i386: Reorder DisasContext members Richard Henderson
                   ` (24 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

After fixing a typo in the comment, fixup for CODING_STYLE.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index b9b94f0625..d48c0f82a9 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -8521,15 +8521,16 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
     dc->jmp_opt = !(dc->base.singlestep_enabled ||
                     (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
-    /* Do not optimize repz jumps at all in icount mode, because
-       rep movsS instructions are execured with different paths
-       in !repz_opt and repz_opt modes. The first one was used
-       always except single step mode. And this setting
-       disables jumps optimization and control paths become
-       equivalent in run and single step modes.
-       Now there will be no jump optimization for repz in
-       record/replay modes and there will always be an
-       additional step for ecx=0 when icount is enabled.
+    /*
+     * Do not optimize repz jumps at all in icount mode, because
+     * rep movsS instructions are executed with different paths
+     * in !repz_opt and repz_opt modes. The first one was used
+     * always except single step mode. And this setting
+     * disables jumps optimization and control paths become
+     * equivalent in run and single step modes.
+     * Now there will be no jump optimization for repz in
+     * record/replay modes and there will always be an
+     * additional step for ecx=0 when icount is enabled.
      */
     dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
 
-- 
2.25.1



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

* [PATCH v2 28/50] target/i386: Reorder DisasContext members
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (26 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 27/50] target/i386: Fix the comment for repz_opt Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:49   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr Richard Henderson
                   ` (23 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Sort all of the single-byte members to the same area
of the structure, eliminating 8 bytes of padding.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index d48c0f82a9..18f1c0342f 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -76,20 +76,24 @@ static TCGv_i64 cpu_bndu[4];
 typedef struct DisasContext {
     DisasContextBase base;
 
-    /* current insn context */
-    int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
-    uint8_t prefix;
+    target_ulong pc;       /* pc = eip + cs_base */
+    target_ulong pc_start; /* pc at TB entry */
+    target_ulong cs_base;  /* base of CS segment */
+
     MemOp aflag;
     MemOp dflag;
-    target_ulong pc_start;
-    target_ulong pc; /* pc = eip + cs_base */
-    /* current block context */
-    target_ulong cs_base; /* base of CS segment */
+
+    int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
+    uint8_t prefix;
 
 #ifndef CONFIG_USER_ONLY
     uint8_t cpl;   /* code priv level */
     uint8_t iopl;  /* i/o priv level */
 #endif
+    uint8_t vex_l;  /* vex vector length */
+    uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
+    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
+    uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
 
 #ifdef TARGET_X86_64
     uint8_t rex_r;
@@ -97,16 +101,13 @@ typedef struct DisasContext {
     uint8_t rex_b;
     bool rex_w;
 #endif
-    uint8_t vex_l;  /* vex vector length */
-    uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
-    CCOp cc_op;  /* current CC operation */
-    bool cc_op_dirty;
     bool jmp_opt; /* use direct block chaining for direct jumps */
     bool repz_opt; /* optimize jumps within repz instructions */
+    bool cc_op_dirty;
+
+    CCOp cc_op;  /* current CC operation */
     int mem_index; /* select memory access functions */
     uint32_t flags; /* all execution flags */
-    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
-    uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
     int cpuid_features;
     int cpuid_ext_features;
     int cpuid_ext2_features;
-- 
2.25.1



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

* [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (27 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 28/50] target/i386: Reorder DisasContext members Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:49   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 30/50] target/i386: Assert !SVME for user-only Richard Henderson
                   ` (22 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

This removes an ifdef from the middle of disas_insn,
and ensures that the branch is not reachable.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 18f1c0342f..a510dd10b1 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -179,6 +179,19 @@ typedef struct DisasContext {
 #define REX_B(S)       0
 #endif
 
+/*
+ * Many sysemu-only helpers are not reachable for user-only.
+ * Define stub generators here, so that we need not either sprinkle
+ * ifdefs through the translator, nor provide the helper function.
+ */
+#define STUB_HELPER(NAME, ...) \
+    static inline void gen_helper_##NAME(__VA_ARGS__) \
+    { qemu_build_not_reached(); }
+
+#ifdef CONFIG_USER_ONLY
+STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
+#endif
+
 static void gen_eob(DisasContext *s);
 static void gen_jr(DisasContext *s, TCGv dest);
 static void gen_jmp(DisasContext *s, target_ulong eip);
@@ -8075,7 +8088,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x121: /* mov reg, drN */
     case 0x123: /* mov drN, reg */
         if (check_cpl0(s)) {
-#ifndef CONFIG_USER_ONLY
             modrm = x86_ldub_code(env, s);
             /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
              * AMD documentation (24594.pdf) and testing of
@@ -8104,7 +8116,6 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
                 gen_op_mov_reg_v(s, ot, rm, s->T0);
             }
-#endif /* !CONFIG_USER_ONLY */
         }
         break;
     case 0x106: /* clts */
-- 
2.25.1



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

* [PATCH v2 30/50] target/i386: Assert !SVME for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (28 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:51   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 31/50] target/i386: Assert !GUEST " Richard Henderson
                   ` (21 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Most of the VMM instructions are already disabled for
user-only, by being usable only from ring 0.

The spec is intentionally loose for VMMCALL, allowing
the VMM to define syscalls for user-only.  However,
linux does not do so; VMMCALL is illegal.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index a510dd10b1..f58e0f480a 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -138,10 +138,12 @@ typedef struct DisasContext {
 #define PE(S)     true
 #define CPL(S)    3
 #define IOPL(S)   0
+#define SVME(S)   false
 #else
 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
 #define CPL(S)    ((S)->cpl)
 #define IOPL(S)   ((S)->iopl)
+#define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
 #endif
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
 #define VM86(S)   false
@@ -7495,7 +7497,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xd8: /* VMRUN */
-            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
+            if (!SVME(s) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7510,7 +7512,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xd9: /* VMMCALL */
-            if (!(s->flags & HF_SVME_MASK)) {
+            if (!SVME(s)) {
                 goto illegal_op;
             }
             gen_update_cc_op(s);
@@ -7519,7 +7521,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xda: /* VMLOAD */
-            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
+            if (!SVME(s) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7531,7 +7533,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdb: /* VMSAVE */
-            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
+            if (!SVME(s) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7543,8 +7545,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdc: /* STGI */
-            if ((!(s->flags & HF_SVME_MASK)
-                   && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
+            if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
                 || !PE(s)) {
                 goto illegal_op;
             }
@@ -7558,7 +7559,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdd: /* CLGI */
-            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
+            if (!SVME(s) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -7570,8 +7571,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xde: /* SKINIT */
-            if ((!(s->flags & HF_SVME_MASK)
-                 && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
+            if ((!SVME(s) && !(s->cpuid_ext3_features & CPUID_EXT3_SKINIT))
                 || !PE(s)) {
                 goto illegal_op;
             }
@@ -7581,7 +7581,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         case 0xdf: /* INVLPGA */
-            if (!(s->flags & HF_SVME_MASK) || !PE(s)) {
+            if (!SVME(s) || !PE(s)) {
                 goto illegal_op;
             }
             if (!check_cpl0(s)) {
@@ -8516,6 +8516,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(SS32(dc) == ((flags & HF_SS32_MASK) != 0));
     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
+    g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
 
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-- 
2.25.1



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

* [PATCH v2 31/50] target/i386: Assert !GUEST for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (29 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 30/50] target/i386: Assert !SVME for user-only Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:51   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 32/50] target/i386: Implement skinit in translate.c Richard Henderson
                   ` (20 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

For user-only, we do not need to check for VMM intercept.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index f58e0f480a..57ae515796 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -139,11 +139,13 @@ typedef struct DisasContext {
 #define CPL(S)    3
 #define IOPL(S)   0
 #define SVME(S)   false
+#define GUEST(S)  false
 #else
 #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
 #define CPL(S)    ((S)->cpl)
 #define IOPL(S)   ((S)->iopl)
 #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
+#define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
 #endif
 #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
 #define VM86(S)   false
@@ -677,7 +679,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
             tcg_abort();
         }
     }
-    if(s->flags & HF_GUEST_MASK) {
+    if (GUEST(s)) {
         gen_update_cc_op(s);
         gen_jmp_im(s, cur_eip);
         svm_flags |= (1 << (4 + ot));
@@ -2417,8 +2419,9 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
                               uint32_t type, uint64_t param)
 {
     /* no SVM activated; fast case */
-    if (likely(!(s->flags & HF_GUEST_MASK)))
+    if (likely(!GUEST(s))) {
         return;
+    }
     gen_update_cc_op(s);
     gen_jmp_im(s, pc_start - s->cs_base);
     gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
@@ -8517,6 +8520,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
     g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
     g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
     g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
+    g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
 
     dc->cc_op = CC_OP_DYNAMIC;
     dc->cc_op_dirty = false;
-- 
2.25.1



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

* [PATCH v2 32/50] target/i386: Implement skinit in translate.c
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (30 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 31/50] target/i386: Assert !GUEST " Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:51   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only Richard Henderson
                   ` (19 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Our sysemu implementation is a stub.  We can already intercept
instructions for vmexit, and raising #UD is trivial.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                | 1 -
 target/i386/tcg/sysemu/svm_helper.c | 7 -------
 target/i386/tcg/translate.c         | 7 +++----
 target/i386/tcg/user/svm_stubs.c    | 4 ----
 4 files changed, 3 insertions(+), 16 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 095520f81f..7a09efd55b 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -117,7 +117,6 @@ DEF_HELPER_2(vmload, void, env, int)
 DEF_HELPER_2(vmsave, void, env, int)
 DEF_HELPER_1(stgi, void, env)
 DEF_HELPER_1(clgi, void, env)
-DEF_HELPER_1(skinit, void, env)
 DEF_HELPER_2(invlpga, void, env, int)
 
 /* x86 FPU */
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index c4e8e717a9..79c73d67af 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -412,13 +412,6 @@ void helper_clgi(CPUX86State *env)
     env->hflags2 &= ~HF2_GIF_MASK;
 }
 
-void helper_skinit(CPUX86State *env)
-{
-    cpu_svm_check_intercept_param(env, SVM_EXIT_SKINIT, 0, GETPC());
-    /* XXX: not implemented */
-    raise_exception(env, EXCP06_ILLOP);
-}
-
 void helper_invlpga(CPUX86State *env, int aflag)
 {
     X86CPU *cpu = env_archcpu(env);
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 57ae515796..aeb72cd846 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -7578,10 +7578,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 || !PE(s)) {
                 goto illegal_op;
             }
-            gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_skinit(cpu_env);
-            break;
+            gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT);
+            /* If not intercepted, not implemented -- raise #UD. */
+            goto illegal_op;
 
         case 0xdf: /* INVLPGA */
             if (!SVME(s) || !PE(s)) {
diff --git a/target/i386/tcg/user/svm_stubs.c b/target/i386/tcg/user/svm_stubs.c
index 97528b56ad..63b37f0de6 100644
--- a/target/i386/tcg/user/svm_stubs.c
+++ b/target/i386/tcg/user/svm_stubs.c
@@ -46,10 +46,6 @@ void helper_clgi(CPUX86State *env)
 {
 }
 
-void helper_skinit(CPUX86State *env)
-{
-}
-
 void helper_invlpga(CPUX86State *env, int aflag)
 {
 }
-- 
2.25.1



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

* [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (31 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 32/50] target/i386: Implement skinit in translate.c Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:52   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 34/50] target/i386: Mark some helpers as noreturn Richard Henderson
                   ` (18 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Use STUB_HELPER to ensure that such calls are always eliminated.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h             |  3 +--
 target/i386/tcg/translate.c      |  9 ++++++++
 target/i386/tcg/user/svm_stubs.c | 38 --------------------------------
 3 files changed, 10 insertions(+), 40 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 7a09efd55b..d0f7f07c6c 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -107,8 +107,6 @@ DEF_HELPER_2(inl, tl, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
-#endif /* !CONFIG_USER_ONLY */
-
 DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
 DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32)
 DEF_HELPER_3(vmrun, void, env, int, int)
@@ -118,6 +116,7 @@ DEF_HELPER_2(vmsave, void, env, int)
 DEF_HELPER_1(stgi, void, env)
 DEF_HELPER_1(clgi, void, env)
 DEF_HELPER_2(invlpga, void, env, int)
+#endif /* !CONFIG_USER_ONLY */
 
 /* x86 FPU */
 
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index aeb72cd846..9af0d6f2b5 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -193,7 +193,16 @@ typedef struct DisasContext {
     { qemu_build_not_reached(); }
 
 #ifdef CONFIG_USER_ONLY
+STUB_HELPER(clgi, TCGv_env env)
+STUB_HELPER(invlpga, TCGv_env env, TCGv_i32 aflag)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
+STUB_HELPER(stgi, TCGv_env env)
+STUB_HELPER(svm_check_intercept_param, TCGv_env env, TCGv_i32 t, TCGv_i64 p)
+STUB_HELPER(svm_check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 p, TCGv_i32 a)
+STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
+STUB_HELPER(vmmcall, TCGv_env env)
+STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
+STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
 #endif
 
 static void gen_eob(DisasContext *s);
diff --git a/target/i386/tcg/user/svm_stubs.c b/target/i386/tcg/user/svm_stubs.c
index 63b37f0de6..48a43bdcea 100644
--- a/target/i386/tcg/user/svm_stubs.c
+++ b/target/i386/tcg/user/svm_stubs.c
@@ -22,51 +22,13 @@
 #include "exec/helper-proto.h"
 #include "tcg/helper-tcg.h"
 
-void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
-{
-}
-
-void helper_vmmcall(CPUX86State *env)
-{
-}
-
-void helper_vmload(CPUX86State *env, int aflag)
-{
-}
-
-void helper_vmsave(CPUX86State *env, int aflag)
-{
-}
-
-void helper_stgi(CPUX86State *env)
-{
-}
-
-void helper_clgi(CPUX86State *env)
-{
-}
-
-void helper_invlpga(CPUX86State *env, int aflag)
-{
-}
-
 void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1,
                 uintptr_t retaddr)
 {
     assert(0);
 }
 
-void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
-                                      uint64_t param)
-{
-}
-
 void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                                    uint64_t param, uintptr_t retaddr)
 {
 }
-
-void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
-                         uint32_t next_eip_addend)
-{
-}
-- 
2.25.1



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

* [PATCH v2 34/50] target/i386: Mark some helpers as noreturn
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (32 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:56   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 35/50] target/i386: Simplify gen_debug usage Richard Henderson
                   ` (17 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Any helper that always raises an exception or interrupt,
or simply exits to the main loop, can be so marked.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h          | 18 +++++++++---------
 target/i386/tcg/bpt_helper.c  |  2 +-
 target/i386/tcg/excp_helper.c | 18 ++++++++++--------
 target/i386/tcg/misc_helper.c | 14 +++++++-------
 target/i386/tcg/translate.c   |  3 ++-
 5 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index d0f7f07c6c..f794d1c7c7 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -60,14 +60,14 @@ DEF_HELPER_2(sysexit, void, env, int)
 DEF_HELPER_2(syscall, void, env, int)
 DEF_HELPER_2(sysret, void, env, int)
 #endif
-DEF_HELPER_2(hlt, void, env, int)
-DEF_HELPER_2(monitor, void, env, tl)
-DEF_HELPER_2(mwait, void, env, int)
-DEF_HELPER_2(pause, void, env, int)
-DEF_HELPER_1(debug, void, env)
+DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
+DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_1(debug, TCG_CALL_NO_WG, noreturn, env)
 DEF_HELPER_1(reset_rf, void, env)
-DEF_HELPER_3(raise_interrupt, void, env, int, int)
-DEF_HELPER_2(raise_exception, void, env, int)
+DEF_HELPER_FLAGS_3(raise_interrupt, TCG_CALL_NO_WG, noreturn, env, int, int)
+DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, noreturn, env, int)
 DEF_HELPER_1(cli, void, env)
 DEF_HELPER_1(sti, void, env)
 DEF_HELPER_1(clac, void, env)
@@ -86,12 +86,12 @@ DEF_HELPER_2(cmpxchg8b, void, env, tl)
 DEF_HELPER_2(cmpxchg16b_unlocked, void, env, tl)
 DEF_HELPER_2(cmpxchg16b, void, env, tl)
 #endif
-DEF_HELPER_1(single_step, void, env)
+DEF_HELPER_FLAGS_1(single_step, TCG_CALL_NO_WG, noreturn, env)
 DEF_HELPER_1(rechecking_single_step, void, env)
 DEF_HELPER_1(cpuid, void, env)
 DEF_HELPER_1(rdtsc, void, env)
 DEF_HELPER_1(rdtscp, void, env)
-DEF_HELPER_1(rdpmc, void, env)
+DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
 DEF_HELPER_1(rdmsr, void, env)
 DEF_HELPER_1(wrmsr, void, env)
 
diff --git a/target/i386/tcg/bpt_helper.c b/target/i386/tcg/bpt_helper.c
index fb2a65ac9c..83cd89581e 100644
--- a/target/i386/tcg/bpt_helper.c
+++ b/target/i386/tcg/bpt_helper.c
@@ -22,7 +22,7 @@
 #include "exec/helper-proto.h"
 #include "helper-tcg.h"
 
-void helper_single_step(CPUX86State *env)
+void QEMU_NORETURN helper_single_step(CPUX86State *env)
 {
 #ifndef CONFIG_USER_ONLY
     check_hw_breakpoints(env, true);
diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c
index 0183f3932e..bdae887d0a 100644
--- a/target/i386/tcg/excp_helper.c
+++ b/target/i386/tcg/excp_helper.c
@@ -25,12 +25,13 @@
 #include "exec/helper-proto.h"
 #include "helper-tcg.h"
 
-void helper_raise_interrupt(CPUX86State *env, int intno, int next_eip_addend)
+void QEMU_NORETURN helper_raise_interrupt(CPUX86State *env, int intno,
+                                          int next_eip_addend)
 {
     raise_interrupt(env, intno, 1, 0, next_eip_addend);
 }
 
-void helper_raise_exception(CPUX86State *env, int exception_index)
+void QEMU_NORETURN helper_raise_exception(CPUX86State *env, int exception_index)
 {
     raise_exception(env, exception_index);
 }
@@ -116,24 +117,25 @@ void QEMU_NORETURN raise_interrupt(CPUX86State *env, int intno, int is_int,
     raise_interrupt2(env, intno, is_int, error_code, next_eip_addend, 0);
 }
 
-void raise_exception_err(CPUX86State *env, int exception_index,
-                         int error_code)
+void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index,
+                                       int error_code)
 {
     raise_interrupt2(env, exception_index, 0, error_code, 0, 0);
 }
 
-void raise_exception_err_ra(CPUX86State *env, int exception_index,
-                            int error_code, uintptr_t retaddr)
+void QEMU_NORETURN raise_exception_err_ra(CPUX86State *env, int exception_index,
+                                          int error_code, uintptr_t retaddr)
 {
     raise_interrupt2(env, exception_index, 0, error_code, 0, retaddr);
 }
 
-void raise_exception(CPUX86State *env, int exception_index)
+void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index)
 {
     raise_interrupt2(env, exception_index, 0, 0, 0, 0);
 }
 
-void raise_exception_ra(CPUX86State *env, int exception_index, uintptr_t retaddr)
+void QEMU_NORETURN raise_exception_ra(CPUX86State *env, int exception_index,
+                                      uintptr_t retaddr)
 {
     raise_interrupt2(env, exception_index, 0, 0, 0, retaddr);
 }
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index a30379283e..0e9a4f0bfc 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -96,7 +96,7 @@ void helper_rdtscp(CPUX86State *env)
     env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
 }
 
-void helper_rdpmc(CPUX86State *env)
+void QEMU_NORETURN helper_rdpmc(CPUX86State *env)
 {
     if (((env->cr[4] & CR4_PCE_MASK) == 0 ) &&
         ((env->hflags & HF_CPL_MASK) != 0)) {
@@ -109,7 +109,7 @@ void helper_rdpmc(CPUX86State *env)
     raise_exception_err(env, EXCP06_ILLOP, 0);
 }
 
-static void do_pause(X86CPU *cpu)
+static QEMU_NORETURN void do_pause(X86CPU *cpu)
 {
     CPUState *cs = CPU(cpu);
 
@@ -118,7 +118,7 @@ static void do_pause(X86CPU *cpu)
     cpu_loop_exit(cs);
 }
 
-static void do_hlt(X86CPU *cpu)
+static QEMU_NORETURN void do_hlt(X86CPU *cpu)
 {
     CPUState *cs = CPU(cpu);
     CPUX86State *env = &cpu->env;
@@ -129,7 +129,7 @@ static void do_hlt(X86CPU *cpu)
     cpu_loop_exit(cs);
 }
 
-void helper_hlt(CPUX86State *env, int next_eip_addend)
+void QEMU_NORETURN helper_hlt(CPUX86State *env, int next_eip_addend)
 {
     X86CPU *cpu = env_archcpu(env);
 
@@ -148,7 +148,7 @@ void helper_monitor(CPUX86State *env, target_ulong ptr)
     cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
 }
 
-void helper_mwait(CPUX86State *env, int next_eip_addend)
+void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
 {
     CPUState *cs = env_cpu(env);
     X86CPU *cpu = env_archcpu(env);
@@ -167,7 +167,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     }
 }
 
-void helper_pause(CPUX86State *env, int next_eip_addend)
+void QEMU_NORETURN helper_pause(CPUX86State *env, int next_eip_addend)
 {
     X86CPU *cpu = env_archcpu(env);
 
@@ -177,7 +177,7 @@ void helper_pause(CPUX86State *env, int next_eip_addend)
     do_pause(cpu);
 }
 
-void helper_debug(CPUX86State *env)
+void QEMU_NORETURN helper_debug(CPUX86State *env)
 {
     CPUState *cs = env_cpu(env);
 
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 9af0d6f2b5..8419aaa62c 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -7282,6 +7282,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_update_cc_op(s);
         gen_jmp_im(s, pc_start - s->cs_base);
         gen_helper_rdpmc(cpu_env);
+        s->base.is_jmp = DISAS_NORETURN;
         break;
     case 0x134: /* sysenter */
         /* For Intel SYSENTER is valid on 64-bit */
@@ -7443,7 +7444,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             gen_update_cc_op(s);
             gen_jmp_im(s, pc_start - s->cs_base);
             gen_helper_mwait(cpu_env, tcg_const_i32(s->pc - pc_start));
-            gen_eob(s);
+            s->base.is_jmp = DISAS_NORETURN;
             break;
 
         case 0xca: /* clac */
-- 
2.25.1



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

* [PATCH v2 35/50] target/i386: Simplify gen_debug usage
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (33 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 34/50] target/i386: Mark some helpers as noreturn Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:56   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg Richard Henderson
                   ` (16 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Both invocations pass the start of the current instruction,
which is available as s->base.pc_next.  The function sets
is_jmp, so we can eliminate a second setting.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 8419aaa62c..8a02c5a373 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2614,10 +2614,10 @@ static void gen_interrupt(DisasContext *s, int intno,
     s->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_debug(DisasContext *s, target_ulong cur_eip)
+static void gen_debug(DisasContext *s)
 {
     gen_update_cc_op(s);
-    gen_jmp_im(s, cur_eip);
+    gen_jmp_im(s, s->base.pc_next - s->cs_base);
     gen_helper_debug(cpu_env);
     s->base.is_jmp = DISAS_NORETURN;
 }
@@ -7152,7 +7152,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
 #ifdef WANT_ICEBP
     case 0xf1: /* icebp (undocumented, exits to external debugger) */
         gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
-        gen_debug(s, pc_start - s->cs_base);
+        gen_debug(s);
         break;
 #endif
     case 0xfa: /* cli */
@@ -8592,8 +8592,7 @@ static bool i386_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
     /* If RF is set, suppress an internally generated breakpoint.  */
     int flags = dc->base.tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY;
     if (bp->flags & flags) {
-        gen_debug(dc, dc->base.pc_next - dc->cs_base);
-        dc->base.is_jmp = DISAS_NORETURN;
+        gen_debug(dc);
         /* The address covered by the breakpoint must be included in
            [tb->pc, tb->pc + tb->size) in order to for it to be
            properly cleared -- thus we increment the PC here so that
-- 
2.25.1



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

* [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (34 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 35/50] target/i386: Simplify gen_debug usage Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:57   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept Richard Henderson
                   ` (15 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The param argument to helper_svm_check_intercept_param is always 0;
eliminate it and rename to helper_svm_check_intercept.  Fold
gen_sve_check_intercept_param into gen_svm_check_intercept.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                |  2 +-
 target/i386/tcg/sysemu/svm_helper.c |  5 ++---
 target/i386/tcg/translate.c         | 16 ++++------------
 3 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index f794d1c7c7..86484a4ec4 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -107,7 +107,7 @@ DEF_HELPER_2(inl, tl, env, i32)
 
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
-DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
+DEF_HELPER_2(svm_check_intercept, void, env, i32)
 DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32)
 DEF_HELPER_3(vmrun, void, env, int, int)
 DEF_HELPER_1(vmmcall, void, env)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 79c73d67af..b431016e72 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -506,10 +506,9 @@ void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
     }
 }
 
-void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
-                                      uint64_t param)
+void helper_svm_check_intercept(CPUX86State *env, uint32_t type)
 {
-    cpu_svm_check_intercept_param(env, type, param, GETPC());
+    cpu_svm_check_intercept_param(env, type, 0, GETPC());
 }
 
 void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 8a02c5a373..12ef2cf064 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -197,7 +197,7 @@ STUB_HELPER(clgi, TCGv_env env)
 STUB_HELPER(invlpga, TCGv_env env, TCGv_i32 aflag)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
 STUB_HELPER(stgi, TCGv_env env)
-STUB_HELPER(svm_check_intercept_param, TCGv_env env, TCGv_i32 t, TCGv_i64 p)
+STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
 STUB_HELPER(svm_check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 p, TCGv_i32 a)
 STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
 STUB_HELPER(vmmcall, TCGv_env env)
@@ -2423,9 +2423,8 @@ static inline int svm_is_rep(int prefixes)
     return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
 }
 
-static inline void
-gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
-                              uint32_t type, uint64_t param)
+static void gen_svm_check_intercept(DisasContext *s, target_ulong pc_start,
+                                    uint32_t type)
 {
     /* no SVM activated; fast case */
     if (likely(!GUEST(s))) {
@@ -2433,14 +2432,7 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
     }
     gen_update_cc_op(s);
     gen_jmp_im(s, pc_start - s->cs_base);
-    gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
-                                         tcg_const_i64(param));
-}
-
-static inline void
-gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
-{
-    gen_svm_check_intercept_param(s, pc_start, type, 0);
+    gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type));
 }
 
 static inline void gen_stack_update(DisasContext *s, int addend)
-- 
2.25.1



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

* [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (35 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:58   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit Richard Henderson
                   ` (14 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

When exiting helper_svm_check_intercept via exception, cpu_vmexit
calls cpu_restore_state, which will recover eip and cc_op via unwind.
Therefore we do not need to store eip or cc_op before the call.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 45 +++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 12ef2cf064..d0fef4cce8 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2423,15 +2423,12 @@ static inline int svm_is_rep(int prefixes)
     return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
 }
 
-static void gen_svm_check_intercept(DisasContext *s, target_ulong pc_start,
-                                    uint32_t type)
+static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
 {
     /* no SVM activated; fast case */
     if (likely(!GUEST(s))) {
         return;
     }
-    gen_update_cc_op(s);
-    gen_jmp_im(s, pc_start - s->cs_base);
     gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type));
 }
 
@@ -6639,7 +6636,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         val = 0;
         goto do_lret;
     case 0xcf: /* iret */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_IRET);
+        gen_svm_check_intercept(s, SVM_EXIT_IRET);
         if (!PE(s) || VM86(s)) {
             /* real mode or vm86 mode */
             if (!check_vm86_iopl(s)) {
@@ -6761,7 +6758,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         /************************/
         /* flags */
     case 0x9c: /* pushf */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
+        gen_svm_check_intercept(s, SVM_EXIT_PUSHF);
         if (check_vm86_iopl(s)) {
             gen_update_cc_op(s);
             gen_helper_read_eflags(s->T0, cpu_env);
@@ -6769,7 +6766,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         }
         break;
     case 0x9d: /* popf */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
+        gen_svm_check_intercept(s, SVM_EXIT_POPF);
         if (check_vm86_iopl(s)) {
             ot = gen_pop_T0(s);
             if (CPL(s) == 0) {
@@ -7143,7 +7140,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
 #ifdef WANT_ICEBP
     case 0xf1: /* icebp (undocumented, exits to external debugger) */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_ICEBP);
+        gen_svm_check_intercept(s, SVM_EXIT_ICEBP);
         gen_debug(s);
         break;
 #endif
@@ -7347,7 +7344,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 0: /* sldt */
             if (!PE(s) || VM86(s))
                 goto illegal_op;
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_READ);
+            gen_svm_check_intercept(s, SVM_EXIT_LDTR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, ldt.selector));
             ot = mod == 3 ? dflag : MO_16;
@@ -7357,7 +7354,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!PE(s) || VM86(s))
                 goto illegal_op;
             if (check_cpl0(s)) {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
+                gen_svm_check_intercept(s, SVM_EXIT_LDTR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_lldt(cpu_env, s->tmp2_i32);
@@ -7366,7 +7363,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         case 1: /* str */
             if (!PE(s) || VM86(s))
                 goto illegal_op;
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_READ);
+            gen_svm_check_intercept(s, SVM_EXIT_TR_READ);
             tcg_gen_ld32u_tl(s->T0, cpu_env,
                              offsetof(CPUX86State, tr.selector));
             ot = mod == 3 ? dflag : MO_16;
@@ -7376,7 +7373,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!PE(s) || VM86(s))
                 goto illegal_op;
             if (check_cpl0(s)) {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
+                gen_svm_check_intercept(s, SVM_EXIT_TR_WRITE);
                 gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
                 tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
                 gen_helper_ltr(cpu_env, s->tmp2_i32);
@@ -7404,7 +7401,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         switch (modrm) {
         CASE_MODRM_MEM_OP(0): /* sgdt */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_READ);
+            gen_svm_check_intercept(s, SVM_EXIT_GDTR_READ);
             gen_lea_modrm(env, s, modrm);
             tcg_gen_ld32u_tl(s->T0,
                              cpu_env, offsetof(CPUX86State, gdt.limit));
@@ -7460,7 +7457,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_MEM_OP(1): /* sidt */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_READ);
+            gen_svm_check_intercept(s, SVM_EXIT_IDTR_READ);
             gen_lea_modrm(env, s, modrm);
             tcg_gen_ld32u_tl(s->T0, cpu_env, offsetof(CPUX86State, idt.limit));
             gen_op_st_v(s, MO_16, s->T0, s->A0);
@@ -7580,7 +7577,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 || !PE(s)) {
                 goto illegal_op;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_SKINIT);
+            gen_svm_check_intercept(s, SVM_EXIT_SKINIT);
             /* If not intercepted, not implemented -- raise #UD. */
             goto illegal_op;
 
@@ -7600,7 +7597,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!check_cpl0(s)) {
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
+            gen_svm_check_intercept(s, SVM_EXIT_GDTR_WRITE);
             gen_lea_modrm(env, s, modrm);
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
@@ -7616,7 +7613,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!check_cpl0(s)) {
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
+            gen_svm_check_intercept(s, SVM_EXIT_IDTR_WRITE);
             gen_lea_modrm(env, s, modrm);
             gen_op_ld_v(s, MO_16, s->T1, s->A0);
             gen_add_A0_im(s, 2);
@@ -7629,7 +7626,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             break;
 
         CASE_MODRM_OP(4): /* smsw */
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_CR0);
+            gen_svm_check_intercept(s, SVM_EXIT_READ_CR0);
             tcg_gen_ld_tl(s->T0, cpu_env, offsetof(CPUX86State, cr[0]));
             /*
              * In 32-bit mode, the higher 16 bits of the destination
@@ -7661,7 +7658,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!check_cpl0(s)) {
                 break;
             }
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
+            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
             gen_helper_lmsw(cpu_env, s->T0);
             gen_jmp_im(s, s->pc - s->cs_base);
@@ -7718,7 +7715,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x108: /* invd */
     case 0x109: /* wbinvd */
         if (check_cpl0(s)) {
-            gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
+            gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
             /* nothing to do */
         }
         break;
@@ -8108,14 +8105,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 goto illegal_op;
             }
             if (b & 2) {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
+                gen_svm_check_intercept(s, SVM_EXIT_WRITE_DR0 + reg);
                 gen_op_mov_v_reg(s, ot, s->T0, rm);
                 tcg_gen_movi_i32(s->tmp2_i32, reg);
                 gen_helper_set_dr(cpu_env, s->tmp2_i32, s->T0);
                 gen_jmp_im(s, s->pc - s->cs_base);
                 gen_eob(s);
             } else {
-                gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
+                gen_svm_check_intercept(s, SVM_EXIT_READ_DR0 + reg);
                 tcg_gen_movi_i32(s->tmp2_i32, reg);
                 gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32);
                 gen_op_mov_reg_v(s, ot, rm, s->T0);
@@ -8124,7 +8121,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         break;
     case 0x106: /* clts */
         if (check_cpl0(s)) {
-            gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
+            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
             gen_helper_clts(cpu_env);
             /* abort block because static cpu state changed */
             gen_jmp_im(s, s->pc - s->cs_base);
@@ -8351,7 +8348,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         gen_nop_modrm(env, s, modrm);
         break;
     case 0x1aa: /* rsm */
-        gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM);
+        gen_svm_check_intercept(s, SVM_EXIT_RSM);
         if (!(s->flags & HF_SMM_MASK))
             goto illegal_op;
 #ifdef CONFIG_USER_ONLY
-- 
2.25.1



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

* [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (36 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:58   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw Richard Henderson
                   ` (13 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

This function is only called from tcg/sysemu/.
There is no need for a stub in tcg/user/.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/helper-tcg.h     | 4 +++-
 target/i386/tcg/user/svm_stubs.c | 6 ------
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 97fb7a226a..85a8b0ebd6 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -77,10 +77,12 @@ extern const uint8_t parity_table[256];
 /* misc_helper.c */
 void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask);
 
-/* svm_helper.c */
+/* sysemu/svm_helper.c */
+#ifndef CONFIG_USER_ONLY
 void QEMU_NORETURN cpu_vmexit(CPUX86State *nenv, uint32_t exit_code,
                               uint64_t exit_info_1, uintptr_t retaddr);
 void do_vmexit(CPUX86State *env);
+#endif
 
 /* seg_helper.c */
 void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
diff --git a/target/i386/tcg/user/svm_stubs.c b/target/i386/tcg/user/svm_stubs.c
index 48a43bdcea..db818f89a8 100644
--- a/target/i386/tcg/user/svm_stubs.c
+++ b/target/i386/tcg/user/svm_stubs.c
@@ -22,12 +22,6 @@
 #include "exec/helper-proto.h"
 #include "tcg/helper-tcg.h"
 
-void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1,
-                uintptr_t retaddr)
-{
-    assert(0);
-}
-
 void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                                    uint64_t param, uintptr_t retaddr)
 {
-- 
2.25.1



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

* [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (37 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:30   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt Richard Henderson
                   ` (12 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Pull the svm intercept check into the translator.
Pull the entire implementation of lmsw into the translator.
Push the check for CR8LEG into the regno validation switch.
Unify the gen_io_start check between read/write.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                 |  5 +-
 target/i386/tcg/misc_helper.c        |  8 ---
 target/i386/tcg/sysemu/misc_helper.c |  2 -
 target/i386/tcg/translate.c          | 97 +++++++++++++++-------------
 4 files changed, 54 insertions(+), 58 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 86484a4ec4..ebfaca66dd 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -42,9 +42,8 @@ DEF_HELPER_5(lcall_protected, void, env, int, tl, int, tl)
 DEF_HELPER_2(iret_real, void, env, int)
 DEF_HELPER_3(iret_protected, void, env, int, int)
 DEF_HELPER_3(lret_protected, void, env, int, int)
-DEF_HELPER_2(read_crN, tl, env, int)
-DEF_HELPER_3(write_crN, void, env, int, tl)
-DEF_HELPER_2(lmsw, void, env, tl)
+DEF_HELPER_FLAGS_2(read_crN, TCG_CALL_NO_RWG, tl, env, int)
+DEF_HELPER_FLAGS_3(write_crN, TCG_CALL_NO_RWG, void, env, int, tl)
 DEF_HELPER_1(clts, void, env)
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index 0e9a4f0bfc..931dbd9db0 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -60,14 +60,6 @@ void helper_cpuid(CPUX86State *env)
     env->regs[R_EDX] = edx;
 }
 
-void helper_lmsw(CPUX86State *env, target_ulong t0)
-{
-    /* only 4 lower bits of CR0 are modified. PE cannot be set to zero
-       if already set to one. */
-    t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
-    helper_write_crN(env, 0, t0);
-}
-
 void helper_invlpg(CPUX86State *env, target_ulong addr)
 {
     X86CPU *cpu = env_archcpu(env);
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index 66e7939537..c7381ef7e8 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -65,7 +65,6 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
 {
     target_ulong val;
 
-    cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC());
     switch (reg) {
     default:
         val = env->cr[reg];
@@ -83,7 +82,6 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
 
 void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
 {
-    cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC());
     switch (reg) {
     case 0:
         cpu_x86_update_cr0(env, t0);
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index d0fef4cce8..6804835712 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -7654,13 +7654,22 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
             gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
             break;
+
         CASE_MODRM_OP(6): /* lmsw */
             if (!check_cpl0(s)) {
                 break;
             }
             gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0);
             gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
-            gen_helper_lmsw(cpu_env, s->T0);
+            /*
+             * Only the 4 lower bits of CR0 are modified.
+             * PE cannot be set to zero if already set to one.
+             */
+            tcg_gen_ld_tl(s->T1, cpu_env, offsetof(CPUX86State, cr[0]));
+            tcg_gen_andi_tl(s->T0, s->T0, 0xf);
+            tcg_gen_andi_tl(s->T1, s->T1, ~0xe);
+            tcg_gen_or_tl(s->T0, s->T0, s->T1);
+            gen_helper_write_crN(cpu_env, tcg_constant_i32(0), s->T0);
             gen_jmp_im(s, s->pc - s->cs_base);
             gen_eob(s);
             break;
@@ -8034,58 +8043,56 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         modrm = x86_ldub_code(env, s);
         gen_nop_modrm(env, s, modrm);
         break;
+
     case 0x120: /* mov reg, crN */
     case 0x122: /* mov crN, reg */
-        if (check_cpl0(s)) {
-            modrm = x86_ldub_code(env, s);
-            /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
-             * AMD documentation (24594.pdf) and testing of
-             * intel 386 and 486 processors all show that the mod bits
-             * are assumed to be 1's, regardless of actual values.
-             */
-            rm = (modrm & 7) | REX_B(s);
-            reg = ((modrm >> 3) & 7) | REX_R(s);
-            if (CODE64(s))
-                ot = MO_64;
-            else
-                ot = MO_32;
-            if ((prefixes & PREFIX_LOCK) && (reg == 0) &&
+        if (!check_cpl0(s)) {
+            break;
+        }
+        modrm = x86_ldub_code(env, s);
+        /*
+         * Ignore the mod bits (assume (modrm&0xc0)==0xc0).
+         * AMD documentation (24594.pdf) and testing of Intel 386 and 486
+         * processors all show that the mod bits are assumed to be 1's,
+         * regardless of actual values.
+         */
+        rm = (modrm & 7) | REX_B(s);
+        reg = ((modrm >> 3) & 7) | REX_R(s);
+        switch (reg) {
+        case 0:
+            if ((prefixes & PREFIX_LOCK) &&
                 (s->cpuid_ext3_features & CPUID_EXT3_CR8LEG)) {
                 reg = 8;
             }
-            switch(reg) {
-            case 0:
-            case 2:
-            case 3:
-            case 4:
-            case 8:
-                gen_update_cc_op(s);
-                gen_jmp_im(s, pc_start - s->cs_base);
-                if (b & 2) {
-                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_io_start();
-                    }
-                    gen_op_mov_v_reg(s, ot, s->T0, rm);
-                    gen_helper_write_crN(cpu_env, tcg_const_i32(reg),
-                                         s->T0);
-                    gen_jmp_im(s, s->pc - s->cs_base);
-                    gen_eob(s);
-                } else {
-                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_io_start();
-                    }
-                    gen_helper_read_crN(s->T0, cpu_env, tcg_const_i32(reg));
-                    gen_op_mov_reg_v(s, ot, rm, s->T0);
-                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-                        gen_jmp(s, s->pc - s->cs_base);
-                    }
-                }
-                break;
-            default:
-                goto unknown_op;
+            break;
+        case 2:
+        case 3:
+        case 4:
+            break;
+        default:
+            goto unknown_op;
+        }
+        ot  = (CODE64(s) ? MO_64 : MO_32);
+
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            gen_io_start();
+        }
+        if (b & 2) {
+            gen_svm_check_intercept(s, SVM_EXIT_WRITE_CR0 + reg);
+            gen_op_mov_v_reg(s, ot, s->T0, rm);
+            gen_helper_write_crN(cpu_env, tcg_constant_i32(reg), s->T0);
+            gen_jmp_im(s, s->pc - s->cs_base);
+            gen_eob(s);
+        } else {
+            gen_svm_check_intercept(s, SVM_EXIT_READ_CR0 + reg);
+            gen_helper_read_crN(s->T0, cpu_env, tcg_constant_i32(reg));
+            gen_op_mov_reg_v(s, ot, rm, s->T0);
+            if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+                gen_jmp(s, s->pc - s->cs_base);
             }
         }
         break;
+
     case 0x121: /* mov reg, drN */
     case 0x123: /* mov drN, reg */
         if (check_cpl0(s)) {
-- 
2.25.1



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

* [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (38 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18  9:59   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu Richard Henderson
                   ` (11 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Having the callers upcast to X86CPU is a waste, since we
don't need it.  We even have to recover env in do_hlt.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/misc_helper.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index 931dbd9db0..23287b330e 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -101,19 +101,18 @@ void QEMU_NORETURN helper_rdpmc(CPUX86State *env)
     raise_exception_err(env, EXCP06_ILLOP, 0);
 }
 
-static QEMU_NORETURN void do_pause(X86CPU *cpu)
+static void QEMU_NORETURN do_pause(CPUX86State *env)
 {
-    CPUState *cs = CPU(cpu);
+    CPUState *cs = env_cpu(env);
 
     /* Just let another CPU run.  */
     cs->exception_index = EXCP_INTERRUPT;
     cpu_loop_exit(cs);
 }
 
-static QEMU_NORETURN void do_hlt(X86CPU *cpu)
+static void QEMU_NORETURN do_hlt(CPUX86State *env)
 {
-    CPUState *cs = CPU(cpu);
-    CPUX86State *env = &cpu->env;
+    CPUState *cs = env_cpu(env);
 
     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
     cs->halted = 1;
@@ -123,12 +122,10 @@ static QEMU_NORETURN void do_hlt(X86CPU *cpu)
 
 void QEMU_NORETURN helper_hlt(CPUX86State *env, int next_eip_addend)
 {
-    X86CPU *cpu = env_archcpu(env);
-
     cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
     env->eip += next_eip_addend;
 
-    do_hlt(cpu);
+    do_hlt(env);
 }
 
 void helper_monitor(CPUX86State *env, target_ulong ptr)
@@ -143,7 +140,6 @@ void helper_monitor(CPUX86State *env, target_ulong ptr)
 void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
 {
     CPUState *cs = env_cpu(env);
-    X86CPU *cpu = env_archcpu(env);
 
     if ((uint32_t)env->regs[R_ECX] != 0) {
         raise_exception_ra(env, EXCP0D_GPF, GETPC());
@@ -153,20 +149,18 @@ void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
 
     /* XXX: not complete but not completely erroneous */
     if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
-        do_pause(cpu);
+        do_pause(env);
     } else {
-        do_hlt(cpu);
+        do_hlt(env);
     }
 }
 
 void QEMU_NORETURN helper_pause(CPUX86State *env, int next_eip_addend)
 {
-    X86CPU *cpu = env_archcpu(env);
-
     cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC());
     env->eip += next_eip_addend;
 
-    do_pause(cpu);
+    do_pause(env);
 }
 
 void QEMU_NORETURN helper_debug(CPUX86State *env)
-- 
2.25.1



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

* [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (39 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:00   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 42/50] target/i386: Unify invlpg, invlpga Richard Henderson
                   ` (10 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

These instructions are all privileged.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                 |  8 ++--
 target/i386/tcg/helper-tcg.h         |  1 +
 target/i386/tcg/misc_helper.c        | 55 +---------------------------
 target/i386/tcg/sysemu/misc_helper.c | 53 +++++++++++++++++++++++++++
 target/i386/tcg/translate.c          |  4 ++
 5 files changed, 63 insertions(+), 58 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index ebfaca66dd..ab72eba52a 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -51,7 +51,6 @@ DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl)
 #endif /* !CONFIG_USER_ONLY */
 
 DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int)
-DEF_HELPER_2(invlpg, void, env, tl)
 
 DEF_HELPER_1(sysenter, void, env)
 DEF_HELPER_2(sysexit, void, env, int)
@@ -59,9 +58,6 @@ DEF_HELPER_2(sysexit, void, env, int)
 DEF_HELPER_2(syscall, void, env, int)
 DEF_HELPER_2(sysret, void, env, int)
 #endif
-DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
-DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
-DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
 DEF_HELPER_FLAGS_2(pause, TCG_CALL_NO_WG, noreturn, env, int)
 DEF_HELPER_FLAGS_1(debug, TCG_CALL_NO_WG, noreturn, env)
 DEF_HELPER_1(reset_rf, void, env)
@@ -115,6 +111,10 @@ DEF_HELPER_2(vmsave, void, env, int)
 DEF_HELPER_1(stgi, void, env)
 DEF_HELPER_1(clgi, void, env)
 DEF_HELPER_2(invlpga, void, env, int)
+DEF_HELPER_2(invlpg, void, env, tl)
+DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
+DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
 #endif /* !CONFIG_USER_ONLY */
 
 /* x86 FPU */
diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h
index 85a8b0ebd6..2510cc244e 100644
--- a/target/i386/tcg/helper-tcg.h
+++ b/target/i386/tcg/helper-tcg.h
@@ -76,6 +76,7 @@ extern const uint8_t parity_table[256];
 
 /* misc_helper.c */
 void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask);
+void do_pause(CPUX86State *env) QEMU_NORETURN;
 
 /* sysemu/svm_helper.c */
 #ifndef CONFIG_USER_ONLY
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index 23287b330e..baffa5d7ba 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -60,14 +60,6 @@ void helper_cpuid(CPUX86State *env)
     env->regs[R_EDX] = edx;
 }
 
-void helper_invlpg(CPUX86State *env, target_ulong addr)
-{
-    X86CPU *cpu = env_archcpu(env);
-
-    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC());
-    tlb_flush_page(CPU(cpu), addr);
-}
-
 void helper_rdtsc(CPUX86State *env)
 {
     uint64_t val;
@@ -101,7 +93,7 @@ void QEMU_NORETURN helper_rdpmc(CPUX86State *env)
     raise_exception_err(env, EXCP06_ILLOP, 0);
 }
 
-static void QEMU_NORETURN do_pause(CPUX86State *env)
+void QEMU_NORETURN do_pause(CPUX86State *env)
 {
     CPUState *cs = env_cpu(env);
 
@@ -110,51 +102,6 @@ static void QEMU_NORETURN do_pause(CPUX86State *env)
     cpu_loop_exit(cs);
 }
 
-static void QEMU_NORETURN do_hlt(CPUX86State *env)
-{
-    CPUState *cs = env_cpu(env);
-
-    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
-    cs->halted = 1;
-    cs->exception_index = EXCP_HLT;
-    cpu_loop_exit(cs);
-}
-
-void QEMU_NORETURN helper_hlt(CPUX86State *env, int next_eip_addend)
-{
-    cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
-    env->eip += next_eip_addend;
-
-    do_hlt(env);
-}
-
-void helper_monitor(CPUX86State *env, target_ulong ptr)
-{
-    if ((uint32_t)env->regs[R_ECX] != 0) {
-        raise_exception_ra(env, EXCP0D_GPF, GETPC());
-    }
-    /* XXX: store address? */
-    cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
-}
-
-void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
-{
-    CPUState *cs = env_cpu(env);
-
-    if ((uint32_t)env->regs[R_ECX] != 0) {
-        raise_exception_ra(env, EXCP0D_GPF, GETPC());
-    }
-    cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
-    env->eip += next_eip_addend;
-
-    /* XXX: not complete but not completely erroneous */
-    if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
-        do_pause(env);
-    } else {
-        do_hlt(env);
-    }
-}
-
 void QEMU_NORETURN helper_pause(CPUX86State *env, int next_eip_addend)
 {
     cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC());
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index c7381ef7e8..803c39e2fb 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -438,3 +438,56 @@ void helper_rdmsr(CPUX86State *env)
     env->regs[R_EAX] = (uint32_t)(val);
     env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
+
+void helper_invlpg(CPUX86State *env, target_ulong addr)
+{
+    X86CPU *cpu = env_archcpu(env);
+
+    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC());
+    tlb_flush_page(CPU(cpu), addr);
+}
+
+static void QEMU_NORETURN do_hlt(CPUX86State *env)
+{
+    CPUState *cs = env_cpu(env);
+
+    env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
+    cs->halted = 1;
+    cs->exception_index = EXCP_HLT;
+    cpu_loop_exit(cs);
+}
+
+void QEMU_NORETURN helper_hlt(CPUX86State *env, int next_eip_addend)
+{
+    cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
+    env->eip += next_eip_addend;
+
+    do_hlt(env);
+}
+
+void helper_monitor(CPUX86State *env, target_ulong ptr)
+{
+    if ((uint32_t)env->regs[R_ECX] != 0) {
+        raise_exception_ra(env, EXCP0D_GPF, GETPC());
+    }
+    /* XXX: store address? */
+    cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
+}
+
+void QEMU_NORETURN helper_mwait(CPUX86State *env, int next_eip_addend)
+{
+    CPUState *cs = env_cpu(env);
+
+    if ((uint32_t)env->regs[R_ECX] != 0) {
+        raise_exception_ra(env, EXCP0D_GPF, GETPC());
+    }
+    cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
+    env->eip += next_eip_addend;
+
+    /* XXX: not complete but not completely erroneous */
+    if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
+        do_pause(env);
+    } else {
+        do_hlt(env);
+    }
+}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 6804835712..76a6503f3d 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -194,7 +194,11 @@ typedef struct DisasContext {
 
 #ifdef CONFIG_USER_ONLY
 STUB_HELPER(clgi, TCGv_env env)
+STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
 STUB_HELPER(invlpga, TCGv_env env, TCGv_i32 aflag)
+STUB_HELPER(invlpg, TCGv_env env, TCGv addr)
+STUB_HELPER(monitor, TCGv_env env, TCGv addr)
+STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
 STUB_HELPER(stgi, TCGv_env env)
 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
-- 
2.25.1



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

* [PATCH v2 42/50] target/i386: Unify invlpg, invlpga
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (40 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:00   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param Richard Henderson
                   ` (9 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Use a single helper, flush_page, to do the work.
Use gen_svm_check_intercept.
Perform the zero-extension for invlpga inline.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                 |  3 +--
 target/i386/tcg/sysemu/misc_helper.c |  7 ++-----
 target/i386/tcg/sysemu/svm_helper.c  | 18 ------------------
 target/i386/tcg/translate.c          | 20 ++++++++++++--------
 4 files changed, 15 insertions(+), 33 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index ab72eba52a..0264fba335 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -110,8 +110,7 @@ DEF_HELPER_2(vmload, void, env, int)
 DEF_HELPER_2(vmsave, void, env, int)
 DEF_HELPER_1(stgi, void, env)
 DEF_HELPER_1(clgi, void, env)
-DEF_HELPER_2(invlpga, void, env, int)
-DEF_HELPER_2(invlpg, void, env, tl)
+DEF_HELPER_FLAGS_2(flush_page, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
 DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
 DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/misc_helper.c
index 803c39e2fb..0cef2f1a4c 100644
--- a/target/i386/tcg/sysemu/misc_helper.c
+++ b/target/i386/tcg/sysemu/misc_helper.c
@@ -439,12 +439,9 @@ void helper_rdmsr(CPUX86State *env)
     env->regs[R_EDX] = (uint32_t)(val >> 32);
 }
 
-void helper_invlpg(CPUX86State *env, target_ulong addr)
+void helper_flush_page(CPUX86State *env, target_ulong addr)
 {
-    X86CPU *cpu = env_archcpu(env);
-
-    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC());
-    tlb_flush_page(CPU(cpu), addr);
+    tlb_flush_page(env_cpu(env), addr);
 }
 
 static void QEMU_NORETURN do_hlt(CPUX86State *env)
diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index b431016e72..9d671297cf 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -412,24 +412,6 @@ void helper_clgi(CPUX86State *env)
     env->hflags2 &= ~HF2_GIF_MASK;
 }
 
-void helper_invlpga(CPUX86State *env, int aflag)
-{
-    X86CPU *cpu = env_archcpu(env);
-    target_ulong addr;
-
-    cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPGA, 0, GETPC());
-
-    if (aflag == 2) {
-        addr = env->regs[R_EAX];
-    } else {
-        addr = (uint32_t)env->regs[R_EAX];
-    }
-
-    /* XXX: could use the ASID to see if it is needed to do the
-       flush */
-    tlb_flush_page(CPU(cpu), addr);
-}
-
 void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
                                    uint64_t param, uintptr_t retaddr)
 {
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 76a6503f3d..104101c8a8 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -194,9 +194,8 @@ typedef struct DisasContext {
 
 #ifdef CONFIG_USER_ONLY
 STUB_HELPER(clgi, TCGv_env env)
+STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
-STUB_HELPER(invlpga, TCGv_env env, TCGv_i32 aflag)
-STUB_HELPER(invlpg, TCGv_env env, TCGv addr)
 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
@@ -7592,9 +7591,15 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!check_cpl0(s)) {
                 break;
             }
-            gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
-            gen_helper_invlpga(cpu_env, tcg_const_i32(s->aflag - 1));
+            gen_svm_check_intercept(s, SVM_EXIT_INVLPGA);
+            if (s->aflag == MO_64) {
+                tcg_gen_mov_tl(s->A0, cpu_regs[R_EAX]);
+            } else {
+                tcg_gen_ext32u_tl(s->A0, cpu_regs[R_EAX]);
+            }
+            gen_helper_flush_page(cpu_env, s->A0);
+            gen_jmp_im(s, s->pc - s->cs_base);
+            gen_eob(s);
             break;
 
         CASE_MODRM_MEM_OP(2): /* lgdt */
@@ -7682,10 +7687,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
             if (!check_cpl0(s)) {
                 break;
             }
-            gen_update_cc_op(s);
-            gen_jmp_im(s, pc_start - s->cs_base);
+            gen_svm_check_intercept(s, SVM_EXIT_INVLPG);
             gen_lea_modrm(env, s, modrm);
-            gen_helper_invlpg(cpu_env, s->A0);
+            gen_helper_flush_page(cpu_env, s->A0);
             gen_jmp_im(s, s->pc - s->cs_base);
             gen_eob(s);
             break;
-- 
2.25.1



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

* [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (41 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 42/50] target/i386: Unify invlpg, invlpga Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:01   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr Richard Henderson
                   ` (8 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The user-version is a no-op.  This lets us completely
remove tcg/user/svm_stubs.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/cpu.h                |  8 ++++++++
 target/i386/tcg/user/svm_stubs.c | 28 ----------------------------
 target/i386/tcg/user/meson.build |  1 -
 3 files changed, 8 insertions(+), 29 deletions(-)
 delete mode 100644 target/i386/tcg/user/svm_stubs.c

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 324ef92beb..e6836393f7 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2146,8 +2146,16 @@ static inline void cpu_set_fpuc(CPUX86State *env, uint16_t fpuc)
 void helper_lock_init(void);
 
 /* svm_helper.c */
+#ifdef CONFIG_USER_ONLY
+static inline void
+cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
+                              uint64_t param, uintptr_t retaddr)
+{ /* no-op */ }
+#else
 void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
                                    uint64_t param, uintptr_t retaddr);
+#endif
+
 /* apic.c */
 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
 void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
diff --git a/target/i386/tcg/user/svm_stubs.c b/target/i386/tcg/user/svm_stubs.c
deleted file mode 100644
index db818f89a8..0000000000
--- a/target/i386/tcg/user/svm_stubs.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *  x86 SVM helpers (user-mode)
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "tcg/helper-tcg.h"
-
-void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
-                                   uint64_t param, uintptr_t retaddr)
-{
-}
diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.build
index 9eac0e69ca..3555b15bdd 100644
--- a/target/i386/tcg/user/meson.build
+++ b/target/i386/tcg/user/meson.build
@@ -1,6 +1,5 @@
 i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files(
   'excp_helper.c',
   'misc_stubs.c',
-  'svm_stubs.c',
   'seg_helper.c',
 ))
-- 
2.25.1



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

* [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (42 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:01   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 45/50] target/i386: Exit tb after wrmsr Richard Henderson
                   ` (7 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h              |  8 ++++----
 target/i386/tcg/translate.c       |  4 ++++
 target/i386/tcg/user/misc_stubs.c | 20 --------------------
 3 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 0264fba335..1d85f033df 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -42,8 +42,6 @@ DEF_HELPER_5(lcall_protected, void, env, int, tl, int, tl)
 DEF_HELPER_2(iret_real, void, env, int)
 DEF_HELPER_3(iret_protected, void, env, int, int)
 DEF_HELPER_3(lret_protected, void, env, int, int)
-DEF_HELPER_FLAGS_2(read_crN, TCG_CALL_NO_RWG, tl, env, int)
-DEF_HELPER_FLAGS_3(write_crN, TCG_CALL_NO_RWG, void, env, int, tl)
 DEF_HELPER_1(clts, void, env)
 
 #ifndef CONFIG_USER_ONLY
@@ -87,8 +85,6 @@ DEF_HELPER_1(cpuid, void, env)
 DEF_HELPER_1(rdtsc, void, env)
 DEF_HELPER_1(rdtscp, void, env)
 DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
-DEF_HELPER_1(rdmsr, void, env)
-DEF_HELPER_1(wrmsr, void, env)
 
 DEF_HELPER_2(check_iob, void, env, i32)
 DEF_HELPER_2(check_iow, void, env, i32)
@@ -114,6 +110,10 @@ DEF_HELPER_FLAGS_2(flush_page, TCG_CALL_NO_RWG, void, env, tl)
 DEF_HELPER_FLAGS_2(hlt, TCG_CALL_NO_WG, noreturn, env, int)
 DEF_HELPER_FLAGS_2(monitor, TCG_CALL_NO_WG, void, env, tl)
 DEF_HELPER_FLAGS_2(mwait, TCG_CALL_NO_WG, noreturn, env, int)
+DEF_HELPER_1(rdmsr, void, env)
+DEF_HELPER_1(wrmsr, void, env)
+DEF_HELPER_FLAGS_2(read_crN, TCG_CALL_NO_RWG, tl, env, int)
+DEF_HELPER_FLAGS_3(write_crN, TCG_CALL_NO_RWG, void, env, int, tl)
 #endif /* !CONFIG_USER_ONLY */
 
 /* x86 FPU */
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 104101c8a8..2aa2410336 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -198,6 +198,8 @@ STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
+STUB_HELPER(rdmsr, TCGv_env env)
+STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
 STUB_HELPER(stgi, TCGv_env env)
 STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
@@ -206,6 +208,8 @@ STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
 STUB_HELPER(vmmcall, TCGv_env env)
 STUB_HELPER(vmrun, TCGv_env env, TCGv_i32 aflag, TCGv_i32 pc_ofs)
 STUB_HELPER(vmsave, TCGv_env env, TCGv_i32 aflag)
+STUB_HELPER(write_crN, TCGv_env env, TCGv_i32 reg, TCGv val)
+STUB_HELPER(wrmsr, TCGv_env env)
 #endif
 
 static void gen_eob(DisasContext *s);
diff --git a/target/i386/tcg/user/misc_stubs.c b/target/i386/tcg/user/misc_stubs.c
index 84df4e65ff..df38b44d6e 100644
--- a/target/i386/tcg/user/misc_stubs.c
+++ b/target/i386/tcg/user/misc_stubs.c
@@ -53,23 +53,3 @@ target_ulong helper_inl(CPUX86State *env, uint32_t port)
     g_assert_not_reached();
     return 0;
 }
-
-target_ulong helper_read_crN(CPUX86State *env, int reg)
-{
-    g_assert_not_reached();
-}
-
-void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
-{
-    g_assert_not_reached();
-}
-
-void helper_wrmsr(CPUX86State *env)
-{
-    g_assert_not_reached();
-}
-
-void helper_rdmsr(CPUX86State *env)
-{
-    g_assert_not_reached();
-}
-- 
2.25.1



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

* [PATCH v2 45/50] target/i386: Exit tb after wrmsr
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (43 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:02   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 46/50] target/i386: Tidy gen_check_io Richard Henderson
                   ` (6 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

At minimum, wrmsr can change efer, which affects HF_LMA.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 2aa2410336..6eeaa3a98b 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -7260,6 +7260,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
                 gen_helper_rdmsr(cpu_env);
             } else {
                 gen_helper_wrmsr(cpu_env);
+                gen_jmp_im(s, s->pc - s->cs_base);
+                gen_eob(s);
             }
         }
         break;
-- 
2.25.1



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

* [PATCH v2 46/50] target/i386: Tidy gen_check_io
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (44 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 45/50] target/i386: Exit tb after wrmsr Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:18   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 47/50] target/i386: Pass in port to gen_check_io Richard Henderson
                   ` (5 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Get cur_eip from DisasContext.  Do not require the caller
to use svm_is_rep; get prefix from DisasContext.  Use the
proper symbolic constants for SVM_IOIO_*.

While we're touching all call sites, return bool in
preparation for gen_check_io raising #GP.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 57 +++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 27 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 6eeaa3a98b..02c76537a6 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -674,13 +674,10 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
     }
 }
 
-static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
-                         uint32_t svm_flags)
+static bool gen_check_io(DisasContext *s, MemOp ot, uint32_t svm_flags)
 {
-    target_ulong next_eip;
-
+    tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
-        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         switch (ot) {
         case MO_8:
             gen_helper_check_iob(cpu_env, s->tmp2_i32);
@@ -696,15 +693,20 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
         }
     }
     if (GUEST(s)) {
+        target_ulong cur_eip = s->base.pc_next - s->cs_base;
+        target_ulong next_eip = s->pc - s->cs_base;
+
         gen_update_cc_op(s);
         gen_jmp_im(s, cur_eip);
-        svm_flags |= (1 << (4 + ot));
-        next_eip = s->pc - s->cs_base;
-        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
+        if (s->prefix & (PREFIX_REPZ | PREFIX_REPNZ)) {
+            svm_flags |= SVM_IOIO_REP_MASK;
+        }
+        svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
         gen_helper_svm_check_io(cpu_env, s->tmp2_i32,
-                                tcg_const_i32(svm_flags),
-                                tcg_const_i32(next_eip - cur_eip));
+                                tcg_constant_i32(svm_flags),
+                                tcg_constant_i32(next_eip - cur_eip));
     }
+    return true;
 }
 
 static inline void gen_movs(DisasContext *s, MemOp ot)
@@ -2425,11 +2427,6 @@ static void gen_movl_seg_T0(DisasContext *s, X86Seg seg_reg)
     }
 }
 
-static inline int svm_is_rep(int prefixes)
-{
-    return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
-}
-
 static void gen_svm_check_intercept(DisasContext *s, uint32_t type)
 {
     /* no SVM activated; fast case */
@@ -6483,8 +6480,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6d:
         ot = mo_b_d32(b, dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base, 
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes) | 4);
+        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
+            break;
+        }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6502,8 +6500,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6f:
         ot = mo_b_d32(b, dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes) | 4);
+        if (!gen_check_io(s, ot, SVM_IOIO_STR_MASK)) {
+            break;
+        }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6526,8 +6525,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
-        gen_check_io(s, ot, pc_start - s->cs_base,
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
+        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK)) {
+            break;
+        }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6544,8 +6544,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
         ot = mo_b_d32(b, dflag);
         val = x86_ldub_code(env, s);
         tcg_gen_movi_tl(s->T0, val);
-        gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes));
+        if (!gen_check_io(s, ot, 0)) {
+            break;
+        }
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6563,8 +6564,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xed:
         ot = mo_b_d32(b, dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
-                     SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
+        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK)) {
+            break;
+        }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
@@ -6580,8 +6582,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xef:
         ot = mo_b_d32(b, dflag);
         tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        gen_check_io(s, ot, pc_start - s->cs_base,
-                     svm_is_rep(prefixes));
+        if (!gen_check_io(s, ot, 0)) {
+            break;
+        }
         gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
 
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-- 
2.25.1



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

* [PATCH v2 47/50] target/i386: Pass in port to gen_check_io
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (45 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 46/50] target/i386: Tidy gen_check_io Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:20   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 48/50] target/i386: Create helper_check_io Richard Henderson
                   ` (4 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Pass in a pre-truncated TCGv_i32 value.  We were doing the
truncation of EDX in multiple places, now only once per insn.
While all callers use s->tmp2_i32, for cleanliness of the
subroutine, use a parameter anyway.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/translate.c | 55 +++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 02c76537a6..19bfdbd0a3 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -674,19 +674,23 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
     }
 }
 
-static bool gen_check_io(DisasContext *s, MemOp ot, uint32_t svm_flags)
+/*
+ * Validate that access to [port, port + 1<<ot) is allowed.
+ * Raise #GP, or VMM exit if not.
+ */
+static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
+                         uint32_t svm_flags)
 {
-    tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
         switch (ot) {
         case MO_8:
-            gen_helper_check_iob(cpu_env, s->tmp2_i32);
+            gen_helper_check_iob(cpu_env, port);
             break;
         case MO_16:
-            gen_helper_check_iow(cpu_env, s->tmp2_i32);
+            gen_helper_check_iow(cpu_env, port);
             break;
         case MO_32:
-            gen_helper_check_iol(cpu_env, s->tmp2_i32);
+            gen_helper_check_iol(cpu_env, port);
             break;
         default:
             tcg_abort();
@@ -702,7 +706,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, uint32_t svm_flags)
             svm_flags |= SVM_IOIO_REP_MASK;
         }
         svm_flags |= 1 << (SVM_IOIO_SIZE_SHIFT + ot);
-        gen_helper_svm_check_io(cpu_env, s->tmp2_i32,
+        gen_helper_svm_check_io(cpu_env, port,
                                 tcg_constant_i32(svm_flags),
                                 tcg_constant_i32(next_eip - cur_eip));
     }
@@ -6479,8 +6483,10 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6c: /* insS */
     case 0x6d:
         ot = mo_b_d32(b, dflag);
-        tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
+        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
+        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
+        if (!gen_check_io(s, ot, s->tmp2_i32,
+                          SVM_IOIO_TYPE_MASK | SVM_IOIO_STR_MASK)) {
             break;
         }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6499,8 +6505,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0x6e: /* outsS */
     case 0x6f:
         ot = mo_b_d32(b, dflag);
-        tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        if (!gen_check_io(s, ot, SVM_IOIO_STR_MASK)) {
+        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
+        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
+        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_STR_MASK)) {
             break;
         }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -6524,14 +6531,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xe5:
         ot = mo_b_d32(b, dflag);
         val = x86_ldub_code(env, s);
-        tcg_gen_movi_tl(s->T0, val);
-        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK)) {
+        tcg_gen_movi_i32(s->tmp2_i32, val);
+        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
             break;
         }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        tcg_gen_movi_i32(s->tmp2_i32, val);
         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
         gen_bpt_io(s, s->tmp2_i32, ot);
@@ -6543,16 +6549,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xe7:
         ot = mo_b_d32(b, dflag);
         val = x86_ldub_code(env, s);
-        tcg_gen_movi_tl(s->T0, val);
-        if (!gen_check_io(s, ot, 0)) {
+        tcg_gen_movi_i32(s->tmp2_i32, val);
+        if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
             break;
         }
-        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
-
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        tcg_gen_movi_i32(s->tmp2_i32, val);
+        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
         gen_bpt_io(s, s->tmp2_i32, ot);
@@ -6563,14 +6567,14 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xec:
     case 0xed:
         ot = mo_b_d32(b, dflag);
-        tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        if (!gen_check_io(s, ot, SVM_IOIO_TYPE_MASK)) {
+        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
+        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
+        if (!gen_check_io(s, ot, s->tmp2_i32, SVM_IOIO_TYPE_MASK)) {
             break;
         }
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
         gen_helper_in_func(ot, s->T1, s->tmp2_i32);
         gen_op_mov_reg_v(s, ot, R_EAX, s->T1);
         gen_bpt_io(s, s->tmp2_i32, ot);
@@ -6581,16 +6585,15 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
     case 0xee:
     case 0xef:
         ot = mo_b_d32(b, dflag);
-        tcg_gen_ext16u_tl(s->T0, cpu_regs[R_EDX]);
-        if (!gen_check_io(s, ot, 0)) {
+        tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_EDX]);
+        tcg_gen_ext16u_i32(s->tmp2_i32, s->tmp2_i32);
+        if (!gen_check_io(s, ot, s->tmp2_i32, 0)) {
             break;
         }
-        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
-
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
             gen_io_start();
         }
-        tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
+        gen_op_mov_v_reg(s, ot, s->T1, R_EAX);
         tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
         gen_helper_out_func(ot, s->tmp2_i32, s->tmp3_i32);
         gen_bpt_io(s, s->tmp2_i32, ot);
-- 
2.25.1



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

* [PATCH v2 48/50] target/i386: Create helper_check_io
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (46 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 47/50] target/i386: Pass in port to gen_check_io Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:21   ` Paolo Bonzini
  2021-05-14 15:13 ` [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu Richard Henderson
                   ` (3 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

Drop helper_check_io[bwl] and expose their common
subroutine to tcg directly.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h         |  4 +---
 target/i386/tcg/seg_helper.c | 21 +++------------------
 target/i386/tcg/translate.c  | 14 +-------------
 3 files changed, 5 insertions(+), 34 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 1d85f033df..47d0d67699 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -86,9 +86,7 @@ DEF_HELPER_1(rdtsc, void, env)
 DEF_HELPER_1(rdtscp, void, env)
 DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
 
-DEF_HELPER_2(check_iob, void, env, i32)
-DEF_HELPER_2(check_iow, void, env, i32)
-DEF_HELPER_2(check_iol, void, env, i32)
+DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32)
 DEF_HELPER_3(outb, void, env, i32, i32)
 DEF_HELPER_2(inb, tl, env, i32)
 DEF_HELPER_3(outw, void, env, i32, i32)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index cf3f051524..69d6e8f602 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -2418,10 +2418,10 @@ void helper_verw(CPUX86State *env, target_ulong selector1)
 }
 
 /* check if Port I/O is allowed in TSS */
-static inline void check_io(CPUX86State *env, int addr, int size,
-                            uintptr_t retaddr)
+void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
 {
-    int io_offset, val, mask;
+    uintptr_t retaddr = GETPC();
+    uint32_t io_offset, val, mask;
 
     /* TSS must be a valid 32 bit one */
     if (!(env->tr.flags & DESC_P_MASK) ||
@@ -2444,18 +2444,3 @@ static inline void check_io(CPUX86State *env, int addr, int size,
         raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr);
     }
 }
-
-void helper_check_iob(CPUX86State *env, uint32_t t0)
-{
-    check_io(env, t0, 1, GETPC());
-}
-
-void helper_check_iow(CPUX86State *env, uint32_t t0)
-{
-    check_io(env, t0, 2, GETPC());
-}
-
-void helper_check_iol(CPUX86State *env, uint32_t t0)
-{
-    check_io(env, t0, 4, GETPC());
-}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 19bfdbd0a3..860c75c2b1 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -682,19 +682,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
                          uint32_t svm_flags)
 {
     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
-        switch (ot) {
-        case MO_8:
-            gen_helper_check_iob(cpu_env, port);
-            break;
-        case MO_16:
-            gen_helper_check_iow(cpu_env, port);
-            break;
-        case MO_32:
-            gen_helper_check_iol(cpu_env, port);
-            break;
-        default:
-            tcg_abort();
-        }
+        gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
     }
     if (GUEST(s)) {
         target_ulong cur_eip = s->base.pc_next - s->cs_base;
-- 
2.25.1



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

* [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (47 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 48/50] target/i386: Create helper_check_io Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-14 17:45   ` Richard Henderson
  2021-05-14 15:13 ` [PATCH v2 50/50] target/i386: Remove user-only i/o stubs Richard Henderson
                   ` (2 subsequent siblings)
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

The we never allow i/o from user-only, and the tss check
that helper_check_io does will always fail.  Use an ifdef
within gen_check_io and return false, indicating that an
exception is known to be raised.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h                |  2 +-
 target/i386/tcg/seg_helper.c        | 28 ----------------------------
 target/i386/tcg/sysemu/seg_helper.c | 29 +++++++++++++++++++++++++++++
 target/i386/tcg/translate.c         | 11 +++++++++++
 4 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 47d0d67699..3fd0253298 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -86,7 +86,6 @@ DEF_HELPER_1(rdtsc, void, env)
 DEF_HELPER_1(rdtscp, void, env)
 DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
 
-DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32)
 DEF_HELPER_3(outb, void, env, i32, i32)
 DEF_HELPER_2(inb, tl, env, i32)
 DEF_HELPER_3(outw, void, env, i32, i32)
@@ -95,6 +94,7 @@ DEF_HELPER_3(outl, void, env, i32, i32)
 DEF_HELPER_2(inl, tl, env, i32)
 
 #ifndef CONFIG_USER_ONLY
+DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32)
 DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
 DEF_HELPER_2(svm_check_intercept, void, env, i32)
 DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 69d6e8f602..2f6cdc8239 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -2416,31 +2416,3 @@ void helper_verw(CPUX86State *env, target_ulong selector1)
     }
     CC_SRC = eflags | CC_Z;
 }
-
-/* check if Port I/O is allowed in TSS */
-void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
-{
-    uintptr_t retaddr = GETPC();
-    uint32_t io_offset, val, mask;
-
-    /* TSS must be a valid 32 bit one */
-    if (!(env->tr.flags & DESC_P_MASK) ||
-        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
-        env->tr.limit < 103) {
-        goto fail;
-    }
-    io_offset = cpu_lduw_kernel_ra(env, env->tr.base + 0x66, retaddr);
-    io_offset += (addr >> 3);
-    /* Note: the check needs two bytes */
-    if ((io_offset + 1) > env->tr.limit) {
-        goto fail;
-    }
-    val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr);
-    val >>= (addr & 7);
-    mask = (1 << size) - 1;
-    /* all bits must be zero to allow the I/O */
-    if ((val & mask) != 0) {
-    fail:
-        raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr);
-    }
-}
diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/seg_helper.c
index e0d7b32b82..82c0856c41 100644
--- a/target/i386/tcg/sysemu/seg_helper.c
+++ b/target/i386/tcg/sysemu/seg_helper.c
@@ -23,6 +23,7 @@
 #include "exec/helper-proto.h"
 #include "exec/cpu_ldst.h"
 #include "tcg/helper-tcg.h"
+#include "../seg_helper.h"
 
 #ifdef TARGET_X86_64
 void helper_syscall(CPUX86State *env, int next_eip_addend)
@@ -123,3 +124,31 @@ void x86_cpu_do_interrupt(CPUState *cs)
         env->old_exception = -1;
     }
 }
+
+/* check if Port I/O is allowed in TSS */
+void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
+{
+    uintptr_t retaddr = GETPC();
+    uint32_t io_offset, val, mask;
+
+    /* TSS must be a valid 32 bit one */
+    if (!(env->tr.flags & DESC_P_MASK) ||
+        ((env->tr.flags >> DESC_TYPE_SHIFT) & 0xf) != 9 ||
+        env->tr.limit < 103) {
+        goto fail;
+    }
+    io_offset = cpu_lduw_kernel_ra(env, env->tr.base + 0x66, retaddr);
+    io_offset += (addr >> 3);
+    /* Note: the check needs two bytes */
+    if ((io_offset + 1) > env->tr.limit) {
+        goto fail;
+    }
+    val = cpu_lduw_kernel_ra(env, env->tr.base + io_offset, retaddr);
+    val >>= (addr & 7);
+    mask = (1 << size) - 1;
+    /* all bits must be zero to allow the I/O */
+    if ((val & mask) != 0) {
+    fail:
+        raise_exception_err_ra(env, EXCP0D_GPF, 0, retaddr);
+    }
+}
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 860c75c2b1..bcc642bf6e 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -193,6 +193,7 @@ typedef struct DisasContext {
     { qemu_build_not_reached(); }
 
 #ifdef CONFIG_USER_ONLY
+STUB_HELPER(check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 size)
 STUB_HELPER(clgi, TCGv_env env)
 STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
@@ -217,6 +218,7 @@ static void gen_jr(DisasContext *s, TCGv dest);
 static void gen_jmp(DisasContext *s, target_ulong eip);
 static void gen_jmp_tb(DisasContext *s, target_ulong eip, int tb_num);
 static void gen_op(DisasContext *s1, int op, MemOp ot, int d);
+static void gen_exception_gpf(DisasContext *s);
 
 /* i386 arith/logic operations */
 enum {
@@ -681,6 +683,14 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
 static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
                          uint32_t svm_flags)
 {
+#ifdef CONFIG_USER_ONLY
+    /*
+     * We do not implement the iopriv(2) syscall, so the TSS check
+     * will always fail.
+     */
+    gen_exception_gpf(s);
+    return false;
+#else
     if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
         gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
     }
@@ -699,6 +709,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
                                 tcg_constant_i32(next_eip - cur_eip));
     }
     return true;
+#endif
 }
 
 static inline void gen_movs(DisasContext *s, MemOp ot)
-- 
2.25.1



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

* [PATCH v2 50/50] target/i386: Remove user-only i/o stubs
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (48 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu Richard Henderson
@ 2021-05-14 15:13 ` Richard Henderson
  2021-05-18 10:23   ` Paolo Bonzini
  2021-05-14 16:09 ` [PATCH v2 00/50] target/i386 translate cleanups no-reply
  2021-05-18 10:31 ` Paolo Bonzini
  51 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 15:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

With the previous patch for check_io, we now have enough for
the compiler to dead-code eliminate all of the i/o helpers.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/helper.h              |  3 +-
 target/i386/tcg/translate.c       |  6 ++++
 target/i386/tcg/user/misc_stubs.c | 55 -------------------------------
 target/i386/tcg/user/meson.build  |  1 -
 4 files changed, 7 insertions(+), 58 deletions(-)
 delete mode 100644 target/i386/tcg/user/misc_stubs.c

diff --git a/target/i386/helper.h b/target/i386/helper.h
index 3fd0253298..f3d8c3f949 100644
--- a/target/i386/helper.h
+++ b/target/i386/helper.h
@@ -86,14 +86,13 @@ DEF_HELPER_1(rdtsc, void, env)
 DEF_HELPER_1(rdtscp, void, env)
 DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
 
+#ifndef CONFIG_USER_ONLY
 DEF_HELPER_3(outb, void, env, i32, i32)
 DEF_HELPER_2(inb, tl, env, i32)
 DEF_HELPER_3(outw, void, env, i32, i32)
 DEF_HELPER_2(inw, tl, env, i32)
 DEF_HELPER_3(outl, void, env, i32, i32)
 DEF_HELPER_2(inl, tl, env, i32)
-
-#ifndef CONFIG_USER_ONLY
 DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32)
 DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
 DEF_HELPER_2(svm_check_intercept, void, env, i32)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index bcc642bf6e..08ff3fe232 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -197,8 +197,14 @@ STUB_HELPER(check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 size)
 STUB_HELPER(clgi, TCGv_env env)
 STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
 STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
+STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
+STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
+STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
 STUB_HELPER(monitor, TCGv_env env, TCGv addr)
 STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
+STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
+STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
+STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
 STUB_HELPER(rdmsr, TCGv_env env)
 STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
 STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
diff --git a/target/i386/tcg/user/misc_stubs.c b/target/i386/tcg/user/misc_stubs.c
deleted file mode 100644
index df38b44d6e..0000000000
--- a/target/i386/tcg/user/misc_stubs.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  x86 misc helpers
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-
-void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
-{
-    g_assert_not_reached();
-}
-
-target_ulong helper_inb(CPUX86State *env, uint32_t port)
-{
-    g_assert_not_reached();
-    return 0;
-}
-
-void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
-{
-    g_assert_not_reached();
-}
-
-target_ulong helper_inw(CPUX86State *env, uint32_t port)
-{
-    g_assert_not_reached();
-    return 0;
-}
-
-void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
-{
-    g_assert_not_reached();
-}
-
-target_ulong helper_inl(CPUX86State *env, uint32_t port)
-{
-    g_assert_not_reached();
-    return 0;
-}
diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.build
index 3555b15bdd..1df6bc4343 100644
--- a/target/i386/tcg/user/meson.build
+++ b/target/i386/tcg/user/meson.build
@@ -1,5 +1,4 @@
 i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files(
   'excp_helper.c',
-  'misc_stubs.c',
   'seg_helper.c',
 ))
-- 
2.25.1



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

* Re: [PATCH v2 00/50] target/i386 translate cleanups
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (49 preceding siblings ...)
  2021-05-14 15:13 ` [PATCH v2 50/50] target/i386: Remove user-only i/o stubs Richard Henderson
@ 2021-05-14 16:09 ` no-reply
  2021-05-18 10:31 ` Paolo Bonzini
  51 siblings, 0 replies; 106+ messages in thread
From: no-reply @ 2021-05-14 16:09 UTC (permalink / raw)
  To: richard.henderson; +Cc: pbonzini, cfontana, qemu-devel, ehabkost, f4bug

Patchew URL: https://patchew.org/QEMU/20210514151342.384376-1-richard.henderson@linaro.org/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 20210514151342.384376-1-richard.henderson@linaro.org
Subject: [PATCH v2 00/50] target/i386 translate cleanups

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
   2d3fc4e..9666299  master     -> master
 - [tag update]      patchew/20210325153529.75831-1-andrew@daynix.com -> patchew/20210325153529.75831-1-andrew@daynix.com
 - [tag update]      patchew/20210512040250.203953-1-iii@linux.ibm.com -> patchew/20210512040250.203953-1-iii@linux.ibm.com
 - [tag update]      patchew/20210512214642.2803189-1-jsnow@redhat.com -> patchew/20210512214642.2803189-1-jsnow@redhat.com
 * [new tag]         patchew/20210514151342.384376-1-richard.henderson@linaro.org -> patchew/20210514151342.384376-1-richard.henderson@linaro.org
Switched to a new branch 'test'
e202c8c target/i386: Remove user-only i/o stubs
1d820c0 target/i386: Move helper_check_io to sysemu
50e4fb4 target/i386: Create helper_check_io
6814811 target/i386: Pass in port to gen_check_io
8f6e5bb target/i386: Tidy gen_check_io
4282091 target/i386: Exit tb after wrmsr
5555941 target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr
0010e63 target/i386: Inline user cpu_svm_check_intercept_param
946b94c target/i386: Unify invlpg, invlpga
46e15b6 target/i386: Move invlpg, hlt, monitor, mwait to sysemu
fc622c8 target/i386: Pass env to do_pause and do_hlt
eff322a target/i386: Cleanup read_crN, write_crN, lmsw
f975359 target/i386: Remove user stub for cpu_vmexit
01ec488 target/i386: Remove pc_start argument to gen_svm_check_intercept
e533b1a target/i386: Tidy svm_check_intercept from tcg
07bc5bb target/i386: Simplify gen_debug usage
33b7b33 target/i386: Mark some helpers as noreturn
9e4eefd target/i386: Eliminate SVM helpers for user-only
a4b7e86 target/i386: Implement skinit in translate.c
11f0dd5 target/i386: Assert !GUEST for user-only
0b9152d target/i386: Assert !SVME for user-only
1619090 target/i386: Add stub generator for helper_set_dr
6b31254 target/i386: Reorder DisasContext members
a196b94 target/i386: Fix the comment for repz_opt
05d9ac8 target/i386: Reduce DisasContext jmp_opt, repz_opt to bool
2248cea target/i386: Leave TF in DisasContext.flags
3e5c314 target/i386: Reduce DisasContext popl_esp_hack and rip_offset to uint8_t
d2ff6f0 target/i386: Reduce DisasContext.vex_[lv] to uint8_t
1045677 target/i386: Reduce DisasContext.prefix to uint8_t
b052ed9 target/i386: Reduce DisasContext.override to int8_t
04bd526 target/i386: Reduce DisasContext.flags to uint32_t
25a9164 target/i386: Remove DisasContext.f_st as unused
9c8cd54 target/i386: Move rex_w into DisasContext
be9c7a6 target/i386: Move rex_r into DisasContext
8f59d5d target/i386: Tidy REX_B, REX_X definition
86d68fb target/i386: Introduce REX_PREFIX
df0e9ba target/i386: Assert !ADDSEG for x86_64 user-only
afbeac9 target/i386: Assert LMA for x86_64 user-only
ef457bd target/i386: Assert CODE64 for x86_64 user-only
bb9e685 target/i386: Assert SS32 for x86_64 user-only
926c3fc target/i386: Assert CODE32 for x86_64 user-only
47c6cc1 target/i386: Assert !VM86 for x86_64 user-only
4b8ee2f target/i386: Assert IOPL is 0 for user-only
46331b6 target/i386: Assert CPL is 3 for user-only
e5377a8 target/i386: Assert PE is set for user-only
f3dcdd9 target/i386: Split out check_iopl
f6f133e target/i386: Split out check_vm86_iopl
5497a8a target/i386: Unify code paths for IRET
7f7ed03 target/i386: Split out check_cpl0
9eee238 target/i386: Split out gen_exception_gpf

=== OUTPUT BEGIN ===
1/50 Checking commit 9eee2384d266 (target/i386: Split out gen_exception_gpf)
2/50 Checking commit 7f7ed0354a5f (target/i386: Split out check_cpl0)
3/50 Checking commit 5497a8ae5aba (target/i386: Unify code paths for IRET)
4/50 Checking commit f6f133e635f0 (target/i386: Split out check_vm86_iopl)
5/50 Checking commit f3dcdd958c30 (target/i386: Split out check_iopl)
6/50 Checking commit e5377a824c04 (target/i386: Assert PE is set for user-only)
ERROR: braces {} are necessary for all arms of this statement
#128: FILE: target/i386/tcg/translate.c:7310:
+            if (!PE(s) || s->vm86)
[...]

ERROR: braces {} are necessary for all arms of this statement
#146: FILE: target/i386/tcg/translate.c:7329:
+            if (!PE(s) || s->vm86)
[...]

ERROR: braces {} are necessary for all arms of this statement
#164: FILE: target/i386/tcg/translate.c:7349:
+            if (!PE(s) || s->vm86)
[...]

ERROR: braces {} are necessary for all arms of this statement
#236: FILE: target/i386/tcg/translate.c:7720:
+            if (!PE(s) || s->vm86)
[...]

ERROR: braces {} are necessary for all arms of this statement
#245: FILE: target/i386/tcg/translate.c:7768:
+            if (!PE(s) || s->vm86)
[...]

total: 5 errors, 0 warnings, 244 lines checked

Patch 6/50 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

7/50 Checking commit 46331b60bf94 (target/i386: Assert CPL is 3 for user-only)
8/50 Checking commit 4b8ee2f3f077 (target/i386: Assert IOPL is 0 for user-only)
9/50 Checking commit 47c6cc104278 (target/i386: Assert !VM86 for x86_64 user-only)
ERROR: braces {} are necessary for all arms of this statement
#130: FILE: target/i386/tcg/translate.c:7322:
+            if (!PE(s) || VM86(s))
[...]

ERROR: braces {} are necessary for all arms of this statement
#148: FILE: target/i386/tcg/translate.c:7341:
+            if (!PE(s) || VM86(s))
[...]

ERROR: braces {} are necessary for all arms of this statement
#166: FILE: target/i386/tcg/translate.c:7361:
+            if (!PE(s) || VM86(s))
[...]

ERROR: braces {} are necessary for all arms of this statement
#175: FILE: target/i386/tcg/translate.c:7732:
+            if (!PE(s) || VM86(s))
[...]

ERROR: braces {} are necessary for all arms of this statement
#184: FILE: target/i386/tcg/translate.c:7780:
+            if (!PE(s) || VM86(s))
[...]

total: 5 errors, 0 warnings, 159 lines checked

Patch 9/50 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

10/50 Checking commit 926c3fc7270b (target/i386: Assert CODE32 for x86_64 user-only)
11/50 Checking commit bb9e68525fbe (target/i386: Assert SS32 for x86_64 user-only)
12/50 Checking commit ef457bdf9f4f (target/i386: Assert CODE64 for x86_64 user-only)
13/50 Checking commit afbeac994eb8 (target/i386: Assert LMA for x86_64 user-only)
14/50 Checking commit df0e9ba61de2 (target/i386: Assert !ADDSEG for x86_64 user-only)
15/50 Checking commit 86d68fb10f01 (target/i386: Introduce REX_PREFIX)
16/50 Checking commit 8f59d5d4bb24 (target/i386: Tidy REX_B, REX_X definition)
17/50 Checking commit be9c7a6cea20 (target/i386: Move rex_r into DisasContext)
18/50 Checking commit 9c8cd545d35c (target/i386: Move rex_w into DisasContext)
19/50 Checking commit 25a91640ee31 (target/i386: Remove DisasContext.f_st as unused)
20/50 Checking commit 04bd52617731 (target/i386: Reduce DisasContext.flags to uint32_t)
21/50 Checking commit b052ed9d2425 (target/i386: Reduce DisasContext.override to int8_t)
22/50 Checking commit 104567771296 (target/i386: Reduce DisasContext.prefix to uint8_t)
23/50 Checking commit d2ff6f020e1d (target/i386: Reduce DisasContext.vex_[lv] to uint8_t)
24/50 Checking commit 3e5c31499dbd (target/i386: Reduce DisasContext popl_esp_hack and rip_offset to uint8_t)
25/50 Checking commit 2248cea6f655 (target/i386: Leave TF in DisasContext.flags)
26/50 Checking commit 05d9ac8f6f1c (target/i386: Reduce DisasContext jmp_opt, repz_opt to bool)
27/50 Checking commit a196b94506cc (target/i386: Fix the comment for repz_opt)
28/50 Checking commit 6b3125424e7e (target/i386: Reorder DisasContext members)
29/50 Checking commit 1619090fbe83 (target/i386: Add stub generator for helper_set_dr)
30/50 Checking commit 0b9152d9326a (target/i386: Assert !SVME for user-only)
31/50 Checking commit 11f0dd55a271 (target/i386: Assert !GUEST for user-only)
32/50 Checking commit a4b7e867551d (target/i386: Implement skinit in translate.c)
33/50 Checking commit 9e4eefdeb4b0 (target/i386: Eliminate SVM helpers for user-only)
34/50 Checking commit 33b7b33509a7 (target/i386: Mark some helpers as noreturn)
35/50 Checking commit 07bc5bb234b8 (target/i386: Simplify gen_debug usage)
36/50 Checking commit e533b1a32fe7 (target/i386: Tidy svm_check_intercept from tcg)
37/50 Checking commit 01ec488d9b2f (target/i386: Remove pc_start argument to gen_svm_check_intercept)
WARNING: line over 80 characters
#178: FILE: target/i386/tcg/translate.c:7718:
+            gen_svm_check_intercept(s, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);

total: 0 errors, 1 warnings, 176 lines checked

Patch 37/50 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
38/50 Checking commit f975359de16a (target/i386: Remove user stub for cpu_vmexit)
39/50 Checking commit eff322ae04ac (target/i386: Cleanup read_crN, write_crN, lmsw)
40/50 Checking commit fc622c84f2fe (target/i386: Pass env to do_pause and do_hlt)
41/50 Checking commit 46e15b62a0e1 (target/i386: Move invlpg, hlt, monitor, mwait to sysemu)
42/50 Checking commit 946b94c8cd37 (target/i386: Unify invlpg, invlpga)
43/50 Checking commit 0010e63fa742 (target/i386: Inline user cpu_svm_check_intercept_param)
Use of uninitialized value $acpi_testexpected in string eq at ./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#51: 
deleted file mode 100644

total: 0 errors, 1 warnings, 22 lines checked

Patch 43/50 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
44/50 Checking commit 5555941839dc (target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr)
45/50 Checking commit 428209161b08 (target/i386: Exit tb after wrmsr)
46/50 Checking commit 8f6e5bb5a6b5 (target/i386: Tidy gen_check_io)
47/50 Checking commit 6814811fafd4 (target/i386: Pass in port to gen_check_io)
48/50 Checking commit 50e4fb44910d (target/i386: Create helper_check_io)
49/50 Checking commit 1d820c0db728 (target/i386: Move helper_check_io to sysemu)
50/50 Checking commit e202c8cd8ba5 (target/i386: Remove user-only i/o stubs)
Use of uninitialized value $acpi_testexpected in string eq at ./scripts/checkpatch.pl line 1529.
WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#70: 
deleted file mode 100644

total: 0 errors, 1 warnings, 34 lines checked

Patch 50/50 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20210514151342.384376-1-richard.henderson@linaro.org/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-devel@redhat.com

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

* Re: [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu
  2021-05-14 15:13 ` [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu Richard Henderson
@ 2021-05-14 17:45   ` Richard Henderson
  2021-05-18 10:22     ` Paolo Bonzini
  0 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-14 17:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: pbonzini, f4bug, ehabkost, cfontana

On 5/14/21 10:13 AM, Richard Henderson wrote:
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -193,6 +193,7 @@ typedef struct DisasContext {
>       { qemu_build_not_reached(); }
>   
>   #ifdef CONFIG_USER_ONLY
> +STUB_HELPER(check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 size)
>   STUB_HELPER(clgi, TCGv_env env)
>   STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
>   STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
...
> @@ -681,6 +683,14 @@ static void gen_helper_out_func(MemOp ot, TCGv_i32 v, TCGv_i32 n)
>   static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
>                            uint32_t svm_flags)
>   {
> +#ifdef CONFIG_USER_ONLY
> +    /*
> +     * We do not implement the iopriv(2) syscall, so the TSS check
> +     * will always fail.
> +     */
> +    gen_exception_gpf(s);
> +    return false;
> +#else
>       if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
>           gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
>       }
> @@ -699,6 +709,7 @@ static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
>                                   tcg_constant_i32(next_eip - cur_eip));
>       }
>       return true;
> +#endif

This ifdef means the STUB_HELPER above isn't even used.
This is caught by clang as an unused inline function.
Will fix for v3.


r~


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

* Re: [PATCH v2 01/50] target/i386: Split out gen_exception_gpf
  2021-05-14 15:12 ` [PATCH v2 01/50] target/i386: Split out gen_exception_gpf Richard Henderson
@ 2021-05-18  9:08   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 68 ++++++++++++++++++++-----------------
>   1 file changed, 37 insertions(+), 31 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index db56a48343..2672e08197 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -1276,6 +1276,12 @@ static void gen_illegal_opcode(DisasContext *s)
>       gen_exception(s, EXCP06_ILLOP, s->pc_start - s->cs_base);
>   }
>   
> +/* Generate #GP for the current instruction. */
> +static void gen_exception_gpf(DisasContext *s)
> +{
> +    gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
> +}
> +
>   /* if d == OR_TMP0, it means memory operand (address in A0) */
>   static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
>   {
> @@ -4502,7 +4508,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       s->vex_l = 0;
>       s->vex_v = 0;
>       if (sigsetjmp(s->jmpbuf, 0) != 0) {
> -        gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +        gen_exception_gpf(s);
>           return s->pc;
>       }
>   
> @@ -6567,7 +6573,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               set_cc_op(s, CC_OP_EFLAGS);
>           } else if (s->vm86) {
>               if (s->iopl != 3) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>               } else {
>                   gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
>                   set_cc_op(s, CC_OP_EFLAGS);
> @@ -6689,7 +6695,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x9c: /* pushf */
>           gen_svm_check_intercept(s, pc_start, SVM_EXIT_PUSHF);
>           if (s->vm86 && s->iopl != 3) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_update_cc_op(s);
>               gen_helper_read_eflags(s->T0, cpu_env);
> @@ -6699,7 +6705,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x9d: /* popf */
>           gen_svm_check_intercept(s, pc_start, SVM_EXIT_POPF);
>           if (s->vm86 && s->iopl != 3) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               ot = gen_pop_T0(s);
>               if (s->cpl == 0) {
> @@ -7061,7 +7067,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0xcd: /* int N */
>           val = x86_ldub_code(env, s);
>           if (s->vm86 && s->iopl != 3) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_interrupt(s, val, pc_start - s->cs_base, s->pc - s->cs_base);
>           }
> @@ -7084,13 +7090,13 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (s->cpl <= s->iopl) {
>                   gen_helper_cli(cpu_env);
>               } else {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>               }
>           } else {
>               if (s->iopl == 3) {
>                   gen_helper_cli(cpu_env);
>               } else {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>               }
>           }
>           break;
> @@ -7101,7 +7107,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               gen_jmp_im(s, s->pc - s->cs_base);
>               gen_eob_inhibit_irq(s, true);
>           } else {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           }
>           break;
>       case 0x62: /* bound */
> @@ -7194,7 +7200,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x130: /* wrmsr */
>       case 0x132: /* rdmsr */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_update_cc_op(s);
>               gen_jmp_im(s, pc_start - s->cs_base);
> @@ -7226,7 +7232,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
>               goto illegal_op;
>           if (!s->pe) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_helper_sysenter(cpu_env);
>               gen_eob(s);
> @@ -7237,7 +7243,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           if (CODE64(s) && env->cpuid_vendor1 != CPUID_VENDOR_INTEL_1)
>               goto illegal_op;
>           if (!s->pe) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_helper_sysexit(cpu_env, tcg_const_i32(dflag - 1));
>               gen_eob(s);
> @@ -7256,7 +7262,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0x107: /* sysret */
>           if (!s->pe) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_helper_sysret(cpu_env, tcg_const_i32(dflag - 1));
>               /* condition codes are modified only in long mode */
> @@ -7278,7 +7284,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0xf4: /* hlt */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_update_cc_op(s);
>               gen_jmp_im(s, pc_start - s->cs_base);
> @@ -7304,7 +7310,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!s->pe || s->vm86)
>                   goto illegal_op;
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>               } else {
>                   gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
>                   gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
> @@ -7325,7 +7331,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!s->pe || s->vm86)
>                   goto illegal_op;
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>               } else {
>                   gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
>                   gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
> @@ -7441,7 +7447,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
> @@ -7458,7 +7464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7483,7 +7489,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7496,7 +7502,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7511,7 +7517,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7525,7 +7531,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7549,7 +7555,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   goto illegal_op;
>               }
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7559,7 +7565,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>   
>           CASE_MODRM_MEM_OP(2): /* lgdt */
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
> @@ -7576,7 +7582,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>   
>           CASE_MODRM_MEM_OP(3): /* lidt */
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
> @@ -7622,7 +7628,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               break;
>           CASE_MODRM_OP(6): /* lmsw */
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
> @@ -7634,7 +7640,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>   
>           CASE_MODRM_MEM_OP(7): /* invlpg */
>               if (s->cpl != 0) {
> -                gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                gen_exception_gpf(s);
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7649,7 +7655,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>   #ifdef TARGET_X86_64
>               if (CODE64(s)) {
>                   if (s->cpl != 0) {
> -                    gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +                    gen_exception_gpf(s);
>                   } else {
>                       tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
>                       tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
> @@ -7685,7 +7691,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x108: /* invd */
>       case 0x109: /* wbinvd */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
>               /* nothing to do */
> @@ -8009,7 +8015,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x120: /* mov reg, crN */
>       case 0x122: /* mov crN, reg */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               modrm = x86_ldub_code(env, s);
>               /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
> @@ -8063,7 +8069,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>       case 0x121: /* mov reg, drN */
>       case 0x123: /* mov drN, reg */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>   #ifndef CONFIG_USER_ONLY
>               modrm = x86_ldub_code(env, s);
> @@ -8099,7 +8105,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0x106: /* clts */
>           if (s->cpl != 0) {
> -            gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
> +            gen_exception_gpf(s);
>           } else {
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
>               gen_helper_clts(cpu_env);
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 02/50] target/i386: Split out check_cpl0
  2021-05-14 15:12 ` [PATCH v2 02/50] target/i386: Split out check_cpl0 Richard Henderson
@ 2021-05-18  9:10   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:10 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> Split out the check for CPL != 0 and the raising of #GP.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> ---
>   target/i386/tcg/translate.c | 79 ++++++++++++++-----------------------
>   1 file changed, 30 insertions(+), 49 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 2672e08197..61b30117a3 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -1282,6 +1282,16 @@ static void gen_exception_gpf(DisasContext *s)
>       gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base);
>   }
>   
> +/* Check for cpl == 0; if not, raise #GP and return false. */
> +static bool check_cpl0(DisasContext *s)
> +{
> +    if (s->cpl == 0) {
> +        return true;
> +    }
> +    gen_exception_gpf(s);
> +    return false;
> +}
> +
>   /* if d == OR_TMP0, it means memory operand (address in A0) */
>   static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
>   {
> @@ -7199,9 +7209,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0x130: /* wrmsr */
>       case 0x132: /* rdmsr */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>               gen_update_cc_op(s);
>               gen_jmp_im(s, pc_start - s->cs_base);
>               if (b & 2) {
> @@ -7283,9 +7291,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           gen_helper_cpuid(cpu_env);
>           break;
>       case 0xf4: /* hlt */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>               gen_update_cc_op(s);
>               gen_jmp_im(s, pc_start - s->cs_base);
>               gen_helper_hlt(cpu_env, tcg_const_i32(s->pc - pc_start));
> @@ -7309,9 +7315,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           case 2: /* lldt */
>               if (!s->pe || s->vm86)
>                   goto illegal_op;
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> -            } else {
> +            if (check_cpl0(s)) {
>                   gen_svm_check_intercept(s, pc_start, SVM_EXIT_LDTR_WRITE);
>                   gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
>                   tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> @@ -7330,9 +7334,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           case 3: /* ltr */
>               if (!s->pe || s->vm86)
>                   goto illegal_op;
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> -            } else {
> +            if (check_cpl0(s)) {
>                   gen_svm_check_intercept(s, pc_start, SVM_EXIT_TR_WRITE);
>                   gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0);
>                   tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
> @@ -7446,8 +7448,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                                    | PREFIX_REPZ | PREFIX_REPNZ))) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
> @@ -7463,8 +7464,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!(s->flags & HF_SVME_MASK) || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7488,8 +7488,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!(s->flags & HF_SVME_MASK) || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7501,8 +7500,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!(s->flags & HF_SVME_MASK) || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7516,8 +7514,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7530,8 +7527,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!(s->flags & HF_SVME_MASK) || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7554,8 +7550,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               if (!(s->flags & HF_SVME_MASK) || !s->pe) {
>                   goto illegal_op;
>               }
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7564,8 +7559,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               break;
>   
>           CASE_MODRM_MEM_OP(2): /* lgdt */
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_GDTR_WRITE);
> @@ -7581,8 +7575,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               break;
>   
>           CASE_MODRM_MEM_OP(3): /* lidt */
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_IDTR_WRITE);
> @@ -7627,8 +7620,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               gen_helper_wrpkru(cpu_env, s->tmp2_i32, s->tmp1_i64);
>               break;
>           CASE_MODRM_OP(6): /* lmsw */
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
> @@ -7639,8 +7631,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               break;
>   
>           CASE_MODRM_MEM_OP(7): /* invlpg */
> -            if (s->cpl != 0) {
> -                gen_exception_gpf(s);
> +            if (!check_cpl0(s)) {
>                   break;
>               }
>               gen_update_cc_op(s);
> @@ -7654,9 +7645,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           case 0xf8: /* swapgs */
>   #ifdef TARGET_X86_64
>               if (CODE64(s)) {
> -                if (s->cpl != 0) {
> -                    gen_exception_gpf(s);
> -                } else {
> +                if (check_cpl0(s)) {
>                       tcg_gen_mov_tl(s->T0, cpu_seg_base[R_GS]);
>                       tcg_gen_ld_tl(cpu_seg_base[R_GS], cpu_env,
>                                     offsetof(CPUX86State, kernelgsbase));
> @@ -7690,9 +7679,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>   
>       case 0x108: /* invd */
>       case 0x109: /* wbinvd */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>               gen_svm_check_intercept(s, pc_start, (b & 2) ? SVM_EXIT_INVD : SVM_EXIT_WBINVD);
>               /* nothing to do */
>           }
> @@ -8014,9 +8001,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0x120: /* mov reg, crN */
>       case 0x122: /* mov crN, reg */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>               modrm = x86_ldub_code(env, s);
>               /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
>                * AMD documentation (24594.pdf) and testing of
> @@ -8068,9 +8053,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           break;
>       case 0x121: /* mov reg, drN */
>       case 0x123: /* mov drN, reg */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>   #ifndef CONFIG_USER_ONLY
>               modrm = x86_ldub_code(env, s);
>               /* Ignore the mod bits (assume (modrm&0xc0)==0xc0).
> @@ -8104,9 +8087,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>           }
>           break;
>       case 0x106: /* clts */
> -        if (s->cpl != 0) {
> -            gen_exception_gpf(s);
> -        } else {
> +        if (check_cpl0(s)) {
>               gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0);
>               gen_helper_clts(cpu_env);
>               /* abort block because static cpu state changed */
> 



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

* Re: [PATCH v2 03/50] target/i386: Unify code paths for IRET
  2021-05-14 15:12 ` [PATCH v2 03/50] target/i386: Unify code paths for IRET Richard Henderson
@ 2021-05-18  9:11   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:11 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> In vm86 mode, we use the same helper as real-mode, but with
> an extra check for IOPL.  All non-exceptional paths set EFLAGS.
> 
> Signed-off-by: Richard Henderson<richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 16 ++++++----------
>   1 file changed, 6 insertions(+), 10 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 05/50] target/i386: Split out check_iopl
  2021-05-14 15:12 ` [PATCH v2 05/50] target/i386: Split out check_iopl Richard Henderson
@ 2021-05-18  9:14   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:14 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 28 +++++++++++++---------------
>   1 file changed, 13 insertions(+), 15 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 06/50] target/i386: Assert PE is set for user-only
  2021-05-14 15:12 ` [PATCH v2 06/50] target/i386: Assert PE is set for user-only Richard Henderson
@ 2021-05-18  9:15   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:15 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> A user-mode executable is never in real-mode.  Since we're adding
> an accessor macro, pull the value directly out of flags for sysemu.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 07/50] target/i386: Assert CPL is 3 for user-only
  2021-05-14 15:12 ` [PATCH v2 07/50] target/i386: Assert CPL is 3 " Richard Henderson
@ 2021-05-18  9:17   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:17 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> A user-mode executable always runs in ring 3.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 08/50] target/i386: Assert IOPL is 0 for user-only
  2021-05-14 15:13 ` [PATCH v2 08/50] target/i386: Assert IOPL is 0 " Richard Henderson
@ 2021-05-18  9:18   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:18 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> On real hardware, the linux kernel has the iopl(2) syscall which
> can set IOPL to 3, to allow e.g. the xserver to briefly disable
> interrupts while programming the graphics card.
> 
> However, QEMU cannot and does not implement this syscall, so the
> IOPL is never changed from 0.  Which means that all of the checks
> vs CPL <= IOPL are false for user-only.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only Richard Henderson
@ 2021-05-18  9:19   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:19 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> For i386-linux-user, we can enter vm86 mode via the vm86(2) syscall.
> That syscall explicitly returns to 32-bit mode, and the syscall does
> not exist for a 64-bit x86_64 executable.
> 
> Since we're adding an accessor macro, pull the value directly out of
> flags otherwise.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 40 ++++++++++++++++++++-----------------
>   1 file changed, 22 insertions(+), 18 deletions(-)


Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 10/50] target/i386: Assert CODE32 for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 10/50] target/i386: Assert CODE32 " Richard Henderson
@ 2021-05-18  9:20   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> For user-only, CODE32 == !VM86, because we are never in real-mode.
> Since we cannot enter vm86 mode for x86_64 user-only, CODE32 is
> always set.
> 
> Since we're adding an accessor macro, pull the value directly out
> of flags otherwise.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 13 +++++++------
>   1 file changed, 7 insertions(+), 6 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 11/50] target/i386: Assert SS32 for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 11/50] target/i386: Assert SS32 " Richard Henderson
@ 2021-05-18  9:20   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> For user-only, SS32 == !VM86, because we are never in
> real-mode.  Since we cannot enter vm86 mode for x86_64
> user-only, SS32 is always set.
> 
> Since we're adding an accessor macro, pull the value
> directly out of flags otherwise.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 12/50] target/i386: Assert CODE64 for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 12/50] target/i386: Assert CODE64 " Richard Henderson
@ 2021-05-18  9:21   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> For x86_64 user-only, there is no way to leave 64-bit mode.
> 
> Without x86_64, there is no way to enter 64-bit mode.  There is
> an existing macro to aid with that; simply place it in the right
> place in the ifdef chain.
> 
> Since we're adding an accessor macro, pull the value directly out
> of flags when we're not assuming a constant.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 13/50] target/i386: Assert LMA for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 13/50] target/i386: Assert LMA " Richard Henderson
@ 2021-05-18  9:21   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> LMA is a pre-requisite for CODE64, so there is no way to disable it
> for x86_64-linux-user, and there is no way to enable it for i386.
> 
> Since we're adding an accessor macro, pull the value directly out
> of flags when we're not assuming a constant.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 14/50] target/i386: Assert !ADDSEG for x86_64 user-only
  2021-05-14 15:13 ` [PATCH v2 14/50] target/i386: Assert !ADDSEG " Richard Henderson
@ 2021-05-18  9:23   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> LMA disables traditional segmentation, exposing a flat address space.
> This means that ADDSEG is off.
> 
> Since we're adding an accessor macro, pull the value directly out
> of flags otherwise.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 15/50] target/i386: Introduce REX_PREFIX
  2021-05-14 15:13 ` [PATCH v2 15/50] target/i386: Introduce REX_PREFIX Richard Henderson
@ 2021-05-18  9:26   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:26 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The existing flag, x86_64_hregs, does not accurately describe
> its setting.  It is true if and only if a REX prefix has been
> seen.  Yes, that affects the "h" regs, but that's secondary.
> 
> Add PREFIX_REX and include this bit in s->prefix.  Add REX_PREFIX
> so that the check folds away when x86_64 is compiled out.
> 
> Fold away the reg >= 8 check, because bit 3 of the register
> number comes from the REX prefix in the first place.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 29 +++++++++++------------------
>   1 file changed, 11 insertions(+), 18 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition
  2021-05-14 15:13 ` [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition Richard Henderson
@ 2021-05-18  9:28   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Change the storage from int to uint8_t since the value is in {0,8}.
> For x86_64 add 0 in the macros to (1) promote the type back to int,
> and (2) make the macro an rvalue.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Might be easier in the end to put all rex bits in the same uint8_t, but 
that can be done later.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

Paolo

> ---
>   target/i386/tcg/translate.c | 17 +++++++----------
>   1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 79a37fb1a7..9bb37215d8 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -41,14 +41,6 @@
>   #define PREFIX_VEX    0x20
>   #define PREFIX_REX    0x40
>   
> -#ifdef TARGET_X86_64
> -#define REX_X(s) ((s)->rex_x)
> -#define REX_B(s) ((s)->rex_b)
> -#else
> -#define REX_X(s) 0
> -#define REX_B(s) 0
> -#endif
> -
>   #ifdef TARGET_X86_64
>   # define ctztl  ctz64
>   # define clztl  clz64
> @@ -100,7 +92,8 @@ typedef struct DisasContext {
>   #endif
>   
>   #ifdef TARGET_X86_64
> -    int rex_x, rex_b;
> +    uint8_t rex_x;
> +    uint8_t rex_b;
>   #endif
>       int vex_l;  /* vex vector length */
>       int vex_v;  /* vex vvvv register, without 1's complement.  */
> @@ -173,8 +166,12 @@ typedef struct DisasContext {
>   
>   #ifdef TARGET_X86_64
>   #define REX_PREFIX(S)  (((S)->prefix & PREFIX_REX) != 0)
> +#define REX_X(S)       ((S)->rex_x + 0)
> +#define REX_B(S)       ((S)->rex_b + 0)
>   #else
>   #define REX_PREFIX(S)  false
> +#define REX_X(S)       0
> +#define REX_B(S)       0
>   #endif
>   
>   static void gen_eob(DisasContext *s);
> @@ -4617,7 +4614,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>               rex_w = (b >> 3) & 1;
>               rex_r = (b & 0x4) << 1;
>               s->rex_x = (b & 0x2) << 2;
> -            REX_B(s) = (b & 0x1) << 3;
> +            s->rex_b = (b & 0x1) << 3;
>               goto next_byte;
>           }
>           break;
> 



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

* Re: [PATCH v2 17/50] target/i386: Move rex_r into DisasContext
  2021-05-14 15:13 ` [PATCH v2 17/50] target/i386: Move rex_r into DisasContext Richard Henderson
@ 2021-05-18  9:28   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:28 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Treat this flag exactly like we treat rex_b and rex_x.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 84 ++++++++++++++++++++-----------------
>   1 file changed, 45 insertions(+), 39 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 18/50] target/i386: Move rex_w into DisasContext
  2021-05-14 15:13 ` [PATCH v2 18/50] target/i386: Move rex_w " Richard Henderson
@ 2021-05-18  9:30   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Treat this flag exactly like we treat the other rex bits.
> The -1 initialization is unused; the two tests are > 0 and == 1,
> so the value can be reduced to a bool.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused
  2021-05-14 15:13 ` [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused Richard Henderson
@ 2021-05-18  9:30   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 2 --
>   1 file changed, 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 4222f09b6f..7e296b39f5 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -101,7 +101,6 @@ typedef struct DisasContext {
>       int vex_v;  /* vex vvvv register, without 1's complement.  */
>       CCOp cc_op;  /* current CC operation */
>       bool cc_op_dirty;
> -    int f_st;   /* currently unused */
>       int tf;     /* TF cpu flag */
>       int jmp_opt; /* use direct block chaining for direct jumps */
>       int repz_opt; /* optimize jumps within repz instructions */
> @@ -8507,7 +8506,6 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
>       g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
>       g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
>   
> -    dc->f_st = 0;
>       dc->tf = (flags >> TF_SHIFT) & 1;
>       dc->cc_op = CC_OP_DYNAMIC;
>       dc->cc_op_dirty = false;
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t
  2021-05-14 15:13 ` [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t Richard Henderson
@ 2021-05-18  9:30   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The value comes from tb->flags, which is uint32_t.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 7e296b39f5..ca7f0a8cf4 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -105,7 +105,7 @@ typedef struct DisasContext {
>       int jmp_opt; /* use direct block chaining for direct jumps */
>       int repz_opt; /* optimize jumps within repz instructions */
>       int mem_index; /* select memory access functions */
> -    uint64_t flags; /* all execution flags */
> +    uint32_t flags; /* all execution flags */
>       int popl_esp_hack; /* for correct popl with esp base handling */
>       int rip_offset; /* only used in x86_64, but left for simplicity */
>       int cpuid_features;
> 


Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t
  2021-05-14 15:13 ` [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t Richard Henderson
@ 2021-05-18  9:31   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The range of values is -1 (none) to 5 (R_GS).
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index ca7f0a8cf4..44a28858aa 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -77,7 +77,7 @@ typedef struct DisasContext {
>       DisasContextBase base;
>   
>       /* current insn context */
> -    int override; /* -1 if no override */
> +    int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
>       int prefix;
>       MemOp aflag;
>       MemOp dflag;
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t
  2021-05-14 15:13 ` [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t Richard Henderson
@ 2021-05-18  9:31   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The highest bit in this set is 0x40 (PREFIX_REX).
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 44a28858aa..61c0573c2f 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -78,7 +78,7 @@ typedef struct DisasContext {
>   
>       /* current insn context */
>       int8_t override; /* -1 if no override, else R_CS, R_DS, etc */
> -    int prefix;
> +    uint8_t prefix;
>       MemOp aflag;
>       MemOp dflag;
>       target_ulong pc_start;
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] to uint8_t
  2021-05-14 15:13 ` [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] " Richard Henderson
@ 2021-05-18  9:32   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:32 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Currently, vex_l is either {0,1}; if in the future we implement
> AVX-512, the max value will be 2.  In vex_v we store a register
> number.  This is 0-15 for SSE, and 0-31 for AVX-512.
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 61c0573c2f..1367e53e4e 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -97,8 +97,8 @@ typedef struct DisasContext {
>       uint8_t rex_b;
>       bool rex_w;
>   #endif
> -    int vex_l;  /* vex vector length */
> -    int vex_v;  /* vex vvvv register, without 1's complement.  */
> +    uint8_t vex_l;  /* vex vector length */
> +    uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
>       CCOp cc_op;  /* current CC operation */
>       bool cc_op_dirty;
>       int tf;     /* TF cpu flag */
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset to uint8_t
  2021-05-14 15:13 ` [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset " Richard Henderson
@ 2021-05-18  9:34   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:34 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Both of these fields store the size of a single memory access,
> so the range of values is 0-8.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 1367e53e4e..847502046f 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -106,8 +106,8 @@ typedef struct DisasContext {
>       int repz_opt; /* optimize jumps within repz instructions */
>       int mem_index; /* select memory access functions */
>       uint32_t flags; /* all execution flags */
> -    int popl_esp_hack; /* for correct popl with esp base handling */
> -    int rip_offset; /* only used in x86_64, but left for simplicity */
> +    uint8_t popl_esp_hack; /* for correct popl with esp base handling */
> +    uint8_t rip_offset; /* only used in x86_64, but left for simplicity */
>       int cpuid_features;
>       int cpuid_ext_features;
>       int cpuid_ext2_features;
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags
  2021-05-14 15:13 ` [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags Richard Henderson
@ 2021-05-18  9:36   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:36 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> It's just as easy to clear the flag with AND than assignment.
> In two cases the test for the bit can be folded together with
> the test for HF_INHIBIT_IRQ_MASK.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 14 ++++++--------
>   1 file changed, 6 insertions(+), 8 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool
  2021-05-14 15:13 ` [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool Richard Henderson
@ 2021-05-18  9:36   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:36 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 3f6214c624..b9b94f0625 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -101,8 +101,8 @@ typedef struct DisasContext {
>       uint8_t vex_v;  /* vex vvvv register, without 1's complement.  */
>       CCOp cc_op;  /* current CC operation */
>       bool cc_op_dirty;
> -    int jmp_opt; /* use direct block chaining for direct jumps */
> -    int repz_opt; /* optimize jumps within repz instructions */
> +    bool jmp_opt; /* use direct block chaining for direct jumps */
> +    bool repz_opt; /* optimize jumps within repz instructions */
>       int mem_index; /* select memory access functions */
>       uint32_t flags; /* all execution flags */
>       uint8_t popl_esp_hack; /* for correct popl with esp base handling */
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 27/50] target/i386: Fix the comment for repz_opt
  2021-05-14 15:13 ` [PATCH v2 27/50] target/i386: Fix the comment for repz_opt Richard Henderson
@ 2021-05-18  9:48   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> After fixing a typo in the comment, fixup for CODING_STYLE.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 19 ++++++++++---------
>   1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index b9b94f0625..d48c0f82a9 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -8521,15 +8521,16 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
>       dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
>       dc->jmp_opt = !(dc->base.singlestep_enabled ||
>                       (flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
> -    /* Do not optimize repz jumps at all in icount mode, because
> -       rep movsS instructions are execured with different paths
> -       in !repz_opt and repz_opt modes. The first one was used
> -       always except single step mode. And this setting
> -       disables jumps optimization and control paths become
> -       equivalent in run and single step modes.
> -       Now there will be no jump optimization for repz in
> -       record/replay modes and there will always be an
> -       additional step for ecx=0 when icount is enabled.
> +    /*
> +     * Do not optimize repz jumps at all in icount mode, because
> +     * rep movsS instructions are executed with different paths
> +     * in !repz_opt and repz_opt modes. The first one was used
> +     * always except single step mode. And this setting
> +     * disables jumps optimization and control paths become
> +     * equivalent in run and single step modes.
> +     * Now there will be no jump optimization for repz in
> +     * record/replay modes and there will always be an
> +     * additional step for ecx=0 when icount is enabled.
>        */
>       dc->repz_opt = !dc->jmp_opt && !(tb_cflags(dc->base.tb) & CF_USE_ICOUNT);
>   
> 

The comment is still quite unreadable, so perhaps something like this

	/*
	 * If jmp_opt, we want to handle each string instruction individually.
	 * For icount also disable repz optimization so that each iteration
	 * is accounted separately.
	 */

Paolo



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

* Re: [PATCH v2 04/50] target/i386: Split out check_vm86_iopl
  2021-05-14 15:12 ` [PATCH v2 04/50] target/i386: Split out check_vm86_iopl Richard Henderson
@ 2021-05-18  9:48   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 25 ++++++++++++++-----------
>   1 file changed, 14 insertions(+), 11 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 28/50] target/i386: Reorder DisasContext members
  2021-05-14 15:13 ` [PATCH v2 28/50] target/i386: Reorder DisasContext members Richard Henderson
@ 2021-05-18  9:49   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:49 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Sort all of the single-byte members to the same area
> of the structure, eliminating 8 bytes of padding.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 27 ++++++++++++++-------------
>   1 file changed, 14 insertions(+), 13 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr
  2021-05-14 15:13 ` [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr Richard Henderson
@ 2021-05-18  9:49   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:49 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> This removes an ifdef from the middle of disas_insn,
> and ensures that the branch is not reachable.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 15 +++++++++++++--
>   1 file changed, 13 insertions(+), 2 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 30/50] target/i386: Assert !SVME for user-only
  2021-05-14 15:13 ` [PATCH v2 30/50] target/i386: Assert !SVME for user-only Richard Henderson
@ 2021-05-18  9:51   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Most of the VMM instructions are already disabled for
> user-only, by being usable only from ring 0.
> 
> The spec is intentionally loose for VMMCALL, allowing
> the VMM to define syscalls for user-only.  However,
> linux does not do so; VMMCALL is illegal.

Perhaps:

However we're not emulating any VMM, so VMMCALL can just raise #UD 
unconditionally.

Paolo



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

* Re: [PATCH v2 31/50] target/i386: Assert !GUEST for user-only
  2021-05-14 15:13 ` [PATCH v2 31/50] target/i386: Assert !GUEST " Richard Henderson
@ 2021-05-18  9:51   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> For user-only, we do not need to check for VMM intercept.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

>   target/i386/tcg/translate.c | 8 ++++++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index f58e0f480a..57ae515796 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -139,11 +139,13 @@ typedef struct DisasContext {
>   #define CPL(S)    3
>   #define IOPL(S)   0
>   #define SVME(S)   false
> +#define GUEST(S)  false
>   #else
>   #define PE(S)     (((S)->flags & HF_PE_MASK) != 0)
>   #define CPL(S)    ((S)->cpl)
>   #define IOPL(S)   ((S)->iopl)
>   #define SVME(S)   (((S)->flags & HF_SVME_MASK) != 0)
> +#define GUEST(S)  (((S)->flags & HF_GUEST_MASK) != 0)
>   #endif
>   #if defined(CONFIG_USER_ONLY) && defined(TARGET_X86_64)
>   #define VM86(S)   false
> @@ -677,7 +679,7 @@ static void gen_check_io(DisasContext *s, MemOp ot, target_ulong cur_eip,
>               tcg_abort();
>           }
>       }
> -    if(s->flags & HF_GUEST_MASK) {
> +    if (GUEST(s)) {
>           gen_update_cc_op(s);
>           gen_jmp_im(s, cur_eip);
>           svm_flags |= (1 << (4 + ot));
> @@ -2417,8 +2419,9 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
>                                 uint32_t type, uint64_t param)
>   {
>       /* no SVM activated; fast case */
> -    if (likely(!(s->flags & HF_GUEST_MASK)))
> +    if (likely(!GUEST(s))) {
>           return;
> +    }
>       gen_update_cc_op(s);
>       gen_jmp_im(s, pc_start - s->cs_base);
>       gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
> @@ -8517,6 +8520,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
>       g_assert(LMA(dc) == ((flags & HF_LMA_MASK) != 0));
>       g_assert(ADDSEG(dc) == ((flags & HF_ADDSEG_MASK) != 0));
>       g_assert(SVME(dc) == ((flags & HF_SVME_MASK) != 0));
> +    g_assert(GUEST(dc) == ((flags & HF_GUEST_MASK) != 0));
>   
>       dc->cc_op = CC_OP_DYNAMIC;
>       dc->cc_op_dirty = false;
> 



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

* Re: [PATCH v2 32/50] target/i386: Implement skinit in translate.c
  2021-05-14 15:13 ` [PATCH v2 32/50] target/i386: Implement skinit in translate.c Richard Henderson
@ 2021-05-18  9:51   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Our sysemu implementation is a stub.  We can already intercept
> instructions for vmexit, and raising #UD is trivial.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h                | 1 -
>   target/i386/tcg/sysemu/svm_helper.c | 7 -------
>   target/i386/tcg/translate.c         | 7 +++----
>   target/i386/tcg/user/svm_stubs.c    | 4 ----
>   4 files changed, 3 insertions(+), 16 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only
  2021-05-14 15:13 ` [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only Richard Henderson
@ 2021-05-18  9:52   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:52 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Use STUB_HELPER to ensure that such calls are always eliminated.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h             |  3 +--
>   target/i386/tcg/translate.c      |  9 ++++++++
>   target/i386/tcg/user/svm_stubs.c | 38 --------------------------------
>   3 files changed, 10 insertions(+), 40 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 34/50] target/i386: Mark some helpers as noreturn
  2021-05-14 15:13 ` [PATCH v2 34/50] target/i386: Mark some helpers as noreturn Richard Henderson
@ 2021-05-18  9:56   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Any helper that always raises an exception or interrupt,
> or simply exits to the main loop, can be so marked.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h          | 18 +++++++++---------
>   target/i386/tcg/bpt_helper.c  |  2 +-
>   target/i386/tcg/excp_helper.c | 18 ++++++++++--------
>   target/i386/tcg/misc_helper.c | 14 +++++++-------
>   target/i386/tcg/translate.c   |  3 ++-
>   5 files changed, 29 insertions(+), 26 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 35/50] target/i386: Simplify gen_debug usage
  2021-05-14 15:13 ` [PATCH v2 35/50] target/i386: Simplify gen_debug usage Richard Henderson
@ 2021-05-18  9:56   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:56 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Both invocations pass the start of the current instruction,
> which is available as s->base.pc_next.  The function sets
> is_jmp, so we can eliminate a second setting.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 9 ++++-----
>   1 file changed, 4 insertions(+), 5 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg
  2021-05-14 15:13 ` [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg Richard Henderson
@ 2021-05-18  9:57   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:57 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The param argument to helper_svm_check_intercept_param is always 0;
> eliminate it and rename to helper_svm_check_intercept.  Fold
> gen_sve_check_intercept_param into gen_svm_check_intercept.
       ^^^

Too much ARM lately. :)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h                |  2 +-
>   target/i386/tcg/sysemu/svm_helper.c |  5 ++---
>   target/i386/tcg/translate.c         | 16 ++++------------
>   3 files changed, 7 insertions(+), 16 deletions(-)
> 
> diff --git a/target/i386/helper.h b/target/i386/helper.h
> index f794d1c7c7..86484a4ec4 100644
> --- a/target/i386/helper.h
> +++ b/target/i386/helper.h
> @@ -107,7 +107,7 @@ DEF_HELPER_2(inl, tl, env, i32)
>   
>   #ifndef CONFIG_USER_ONLY
>   DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
> -DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64)
> +DEF_HELPER_2(svm_check_intercept, void, env, i32)
>   DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32)
>   DEF_HELPER_3(vmrun, void, env, int, int)
>   DEF_HELPER_1(vmmcall, void, env)
> diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
> index 79c73d67af..b431016e72 100644
> --- a/target/i386/tcg/sysemu/svm_helper.c
> +++ b/target/i386/tcg/sysemu/svm_helper.c
> @@ -506,10 +506,9 @@ void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type,
>       }
>   }
>   
> -void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type,
> -                                      uint64_t param)
> +void helper_svm_check_intercept(CPUX86State *env, uint32_t type)
>   {
> -    cpu_svm_check_intercept_param(env, type, param, GETPC());
> +    cpu_svm_check_intercept_param(env, type, 0, GETPC());
>   }
>   
>   void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 8a02c5a373..12ef2cf064 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -197,7 +197,7 @@ STUB_HELPER(clgi, TCGv_env env)
>   STUB_HELPER(invlpga, TCGv_env env, TCGv_i32 aflag)
>   STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
>   STUB_HELPER(stgi, TCGv_env env)
> -STUB_HELPER(svm_check_intercept_param, TCGv_env env, TCGv_i32 t, TCGv_i64 p)
> +STUB_HELPER(svm_check_intercept, TCGv_env env, TCGv_i32 type)
>   STUB_HELPER(svm_check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 p, TCGv_i32 a)
>   STUB_HELPER(vmload, TCGv_env env, TCGv_i32 aflag)
>   STUB_HELPER(vmmcall, TCGv_env env)
> @@ -2423,9 +2423,8 @@ static inline int svm_is_rep(int prefixes)
>       return ((prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) ? 8 : 0);
>   }
>   
> -static inline void
> -gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
> -                              uint32_t type, uint64_t param)
> +static void gen_svm_check_intercept(DisasContext *s, target_ulong pc_start,
> +                                    uint32_t type)
>   {
>       /* no SVM activated; fast case */
>       if (likely(!GUEST(s))) {
> @@ -2433,14 +2432,7 @@ gen_svm_check_intercept_param(DisasContext *s, target_ulong pc_start,
>       }
>       gen_update_cc_op(s);
>       gen_jmp_im(s, pc_start - s->cs_base);
> -    gen_helper_svm_check_intercept_param(cpu_env, tcg_const_i32(type),
> -                                         tcg_const_i64(param));
> -}
> -
> -static inline void
> -gen_svm_check_intercept(DisasContext *s, target_ulong pc_start, uint64_t type)
> -{
> -    gen_svm_check_intercept_param(s, pc_start, type, 0);
> +    gen_helper_svm_check_intercept(cpu_env, tcg_constant_i32(type));
>   }
>   
>   static inline void gen_stack_update(DisasContext *s, int addend)
> 



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

* Re: [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept
  2021-05-14 15:13 ` [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept Richard Henderson
@ 2021-05-18  9:58   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:58 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> When exiting helper_svm_check_intercept via exception, cpu_vmexit
> calls cpu_restore_state, which will recover eip and cc_op via unwind.
> Therefore we do not need to store eip or cc_op before the call.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 45 +++++++++++++++++--------------------
>   1 file changed, 21 insertions(+), 24 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit
  2021-05-14 15:13 ` [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit Richard Henderson
@ 2021-05-18  9:58   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:58 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> This function is only called from tcg/sysemu/.
> There is no need for a stub in tcg/user/.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/helper-tcg.h     | 4 +++-
>   target/i386/tcg/user/svm_stubs.c | 6 ------
>   2 files changed, 3 insertions(+), 7 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt
  2021-05-14 15:13 ` [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt Richard Henderson
@ 2021-05-18  9:59   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18  9:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Having the callers upcast to X86CPU is a waste, since we
> don't need it.  We even have to recover env in do_hlt.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/misc_helper.c | 22 ++++++++--------------
>   1 file changed, 8 insertions(+), 14 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu
  2021-05-14 15:13 ` [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu Richard Henderson
@ 2021-05-18 10:00   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> These instructions are all privileged.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h                 |  8 ++--
>   target/i386/tcg/helper-tcg.h         |  1 +
>   target/i386/tcg/misc_helper.c        | 55 +---------------------------
>   target/i386/tcg/sysemu/misc_helper.c | 53 +++++++++++++++++++++++++++
>   target/i386/tcg/translate.c          |  4 ++
>   5 files changed, 63 insertions(+), 58 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 42/50] target/i386: Unify invlpg, invlpga
  2021-05-14 15:13 ` [PATCH v2 42/50] target/i386: Unify invlpg, invlpga Richard Henderson
@ 2021-05-18 10:00   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Use a single helper, flush_page, to do the work.
> Use gen_svm_check_intercept.
> Perform the zero-extension for invlpga inline.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h                 |  3 +--
>   target/i386/tcg/sysemu/misc_helper.c |  7 ++-----
>   target/i386/tcg/sysemu/svm_helper.c  | 18 ------------------
>   target/i386/tcg/translate.c          | 20 ++++++++++++--------
>   4 files changed, 15 insertions(+), 33 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param
  2021-05-14 15:13 ` [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param Richard Henderson
@ 2021-05-18 10:01   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> The user-version is a no-op.  This lets us completely
> remove tcg/user/svm_stubs.c.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/cpu.h                |  8 ++++++++
>   target/i386/tcg/user/svm_stubs.c | 28 ----------------------------
>   target/i386/tcg/user/meson.build |  1 -
>   3 files changed, 8 insertions(+), 29 deletions(-)
>   delete mode 100644 target/i386/tcg/user/svm_stubs.c

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr
  2021-05-14 15:13 ` [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr Richard Henderson
@ 2021-05-18 10:01   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h              |  8 ++++----
>   target/i386/tcg/translate.c       |  4 ++++
>   target/i386/tcg/user/misc_stubs.c | 20 --------------------
>   3 files changed, 8 insertions(+), 24 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 45/50] target/i386: Exit tb after wrmsr
  2021-05-14 15:13 ` [PATCH v2 45/50] target/i386: Exit tb after wrmsr Richard Henderson
@ 2021-05-18 10:02   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, qemu-stable, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> At minimum, wrmsr can change efer, which affects HF_LMA.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index 2aa2410336..6eeaa3a98b 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -7260,6 +7260,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
>                   gen_helper_rdmsr(cpu_env);
>               } else {
>                   gen_helper_wrmsr(cpu_env);
> +                gen_jmp_im(s, s->pc - s->cs_base);
> +                gen_eob(s);
>               }
>           }
>           break;
> 

Cc: qemu-stable@nongnu.org
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 46/50] target/i386: Tidy gen_check_io
  2021-05-14 15:13 ` [PATCH v2 46/50] target/i386: Tidy gen_check_io Richard Henderson
@ 2021-05-18 10:18   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:18 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Get cur_eip from DisasContext.  Do not require the caller
> to use svm_is_rep; get prefix from DisasContext.  Use the
> proper symbolic constants for SVM_IOIO_*.
> 
> While we're touching all call sites, return bool in
> preparation for gen_check_io raising #GP.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 57 +++++++++++++++++++------------------
>   1 file changed, 30 insertions(+), 27 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 47/50] target/i386: Pass in port to gen_check_io
  2021-05-14 15:13 ` [PATCH v2 47/50] target/i386: Pass in port to gen_check_io Richard Henderson
@ 2021-05-18 10:20   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Pass in a pre-truncated TCGv_i32 value.  We were doing the
> truncation of EDX in multiple places, now only once per insn.
> While all callers use s->tmp2_i32, for cleanliness of the
> subroutine, use a parameter anyway.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/translate.c | 55 +++++++++++++++++++------------------
>   1 file changed, 29 insertions(+), 26 deletions(-)

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 48/50] target/i386: Create helper_check_io
  2021-05-14 15:13 ` [PATCH v2 48/50] target/i386: Create helper_check_io Richard Henderson
@ 2021-05-18 10:21   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Drop helper_check_io[bwl] and expose their common
> subroutine to tcg directly.
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/helper.h         |  4 +---
>   target/i386/tcg/seg_helper.c | 21 +++------------------
>   target/i386/tcg/translate.c  | 14 +-------------
>   3 files changed, 5 insertions(+), 34 deletions(-)


Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu
  2021-05-14 17:45   ` Richard Henderson
@ 2021-05-18 10:22     ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:22 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 19:45, Richard Henderson wrote:
> On 5/14/21 10:13 AM, Richard Henderson wrote:
>> --- a/target/i386/tcg/translate.c
>> +++ b/target/i386/tcg/translate.c
>> @@ -193,6 +193,7 @@ typedef struct DisasContext {
>>       { qemu_build_not_reached(); }
>>   #ifdef CONFIG_USER_ONLY
>> +STUB_HELPER(check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 size)
>>   STUB_HELPER(clgi, TCGv_env env)
>>   STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
>>   STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
> ...
>> @@ -681,6 +683,14 @@ static void gen_helper_out_func(MemOp ot, 
>> TCGv_i32 v, TCGv_i32 n)
>>   static bool gen_check_io(DisasContext *s, MemOp ot, TCGv_i32 port,
>>                            uint32_t svm_flags)
>>   {
>> +#ifdef CONFIG_USER_ONLY
>> +    /*
>> +     * We do not implement the iopriv(2) syscall, so the TSS check
>> +     * will always fail.
>> +     */
>> +    gen_exception_gpf(s);
>> +    return false;
>> +#else
>>       if (PE(s) && (CPL(s) > IOPL(s) || VM86(s))) {
>>           gen_helper_check_io(cpu_env, port, tcg_constant_i32(1 << ot));
>>       }
>> @@ -699,6 +709,7 @@ static bool gen_check_io(DisasContext *s, MemOp 
>> ot, TCGv_i32 port,
>>                                   tcg_constant_i32(next_eip - cur_eip));
>>       }
>>       return true;
>> +#endif
> 
> This ifdef means the STUB_HELPER above isn't even used.
> This is caught by clang as an unused inline function.
> Will fix for v3.

While you're at it it's ioperm, not iopriv.

Paolo



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

* Re: [PATCH v2 50/50] target/i386: Remove user-only i/o stubs
  2021-05-14 15:13 ` [PATCH v2 50/50] target/i386: Remove user-only i/o stubs Richard Henderson
@ 2021-05-18 10:23   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:23 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> With the previous patch for check_io, we now have enough for
> the compiler to dead-code eliminate all of the i/o helpers.
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

> ---
>   target/i386/helper.h              |  3 +-
>   target/i386/tcg/translate.c       |  6 ++++
>   target/i386/tcg/user/misc_stubs.c | 55 -------------------------------
>   target/i386/tcg/user/meson.build  |  1 -
>   4 files changed, 7 insertions(+), 58 deletions(-)
>   delete mode 100644 target/i386/tcg/user/misc_stubs.c
> 
> diff --git a/target/i386/helper.h b/target/i386/helper.h
> index 3fd0253298..f3d8c3f949 100644
> --- a/target/i386/helper.h
> +++ b/target/i386/helper.h
> @@ -86,14 +86,13 @@ DEF_HELPER_1(rdtsc, void, env)
>   DEF_HELPER_1(rdtscp, void, env)
>   DEF_HELPER_FLAGS_1(rdpmc, TCG_CALL_NO_WG, noreturn, env)
>   
> +#ifndef CONFIG_USER_ONLY
>   DEF_HELPER_3(outb, void, env, i32, i32)
>   DEF_HELPER_2(inb, tl, env, i32)
>   DEF_HELPER_3(outw, void, env, i32, i32)
>   DEF_HELPER_2(inw, tl, env, i32)
>   DEF_HELPER_3(outl, void, env, i32, i32)
>   DEF_HELPER_2(inl, tl, env, i32)
> -
> -#ifndef CONFIG_USER_ONLY
>   DEF_HELPER_FLAGS_3(check_io, TCG_CALL_NO_WG, void, env, i32, i32)
>   DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl)
>   DEF_HELPER_2(svm_check_intercept, void, env, i32)
> diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
> index bcc642bf6e..08ff3fe232 100644
> --- a/target/i386/tcg/translate.c
> +++ b/target/i386/tcg/translate.c
> @@ -197,8 +197,14 @@ STUB_HELPER(check_io, TCGv_env env, TCGv_i32 port, TCGv_i32 size)
>   STUB_HELPER(clgi, TCGv_env env)
>   STUB_HELPER(flush_page, TCGv_env env, TCGv addr)
>   STUB_HELPER(hlt, TCGv_env env, TCGv_i32 pc_ofs)
> +STUB_HELPER(inb, TCGv ret, TCGv_env env, TCGv_i32 port)
> +STUB_HELPER(inw, TCGv ret, TCGv_env env, TCGv_i32 port)
> +STUB_HELPER(inl, TCGv ret, TCGv_env env, TCGv_i32 port)
>   STUB_HELPER(monitor, TCGv_env env, TCGv addr)
>   STUB_HELPER(mwait, TCGv_env env, TCGv_i32 pc_ofs)
> +STUB_HELPER(outb, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
> +STUB_HELPER(outw, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
> +STUB_HELPER(outl, TCGv_env env, TCGv_i32 port, TCGv_i32 val)
>   STUB_HELPER(rdmsr, TCGv_env env)
>   STUB_HELPER(read_crN, TCGv ret, TCGv_env env, TCGv_i32 reg)
>   STUB_HELPER(set_dr, TCGv_env env, TCGv_i32 reg, TCGv val)
> diff --git a/target/i386/tcg/user/misc_stubs.c b/target/i386/tcg/user/misc_stubs.c
> deleted file mode 100644
> index df38b44d6e..0000000000
> --- a/target/i386/tcg/user/misc_stubs.c
> +++ /dev/null
> @@ -1,55 +0,0 @@
> -/*
> - *  x86 misc helpers
> - *
> - *  Copyright (c) 2003 Fabrice Bellard
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> - *
> - * This library is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * Lesser General Public License for more details.
> - *
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> - */
> -
> -#include "qemu/osdep.h"
> -#include "cpu.h"
> -#include "exec/helper-proto.h"
> -
> -void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
> -{
> -    g_assert_not_reached();
> -}
> -
> -target_ulong helper_inb(CPUX86State *env, uint32_t port)
> -{
> -    g_assert_not_reached();
> -    return 0;
> -}
> -
> -void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
> -{
> -    g_assert_not_reached();
> -}
> -
> -target_ulong helper_inw(CPUX86State *env, uint32_t port)
> -{
> -    g_assert_not_reached();
> -    return 0;
> -}
> -
> -void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
> -{
> -    g_assert_not_reached();
> -}
> -
> -target_ulong helper_inl(CPUX86State *env, uint32_t port)
> -{
> -    g_assert_not_reached();
> -    return 0;
> -}
> diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.build
> index 3555b15bdd..1df6bc4343 100644
> --- a/target/i386/tcg/user/meson.build
> +++ b/target/i386/tcg/user/meson.build
> @@ -1,5 +1,4 @@
>   i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files(
>     'excp_helper.c',
> -  'misc_stubs.c',
>     'seg_helper.c',
>   ))
> 



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

* Re: [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw
  2021-05-14 15:13 ` [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw Richard Henderson
@ 2021-05-18 10:30   ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:30 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:13, Richard Henderson wrote:
> Pull the svm intercept check into the translator.
> Pull the entire implementation of lmsw into the translator.
> Push the check for CR8LEG into the regno validation switch.
> Unify the gen_io_start check between read/write.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>



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

* Re: [PATCH v2 00/50] target/i386 translate cleanups
  2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
                   ` (50 preceding siblings ...)
  2021-05-14 16:09 ` [PATCH v2 00/50] target/i386 translate cleanups no-reply
@ 2021-05-18 10:31 ` Paolo Bonzini
  2021-05-18 10:59   ` Richard Henderson
  51 siblings, 1 reply; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 10:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 14/05/21 17:12, Richard Henderson wrote:
> Supercedes: 20210228232321.322053-1-richard.henderson@linaro.org
> ("i386 cleanup part 3")
> 
> Claudio's prerequite patch set ("i386 cleanup part 2"), is now merged.
> Version 2 here fixes some minor rebase conflicts that crept in.
> Only 4 of the 50 patches have been reviewed.
> 
> Blurb from v1:
> This started out to address a fixme in Claudio's patch set, then
> wandered a bit, with cleanups and bug fixes in the code that I was
> touching.  I stopped when I reached my original goal of removing
> target/i386/tcg/user/*_stubs.c.
> 
> There are a lot of patches, but hopefully they're all small
> enough to be obvious.

Nice, thanks.  I only left minor comments on 27 and 30, feel free to do 
a pull request without v3.

Paolo



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

* Re: [PATCH v2 00/50] target/i386 translate cleanups
  2021-05-18 10:31 ` Paolo Bonzini
@ 2021-05-18 10:59   ` Richard Henderson
  2021-05-18 12:33     ` Paolo Bonzini
  0 siblings, 1 reply; 106+ messages in thread
From: Richard Henderson @ 2021-05-18 10:59 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: cfontana, f4bug, ehabkost

On 5/18/21 5:31 AM, Paolo Bonzini wrote:
> On 14/05/21 17:12, Richard Henderson wrote:
>> Supercedes: 20210228232321.322053-1-richard.henderson@linaro.org
>> ("i386 cleanup part 3")
>>
>> Claudio's prerequite patch set ("i386 cleanup part 2"), is now merged.
>> Version 2 here fixes some minor rebase conflicts that crept in.
>> Only 4 of the 50 patches have been reviewed.
>>
>> Blurb from v1:
>> This started out to address a fixme in Claudio's patch set, then
>> wandered a bit, with cleanups and bug fixes in the code that I was
>> touching.  I stopped when I reached my original goal of removing
>> target/i386/tcg/user/*_stubs.c.
>>
>> There are a lot of patches, but hopefully they're all small
>> enough to be obvious.
> 
> Nice, thanks.  I only left minor comments on 27 and 30, feel free to do a pull 
> request without v3.

Shall I take your comments then as "... Otherwise, R-B"?
Because you didn't actually give them for those two, and they're the only two 
without r-b tags.

You treated patch 49 similarly, but that one already had Phil's r-b.


r~


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

* Re: [PATCH v2 00/50] target/i386 translate cleanups
  2021-05-18 10:59   ` Richard Henderson
@ 2021-05-18 12:33     ` Paolo Bonzini
  0 siblings, 0 replies; 106+ messages in thread
From: Paolo Bonzini @ 2021-05-18 12:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: cfontana, ehabkost, f4bug

On 18/05/21 12:59, Richard Henderson wrote:
> On 5/18/21 5:31 AM, Paolo Bonzini wrote:
>> On 14/05/21 17:12, Richard Henderson wrote:
>>> Supercedes: 20210228232321.322053-1-richard.henderson@linaro.org
>>> ("i386 cleanup part 3")
>>>
>>> Claudio's prerequite patch set ("i386 cleanup part 2"), is now merged.
>>> Version 2 here fixes some minor rebase conflicts that crept in.
>>> Only 4 of the 50 patches have been reviewed.
>>>
>>> Blurb from v1:
>>> This started out to address a fixme in Claudio's patch set, then
>>> wandered a bit, with cleanups and bug fixes in the code that I was
>>> touching.  I stopped when I reached my original goal of removing
>>> target/i386/tcg/user/*_stubs.c.
>>>
>>> There are a lot of patches, but hopefully they're all small
>>> enough to be obvious.
>>
>> Nice, thanks.  I only left minor comments on 27 and 30, feel free to 
>> do a pull request without v3.
> 
> Shall I take your comments then as "... Otherwise, R-B"?
> Because you didn't actually give them for those two, and they're the 
> only two without r-b tags.
> 
> You treated patch 49 similarly, but that one already had Phil's r-b.

Well you're a maintainer so you don't really need R-b's but just to be 
precise: 27 would be completely different, while 30 should have had a 
r-b (it's just a commit message suggestion) and 49 should have had an 
"otherwise r-b".

Paolo



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

end of thread, other threads:[~2021-05-18 12:36 UTC | newest]

Thread overview: 106+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-14 15:12 [PATCH v2 00/50] target/i386 translate cleanups Richard Henderson
2021-05-14 15:12 ` [PATCH v2 01/50] target/i386: Split out gen_exception_gpf Richard Henderson
2021-05-18  9:08   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 02/50] target/i386: Split out check_cpl0 Richard Henderson
2021-05-18  9:10   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 03/50] target/i386: Unify code paths for IRET Richard Henderson
2021-05-18  9:11   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 04/50] target/i386: Split out check_vm86_iopl Richard Henderson
2021-05-18  9:48   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 05/50] target/i386: Split out check_iopl Richard Henderson
2021-05-18  9:14   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 06/50] target/i386: Assert PE is set for user-only Richard Henderson
2021-05-18  9:15   ` Paolo Bonzini
2021-05-14 15:12 ` [PATCH v2 07/50] target/i386: Assert CPL is 3 " Richard Henderson
2021-05-18  9:17   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 08/50] target/i386: Assert IOPL is 0 " Richard Henderson
2021-05-18  9:18   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 09/50] target/i386: Assert !VM86 for x86_64 user-only Richard Henderson
2021-05-18  9:19   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 10/50] target/i386: Assert CODE32 " Richard Henderson
2021-05-18  9:20   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 11/50] target/i386: Assert SS32 " Richard Henderson
2021-05-18  9:20   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 12/50] target/i386: Assert CODE64 " Richard Henderson
2021-05-18  9:21   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 13/50] target/i386: Assert LMA " Richard Henderson
2021-05-18  9:21   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 14/50] target/i386: Assert !ADDSEG " Richard Henderson
2021-05-18  9:23   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 15/50] target/i386: Introduce REX_PREFIX Richard Henderson
2021-05-18  9:26   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 16/50] target/i386: Tidy REX_B, REX_X definition Richard Henderson
2021-05-18  9:28   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 17/50] target/i386: Move rex_r into DisasContext Richard Henderson
2021-05-18  9:28   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 18/50] target/i386: Move rex_w " Richard Henderson
2021-05-18  9:30   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 19/50] target/i386: Remove DisasContext.f_st as unused Richard Henderson
2021-05-18  9:30   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 20/50] target/i386: Reduce DisasContext.flags to uint32_t Richard Henderson
2021-05-18  9:30   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 21/50] target/i386: Reduce DisasContext.override to int8_t Richard Henderson
2021-05-18  9:31   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 22/50] target/i386: Reduce DisasContext.prefix to uint8_t Richard Henderson
2021-05-18  9:31   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 23/50] target/i386: Reduce DisasContext.vex_[lv] " Richard Henderson
2021-05-18  9:32   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 24/50] target/i386: Reduce DisasContext popl_esp_hack and rip_offset " Richard Henderson
2021-05-18  9:34   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 25/50] target/i386: Leave TF in DisasContext.flags Richard Henderson
2021-05-18  9:36   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 26/50] target/i386: Reduce DisasContext jmp_opt, repz_opt to bool Richard Henderson
2021-05-18  9:36   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 27/50] target/i386: Fix the comment for repz_opt Richard Henderson
2021-05-18  9:48   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 28/50] target/i386: Reorder DisasContext members Richard Henderson
2021-05-18  9:49   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 29/50] target/i386: Add stub generator for helper_set_dr Richard Henderson
2021-05-18  9:49   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 30/50] target/i386: Assert !SVME for user-only Richard Henderson
2021-05-18  9:51   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 31/50] target/i386: Assert !GUEST " Richard Henderson
2021-05-18  9:51   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 32/50] target/i386: Implement skinit in translate.c Richard Henderson
2021-05-18  9:51   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 33/50] target/i386: Eliminate SVM helpers for user-only Richard Henderson
2021-05-18  9:52   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 34/50] target/i386: Mark some helpers as noreturn Richard Henderson
2021-05-18  9:56   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 35/50] target/i386: Simplify gen_debug usage Richard Henderson
2021-05-18  9:56   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 36/50] target/i386: Tidy svm_check_intercept from tcg Richard Henderson
2021-05-18  9:57   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 37/50] target/i386: Remove pc_start argument to gen_svm_check_intercept Richard Henderson
2021-05-18  9:58   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 38/50] target/i386: Remove user stub for cpu_vmexit Richard Henderson
2021-05-18  9:58   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 39/50] target/i386: Cleanup read_crN, write_crN, lmsw Richard Henderson
2021-05-18 10:30   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 40/50] target/i386: Pass env to do_pause and do_hlt Richard Henderson
2021-05-18  9:59   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 41/50] target/i386: Move invlpg, hlt, monitor, mwait to sysemu Richard Henderson
2021-05-18 10:00   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 42/50] target/i386: Unify invlpg, invlpga Richard Henderson
2021-05-18 10:00   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 43/50] target/i386: Inline user cpu_svm_check_intercept_param Richard Henderson
2021-05-18 10:01   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 44/50] target/i386: Eliminate user stubs for read/write_crN, rd/wrmsr Richard Henderson
2021-05-18 10:01   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 45/50] target/i386: Exit tb after wrmsr Richard Henderson
2021-05-18 10:02   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 46/50] target/i386: Tidy gen_check_io Richard Henderson
2021-05-18 10:18   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 47/50] target/i386: Pass in port to gen_check_io Richard Henderson
2021-05-18 10:20   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 48/50] target/i386: Create helper_check_io Richard Henderson
2021-05-18 10:21   ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 49/50] target/i386: Move helper_check_io to sysemu Richard Henderson
2021-05-14 17:45   ` Richard Henderson
2021-05-18 10:22     ` Paolo Bonzini
2021-05-14 15:13 ` [PATCH v2 50/50] target/i386: Remove user-only i/o stubs Richard Henderson
2021-05-18 10:23   ` Paolo Bonzini
2021-05-14 16:09 ` [PATCH v2 00/50] target/i386 translate cleanups no-reply
2021-05-18 10:31 ` Paolo Bonzini
2021-05-18 10:59   ` Richard Henderson
2021-05-18 12:33     ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.