Commit b3a9e57d authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging



target-i386: tcg: Handle clflushopt/clwb/pcommit instructions

A small update to TCG code so it can handle the new
clflushopt/clwb/pcommit instructions.

# gpg: Signature made Sat 07 Nov 2015 14:50:54 GMT using RSA key ID 984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"

* remotes/ehabkost/tags/x86-pull-request:
  target-i386: Add clflushopt/clwb/pcommit to TCG_7_0_EBX_FEATURES
  target-i386: tcg: Check right CPUID bits for clflushopt/pcommit
  target-i386: tcg: Accept clwb instruction

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents c4a7bf54 0c47242b
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -345,7 +345,9 @@ static const char *cpuid_6_feature_name[] = {
#define TCG_SVM_FEATURES 0
#define TCG_KVM_FEATURES 0
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
          CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
          CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
          CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT |            \
          CPUID_7_0_EBX_CLWB)
          /* missing:
          CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
          CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
+31 −8
Original line number Diff line number Diff line
@@ -7716,20 +7716,43 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
            }
            break;
        case 5: /* lfence */
        case 6: /* mfence */
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
                goto illegal_op;
            break;
        case 7: /* sfence / clflush */
        case 6: /* mfence/clwb */
            if (s->prefix & PREFIX_DATA) {
                /* clwb */
                if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLWB))
                    goto illegal_op;
                gen_nop_modrm(env, s, modrm);
            } else {
                /* mfence */
                if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
                    goto illegal_op;
            }
            break;
        case 7: /* sfence / clflush / clflushopt / pcommit */
            if ((modrm & 0xc7) == 0xc0) {
                if (s->prefix & PREFIX_DATA) {
                    /* pcommit */
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_PCOMMIT))
                        goto illegal_op;
                } else {
                    /* sfence */
                    /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX */
                    if (!(s->cpuid_features & CPUID_SSE))
                        goto illegal_op;
                }
            } else {
                if (s->prefix & PREFIX_DATA) {
                    /* clflushopt */
                    if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_CLFLUSHOPT))
                        goto illegal_op;
                } else {
                    /* clflush */
                    if (!(s->cpuid_features & CPUID_CLFLUSH))
                        goto illegal_op;
                }
                gen_lea_modrm(env, s, modrm);
            }
            break;