diff --git a/xen/arch/x86/psr.c b/xen/arch/x86/psr.c
index 97f1c33..aa902d2 100644
--- a/xen/arch/x86/psr.c
+++ b/xen/arch/x86/psr.c
@@ -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)
