Add support for Intel TDX instructions.

H.J. Lu hjl.tools@gmail.com
Wed Sep 23 00:54:16 GMT 2020


On Sun, Sep 20, 2020 at 11:17 PM Cui, Lili <lili.cui@intel.com> wrote:
>
> Hi all,
>
> This patch is about to enable binutils support for Intel TDX.
> Intel Trust Domains Extensions(Intel TDX), more details please refer to
> https://software.intel.com/content/dam/develop/external/us/en/documents/intel-tdx-cpu-architectural-specification.pdf
>
> Make check-gas is ok.
>
> Add support for Intel TDX instructions.
>
> gas/
>         * NEWS: Add TDX.
>         * config/tc-i386.c (cpu_arch): Add .tdx.
>         (cpu_noarch): Likewise.
>         * doc/c-i386.texi: Document tdx.
>         * testsuite/gas/i386/i386.exp: Run tdx tests.
>         * testsuite/gas/i386/tdx.d: Likewise.
>         * testsuite/gas/i386/tdx.s: Likewise.
>         * testsuite/gas/i386/x86-64-tdx.d: Likewise.
>         * testsuite/gas/i386/x86-64-tdx.s: Likewise.
>
> opcodes/
>         * i386-dis.c (enum): Add PREFIX_0F01_REG_1_RM_5,
>         PREFIX_0F01_REG_1_RM_6, PREFIX_0F01_REG_1_RM_7,
>         X86_64_0F01_REG_1_RM_5_P_2, X86_64_0F01_REG_1_RM_6_P_2,
>         X86_64_0F01_REG_1_RM_7_P_2.
>         (prefix_table): Likewise.
>         (x86_64_table): Likewise.
>         (rm_table): Likewise.
>         * i386-gen.c (cpu_flag_init): Add CPU_TDX_FLAGS
>         and CPU_ANY_TDX_FLAGS.
>         (cpu_flags): Add CpuTDX.
>         * i386-opc.h (enum): Add CpuTDX.
>         (i386_cpu_flags): Add cputdx.
>         * i386-opc.tbl: Add TDX insns.
>         * i386-init.h: Regenerate.
>         * i386-tbl.h: Likewise.
> ---
>  gas/NEWS                            |  2 +
>  gas/config/tc-i386.c                |  3 ++
>  gas/doc/c-i386.texi                 |  3 ++
>  gas/testsuite/gas/i386/i386.exp     |  2 +
>  gas/testsuite/gas/i386/tdx.d        | 12 ++++++
>  gas/testsuite/gas/i386/tdx.s        |  5 +++
>  gas/testsuite/gas/i386/x86-64-tdx.d | 15 +++++++
>  gas/testsuite/gas/i386/x86-64-tdx.s |  8 ++++
>  opcodes/i386-dis.c                  | 65 +++++++++++++++++++++++++++--
>  opcodes/i386-gen.c                  |  5 +++
>  opcodes/i386-opc.h                  |  3 ++
>  opcodes/i386-opc.tbl                |  9 ++++
>  12 files changed, 128 insertions(+), 4 deletions(-)
>  create mode 100644 gas/testsuite/gas/i386/tdx.d
>  create mode 100644 gas/testsuite/gas/i386/tdx.s
>  create mode 100644 gas/testsuite/gas/i386/x86-64-tdx.d
>  create mode 100644 gas/testsuite/gas/i386/x86-64-tdx.s
>
> diff --git a/gas/NEWS b/gas/NEWS
> index d709edf9b5..8c9b925005 100644
> --- a/gas/NEWS
> +++ b/gas/NEWS
> @@ -1,5 +1,7 @@
>  -*- text -*-
>
> +* Add support for Intel TDX instructions.
> +
>  * Added a .nop directive to generate a single no-op instruction in a target
>    neutral manner.  This instruction does have an effect on DWARF line number
>    generation, if that is active.
> diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
> index d237352fbe..b7934ba8ee 100644
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -1220,6 +1220,8 @@ static const arch_entry cpu_arch[] =
>      CPU_AVX512_BF16_FLAGS, 0 },
>    { STRING_COMMA_LEN (".avx512_vp2intersect"), PROCESSOR_UNKNOWN,
>      CPU_AVX512_VP2INTERSECT_FLAGS, 0 },
> +  { STRING_COMMA_LEN (".tdx"), PROCESSOR_UNKNOWN,
> +    CPU_TDX_FLAGS, 0 },
>    { STRING_COMMA_LEN (".enqcmd"), PROCESSOR_UNKNOWN,
>      CPU_ENQCMD_FLAGS, 0 },
>    { STRING_COMMA_LEN (".serialize"), PROCESSOR_UNKNOWN,
> @@ -1278,6 +1280,7 @@ static const noarch_entry cpu_noarch[] =
>    { STRING_COMMA_LEN ("noavx512_bf16"), CPU_ANY_AVX512_BF16_FLAGS },
>    { STRING_COMMA_LEN ("noavx512_vp2intersect"),
>      CPU_ANY_AVX512_VP2INTERSECT_FLAGS },
> +  { STRING_COMMA_LEN ("notdx"), CPU_ANY_TDX_FLAGS },
>    { STRING_COMMA_LEN ("noenqcmd"), CPU_ANY_ENQCMD_FLAGS },
>    { STRING_COMMA_LEN ("noserialize"), CPU_ANY_SERIALIZE_FLAGS },
>    { STRING_COMMA_LEN ("notsxldtrk"), CPU_ANY_TSXLDTRK_FLAGS },
> diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
> index 64a563aacb..d079c8e3bb 100644
> --- a/gas/doc/c-i386.texi
> +++ b/gas/doc/c-i386.texi
> @@ -205,6 +205,7 @@ accept various extension mnemonics.  For example,
>  @code{avx512_vnni},
>  @code{avx512_bitalg},
>  @code{avx512_vp2intersect},
> +@code{tdx},
>  @code{avx512_bf16},
>  @code{noavx512f},
>  @code{noavx512cd},
> @@ -222,6 +223,7 @@ accept various extension mnemonics.  For example,
>  @code{noavx512_vnni},
>  @code{noavx512_bitalg},
>  @code{noavx512_vp2intersect},
> +@code{notdx},
>  @code{noavx512_bf16},
>  @code{noenqcmd},
>  @code{noserialize},
> @@ -1499,6 +1501,7 @@ supported on the CPU specified.  The choices for @var{cpu_type} are:
>  @item @samp{.avx512vbmi} @tab @samp{.avx512_4fmaps} @tab @samp{.avx512_4vnniw}
>  @item @samp{.avx512_vpopcntdq} @tab @samp{.avx512_vbmi2} @tab @samp{.avx512_vnni}
>  @item @samp{.avx512_bitalg} @tab @samp{.avx512_bf16} @tab @samp{.avx512_vp2intersect}
> +@item @samp{.tdx}
>  @item @samp{.clwb} @tab @samp{.rdpid} @tab @samp{.ptwrite} @tab @item @samp{.ibt}
>  @item @samp{.wbnoinvd} @tab @samp{.pconfig} @tab @samp{.waitpkg} @tab @samp{.cldemote}
>  @item @samp{.shstk} @tab @samp{.gfni} @tab @samp{.vaes} @tab @samp{.vpclmulqdq}
> diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
> index 132e5d7834..285d26e231 100644
> --- a/gas/testsuite/gas/i386/i386.exp
> +++ b/gas/testsuite/gas/i386/i386.exp
> @@ -489,6 +489,7 @@ if [gas_32_check] then {
>      run_dump_test "enqcmd-intel"
>      run_list_test "enqcmd-inval"
>      run_dump_test "serialize"
> +    run_dump_test "tdx"
>      run_dump_test "tsxldtrk"
>      run_dump_test "vp2intersect"
>      run_dump_test "vp2intersect-intel"
> @@ -1094,6 +1095,7 @@ if [gas_64_check] then {
>      run_dump_test "x86-64-enqcmd-intel"
>      run_list_test "x86-64-enqcmd-inval"
>      run_dump_test "x86-64-serialize"
> +    run_dump_test "x86-64-tdx"
>      run_dump_test "x86-64-tsxldtrk"
>      run_dump_test "x86-64-vp2intersect"
>      run_dump_test "x86-64-vp2intersect-intel"
> diff --git a/gas/testsuite/gas/i386/tdx.d b/gas/testsuite/gas/i386/tdx.d
> new file mode 100644
> index 0000000000..35263be397
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/tdx.d
> @@ -0,0 +1,12 @@
> +#as:
> +#objdump: -dw
> +#name: TDX insns
> +#source: tdx.s
> +
> +.*: +file format .*
> +
> +Disassembly of section \.text:
> +
> +0+ <_start>:
> +[      ]*[a-f0-9]+:    66 0f 01 cc +   tdcall *
> +#pass
> diff --git a/gas/testsuite/gas/i386/tdx.s b/gas/testsuite/gas/i386/tdx.s
> new file mode 100644
> index 0000000000..6097fe3a76
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/tdx.s
> @@ -0,0 +1,5 @@
> +# Check TDX instructions.
> +
> +       .text
> +_start:
> +       tdcall
> diff --git a/gas/testsuite/gas/i386/x86-64-tdx.d b/gas/testsuite/gas/i386/x86-64-tdx.d
> new file mode 100644
> index 0000000000..ea3e83cde6
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-tdx.d
> @@ -0,0 +1,15 @@
> +#as:
> +#objdump: -dw
> +#name: x86_64 TDX insns
> +#source: x86-64-tdx.s
> +
> +.*: +file format .*
> +
> +Disassembly of section \.text:
> +
> +0+ <_start>:
> +[      ]*[a-f0-9]+:    66 0f 01 cc +   tdcall *
> +[      ]*[a-f0-9]+:    66 0f 01 cd +   seamret *
> +[      ]*[a-f0-9]+:    66 0f 01 ce +   seamops *
> +[      ]*[a-f0-9]+:    66 0f 01 cf +   seamcall *
> +#pass
> diff --git a/gas/testsuite/gas/i386/x86-64-tdx.s b/gas/testsuite/gas/i386/x86-64-tdx.s
> new file mode 100644
> index 0000000000..1cf4035475
> --- /dev/null
> +++ b/gas/testsuite/gas/i386/x86-64-tdx.s
> @@ -0,0 +1,8 @@
> +# Check TDX instructions.
> +
> +       .text
> +_start:
> +       tdcall
> +       seamret
> +       seamops
> +       seamcall
> diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
> index 6d803258ef..89d8fc64fc 100644
> --- a/opcodes/i386-dis.c
> +++ b/opcodes/i386-dis.c
> @@ -945,6 +945,10 @@ enum
>  enum
>  {
>    PREFIX_90 = 0,
> +  PREFIX_0F01_REG_1_RM_4,
> +  PREFIX_0F01_REG_1_RM_5,
> +  PREFIX_0F01_REG_1_RM_6,
> +  PREFIX_0F01_REG_1_RM_7,
>    PREFIX_0F01_REG_3_RM_1,
>    PREFIX_0F01_REG_5_MOD_0,
>    PREFIX_0F01_REG_5_MOD_3_RM_0,
> @@ -1161,6 +1165,9 @@ enum
>    X86_64_EA,
>    X86_64_0F01_REG_0,
>    X86_64_0F01_REG_1,
> +  X86_64_0F01_REG_1_RM_5_PREFIX_2,
> +  X86_64_0F01_REG_1_RM_6_PREFIX_2,
> +  X86_64_0F01_REG_1_RM_7_PREFIX_2,
>    X86_64_0F01_REG_2,
>    X86_64_0F01_REG_3,
>    X86_64_0F24,
> @@ -3062,6 +3069,38 @@ static const struct dis386 prefix_table[][4] = {
>      { NULL, { { NULL, 0 } }, PREFIX_IGNORED }
>    },
>
> +  /* PREFIX_0F01_REG_1_RM_4 */
> +  {
> +    { Bad_Opcode },
> +    { Bad_Opcode },
> +    { "tdcall",        { Skip_MODRM }, 0 },
> +    { Bad_Opcode },
> +  },
> +
> +  /* PREFIX_0F01_REG_1_RM_5 */
> +  {
> +    { Bad_Opcode },
> +    { Bad_Opcode },
> +    { X86_64_TABLE (X86_64_0F01_REG_1_RM_5_PREFIX_2) },
> +    { Bad_Opcode },
> +  },
> +
> +  /* PREFIX_0F01_REG_1_RM_6 */
> +  {
> +    { Bad_Opcode },
> +    { Bad_Opcode },
> +    { X86_64_TABLE (X86_64_0F01_REG_1_RM_6_PREFIX_2) },
> +    { Bad_Opcode },
> +  },
> +
> +  /* PREFIX_0F01_REG_1_RM_7 */
> +  {
> +    { "encls",         { Skip_MODRM }, 0 },
> +    { Bad_Opcode },
> +    { X86_64_TABLE (X86_64_0F01_REG_1_RM_7_PREFIX_2) },
> +    { Bad_Opcode },
> +  },
> +
>    /* PREFIX_0F01_REG_3_RM_1 */
>    {
>      { "vmmcall",       { Skip_MODRM }, 0 },
> @@ -4139,6 +4178,24 @@ static const struct dis386 x86_64_table[][2] = {
>      { "sidt", { M }, 0 },
>    },
>
> +  /* X86_64_0F01_REG_1_RM_5_PREFIX_2 */
> +  {
> +    { Bad_Opcode },
> +    { "seamret",       { Skip_MODRM }, 0 },
> +  },
> +
> +  /* X86_64_0F01_REG_1_RM_6_PREFIX_2 */
> +  {
> +    { Bad_Opcode },
> +    { "seamops",       { Skip_MODRM }, 0 },
> +  },
> +
> +  /* X86_64_0F01_REG_1_RM_7_PREFIX_2 */
> +  {
> +    { Bad_Opcode },
> +    { "seamcall",      { Skip_MODRM }, 0 },
> +  },
> +
>    /* X86_64_0F01_REG_2 */
>    {
>      { "lgdt{Q|Q}", { M }, 0 },
> @@ -8691,10 +8748,10 @@ static const struct dis386 rm_table[][8] = {
>      { "mwait",         { { OP_Mwait, 0 } }, 0 },
>      { "clac",          { Skip_MODRM }, 0 },
>      { "stac",          { Skip_MODRM }, 0 },
> -    { Bad_Opcode },
> -    { Bad_Opcode },
> -    { Bad_Opcode },
> -    { "encls",         { Skip_MODRM }, 0 },
> +    { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_4) },
> +    { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_5) },
> +    { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_6) },
> +    { PREFIX_TABLE (PREFIX_0F01_REG_1_RM_7) },
>    },
>    {
>      /* RM_0F01_REG_2 */
> diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c
> index 3334155071..642297518f 100644
> --- a/opcodes/i386-gen.c
> +++ b/opcodes/i386-gen.c
> @@ -313,6 +313,8 @@ static initializer cpu_flag_init[] =
>      "CpuSERIALIZE" },
>    { "CPU_AVX512_VP2INTERSECT_FLAGS",
>      "CpuAVX512_VP2INTERSECT" },
> +  { "CPU_TDX_FLAGS",
> +    "CpuTDX" },
>    { "CPU_RDPRU_FLAGS",
>      "CpuRDPRU" },
>    { "CPU_MCOMMIT_FLAGS",
> @@ -405,6 +407,8 @@ static initializer cpu_flag_init[] =
>      "CpuSERIALIZE" },
>    { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
>      "CpuAVX512_VP2INTERSECT" },
> +  { "CPU_ANY_TDX_FLAGS",
> +    "CpuTDX" },
>    { "CPU_ANY_TSXLDTRK_FLAGS",
>      "CpuTSXLDTRK" },
>  };
> @@ -611,6 +615,7 @@ static bitfield cpu_flags[] =
>    BITFIELD (CpuAVX512_BITALG),
>    BITFIELD (CpuAVX512_BF16),
>    BITFIELD (CpuAVX512_VP2INTERSECT),
> +  BITFIELD (CpuTDX),
>    BITFIELD (CpuMWAITX),
>    BITFIELD (CpuCLZERO),
>    BITFIELD (CpuOSPKE),
> diff --git a/opcodes/i386-opc.h b/opcodes/i386-opc.h
> index 09ee615db1..3a2e260ff2 100644
> --- a/opcodes/i386-opc.h
> +++ b/opcodes/i386-opc.h
> @@ -210,6 +210,8 @@ enum
>    CpuAVX512_BF16,
>    /* Intel AVX-512 VP2INTERSECT Instructions support required.  */
>    CpuAVX512_VP2INTERSECT,
> +  /* TDX Instructions support required.  */
> +  CpuTDX,
>    /* mwaitx instruction required */
>    CpuMWAITX,
>    /* Clzero instruction required */
> @@ -371,6 +373,7 @@ typedef union i386_cpu_flags
>        unsigned int cpuavx512_bitalg:1;
>        unsigned int cpuavx512_bf16:1;
>        unsigned int cpuavx512_vp2intersect:1;
> +      unsigned int cputdx:1;
>        unsigned int cpumwaitx:1;
>        unsigned int cpuclzero:1;
>        unsigned int cpuospke:1;
> diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl
> index 181d0df1ce..c51d5ea14d 100644
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -4117,3 +4117,12 @@ tilerelease, 0, 0x49c0, None, 2, CpuAMX_TILE|Cpu64, Vex128|VexOpcode=1|VexW0|No_
>  tilezero, 1, 0xf249, None, 1, CpuAMX_TILE|Cpu64, Modrm|Vex128|VexOpcode=1|VexW0|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { RegTMM }
>
>  // AMX instructions end.
> +
> +// TDX instructions.
> +
> +tdcall, 0, 0x660f01cc, None, 3, CpuTDX, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
> +seamret, 0, 0x660f01cd, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
> +seamops, 0, 0x660f01ce, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
> +seamcall, 0, 0x660f01cf, None, 3, CpuTDX|Cpu64, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }
> +
> +// TDX instructions end.
> --
> 2.17.1
>
> Thanks,
> Lili.

OK.

Thanks.

-- 
H.J.


More information about the Binutils mailing list