[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.