|
@@ -397,7 +397,7 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
|
|
|
}
|
|
|
|
|
|
static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
|
|
|
- unsigned int index)
|
|
|
+ unsigned int slot)
|
|
|
{
|
|
|
struct pci_dev *dev = this_leaf->l3->dev;
|
|
|
unsigned int reg = 0;
|
|
@@ -408,21 +408,53 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
|
|
|
if (!dev)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- pci_read_config_dword(dev, 0x1BC + index * 4, ®);
|
|
|
+ pci_read_config_dword(dev, 0x1BC + slot * 4, ®);
|
|
|
return sprintf(buf, "0x%08x\n", reg);
|
|
|
}
|
|
|
|
|
|
-#define SHOW_CACHE_DISABLE(index) \
|
|
|
+#define SHOW_CACHE_DISABLE(slot) \
|
|
|
static ssize_t \
|
|
|
-show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \
|
|
|
+show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf) \
|
|
|
{ \
|
|
|
- return show_cache_disable(this_leaf, buf, index); \
|
|
|
+ return show_cache_disable(this_leaf, buf, slot); \
|
|
|
}
|
|
|
SHOW_CACHE_DISABLE(0)
|
|
|
SHOW_CACHE_DISABLE(1)
|
|
|
|
|
|
+static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu,
|
|
|
+ unsigned slot, unsigned long idx)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ idx |= BIT(30);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * disable index in all 4 subcaches
|
|
|
+ */
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ u32 reg = idx | (i << 20);
|
|
|
+
|
|
|
+ if (!l3->subcaches[i])
|
|
|
+ continue;
|
|
|
+
|
|
|
+ pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We need to WBINVD on a core on the node containing the L3
|
|
|
+ * cache which indices we disable therefore a simple wbinvd()
|
|
|
+ * is not sufficient.
|
|
|
+ */
|
|
|
+ wbinvd_on_cpu(cpu);
|
|
|
+
|
|
|
+ reg |= BIT(31);
|
|
|
+ pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
|
|
|
- const char *buf, size_t count, unsigned int index)
|
|
|
+ const char *buf, size_t count,
|
|
|
+ unsigned int slot)
|
|
|
{
|
|
|
struct pci_dev *dev = this_leaf->l3->dev;
|
|
|
int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
|
|
@@ -448,23 +480,17 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
|
|
|
((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
|
|
|
return -EINVAL;
|
|
|
|
|
|
- val |= BIT(30);
|
|
|
- pci_write_config_dword(dev, 0x1BC + index * 4, val);
|
|
|
- /*
|
|
|
- * We need to WBINVD on a core on the node containing the L3 cache which
|
|
|
- * indices we disable therefore a simple wbinvd() is not sufficient.
|
|
|
- */
|
|
|
- wbinvd_on_cpu(cpu);
|
|
|
- pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31));
|
|
|
+ amd_l3_disable_index(this_leaf->l3, cpu, slot, val);
|
|
|
+
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
-#define STORE_CACHE_DISABLE(index) \
|
|
|
+#define STORE_CACHE_DISABLE(slot) \
|
|
|
static ssize_t \
|
|
|
-store_cache_disable_##index(struct _cpuid4_info *this_leaf, \
|
|
|
+store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \
|
|
|
const char *buf, size_t count) \
|
|
|
{ \
|
|
|
- return store_cache_disable(this_leaf, buf, count, index); \
|
|
|
+ return store_cache_disable(this_leaf, buf, count, slot); \
|
|
|
}
|
|
|
STORE_CACHE_DISABLE(0)
|
|
|
STORE_CACHE_DISABLE(1)
|