[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: refactor psr: L3 CAT: set value: implement write msr flow.
commit 200e8af4e51826b07c1694633a42e818a6465773 Author: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> AuthorDate: Tue Aug 1 11:04:00 2017 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Aug 3 12:35:19 2017 +0200 x86: refactor psr: L3 CAT: set value: implement write msr flow. Continue from previous patch: 'x86: refactor psr: L3 CAT: set value: implement cos id picking flow.' We have got the feature value and COS ID to set. Then, we write MSRs of the designated feature. Till now, set value process is completed. Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/psr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c index b553112..6ea2e4e 100644 --- a/xen/arch/x86/psr.c +++ b/xen/arch/x86/psr.c @@ -113,6 +113,9 @@ static const struct feat_props { /* get_feat_info is used to return feature HW info through sysctl. */ bool (*get_feat_info)(const struct feat_node *feat, uint32_t data[], unsigned int array_len); + + /* write_msr is used to write out feature MSR register. */ + void (*write_msr)(unsigned int cos, uint32_t val, enum cbm_type type); } *feat_props[FEAT_TYPE_NUM]; /* @@ -289,11 +292,17 @@ static bool cat_get_feat_info(const struct feat_node *feat, } /* L3 CAT props */ +static void l3_cat_write_msr(unsigned int cos, uint32_t val, enum cbm_type type) +{ + wrmsrl(MSR_IA32_PSR_L3_MASK(cos), val); +} + static const struct feat_props l3_cat_props = { .cos_num = 1, .type[0] = PSR_CBM_TYPE_L3, .alt_type = PSR_CBM_TYPE_UNKNOWN, .get_feat_info = cat_get_feat_info, + .write_msr = l3_cat_write_msr, }; static void __init parse_psr_bool(char *s, char *value, char *feature, @@ -947,11 +956,79 @@ static int pick_avail_cos(const struct psr_socket_info *info, return -EOVERFLOW; } +static unsigned int get_socket_cpu(unsigned int socket) +{ + if ( likely(socket < nr_sockets) ) + return cpumask_any(socket_cpumask[socket]); + + return nr_cpu_ids; +} + +struct cos_write_info +{ + unsigned int cos; + struct feat_node *feature; + const uint32_t *val; + const struct feat_props *props; +}; + +static void do_write_psr_msrs(void *data) +{ + const struct cos_write_info *info = data; + struct feat_node *feat = info->feature; + const struct feat_props *props = info->props; + unsigned int i, cos = info->cos, cos_num = props->cos_num; + + for ( i = 0; i < cos_num; i++ ) + { + if ( feat->cos_reg_val[cos * cos_num + i] != info->val[i] ) + { + feat->cos_reg_val[cos * cos_num + i] = info->val[i]; + props->write_msr(cos, info->val[i], props->type[i]); + } + } +} + static int write_psr_msrs(unsigned int socket, unsigned int cos, const uint32_t val[], unsigned int array_len, enum psr_feat_type feat_type) { - return -ENOENT; + int ret; + struct psr_socket_info *info = get_socket_info(socket); + struct cos_write_info data = + { + .cos = cos, + .feature = info->features[feat_type], + .props = feat_props[feat_type], + }; + + if ( cos > info->features[feat_type]->cos_max ) + return -EINVAL; + + /* Skip to the feature's value head. */ + ret = skip_prior_features(&array_len, feat_type); + if ( ret < 0 ) + return ret; + + val += ret; + + if ( array_len < feat_props[feat_type]->cos_num ) + return -ENOSPC; + + data.val = val; + + if ( socket == cpu_to_socket(smp_processor_id()) ) + do_write_psr_msrs(&data); + else + { + unsigned int cpu = get_socket_cpu(socket); + + if ( cpu >= nr_cpu_ids ) + return -ENOTSOCK; + on_selected_cpus(cpumask_of(cpu), do_write_psr_msrs, &data, 1); + } + + return 0; } int psr_set_val(struct domain *d, unsigned int socket, -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |