[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: refactor psr: L3 CAT: set value: assemble features value array.
commit 81811cffec3cc090c5d63b5cc09eb7e8512bc3db 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:34:12 2017 +0200 x86: refactor psr: L3 CAT: set value: assemble features value array. Only can one COS ID be used by one domain at one time. That means all enabled features' COS registers at this COS ID are valid for this domain at that time. When user updates a feature's value, we need make sure all other features' values are not affected. So, we firstly need gather an array which contains all features current values and replace the setting feature's value in array to new value. Then, we can try to find if there is a COS ID on which all features' COS registers values are same as the array. If we can find, we just use this COS ID. If fail to find, we need pick a new COS ID. This patch implements value array assembling flow. Signed-off-by: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/psr.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c index f1b5837..f7ba892 100644 --- a/xen/arch/x86/psr.c +++ b/xen/arch/x86/psr.c @@ -210,6 +210,29 @@ static enum psr_feat_type psr_cbm_type_to_feat_type(enum cbm_type type) return feat_type; } +static bool psr_check_cbm(unsigned int cbm_len, unsigned long cbm) +{ + unsigned int first_bit, zero_bit; + + /* Set bits should only in the range of [0, cbm_len]. */ + if ( cbm & (~0ul << cbm_len) ) + return false; + + /* At least one bit need to be set. */ + if ( cbm == 0 ) + return false; + + first_bit = find_first_bit(&cbm, cbm_len); + zero_bit = find_next_zero_bit(&cbm, cbm_len, first_bit); + + /* Set bits should be contiguous. */ + if ( zero_bit < cbm_len && + find_next_bit(&cbm, cbm_len, zero_bit) < cbm_len ) + return false; + + return true; +} + /* CAT common functions implementation. */ static int cat_init_feature(const struct cpuid_leaf *regs, struct feat_node *feat, @@ -601,7 +624,14 @@ int psr_get_val(struct domain *d, unsigned int socket, /* Set value functions */ static unsigned int get_cos_num(void) { - return 0; + unsigned int num = 0, i; + + /* Get all features total amount. */ + for ( i = 0; i < ARRAY_SIZE(feat_props); i++ ) + if ( feat_props[i] ) + num += feat_props[i]->cos_num; + + return num; } static int gather_val_array(uint32_t val[], @@ -609,7 +639,68 @@ static int gather_val_array(uint32_t val[], const struct psr_socket_info *info, unsigned int old_cos) { - return -EINVAL; + unsigned int i; + + if ( !val ) + return -EINVAL; + + /* Get all features current values according to old_cos. */ + for ( i = 0; i < ARRAY_SIZE(info->features); i++ ) + { + unsigned int cos = old_cos, j; + const struct feat_node *feat = info->features[i]; + const struct feat_props *props = feat_props[i]; + + if ( !feat ) + continue; + + if ( !props ) + { + ASSERT_UNREACHABLE(); + return -ENOENT; + } + + if ( array_len < props->cos_num ) + return -ENOSPC; + + /* + * If old_cos exceeds current feature's cos_max, we should get + * default value. So assign cos to 0 which stores default value. + */ + if ( cos > feat->cos_max ) + cos = 0; + + /* Value getting order is same as feature array. */ + for ( j = 0; j < props->cos_num; j++ ) + val[j] = feat->cos_reg_val[cos * props->cos_num + j]; + + array_len -= props->cos_num; + val += props->cos_num; + } + + return 0; +} + +static int skip_prior_features(unsigned int *array_len, + enum psr_feat_type feat_type) +{ + unsigned int i, skip_len = 0; + + for ( i = 0; i < feat_type; i++ ) + { + const struct feat_props *props = feat_props[i]; + + if ( !props ) + continue; + + if ( *array_len <= props->cos_num ) + return -ENOSPC; + + *array_len -= props->cos_num; + skip_len += props->cos_num; + } + + return skip_len; } static int insert_val_into_array(uint32_t val[], @@ -619,6 +710,46 @@ static int insert_val_into_array(uint32_t val[], enum cbm_type type, uint32_t new_val) { + const struct feat_node *feat; + const struct feat_props *props; + unsigned int i; + int ret; + + ASSERT(feat_type < FEAT_TYPE_NUM); + + ret = skip_prior_features(&array_len, feat_type); + if ( ret < 0 ) + return ret; + + val += ret; + + feat = info->features[feat_type]; + if ( !feat ) + return -ENOENT; + + props = feat_props[feat_type]; + if ( !props ) + { + ASSERT_UNREACHABLE(); + return -ENOENT; + } + + if ( array_len < props->cos_num ) + return -ENOSPC; + + if ( !psr_check_cbm(feat->cbm_len, new_val) ) + return -EINVAL; + + /* Value setting position is same as feature array. */ + for ( i = 0; i < props->cos_num; i++ ) + { + if ( type == props->type[i] ) + { + val[i] = new_val; + return 0; + } + } + return -EINVAL; } -- 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 |