[PATCH 4/5] i386/cpu: Support APX CPUIDs

Zhao Liu posted 5 patches 2 days, 5 hours ago
[PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Zhao Liu 2 days, 5 hours ago
APX is enumerated by CPUID.(EAX=0x7, ECX=1).EDX[21]. And this feature
bit also indicates the existence of dedicated CPUID leaf 0x29, called
the Intel APX Advanced Performance Extensions Leaf.

This new CPUID leaf now is populated with enumerations for a select
set of Intel APX sub-features.

CPUID.(EAX=0x29, ECX=0)
 - EAX
   * Maximum Subleaf CPUID.(EAX=0x29, ECX=0).EAX[31:0] = 0
 - EBX
   * Reserved CPUID.(EAX=0x29, ECX=0).EBX[31:1] = 0
   * APX_NCI_NDD_NF CPUID.(EAX=0x29, ECX=0).EBX[0:0] = 1, which
     enumerates the presence of New Conditional Instructions (NCIs),
     explicit New Data Destination (NDD) controls, and explicit Flags
     Suppression (NF) controls for select sets of EVEX-encoded Intel
     APX instructions (present in EVEX map=4, and EVEX map=2 0x0F38).
 - ECX
   * Reserved CPUID.(EAX=0x29, ECX=0).ECX[31:0] = 0
 - EDX
   * Reserved CPUID.(EAX=0x29, ECX=0).EDX[31:0] = 0

Note, APX_NCI_NDD_NF is documented as always enabled for Intel
processors since APX spec (revision v7.0). Now any Intel processor
that enumerates support for APX_F (CPUID.(EAX=0x7, ECX=1).EDX[21])
will also enumerate support for APX_NCI_NDD_NF.

Tested-by: Xudong Hao <xudong.hao@intel.com>
Co-developed-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Co-developed-by: Peter Fang <peter.fang@intel.com>
Signed-off-by: Peter Fang <peter.fang@intel.com>
Signed-off-by: Zhao Liu <zhao1.liu@intel.com>
---
 target/i386/cpu.c | 40 +++++++++++++++++++++++++++++++++++++++-
 target/i386/cpu.h |  8 ++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 16bc4b18266c..9cc553a86442 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1036,6 +1036,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_SGX_12_0_EBX_FEATURES 0
 #define TCG_SGX_12_1_EAX_FEATURES 0
 #define TCG_24_0_EBX_FEATURES 0
+#define TCG_29_0_EBX_FEATURES 0
 
 #if defined CONFIG_USER_ONLY
 #define CPUID_8000_0008_EBX_KERNEL_FEATURES (CPUID_8000_0008_EBX_IBPB | \
@@ -1301,7 +1302,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
             "amx-complex", NULL, "avx-vnni-int16", NULL,
             NULL, NULL, "prefetchiti", NULL,
             NULL, NULL, NULL, "avx10",
-            NULL, NULL, NULL, NULL,
+            NULL, "apx", NULL, NULL,
             NULL, NULL, NULL, NULL,
             NULL, NULL, NULL, NULL,
         },
@@ -1345,6 +1346,25 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         },
         .tcg_features = TCG_24_0_EBX_FEATURES,
     },
+    [FEAT_29_0_EBX] = {
+        .type = CPUID_FEATURE_WORD,
+        .feat_names = {
+            "apx-nci-ndd-nf", NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+            NULL, NULL, NULL, NULL,
+        },
+        .cpuid = {
+            .eax = 0x29,
+            .needs_ecx = true, .ecx = 0,
+            .reg = R_EBX,
+        },
+        .tcg_features = TCG_29_0_EBX_FEATURES,
+    },
     [FEAT_8000_0007_EDX] = {
         .type = CPUID_FEATURE_WORD,
         .feat_names = {
@@ -1996,6 +2016,10 @@ static FeatureDep feature_dependencies[] = {
         .from = { FEAT_7_1_EDX,             CPUID_7_1_EDX_AVX10 },
         .to = { FEAT_24_0_EBX,              ~0ull },
     },
+    {
+        .from = { FEAT_7_1_EDX,             CPUID_7_1_EDX_APX },
+        .to = { FEAT_29_0_EBX,              ~0ull },
+    },
 };
 
 typedef struct X86RegisterInfo32 {
@@ -8411,6 +8435,15 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     }
+    case 0x29:
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        if ((env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_APX) && count == 0) {
+            *ebx = env->features[FEAT_29_0_EBX];
+        }
+        break;
     case 0x40000000:
         /*
          * CPUID code in kvm_arch_init_vcpu() ignores stuff
@@ -9190,6 +9223,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
             x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x24);
         }
 
+        /* Advanced Performance Extensions (APX) requires CPUID[0x29] */
+        if (env->features[FEAT_7_1_EDX] & CPUID_7_1_EDX_APX) {
+            x86_cpu_adjust_level(cpu, &env->cpuid_min_level, 0x29);
+        }
+
         /* SVM requires CPUID[0x8000000A] */
         if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
             x86_cpu_adjust_level(cpu, &env->cpuid_min_xlevel, 0x8000000A);
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 48d4d7fcbb9c..d15a89f8c72e 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -697,6 +697,7 @@ typedef enum FeatureWord {
     FEAT_7_1_EDX,       /* CPUID[EAX=7,ECX=1].EDX */
     FEAT_7_2_EDX,       /* CPUID[EAX=7,ECX=2].EDX */
     FEAT_24_0_EBX,      /* CPUID[EAX=0x24,ECX=0].EBX */
+    FEAT_29_0_EBX,      /* CPUID[EAX=0x29,ECX=0].EBX */
     FEATURE_WORDS,
 } FeatureWord;
 
@@ -1079,6 +1080,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w);
                                          CPUID_24_0_EBX_AVX10_256 | \
                                          CPUID_24_0_EBX_AVX10_512)
 
