|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 12/17] x86/CPUID: shrink max_{,sub}leaf fields according to actual leaf contents
On 15.04.2021 11:52, Roger Pau Monné wrote:
> On Mon, Nov 23, 2020 at 03:33:03PM +0100, Jan Beulich wrote:
>> --- a/tools/tests/cpu-policy/test-cpu-policy.c
>> +++ b/tools/tests/cpu-policy/test-cpu-policy.c
>> @@ -8,10 +8,13 @@
>> #include <err.h>
>>
>> #include <xen-tools/libs.h>
>> +#include <xen/asm/x86-defns.h>
>> #include <xen/asm/x86-vendors.h>
>> #include <xen/lib/x86/cpu-policy.h>
>> #include <xen/domctl.h>
>>
>> +#define XSTATE_FP_SSE (X86_XCR0_FP | X86_XCR0_SSE)
>
> This gets used only once...
>
>> +
>> static unsigned int nr_failures;
>> #define fail(fmt, ...) \
>> ({ \
>> @@ -564,6 +567,103 @@ static void test_cpuid_out_of_range_clea
>> }
>> }
>>
>> +static void test_cpuid_maximum_leaf_shrinking(void)
>> +{
>> + static const struct test {
>> + const char *name;
>> + struct cpuid_policy p;
>> + } tests[] = {
>> + {
>> + .name = "basic",
>> + .p = {
>> + /* Very basic information only. */
>> + .basic.max_leaf = 1,
>> + .basic.raw_fms = 0xc2,
>> + },
>> + },
>> + {
>> + .name = "cache",
>> + .p = {
>> + /* Cache subleaves present. */
>> + .basic.max_leaf = 4,
>> + .cache.subleaf[0].type = 1,
>> + },
>> + },
>> + {
>> + .name = "feat#0",
>> + .p = {
>> + /* Subleaf 0 only with some valid bit. */
>> + .basic.max_leaf = 7,
>> + .feat.max_subleaf = 0,
>> + .feat.fsgsbase = 1,
>> + },
>> + },
>> + {
>> + .name = "feat#1",
>> + .p = {
>> + /* Subleaf 1 only with some valid bit. */
>> + .basic.max_leaf = 7,
>> + .feat.max_subleaf = 1,
>> + .feat.avx_vnni = 1,
>> + },
>> + },
>> + {
>> + .name = "topo",
>> + .p = {
>> + /* Topology subleaves present. */
>> + .basic.max_leaf = 0xb,
>> + .topo.subleaf[0].type = 1,
>> + },
>> + },
>> + {
>> + .name = "xstate",
>> + .p = {
>> + /* First subleaf always valid (and then non-zero). */
>> + .basic.max_leaf = 0xd,
>> + .xstate.xcr0_low = XSTATE_FP_SSE,
>
> ...here.
For now, yes. I'm introducing the constant because I think it wants
using in other places too, to avoid using literal numbers. See e.g.
.xstate.xcr0_low = 7,
in test_cpuid_serialise_success().
> And then I also wonder whether this requires having any
> specific values rather than just using ~0 or any random non-0 value.
I'm afraid I don't understand: There's no ~0 here and no random
non-zero value - all other structure elements are left default-
initialized.
>> --- a/xen/arch/x86/hvm/viridian/viridian.c
>> +++ b/xen/arch/x86/hvm/viridian/viridian.c
>> @@ -121,7 +121,9 @@ void cpuid_viridian_leaves(const struct
>> switch ( leaf )
>> {
>> case 0:
>> - res->a = 0x40000006; /* Maximum leaf */
>> + /* Maximum leaf */
>> + cpuid_viridian_leaves(v, 0x40000006, 0, res);
>> + res->a = res->a | res->b | res->c | res->d ? 0x40000006 :
>> 0x40000004;
>
> I think you would need to adjust this chunk to also take into account
> leaf 0x40000005 now.
Hmm, yes, looks like I failed to take note that I need to re-base
over that addition.
> I also wonder whether we should actually limit HyperV leaves. I think
> it's perfectly fine to report up to the maximum supported by Xen, even
> if it turns out none of the advertised feat are present, as in: Xen
> supports those leaves, but none of the features exposed are
> available.
Well, if the Viridian maintainers (I realize I failed to Cc Paul on the
original submission) think I should leave the Viridian leaves alone
(rather than handling consistently with other leaves), I can drop this
part of the change.
>> --- a/xen/include/public/arch-x86/cpuid.h
>> +++ b/xen/include/public/arch-x86/cpuid.h
>> @@ -113,6 +113,10 @@
>> /* Max. address width in bits taking memory hotplug into account. */
>> #define XEN_CPUID_MACHINE_ADDRESS_WIDTH_MASK (0xffu << 0)
>>
>> -#define XEN_CPUID_MAX_NUM_LEAVES 5
>> +#define XEN_CPUID_MAX_PV_NUM_LEAVES 5
>> +#define XEN_CPUID_MAX_HVM_NUM_LEAVES 4
>> +#define XEN_CPUID_MAX_NUM_LEAVES \
>> + (XEN_CPUID_MAX_PV_NUM_LEAVES > XEN_CPUID_MAX_HVM_NUM_LEAVES ? \
>> + XEN_CPUID_MAX_PV_NUM_LEAVES : XEN_CPUID_MAX_HVM_NUM_LEAVES)
>
> I guess we don't have any form of max macro available here to use?
I'm not aware of one that could be used in pre-processor directives
as well.
>> --- a/xen/lib/x86/cpuid.c
>> +++ b/xen/lib/x86/cpuid.c
>> @@ -238,6 +238,45 @@ void x86_cpuid_policy_clear_out_of_range
>> ARRAY_SIZE(p->extd.raw) - 1);
>> }
>>
>> +void x86_cpuid_policy_shrink_max_leaves(struct cpuid_policy *p)
>> +{
>> + unsigned int i;
>> +
>> + p->basic.raw[0x4] = p->cache.raw[0];
>> +
>> + for ( i = p->feat.max_subleaf; i; --i )
>> + if ( p->feat.raw[i].a | p->feat.raw[i].b |
>> + p->feat.raw[i].c | p->feat.raw[i].d )
>> + break;
>> + p->feat.max_subleaf = i;
>> + p->basic.raw[0x7] = p->feat.raw[0];
>
> Do you need to use p->feat.raw[i] to assure the basic 0x7 leaf is seen
> as populated?
>
> I think in theory raw[0] could be clear while raw[i] cannot as long as
> there's a populated leaf > 0 due to the check above.
Hmm, yes, this may not be very likely, but is definitely possible.
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |