[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 2/2] x86/spec-ctrl: add support for modifying SSBD VIA LS_CFG MSR



>>> On 09.08.18 at 21:42, <brian.woods@xxxxxxx> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -611,14 +611,9 @@ static void init_amd(struct cpuinfo_x86 *c)
>                       ssbd_amd_ls_cfg_mask = 1ull << bit;
>       }
>  
> -     if (ssbd_amd_ls_cfg_mask && !rdmsr_safe(MSR_AMD64_LS_CFG, value)) {
> +     if (ssbd_amd_ls_cfg_mask && !rdmsr_safe(MSR_AMD64_LS_CFG, value))
>               if (!boot_cpu_has(X86_FEATURE_SSBD_AMD_LS_CFG))
>                       setup_force_cpu_cap(X86_FEATURE_SSBD_AMD_LS_CFG);

If the inner if() was not to go away altogether in patch 1, please
fold two successive if()-s like these.

> --- a/xen/arch/x86/spec_ctrl.c
> +++ b/xen/arch/x86/spec_ctrl.c

First of all - I'm not convinced some of the AMD specific code here
wouldn't better live in cpu/amd.c.

> @@ -50,7 +51,16 @@ bool __initdata bsp_delay_spec_ctrl;
>  uint8_t __read_mostly default_xen_spec_ctrl;
>  uint8_t __read_mostly default_spec_ctrl_flags;
>  
> +/* for SSBD support for AMD via LS_CFG */
> +#define SSBD_AMD_MAX_SOCKET 2
> +struct ssbd_amd_ls_cfg_smt_status {
> +    spinlock_t lock;
> +    uint32_t mask;
> +} __attribute__ ((aligned (64)));

Where's this literal 64 coming from? Do you perhaps mean
SMP_CACHE_BYTES? And if this is really needed (as said before,
I think the array would better be dynamically allocated than having
compile time determined fixed size), then please don't open-code
__aligned().

> +bool __read_mostly ssbd_amd_smt_en = false;
> +bool __read_mostly default_xen_ssbd_amd_ls_cfg_en = false;
>  uint64_t __read_mostly ssbd_amd_ls_cfg_mask = 0ull;
> +struct ssbd_amd_ls_cfg_smt_status *ssbd_amd_smt_status[SSBD_AMD_MAX_SOCKET] 
> = {NULL};

Several further pointless initializers.

> +static void ssbd_amd_ls_cfg_set_smt(bool enable_ssbd)
> +{
> +    uint32_t socket, core, thread;
> +    uint64_t enable_mask;
> +    uint64_t ls_cfg;
> +    struct ssbd_amd_ls_cfg_smt_status *status;
> +    const struct cpuinfo_x86  *c =  &current_cpu_data;
> +
> +    socket = c->phys_proc_id;
> +    core   = c->cpu_core_id;
> +    thread = c->apicid & (c->x86_num_siblings - 1);
> +    status = ssbd_amd_smt_status[socket] + core;
> +    enable_mask = (1ull << thread);
> +
> +    spin_lock(&status->lock);
> +
> +    if ( enable_ssbd )
> +    {
> +        if ( !(status->mask & enable_mask) )

So with ->mask being uint32_t, why does enable_mask need to be
uint64_t? Even uint32_t seems way more than needed, but there's
certainly no point going below this. Just that, as expressed before,
you should please use "unsigned int" in favor of uint32_t everywhere,
unless you really need something that's exactly 32-bits wide.

> +        {
> +            status->mask |= enable_mask;
> +            rdmsrl(MSR_AMD64_LS_CFG, ls_cfg);
> +            if ( !(ls_cfg & ssbd_amd_ls_cfg_mask) )
> +            {
> +                ls_cfg |= ssbd_amd_ls_cfg_mask;
> +                wrmsrl(MSR_AMD64_LS_CFG, ls_cfg);
> +            }
> +        }
> +    }
> +    else
> +    {
> +        if ( status->mask & enable_mask )
> +        {
> +            status->mask &= ~enable_mask;
> +            rdmsrl(MSR_AMD64_LS_CFG, ls_cfg);
> +            if ( (ls_cfg & ssbd_amd_ls_cfg_mask) && (status->mask == 0) )

Please prefer the shorter ! over " == 0".

> +            {
> +                ls_cfg &= ~ssbd_amd_ls_cfg_mask;
> +                wrmsrl(MSR_AMD64_LS_CFG, ls_cfg);
> +            }
> +        }
> +    }
> +
> +    spin_unlock(&status->lock);
> +}
> +
> +void ssbd_amd_ls_cfg_set(bool enable_ssbd)
> +{
> +    if ( !ssbd_amd_ls_cfg_mask ||
> +         !boot_cpu_has(X86_FEATURE_SSBD_AMD_LS_CFG) ) {
> +        dprintk(XENLOG_ERR, "SSBD AMD LS CFG: invalid mask or missing 
> feature\n");

If the plan is for the function to also be called at runtime eventually,
this dprintk() needs to go away.

> +        return;
> +    }
> +
> +    if ( ssbd_amd_smt_en )
> +        ssbd_amd_ls_cfg_set_smt(enable_ssbd);
> +    else
> +        ssbd_amd_ls_cfg_set_nonsmt(enable_ssbd);
> +}
> +
> +static int __init ssbd_amd_ls_cfg_init(void)
> +{
> +    uint32_t cores_per_socket, threads_per_core;
> +    const struct cpuinfo_x86  *c =  &boot_cpu_data;
> +    uint32_t core, socket;
> +
> +    if ( !ssbd_amd_ls_cfg_mask ||
> +         !boot_cpu_has(X86_FEATURE_SSBD_AMD_LS_CFG) )
> +        goto ssbd_amd_ls_cfg_init_fail;

Why not simply "return"?

> +    switch ( c->x86 )
> +    {
> +    case 0x15:
> +    case 0x16:
> +        break;
> +
> +    case 0x17:
> +        cores_per_socket = c->x86_max_cores;
> +        threads_per_core = c->x86_num_siblings;
> +
> +        if ( threads_per_core > 1 )
> +        {
> +            ssbd_amd_smt_en = true;
> +            for ( socket = 0; socket < SSBD_AMD_MAX_SOCKET; socket++ )
> +            {
> +                ssbd_amd_smt_status[socket] =
> +                  (struct ssbd_amd_ls_cfg_smt_status *)
> +                  xmalloc_array(struct ssbd_amd_ls_cfg_smt_status,
> +                                cores_per_socket);

Pointless cast.

> +                if ( ssbd_amd_smt_status[socket] == NULL )
> +                {
> +                    dprintk(XENLOG_ERR,
> +                            "SSBD AMD LS CFG: error in status allocing\n");
> +                    goto ssbd_amd_ls_cfg_init_fail;
> +                }
> +            }
> +
> +            for ( socket = 0; socket < SSBD_AMD_MAX_SOCKET; socket++ )
> +            {
> +                for ( core = 0; core < cores_per_socket; core++ )
> +                {
> +                    spin_lock_init(&ssbd_amd_smt_status[socket][core].lock);
> +                    ssbd_amd_smt_status[socket][core].mask = 0;
> +                }
> +            }
> +        }
> +        break;
> +
> +    default:
> +        goto ssbd_amd_ls_cfg_init_fail;
> +    }
> +
> +    if ( default_xen_ssbd_amd_ls_cfg_en )
> +        ssbd_amd_ls_cfg_set(true);
> +
> +    return 0;
> +
> + ssbd_amd_ls_cfg_init_fail:
> +    for ( socket = 0; socket < SSBD_AMD_MAX_SOCKET; socket++ )
> +        if ( ssbd_amd_smt_status[socket] != NULL )
> +           xfree(ssbd_amd_smt_status[socket]);

There's no need for the if() here.

> +    setup_clear_cpu_cap(X86_FEATURE_SSBD_AMD_LS_CFG);

The same feature must not first be forced, and the cleared. Please
take a look at the implementation of the functions.

> +    default_xen_ssbd_amd_ls_cfg_en = false;
> +
> +    dprintk(XENLOG_ERR, "SSBD AMD LS CFG: disalbing SSBD due to errors\n");
> +
> +    return 1;

If the function returns 0 and 1 only, it looks like you've meant to
use bool, false, and true respectively.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

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