@@ -26,6 +26,9 @@
/* Per spec, the maximum COS register number is 128. */
#define MAX_COS_REG_NUM 128
+#define PSR_SOCKET_L3_CAT 0
+#define PSR_SOCKET_L3_CDP 1
+
/* CAT/CDP HW info data structure. */
struct psr_cat_hw_info {
unsigned int cbm_len;
@@ -33,6 +36,8 @@ struct psr_cat_hw_info {
};
struct psr_cat_socket_info {
+ /* bit 1~0: [01]->L3 CAT-only, [10]->L3 CDP */
+ unsigned int feat_mask;
struct psr_cat_hw_info l3_info;
/*
* Store the values of COS registers:
@@ -71,9 +76,7 @@ struct psr_assoc {
struct psr_cmt *__read_mostly psr_cmt;
-static unsigned long *__read_mostly cat_socket_enable;
static struct psr_cat_socket_info *__read_mostly cat_socket_info;
-static unsigned long *__read_mostly cdp_socket_enable;
static unsigned int opt_psr;
static unsigned int __initdata opt_rmid_max = 255;
@@ -238,7 +241,7 @@ static inline void psr_assoc_init(void)
{
unsigned int socket = cpu_to_socket(smp_processor_id());
- if ( test_bit(socket, cat_socket_enable) )
+ if ( cat_socket_info[socket].feat_mask )
psra->cos_mask = ((1ull << get_count_order(
cat_socket_info[socket].l3_info.cos_max)) - 1) << 32;
}
@@ -285,7 +288,7 @@ static struct psr_cat_socket_info *get_cat_socket_info(unsigned int socket)
if ( socket >= nr_sockets )
return ERR_PTR(-ENOTSOCK);
- if ( !test_bit(socket, cat_socket_enable) )
+ if ( !cat_socket_info[socket].feat_mask )
return ERR_PTR(-ENOENT);
return cat_socket_info + socket;
@@ -293,7 +296,7 @@ static struct psr_cat_socket_info *get_cat_socket_info(unsigned int socket)
static inline bool_t cdp_is_enabled(unsigned int socket)
{
- return cdp_socket_enable && test_bit(socket, cdp_socket_enable);
+ return test_bit(PSR_SOCKET_L3_CDP, &cat_socket_info[socket].feat_mask);
}
int psr_get_cat_l3_info(unsigned int socket, uint32_t *cbm_len,
@@ -558,7 +561,7 @@ static void psr_free_cos(struct domain *d)
if( !d->arch.psr_cos_ids )
return;
- for_each_set_bit(socket, cat_socket_enable, nr_sockets)
+ for( socket = 0; socket < nr_sockets; socket++ )
{
if ( (cos = d->arch.psr_cos_ids[socket]) == 0 )
continue;
@@ -614,14 +617,14 @@ static void cat_cpu_init(void)
return;
socket = cpu_to_socket(cpu);
- if ( test_bit(socket, cat_socket_enable) )
+ info = cat_socket_info + socket;
+ if ( info->feat_mask )
return;
cpuid_count(PSR_CPUID_LEVEL_CAT, 0, &eax, &ebx, &ecx, &edx);
if ( ebx & PSR_RESOURCE_TYPE_L3 )
{
cpuid_count(PSR_CPUID_LEVEL_CAT, 1, &eax, &ebx, &ecx, &edx);
- info = cat_socket_info + socket;
info->l3_info.cbm_len = (eax & 0x1f) + 1;
info->l3_info.cos_max = min(opt_cos_max, edx & 0xffff);
@@ -630,10 +633,8 @@ static void cat_cpu_init(void)
spin_lock_init(&info->ref_lock);
- set_bit(socket, cat_socket_enable);
-
if ( (ecx & PSR_CAT_CDP_CAPABILITY) && (opt_psr & PSR_CDP) &&
- cdp_socket_enable && !test_bit(socket, cdp_socket_enable) )
+ !test_bit(PSR_SOCKET_L3_CDP, &info->feat_mask) )
{
/* CODE */
get_cdp_code(info, 0) = (1ull << info->l3_info.cbm_len) - 1;
@@ -649,8 +650,11 @@ static void cat_cpu_init(void)
/* Cut half of cos_max when CDP is enabled. */
info->l3_info.cos_max >>= 1;
- set_bit(socket, cdp_socket_enable);
+ __set_bit(PSR_SOCKET_L3_CDP, &info->feat_mask);
}
+ else
+ __set_bit(PSR_SOCKET_L3_CAT, &info->feat_mask);
+
printk(XENLOG_INFO "CAT: enabled on socket %u, cos_max:%u, cbm_len:%u, CDP:%s\n",
socket, info->l3_info.cos_max, info->l3_info.cbm_len,
cdp_is_enabled(socket) ? "on" : "off");
@@ -663,17 +667,17 @@ static void cat_cpu_fini(unsigned int cpu)
if ( !socket_cpumask[socket] || cpumask_empty(socket_cpumask[socket]) )
{
- if ( cdp_is_enabled(socket) )
- clear_bit(socket, cdp_socket_enable);
+ struct psr_cat_socket_info *info = cat_socket_info + socket;
- clear_bit(socket, cat_socket_enable);
+ if ( cdp_is_enabled(socket) )
+ clear_bit(PSR_SOCKET_L3_CDP, &info->feat_mask);
+ else
+ clear_bit(PSR_SOCKET_L3_CAT, &info->feat_mask);
}
}
static void __init psr_cat_free(void)
{
- xfree(cat_socket_enable);
- cat_socket_enable = NULL;
xfree(cat_socket_info);
cat_socket_info = NULL;
}
@@ -686,12 +690,10 @@ static void __init init_psr_cat(void)
return;
}
- cat_socket_enable = xzalloc_array(unsigned long, BITS_TO_LONGS(nr_sockets));
cat_socket_info = xzalloc_array(struct psr_cat_socket_info, nr_sockets);
- cdp_socket_enable = xzalloc_array(unsigned long, BITS_TO_LONGS(nr_sockets));
- if ( !cat_socket_enable || !cat_socket_info )
- psr_cat_free();
+ if ( !cat_socket_info )
+ printk(XENLOG_INFO "Fail to alloc socket_info!\n");
}
static int psr_cpu_prepare(unsigned int cpu)
'cdp_socket_enable' and 'cat_socket_enable' are used to mask if CDP/CAT are enabled on socket. But they are specific for CAT and CDP. So, replace them with 'feat_mask' which is a general mask. Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com> --- xen/arch/x86/psr.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-)