[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 = ¤t_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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |