|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 2/6] x86/cpuid: Introduce recalculate_xstate()
>>> On 17.01.17 at 12:27, <andrew.cooper3@xxxxxxxxxx> wrote:
> --- a/xen/arch/x86/cpuid.c
> +++ b/xen/arch/x86/cpuid.c
> @@ -80,6 +80,103 @@ static void sanitise_featureset(uint32_t *fs)
> (fs[FEATURESET_e1d] & ~CPUID_COMMON_1D_FEATURES));
> }
>
> +static void recalculate_xstate(struct cpuid_policy *p)
> +{
> + uint64_t xstates = XSTATE_FP_SSE;
> + uint32_t xstate_size = XSTATE_AREA_MIN_SIZE;
> + unsigned int i, Da1 = p->xstate.Da1;
> +
> + /*
> + * The Da1 leaf is the only piece if information preserved in the common
> + * case. Everything else is derived from other feature state.
> + */
"piece of" I think.
> + memset(&p->xstate, 0, sizeof(p->xstate));
> +
> + if ( !p->basic.xsave )
> + return;
> +
> + if ( p->basic.avx )
> + {
> + xstates |= XSTATE_YMM;
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_YMM] +
> + xstate_sizes[_XSTATE_YMM]);
> + }
> +
> + if ( p->feat.mpx )
> + {
> + xstates |= XSTATE_BNDREGS | XSTATE_BNDCSR;
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_BNDCSR] +
> + xstate_sizes[_XSTATE_BNDCSR]);
> + }
> +
> + if ( p->feat.avx512f )
> + {
> + xstates |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_HI_ZMM] +
> + xstate_sizes[_XSTATE_HI_ZMM]);
> + }
> +
> + if ( p->feat.pku )
> + {
> + xstates |= XSTATE_PKRU;
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_PKRU] +
> + xstate_sizes[_XSTATE_PKRU]);
> + }
> +
> + if ( p->extd.lwp )
> + {
> + xstates |= XSTATE_LWP;
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_LWP] +
> + xstate_sizes[_XSTATE_LWP]);
> + }
> +
> + /* Sanity check we aren't advertising unknown states. */
> + ASSERT((xstates & ~XCNTXT_MASK) == 0);
> +
> + p->xstate.max_size = xstate_size;
> + p->xstate.xcr0_low = xstates & ~XSTATE_XSAVES_ONLY;
> + p->xstate.xcr0_high = (xstates & ~XSTATE_XSAVES_ONLY) >> 32;
> +
> + p->xstate.Da1 = Da1;
> + if ( p->xstate.xsaves )
> + {
> + p->xstate.xss_low = xstates & XSTATE_XSAVES_ONLY;
> + p->xstate.xss_high = (xstates & XSTATE_XSAVES_ONLY) >> 32;
> + }
> + else
> + xstates &= ~XSTATE_XSAVES_ONLY;
> +
> + for ( i = 2; i < min(63ul, ARRAY_SIZE(p->xstate.comp)); ++i )
> + {
> + uint64_t curr_xstate = 1ul << i;
> +
> + if ( !(xstates & curr_xstate) )
> + continue;
> +
> + p->xstate.comp[i].size = xstate_sizes[i];
> + p->xstate.comp[i].offset = xstate_offsets[i];
> + p->xstate.comp[i].xss = curr_xstate & XSTATE_XSAVES_ONLY;
> + p->xstate.comp[i].align = curr_xstate & xstate_align;
> +
> + /*
> + * Sanity checks:
> + * - All valid components should have non-zero size.
> + * - All xcr0 components should have non-zero offset.
> + * - All xss components should report 0 offset.
> + */
> + ASSERT(xstate_sizes[i]);
> + if ( curr_xstate & XSTATE_XSAVES_ONLY )
> + ASSERT(xstate_offsets[i] == 0);
> + else
> + ASSERT(xstate_offsets[i]);
> + }
Hmm, now that I look at this again - what business do these
assertions have here? They're checking host information, which
isn't going to change post boot. Such checking, if indeed wanted,
should be done once during system boot.
I also think such checks should be consistent in style - either both
explicitly comparing with zero, or using ! in the if() branch to match
the else one.
> @@ -154,6 +152,13 @@ struct cpuid_policy
> };
> uint32_t /* b */:32, xss_low, xss_high;
> };
> +
> + /* Per-component common state. Valid for i >= 2. */
> + struct {
> + uint32_t size, offset;
> + bool xss:1, align:1;
> + uint32_t _res_d;
I see you've decided against an inner union. Should be fine of
course, at least until we have a need to access the full ECX value
by name.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |