|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 19/28] x86/CPUID: TMUL subleaf 1
EAX holds yet another set of feature bits. Sadly some duplicate pre-
existing bits in the feature subleaves.
Note that the dependency on just AVX512F (and not AVX10) is sufficient,
as long as we synthesize AVX512* when we find AVX10 available.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
RFC: The handling of the duplicated bits is minimal so far. Where / how
the syncing between both instances should happen is tbd. The naming
of the duplicate bits is also subject to better suggestions.
---
v4: New.
--- a/tools/libs/light/libxl_cpuid.c
+++ b/tools/libs/light/libxl_cpuid.c
@@ -345,6 +345,7 @@ int libxl_cpuid_parse_config(libxl_cpuid
CPUID_ENTRY(0x80000021, NA, CPUID_REG_ECX),
CPUID_ENTRY(0x00000024, 1, CPUID_REG_ECX),
CPUID_ENTRY(0x00000029, 0, CPUID_REG_EBX),
+ CPUID_ENTRY(0x0000001e, 1, CPUID_REG_EAX),
#undef MSR_ENTRY
#undef CPUID_ENTRY
};
--- a/tools/misc/xen-cpuid.c
+++ b/tools/misc/xen-cpuid.c
@@ -40,6 +40,7 @@ static const struct {
{ "CPUID 0x80000021.ecx", "e21c" },
{ "CPUID 0x00000024:1.ecx", "24c1" },
{ "CPUID 0x00000029:0.ebx", "29b0" },
+ { "CPUID 0x0000001e:1.eax", "1Ea1" },
};
#define COL_ALIGN "24"
--- a/tools/tests/cpu-policy/test-cpu-policy.c
+++ b/tools/tests/cpu-policy/test-cpu-policy.c
@@ -218,7 +218,7 @@ static void test_cpuid_serialise_success
.nr_leaves = 4 + 0x1d + 1 + 1,
},
- /* Leaf 0x1e serialisation stops at 0. */
+ /* Leaf 0x1e serialisation stops at max_subleaf. */
{
.name = "empty leaf 0x1e",
.p = {
@@ -230,9 +230,10 @@ static void test_cpuid_serialise_success
.name = "partial leaf 0x1e",
.p = {
.basic.max_leaf = 0x1e,
+ .tmul.max_subleaf = 1,
.tmul.maxk = 16,
},
- .nr_leaves = 4 + 0x1e + 1,
+ .nr_leaves = 4 + 0x1e + 1 + 1,
},
};
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -594,6 +594,16 @@ void identify_cpu(struct cpuinfo_x86 *c)
&c->x86_capability[FEATURESET_Da1],
&tmp, &tmp, &tmp);
+ if (cpu_has(c, X86_FEATURE_AMX_TILE) && c->cpuid_level >= 0x1e) {
+ uint32_t max_subleaf;
+
+ cpuid_count(0x1e, 0, &max_subleaf, &tmp, &tmp, &tmp);
+ if (max_subleaf >= 1)
+ cpuid_count(0x1e, 1,
+ &c->x86_capability[FEATURESET_1Ea1],
+ &tmp, &tmp, &tmp);
+ }
+
if (cpu_has(c, X86_FEATURE_AVX10) && c->cpuid_level >= 0x24) {
uint32_t max_subleaf;
--- a/xen/arch/x86/cpu-policy.c
+++ b/xen/arch/x86/cpu-policy.c
@@ -282,6 +282,10 @@ static void recalculate_tile(struct cpu_
p->tmul.raw[0].b &= 0x00ffffff;
p->tmul.raw[0].c = 0,
p->tmul.raw[0].d = 0;
+
+ p->tmul.raw[1].b = 0;
+ p->tmul.raw[1].c = 0;
+ p->tmul.raw[1].d = 0;
}
/*
--- a/xen/arch/x86/lib/cpu-policy/copy-to-buffer.c
+++ b/xen/arch/x86/lib/cpu-policy/copy-to-buffer.c
@@ -132,7 +132,8 @@ int x86_cpuid_copy_to_buffer(const struc
case 0x1e:
for ( subleaf = 0;
- subleaf <= ARRAY_SIZE(p->tmul.raw) - 1; ++subleaf )
+ subleaf <= MIN(p->tmul.max_subleaf,
+ ARRAY_SIZE(p->tmul.raw) - 1); ++subleaf )
COPY_LEAF(leaf, subleaf, &p->tmul.raw[subleaf]);
break;
--- a/xen/arch/x86/lib/cpu-policy/cpuid.c
+++ b/xen/arch/x86/lib/cpu-policy/cpuid.c
@@ -84,6 +84,7 @@ void x86_cpu_policy_to_featureset(
fs[FEATURESET_e21c] = p->extd.e21c;
fs[FEATURESET_24c1] = p->avx10._24c1;
fs[FEATURESET_29b0] = p->apx._29b0;
+ fs[FEATURESET_1Ea1] = p->tmul._1Ea1;
}
void x86_cpu_featureset_to_policy(
@@ -110,6 +111,7 @@ void x86_cpu_featureset_to_policy(
p->extd.e21c = fs[FEATURESET_e21c];
p->avx10._24c1 = fs[FEATURESET_24c1];
p->apx._29b0 = fs[FEATURESET_29b0];
+ p->tmul._1Ea1 = fs[FEATURESET_1Ea1];
}
void x86_cpu_policy_recalc_synth(struct cpu_policy *p)
@@ -233,8 +235,14 @@ void x86_cpu_policy_fill_native(struct c
}
if ( p->basic.max_leaf >= 0x1e )
+ {
cpuid_count_leaf(0x1e, 0, &p->tmul.raw[0]);
+ for ( i = 1; i <= MIN(p->tmul.max_subleaf,
+ ARRAY_SIZE(p->tmul.raw) - 1); ++i )
+ cpuid_count_leaf(0x1e, i, &p->tmul.raw[i]);
+ }
+
if ( p->basic.max_leaf >= 0x24 )
{
cpuid_count_leaf(0x24, 0, &p->avx10.raw[0]);
@@ -333,8 +341,12 @@ void x86_cpu_policy_clear_out_of_range_l
if ( p->basic.max_leaf < 0x1e || !p->tile.max_palette ||
(!p->feat.amx_int8 && !p->feat.amx_bf16 &&
- !p->feat.amx_fp16 && !p->feat.amx_complex) )
+ !p->feat.amx_fp16 && !p->feat.amx_complex &&
+ !p->tmul._1Ea1) )
memset(p->tmul.raw, 0, sizeof(p->tmul.raw));
+ else
+ zero_leaves(p->tmul.raw, p->tmul.max_subleaf + 1,
+ ARRAY_SIZE(p->tmul.raw) - 1);
if ( p->basic.max_leaf < 0x24 )
memset(p->avx10.raw, 0, sizeof(p->avx10.raw));
@@ -356,6 +368,8 @@ void __init x86_cpu_policy_bound_max_lea
min_t(uint32_t, p->feat.max_subleaf, ARRAY_SIZE(p->feat.raw) - 1);
p->tile.max_palette =
min_t(uint32_t, p->tile.max_palette, ARRAY_SIZE(p->tile.raw) - 1);
+ p->tmul.max_subleaf =
+ min_t(uint32_t, p->tmul.max_subleaf, ARRAY_SIZE(p->tmul.raw) - 1);
p->avx10.max_subleaf =
min_t(uint32_t, p->avx10.max_subleaf, ARRAY_SIZE(p->avx10.raw) - 1);
p->apx.max_subleaf =
@@ -400,7 +414,12 @@ void x86_cpu_policy_shrink_max_leaves(st
}
p->basic.raw[0x1d] = p->tile.raw[0];
- p->basic.raw[0x1e] = p->tmul.raw[0];
+ for ( i = p->tmul.max_subleaf; i; --i )
+ if ( p->tmul.raw[i].a | p->tmul.raw[i].b |
+ p->tmul.raw[i].c | p->tmul.raw[i].d )
+ break;
+ p->tmul.max_subleaf = i;
+ p->basic.raw[0x1e] = p->tmul.raw[i];
p->basic.raw[0x24] = p->avx10.raw[0];
--- a/xen/arch/x86/lib/cpu-policy/policy.c
+++ b/xen/arch/x86/lib/cpu-policy/policy.c
@@ -41,8 +41,10 @@ int x86_cpu_policies_are_compatible(cons
FAIL_CPUID(0x1d, 1);
}
- if ( ((guest->feat.amx_int8 || guest->feat.amx_bf16 ||
- guest->feat.amx_fp16 || guest->feat.amx_complex) &&
+ if ( guest->tmul.max_subleaf > host->tmul.max_subleaf ||
+ ((guest->feat.amx_int8 || guest->feat.amx_bf16 ||
+ guest->feat.amx_fp16 || guest->feat.amx_complex ||
+ guest->tmul._1Ea1) &&
(!guest->tmul.maxk || !guest->tmul.maxn)) ||
guest->tmul.maxk > host->tmul.maxk ||
guest->tmul.maxn > host->tmul.maxn )
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -419,6 +419,15 @@ XEN_CPUFEATURE(AVX10_V2_AUX, 19*32
/* Intel-defined CPU features, CPUID level 0x00000029:0.ebx, word 20 */
XEN_CPUFEATURE(APX_NCI_NDD_NF, 20*32+ 0) /*a APX NCI/NDD/NF instruction
forms */
+/* Intel-defined CPU features, CPUID level 0x0000001e:1.eax, word 21 */
+XEN_CPUFEATURE(AMX__INT8, 21*32+ 0) /*a AMX-INT8 Instructions */
+XEN_CPUFEATURE(AMX__BF16, 21*32+ 1) /*a AMX-BF16 Instructions */
+XEN_CPUFEATURE(AMX__COMPLEX, 21*32+ 2) /*a AMX-COMPLEX Instructions */
+XEN_CPUFEATURE(AMX__FP16, 21*32+ 3) /*a AMX-FP16 Instructions */
+XEN_CPUFEATURE(AMX_FP8, 21*32+ 4) /* AMX-FP8 Instructions */
+XEN_CPUFEATURE(AMX_AVX512, 21*32+ 7) /* AMX-AVX512 Instructions */
+XEN_CPUFEATURE(AMX_MOVRS, 21*32+ 8) /* AMX-MOVRS Instructions */
+
#endif /* XEN_CPUFEATURE */
/* Clean up from a default include. Close the enum (for C). */
--- a/xen/include/xen/lib/x86/cpu-policy.h
+++ b/xen/include/xen/lib/x86/cpu-policy.h
@@ -25,6 +25,7 @@
#define FEATURESET_e21c 18 /* 0x80000021.ecx */
#define FEATURESET_24c1 19 /* 0x00000024:1.ecx */
#define FEATURESET_29b0 20 /* 0x00000029:0.ebx */
+#define FEATURESET_1Ea1 21 /* 0x0000001e:1.eax */
struct cpuid_leaf
{
@@ -67,7 +68,7 @@ const char *x86_cpuid_vendor_to_str(unsi
#define CPUID_GUEST_NR_TOPO (1u + 1)
#define CPUID_GUEST_NR_XSTATE (62u + 1)
#define CPUID_GUEST_NR_PALETTE (1u + 1)
-#define CPUID_GUEST_NR_TMUL (0u + 1)
+#define CPUID_GUEST_NR_TMUL (1u + 1)
#define CPUID_GUEST_NR_AVX10 (1u + 1)
#define CPUID_GUEST_NR_APX (0u + 1)
#define CPUID_GUEST_NR_EXTD_INTEL (0x8u + 1)
@@ -293,9 +294,16 @@ struct cpu_policy
struct cpuid_leaf raw[CPUID_GUEST_NR_TMUL];
struct {
/* Subleaf 0. */
- uint32_t /* a */:32;
+ uint32_t max_subleaf;
uint32_t maxk:8, maxn:16, :8;
uint32_t /* c */:32, /* d */:32;
+
+ /* Subleaf 1. */
+ union {
+ uint32_t _1Ea1;
+ struct { DECL_BITFIELD(1Ea1); };
+ };
+ uint32_t /* b */:32, /* c */:32, /* d */:32;
};
} tmul;
--- a/xen/tools/gen-cpuid.py
+++ b/xen/tools/gen-cpuid.py
@@ -302,7 +302,8 @@ def crunch_numbers(state):
# AVX512 features are built on top of AVX512F
AVX512F: [AVX512DQ, AVX512_IFMA, AVX512PF, AVX512ER, AVX512CD,
AVX512BW, AVX512VL, AVX512_4VNNIW, AVX512_4FMAPS,
- AVX512_VNNI, AVX512_VPOPCNTDQ, AVX512_VP2INTERSECT],
+ AVX512_VNNI, AVX512_VPOPCNTDQ, AVX512_VP2INTERSECT,
+ AMX_AVX512],
# AVX512 extensions acting on vectors of bytes/words are made
# dependents of AVX512BW (as to requiring wider than 16-bit mask
@@ -354,7 +355,8 @@ def crunch_numbers(state):
# AMX-TILE means hardware support for tile registers and general non-
# computational instructions. All further AMX features are built on
top
# of AMX-TILE.
- AMX_TILE: [AMX_BF16, AMX_INT8, AMX_FP16, AMX_COMPLEX],
+ AMX_TILE: [AMX_BF16, AMX_INT8, AMX_FP16, AMX_COMPLEX, AMX_FP8,
+ AMX_AVX512, AMX_MOVRS],
# APX discrete features.
APX_F: [APX_NCI_NDD_NF],
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |