@@ -26,20 +26,15 @@
/* Per spec, the maximum COS register number is 128. */
#define MAX_COS_REG_NUM 128
-struct psr_cat_cbm {
- union {
- uint64_t cbm;
- struct {
- uint64_t code;
- uint64_t data;
- };
- };
-};
-
struct psr_cat_socket_info {
unsigned int cbm_len;
unsigned int cos_max;
- struct psr_cat_cbm *cos_to_cbm;
+ /*
+ * Store the values of COS registers:
+ * CAT uses 1 entry for one COS ID;
+ * CDP uses 2 entries for one COS ID and DATA is the first one.
+ */
+ uint64_t cos_reg_val[MAX_COS_REG_NUM];
/*
* Every entry of cos_ref is the reference count of a COS register.
* One entry of cos_ref corresponds to one COS ID.
@@ -49,6 +44,21 @@ struct psr_cat_socket_info {
spinlock_t ref_lock;
};
+/*
+ * get_data - get DATA COS register value from input COS ID.
+ * @info: the struct psr_cat_socket_info pointer.
+ * @cos: the COS ID.
+ */
+#define get_cdp_data(info, cos) \
+ info->cos_reg_val[cos * 2]
+/*
+ * get_cdp_code - get CODE COS register value from input COS ID.
+ * @info: the struct psr_cat_socket_info pointer.
+ * @cos: the COS ID.
+ */
+#define get_cdp_code(info, cos) \
+ info->cos_reg_val[cos * 2 + 1]
+
struct psr_assoc {
uint64_t val;
uint64_t cos_mask;
@@ -66,8 +76,6 @@ static unsigned int __read_mostly opt_cos_max = MAX_COS_REG_NUM - 1;
static uint64_t rmid_mask;
static DEFINE_PER_CPU(struct psr_assoc, psr_assoc);
-static struct psr_cat_cbm *temp_cos_to_cbm;
-
static unsigned int get_socket_cpu(unsigned int socket)
{
if ( likely(socket < nr_sockets) )
@@ -306,6 +314,7 @@ int psr_get_l3_cbm(struct domain *d, unsigned int socket,
{
struct psr_cat_socket_info *info = get_cat_socket_info(socket);
bool_t cdp_enabled = cdp_is_enabled(socket);
+ unsigned int cos = d->arch.psr_cos_ids[socket];
if ( IS_ERR(info) )
return PTR_ERR(info);
@@ -315,21 +324,21 @@ int psr_get_l3_cbm(struct domain *d, unsigned int socket,
case PSR_CBM_TYPE_L3:
if ( cdp_enabled )
return -EXDEV;
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].cbm;
+ *cbm = info->cos_reg_val[cos];
break;
case PSR_CBM_TYPE_L3_CODE:
if ( !cdp_enabled )
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].cbm;
+ *cbm = info->cos_reg_val[cos];
else
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].code;
+ *cbm = get_cdp_code(info, cos);
break;
case PSR_CBM_TYPE_L3_DATA:
if ( !cdp_enabled )
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].cbm;
+ *cbm = info->cos_reg_val[cos];
else
- *cbm = info->cos_to_cbm[d->arch.psr_cos_ids[socket]].data;
+ *cbm = get_cdp_data(info, cos);
break;
default:
@@ -408,7 +417,7 @@ static int write_l3_cbm(unsigned int socket, unsigned int cos,
return 0;
}
-static int find_cos(struct psr_cat_cbm *map, unsigned int *ref,
+static int find_cos(struct psr_cat_socket_info *info, unsigned int *ref,
unsigned int cos_max,
uint64_t cbm_code, uint64_t cbm_data, bool_t cdp_enabled)
{
@@ -417,9 +426,9 @@ static int find_cos(struct psr_cat_cbm *map, unsigned int *ref,
for ( cos = 0; cos <= cos_max; cos++ )
{
if ( (ref[cos] || cos == 0) &&
- ((!cdp_enabled && map[cos].cbm == cbm_code) ||
- (cdp_enabled && map[cos].code == cbm_code &&
- map[cos].data == cbm_data)) )
+ ((!cdp_enabled && info->cos_reg_val[cos] == cbm_code) ||
+ (cdp_enabled && get_cdp_code(info, cos) == cbm_code &&
+ get_cdp_data(info, cos) == cbm_data)) )
return cos;
}
@@ -450,7 +459,6 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
int cos, ret;
uint64_t cbm_data, cbm_code;
bool_t cdp_enabled = cdp_is_enabled(socket);
- struct psr_cat_cbm *map;
struct psr_cat_socket_info *info = get_cat_socket_info(socket);
unsigned int *ref;
@@ -466,7 +474,6 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
cos_max = info->cos_max;
old_cos = d->arch.psr_cos_ids[socket];
- map = info->cos_to_cbm;
ref = info->cos_ref;
switch ( type )
@@ -478,11 +485,11 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
case PSR_CBM_TYPE_L3_CODE:
cbm_code = cbm;
- cbm_data = map[old_cos].data;
+ cbm_data = get_cdp_data(info, old_cos);
break;
case PSR_CBM_TYPE_L3_DATA:
- cbm_code = map[old_cos].code;
+ cbm_code = get_cdp_code(info, old_cos);
cbm_data = cbm;
break;
@@ -492,7 +499,7 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
}
spin_lock(&info->ref_lock);
- cos = find_cos(map, ref, cos_max, cbm_code, cbm_data, cdp_enabled);
+ cos = find_cos(info, ref, cos_max, cbm_code, cbm_data, cdp_enabled);
if ( cos >= 0 )
{
if ( cos == old_cos )
@@ -512,8 +519,9 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
/* We try to avoid writing MSR. */
if ( (cdp_enabled &&
- (map[cos].code != cbm_code || map[cos].data != cbm_data)) ||
- (!cdp_enabled && map[cos].cbm != cbm_code) )
+ (get_cdp_code(info, cos) != cbm_code ||
+ get_cdp_data(info, cos) != cbm_data)) ||
+ (!cdp_enabled && info->cos_reg_val[cos] != cbm_code) )
{
ret = write_l3_cbm(socket, cos, cbm_code, cbm_data, cdp_enabled);
if ( ret )
@@ -521,8 +529,8 @@ int psr_set_l3_cbm(struct domain *d, unsigned int socket,
spin_unlock(&info->ref_lock);
return ret;
}
- map[cos].code = cbm_code;
- map[cos].data = cbm_data;
+ get_cdp_code(info, cos) = cbm_code;
+ get_cdp_data(info, cos) = cbm_data;
}
}
@@ -583,10 +591,7 @@ static int cat_cpu_prepare(unsigned int cpu)
if ( !cat_socket_info )
return 0;
- if ( temp_cos_to_cbm == NULL &&
- (temp_cos_to_cbm = xzalloc_array(struct psr_cat_cbm,
- MAX_COS_REG_NUM)) == NULL )
- return -ENOMEM;
+ /* Keep this function for future usage. */
return 0;
}
@@ -615,10 +620,8 @@ static void cat_cpu_init(void)
info->cbm_len = (eax & 0x1f) + 1;
info->cos_max = min(opt_cos_max, edx & 0xffff);
- info->cos_to_cbm = temp_cos_to_cbm;
- temp_cos_to_cbm = NULL;
/* cos=0 is reserved as default cbm(all ones). */
- info->cos_to_cbm[0].cbm = (1ull << info->cbm_len) - 1;
+ info->cos_reg_val[0] = (1ull << info->cbm_len) - 1;
spin_lock_init(&info->ref_lock);
@@ -627,8 +630,10 @@ static void cat_cpu_init(void)
if ( (ecx & PSR_CAT_CDP_CAPABILITY) && (opt_psr & PSR_CDP) &&
cdp_socket_enable && !test_bit(socket, cdp_socket_enable) )
{
- info->cos_to_cbm[0].code = (1ull << info->cbm_len) - 1;
- info->cos_to_cbm[0].data = (1ull << info->cbm_len) - 1;
+ /* CODE */
+ get_cdp_code(info, 0) = (1ull << info->cbm_len) - 1;
+ /* DATA */
+ get_cdp_data(info, 0) = (1ull << info->cbm_len) - 1;
/* We only write mask1 since mask0 is always all ones by default. */
wrmsrl(MSR_IA32_PSR_L3_MASK(1), (1ull << info->cbm_len) - 1);
@@ -653,14 +658,6 @@ static void cat_cpu_fini(unsigned int cpu)
if ( !socket_cpumask[socket] || cpumask_empty(socket_cpumask[socket]) )
{
- struct psr_cat_socket_info *info = cat_socket_info + socket;
-
- if ( info->cos_to_cbm )
- {
- xfree(info->cos_to_cbm);
- info->cos_to_cbm = NULL;
- }
-
if ( cdp_is_enabled(socket) )
clear_bit(socket, cdp_socket_enable);
'struct psr_cat_cbm' is defined for L3 CAT only. It is not appropriate for other features. This patch replaces it with a generic array, 'uint64_t cos_reg_val[MAX_COS_REG_NUM]', to save values of COS registers. So 'temp_cos_to_cbm' is not useful anymore, remove it. Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com> --- xen/arch/x86/psr.c | 93 ++++++++++++++++++++++++++---------------------------- 1 file changed, 45 insertions(+), 48 deletions(-)