+/*
+ * New Conditional Instructions (NCIs), explicit New Data Destination (NDD)
+ * controls, and explicit Flags Suppression (NF) controls for select sets of
+ * EVEX-encoded Intel APX instructions
+ */
+#define CPUID_29_0_EBX_APX_NCI_NDD_NF         (1U << 0)
+
 /* RAS Features */
 #define CPUID_8000_0007_EBX_OVERFLOW_RECOV    (1U << 0)
 #define CPUID_8000_0007_EBX_SUCCOR      (1U << 1)
-- 
2.34.1
Re: [PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Paolo Bonzini 2 days, 3 hours ago
On Tue, Nov 18, 2025 at 7:36 AM Zhao Liu <zhao1.liu@intel.com> wrote:
>
> APX is enumerated by CPUID.(EAX=0x7, ECX=1).EDX[21]. And this feature
> bit also indicates the existence of dedicated CPUID leaf 0x29, called
> the Intel APX Advanced Performance Extensions Leaf.
>
> This new CPUID leaf now is populated with enumerations for a select
> set of Intel APX sub-features.
>
> CPUID.(EAX=0x29, ECX=0)
>  - EAX
>    * Maximum Subleaf CPUID.(EAX=0x29, ECX=0).EAX[31:0] = 0
>  - EBX
>    * Reserved CPUID.(EAX=0x29, ECX=0).EBX[31:1] = 0
>    * APX_NCI_NDD_NF CPUID.(EAX=0x29, ECX=0).EBX[0:0] = 1, which
>      enumerates the presence of New Conditional Instructions (NCIs),
>      explicit New Data Destination (NDD) controls, and explicit Flags
>      Suppression (NF) controls for select sets of EVEX-encoded Intel
>      APX instructions (present in EVEX map=4, and EVEX map=2 0x0F38).
>  - ECX
>    * Reserved CPUID.(EAX=0x29, ECX=0).ECX[31:0] = 0
>  - EDX
>    * Reserved CPUID.(EAX=0x29, ECX=0).EDX[31:0] = 0
>
> Note, APX_NCI_NDD_NF is documented as always enabled for Intel
> processors since APX spec (revision v7.0). Now any Intel processor
> that enumerates support for APX_F (CPUID.(EAX=0x7, ECX=1).EDX[21])
> will also enumerate support for APX_NCI_NDD_NF.

Please just make the new leaf have constant values based on just
APX_F. We'll add the optional NCI/NDD/NF support if needed, i.e.
never. :)

Paolo
Re: [PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Zhao Liu 1 day, 4 hours ago
> Please just make the new leaf have constant values based on just
> APX_F. We'll add the optional NCI/NDD/NF support if needed, i.e.
> never. :)

Maybe not never?

> > Note, APX_NCI_NDD_NF is documented as always enabled for Intel
> > processors since APX spec (revision v7.0). Now any Intel processor
> > that enumerates support for APX_F (CPUID.(EAX=0x7, ECX=1).EDX[21])
> > will also enumerate support for APX_NCI_NDD_NF.

This sentence (from APX spec rev.7) emphasizes the “Intel” vendor,
and its primary goal was to address and explain compatibility concern
for pre-enabling work based on APX spec v6. Prior to v7, APX included
NCI_NDD_NF by default, but this feature has now been separated from
basic APX and requires explicit checking CPUID bit.

x86 ecosystem advisory group has aligned on APX so it may be possible
for other x86 vendors to implement APX without NCI_NDD_NF and this still
match with the APX spec.

If we default to setting this NCI_NDD_NF bit for APX, then in the future
when we run into other vendors that don't support this feature, we'll not
only have to make it optional again, but we'll also need to do fixes
similar to the ARCH_CAPABILITIES situation - checking vendors, fixing
compatibility issues, and all that stuff.

Therefore, compared to default setting to constant, I think the optional
NCI_NDD_NF now not only aligns with arch spec but also prevents future
compatibility issues. :)

Thanks,
Zhao


Re: [PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Florian Weimer 18 hours ago
* Zhao Liu:

>> Please just make the new leaf have constant values based on just
>> APX_F. We'll add the optional NCI/NDD/NF support if needed, i.e.
>> never. :)
>
> Maybe not never?
>
>> > Note, APX_NCI_NDD_NF is documented as always enabled for Intel
>> > processors since APX spec (revision v7.0). Now any Intel processor
>> > that enumerates support for APX_F (CPUID.(EAX=0x7, ECX=1).EDX[21])
>> > will also enumerate support for APX_NCI_NDD_NF.
>
> This sentence (from APX spec rev.7) emphasizes the “Intel” vendor,
> and its primary goal was to address and explain compatibility concern
> for pre-enabling work based on APX spec v6. Prior to v7, APX included
> NCI_NDD_NF by default, but this feature has now been separated from
> basic APX and requires explicit checking CPUID bit.
>
> x86 ecosystem advisory group has aligned on APX so it may be possible
> for other x86 vendors to implement APX without NCI_NDD_NF and this still
> match with the APX spec.

Well yes, but I doubt that the ecosystem will produce binaries
specialized for APX *without* NDD.  It's fine to enumerate it
separately, but that doesn't have any immediate consequences.  GCC makes
it rather hard to build for APX without NDD, for example.  At least more
difficult than building for AVX-512F without AVX-512VL.

I just don't think software vendors are enthusiastic about having to
create and support not one, but two builds for APX.  If NDD is optional
in practice, it will not be possible to use it except for run-time
generated code and perhaps very targeted optimizations because that
single extra APX will just not use NDD.

I feel like there has been a misunderstanding somewhere.

(sorry for off-topic)

Thanks,
Florian
Re: [PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Paolo Bonzini 18 hours ago
On Wed, Nov 19, 2025 at 7:04 PM Florian Weimer <fweimer@redhat.com> wrote:
> This sentence (from APX spec rev.7) emphasizes the “Intel” vendor,
> > and its primary goal was to address and explain compatibility concern
> > for pre-enabling work based on APX spec v6. Prior to v7, APX included
> > NCI_NDD_NF by default, but this feature has now been separated from
> > basic APX and requires explicit checking CPUID bit.
> >
> > x86 ecosystem advisory group has aligned on APX so it may be possible
> > for other x86 vendors to implement APX without NCI_NDD_NF and this still
> > match with the APX spec.
>
> Well yes, but I doubt that the ecosystem will produce binaries
> specialized for APX *without* NDD.  It's fine to enumerate it
> separately, but that doesn't have any immediate consequences.  GCC makes
> it rather hard to build for APX without NDD, for example.  At least more
> difficult than building for AVX-512F without AVX-512VL.
>
> I just don't think software vendors are enthusiastic about having to
> create and support not one, but two builds for APX.  If NDD is optional
> in practice, it will not be possible to use it except for run-time
> generated code and perhaps very targeted optimizations because that
> single extra APX will just not use NDD.
>
> I feel like there has been a misunderstanding somewhere.

I totally agree and I think this addition to APX was very misguided,
no matter who proposed it.

However, for virtualization we probably should include this code no
matter how much I dislike it, because having to add the bit later
retroactively would be worse.

Paolo
Re: [PATCH 4/5] i386/cpu: Support APX CPUIDs
Posted by Paolo Bonzini 1 day, 4 hours ago
Il mer 19 nov 2025, 08:12 Zhao Liu <zhao1.liu@intel.com> ha scritto:

> > > Note, APX_NCI_NDD_NF is documented as always enabled for Intel
> > > processors since APX spec (revision v7.0). Now any Intel processor
> > > that enumerates support for APX_F (CPUID.(EAX=0x7, ECX=1).EDX[21])
> > > will also enumerate support for APX_NCI_NDD_NF.
>
> This sentence (from APX spec rev.7) emphasizes the “Intel” vendor,
> and its primary goal was to address and explain compatibility concern
> for pre-enabling work based on APX spec v6. Prior to v7, APX included
> NCI_NDD_NF by default, but this feature has now been separated from
> basic APX and requires explicit checking CPUID bit.
>
> x86 ecosystem advisory group has aligned on APX so it may be possible
> for other x86 vendors to implement APX without NCI_NDD_NF and this still
> match with the APX spec.
>

Oh, I was not aware of that. It is really ugly but I guess that's not our
choice. :/ If QEMU ever implements APX emulation it will have NC/NDD/NF
though...

Paolo


> If we default to setting this NCI_NDD_NF bit for APX, then in the future
> when we run into other vendors that don't support this feature, we'll not
> only have to make it optional again, but we'll also need to do fixes
> similar to the ARCH_CAPABILITIES situation - checking vendors, fixing
> compatibility issues, and all that stuff.
>
> Therefore, compared to default setting to constant, I think the optional
> NCI_NDD_NF now not only aligns with arch spec but also prevents future
> compatibility issues. :)
>
> Thanks,
> Zhao
>
>