All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] AMD L3 cache index disable fixes for .35
@ 2010-04-15 16:40 Borislav Petkov
  2010-04-15 16:40 ` [PATCH 1/5] x86, cacheinfo: Unify AMD L3 cache index disable checking Borislav Petkov
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:40 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

Hi,

this is a small patchset of fixes for L3 CID which have accumulated over
the last couple of weeks. They serve as a preparation for disabling L3
cache indices whenever an L3 MCE triggers, has been evaluated and the
offending index thresholded and, if error rate is excessively high,
disabled. Those patches will be coming up later though.

Patches 1,3,4 are cleanups and unifications which save us a little bit
of percpu memory in favor of dynamic allocation. Also, we have an L3
cache descriptor per node now instead of having this information per
CPU.

I triggered a lockdep warning in lockdep_trace_alloc() during testing
due to the fact that we may run with disabled interrupts that early
in the boot process. Therefore, I have a GFP_ATOMIC in patch 3 there
allocating the cache descriptors. I'm open for suggestions in case this
is undesired.

Patch 2 is a fix which triggers when we run as a guest on Xen due to Xen
not exporting CPU PCI config space to the guests.

And finally #5 is a required fix.

The patchset is also available at
git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git l3-for-35

Please queue for .35,
thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/5] x86, cacheinfo: Unify AMD L3 cache index disable checking
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
@ 2010-04-15 16:40 ` Borislav Petkov
  2010-04-15 16:41 ` [PATCH 2/5] x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments Borislav Petkov
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:40 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

All F10h CPUs starting with model 8 resp. 9, stepping 1, support L3
cache index disable. Concentrate the family, model, stepping checking at
one place and enable the feature implicitly on upcoming Fam10h models.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index b3eeb66..acfb083 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -328,18 +328,22 @@ static unsigned int __cpuinit amd_calc_l3_indices(void)
 static void __cpuinit
 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
-	if (index < 3)
+	if (boot_cpu_data.x86 != 0x10)
 		return;
 
-	if (boot_cpu_data.x86 == 0x11)
+	if (index < 3)
 		return;
 
 	/* see errata #382 and #388 */
-	if ((boot_cpu_data.x86 == 0x10) &&
-	    ((boot_cpu_data.x86_model < 0x8) ||
-	     (boot_cpu_data.x86_mask  < 0x1)))
+	if (boot_cpu_data.x86_model < 0x8)
 		return;
 
+	if ((boot_cpu_data.x86_model == 0x8 ||
+	     boot_cpu_data.x86_model == 0x9)
+		&&
+	     boot_cpu_data.x86_mask < 0x1)
+			return;
+
 	this_leaf->can_disable = true;
 	this_leaf->l3_indices  = amd_calc_l3_indices();
 }
@@ -443,8 +447,7 @@ __cpuinit cpuid4_cache_lookup_regs(int index,
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
 		amd_cpuid4(index, &eax, &ebx, &ecx);
-		if (boot_cpu_data.x86 >= 0x10)
-			amd_check_l3_disable(index, this_leaf);
+		amd_check_l3_disable(index, this_leaf);
 	} else {
 		cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
 	}
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
  2010-04-15 16:40 ` [PATCH 1/5] x86, cacheinfo: Unify AMD L3 cache index disable checking Borislav Petkov
@ 2010-04-15 16:41 ` Borislav Petkov
  2010-04-15 16:41 ` [PATCH 3/5] x86, cacheinfo: Reorganize AMD L3 cache structure Borislav Petkov
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:41 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold

From: Frank Arnold <frank.arnold@amd.com>

When running a quest kernel on xen we get:

BUG: unable to handle kernel NULL pointer dereference at 0000000000000038
IP: [<ffffffff8142f2fb>] cpuid4_cache_lookup_regs+0x2ca/0x3df
PGD 0
Oops: 0000 [#1] SMP
last sysfs file:
CPU 0
Modules linked in:

Pid: 0, comm: swapper Tainted: G        W  2.6.34-rc3 #1 /HVM domU
RIP: 0010:[<ffffffff8142f2fb>]  [<ffffffff8142f2fb>] cpuid4_cache_lookup_regs+0x
2ca/0x3df
RSP: 0018:ffff880002203e08  EFLAGS: 00010046
RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000060
RDX: 0000000000000000 RSI: 0000000000000040 RDI: 0000000000000000
RBP: ffff880002203ed8 R08: 00000000000017c0 R09: ffff880002203e38
R10: ffff8800023d5d40 R11: ffffffff81a01e28 R12: ffff880187e6f5c0
R13: ffff880002203e34 R14: ffff880002203e58 R15: ffff880002203e68
FS:  0000000000000000(0000) GS:ffff880002200000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000038 CR3: 0000000001a3c000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process swapper (pid: 0, threadinfo ffffffff81a00000, task ffffffff81a44020)
Stack:
 ffffffff810d7ecb ffff880002203e20 ffffffff81059140 ffff880002203e30
<0> ffffffff810d7ec9 0000000002203e40 000000000050d140 ffff880002203e70
<0> 0000000002008140 0000000000000086 ffff880040020140 ffffffff81068b8b
Call Trace:
 <IRQ>
 [<ffffffff810d7ecb>] ? sync_supers_timer_fn+0x0/0x1c
 [<ffffffff81059140>] ? mod_timer+0x23/0x25
 [<ffffffff810d7ec9>] ? arm_supers_timer+0x34/0x36
 [<ffffffff81068b8b>] ? hrtimer_get_next_event+0xa7/0xc3
 [<ffffffff81058e85>] ? get_next_timer_interrupt+0x19a/0x20d
 [<ffffffff8142fa23>] get_cpu_leaves+0x5c/0x232
 [<ffffffff8106a7b1>] ? sched_clock_local+0x1c/0x82
 [<ffffffff8106a9a0>] ? sched_clock_tick+0x75/0x7a
 [<ffffffff8107748c>] generic_smp_call_function_single_interrupt+0xae/0xd0
 [<ffffffff8101f6ef>] smp_call_function_single_interrupt+0x18/0x27
 [<ffffffff8100a773>] call_function_single_interrupt+0x13/0x20
 <EOI>
 [<ffffffff8143c468>] ? notifier_call_chain+0x14/0x63
 [<ffffffff810295c6>] ? native_safe_halt+0xc/0xd
 [<ffffffff810114eb>] ? default_idle+0x36/0x53
 [<ffffffff81008c22>] cpu_idle+0xaa/0xe4
 [<ffffffff81423a9a>] rest_init+0x7e/0x80
 [<ffffffff81b10dd2>] start_kernel+0x40e/0x419
 [<ffffffff81b102c8>] x86_64_start_reservations+0xb3/0xb7
 [<ffffffff81b103c4>] x86_64_start_kernel+0xf8/0x107
Code: 14 d5 40 ff ae 81 8b 14 02 31 c0 3b 15 47 1c 8b 00 7d 0e 48 8b 05 36 1c 8b
 00 48 63 d2 48 8b 04 d0 c7 85 5c ff ff ff 00 00 00 00 <8b> 70 38 48 8d 8d 5c ff
 ff ff 48 8b 78 10 ba c4 01 00 00 e8 eb
RIP  [<ffffffff8142f2fb>] cpuid4_cache_lookup_regs+0x2ca/0x3df
 RSP <ffff880002203e08>
CR2: 0000000000000038
---[ end trace a7919e7f17c0a726 ]---

The L3 cache index disable feature of AMD CPUs has to be disabled if the
kernel is running as guest on top of a hypervisor because northbridge
devices are not available to the guest. Currently, this fixes a boot
crash on top of Xen. In the future this will become an issue on KVM as
well.

Check if northbridge devices are present and do not enable the feature
if there are none.

Signed-off-by: Frank Arnold <frank.arnold@amd.com>
Acked-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index acfb083..5ab14c8 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -344,6 +344,10 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 	     boot_cpu_data.x86_mask < 0x1)
 			return;
 
+	/* not in virtualized environments */
+	if (num_k8_northbridges == 0)
+		return;
+
 	this_leaf->can_disable = true;
 	this_leaf->l3_indices  = amd_calc_l3_indices();
 }
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] x86, cacheinfo: Reorganize AMD L3 cache structure
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
  2010-04-15 16:40 ` [PATCH 1/5] x86, cacheinfo: Unify AMD L3 cache index disable checking Borislav Petkov
  2010-04-15 16:41 ` [PATCH 2/5] x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments Borislav Petkov
@ 2010-04-15 16:41 ` Borislav Petkov
  2010-04-15 16:41 ` [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node Borislav Petkov
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:41 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

Add a struct representing L3 cache attributes (subcache sizes and
indices count) and move the respective members out of _cpuid4_info.
Also, stash the struct pci_dev ptr into the struct simplifying the code
even more.

There should be no functionality change resulting from this patch except
slightly slimming the _cpuid4_info per-cpu vars.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   53 ++++++++++++++++++++-------------
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 5ab14c8..ff663ca 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -148,13 +148,19 @@ union _cpuid4_leaf_ecx {
 	u32 full;
 };
 
+struct amd_l3_cache {
+	struct	 pci_dev *dev;
+	bool	 can_disable;
+	unsigned indices;
+	u8	 subcaches[4];
+};
+
 struct _cpuid4_info {
 	union _cpuid4_leaf_eax eax;
 	union _cpuid4_leaf_ebx ebx;
 	union _cpuid4_leaf_ecx ecx;
 	unsigned long size;
-	bool can_disable;
-	unsigned int l3_indices;
+	struct amd_l3_cache *l3;
 	DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
 };
 
@@ -164,8 +170,7 @@ struct _cpuid4_info_regs {
 	union _cpuid4_leaf_ebx ebx;
 	union _cpuid4_leaf_ecx ecx;
 	unsigned long size;
-	bool can_disable;
-	unsigned int l3_indices;
+	struct amd_l3_cache *l3;
 };
 
 unsigned short			num_cache_leaves;
@@ -302,7 +307,7 @@ struct _cache_attr {
 };
 
 #ifdef CONFIG_CPU_SUP_AMD
-static unsigned int __cpuinit amd_calc_l3_indices(void)
+static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
 {
 	/*
 	 * We're called over smp_call_function_single() and therefore
@@ -317,12 +322,14 @@ static unsigned int __cpuinit amd_calc_l3_indices(void)
 	pci_read_config_dword(dev, 0x1C4, &val);
 
 	/* calculate subcache sizes */
-	sc0 = !(val & BIT(0));
-	sc1 = !(val & BIT(4));
-	sc2 = !(val & BIT(8))  + !(val & BIT(9));
-	sc3 = !(val & BIT(12)) + !(val & BIT(13));
+	l3->subcaches[0] = sc0 = !(val & BIT(0));
+	l3->subcaches[1] = sc1 = !(val & BIT(4));
+	l3->subcaches[2] = sc2 = !(val & BIT(8))  + !(val & BIT(9));
+	l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
+
+	l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
 
-	return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+	l3->dev = dev;
 }
 
 static void __cpuinit
@@ -348,19 +355,23 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 	if (num_k8_northbridges == 0)
 		return;
 
-	this_leaf->can_disable = true;
-	this_leaf->l3_indices  = amd_calc_l3_indices();
+	this_leaf->l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
+	if (!this_leaf->l3) {
+		printk(KERN_WARNING "Error allocating L3 struct\n");
+		return;
+	}
+
+	this_leaf->l3->can_disable = true;
+	amd_calc_l3_indices(this_leaf->l3);
 }
 
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
 				  unsigned int index)
 {
-	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-	int node = amd_get_nb_id(cpu);
-	struct pci_dev *dev = node_to_k8_nb_misc(node);
+	struct pci_dev *dev = this_leaf->l3->dev;
 	unsigned int reg = 0;
 
-	if (!this_leaf->can_disable)
+	if (!this_leaf->l3 || !this_leaf->l3->can_disable)
 		return -EINVAL;
 
 	if (!dev)
@@ -382,15 +393,14 @@ SHOW_CACHE_DISABLE(1)
 static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
 	const char *buf, size_t count, unsigned int index)
 {
+	struct pci_dev *dev = this_leaf->l3->dev;
 	int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map));
-	int node = amd_get_nb_id(cpu);
-	struct pci_dev *dev = node_to_k8_nb_misc(node);
 	unsigned long val = 0;
 
 #define SUBCACHE_MASK	(3UL << 20)
 #define SUBCACHE_INDEX	0xfff
 
-	if (!this_leaf->can_disable)
+	if (!this_leaf->l3 || !this_leaf->l3->can_disable)
 		return -EINVAL;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -404,7 +414,7 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf,
 
 	/* do not allow writes outside of allowed bits */
 	if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-	    ((val & SUBCACHE_INDEX) > this_leaf->l3_indices))
+	    ((val & SUBCACHE_INDEX) > this_leaf->l3->indices))
 		return -EINVAL;
 
 	val |= BIT(30);
@@ -708,6 +718,7 @@ static void __cpuinit free_cache_attributes(unsigned int cpu)
 	for (i = 0; i < num_cache_leaves; i++)
 		cache_remove_shared_cpu_map(cpu, i);
 
+	kfree(per_cpu(ici_cpuid4_info, cpu)->l3);
 	kfree(per_cpu(ici_cpuid4_info, cpu));
 	per_cpu(ici_cpuid4_info, cpu) = NULL;
 }
@@ -992,7 +1003,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
 
 		this_leaf = CPUID4_INFO_IDX(cpu, i);
 
-		if (this_leaf->can_disable)
+		if (this_leaf->l3 && this_leaf->l3->can_disable)
 			ktype_cache.default_attrs = default_l3_attrs;
 		else
 			ktype_cache.default_attrs = default_attrs;
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
                   ` (2 preceding siblings ...)
  2010-04-15 16:41 ` [PATCH 3/5] x86, cacheinfo: Reorganize AMD L3 cache structure Borislav Petkov
@ 2010-04-15 16:41 ` Borislav Petkov
  2010-04-21 20:46   ` H. Peter Anvin
  2010-04-15 16:41 ` [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches Borislav Petkov
  2010-04-21 20:43 ` [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
  5 siblings, 1 reply; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:41 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

Currently, we're allocating L3 cache info and calculating indices for
each online cpu which is clearly superfluous. Instead, we need to do
this per-node as is each L3 cache.

No functional change, only per-cpu memory savings.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   49 +++++++++++++++++++++++---------
 1 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index ff663ca..c42b5c5 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -307,19 +307,20 @@ struct _cache_attr {
 };
 
 #ifdef CONFIG_CPU_SUP_AMD
+
+/* max 8 nodes on a system */
+static struct amd_l3_cache * __cpuinitdata l3_caches[8];
+
+/*
+ * We're called over smp_call_function_single() and
+ * therefore are on the correct cpu.
+ */
 static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
 {
-	/*
-	 * We're called over smp_call_function_single() and therefore
-	 * are on the correct cpu.
-	 */
-	int cpu = smp_processor_id();
-	int node = cpu_to_node(cpu);
-	struct pci_dev *dev = node_to_k8_nb_misc(node);
 	unsigned int sc0, sc1, sc2, sc3;
 	u32 val = 0;
 
-	pci_read_config_dword(dev, 0x1C4, &val);
+	pci_read_config_dword(l3->dev, 0x1C4, &val);
 
 	/* calculate subcache sizes */
 	l3->subcaches[0] = sc0 = !(val & BIT(0));
@@ -328,13 +329,31 @@ static void __cpuinit amd_calc_l3_indices(struct amd_l3_cache *l3)
 	l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
 
 	l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
+}
+
+static struct amd_l3_cache * __cpuinit amd_init_l3_cache(int node)
+{
+	struct amd_l3_cache *l3;
+	struct pci_dev *dev = node_to_k8_nb_misc(node);
+
+	l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
+	if (!l3) {
+		printk(KERN_WARNING "Error allocating L3 struct\n");
+		return NULL;
+	}
 
 	l3->dev = dev;
+
+	amd_calc_l3_indices(l3);
+
+	return l3;
 }
 
 static void __cpuinit
 amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 {
+	int node;
+
 	if (boot_cpu_data.x86 != 0x10)
 		return;
 
@@ -355,14 +374,16 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
 	if (num_k8_northbridges == 0)
 		return;
 
-	this_leaf->l3 = kzalloc(sizeof(struct amd_l3_cache), GFP_ATOMIC);
-	if (!this_leaf->l3) {
-		printk(KERN_WARNING "Error allocating L3 struct\n");
-		return;
+	node = amd_get_nb_id(smp_processor_id());
+
+	if (!l3_caches[node]) {
+		l3_caches[node] = amd_init_l3_cache(node);
+		l3_caches[node]->can_disable = true;
 	}
 
-	this_leaf->l3->can_disable = true;
-	amd_calc_l3_indices(this_leaf->l3);
+	WARN_ON(!l3_caches[node]);
+
+	this_leaf->l3 = l3_caches[node];
 }
 
 static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf,
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
                   ` (3 preceding siblings ...)
  2010-04-15 16:41 ` [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node Borislav Petkov
@ 2010-04-15 16:41 ` Borislav Petkov
  2010-04-21 20:43 ` [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
  5 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-15 16:41 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

When disabling an L3 cache index, make sure we disable that index in
all four subcaches of the L3. Clarify nomenclature while at it, wrt to
disable slots versus disable index and rename accordingly.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   60 +++++++++++++++++++++++---------
 1 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index c42b5c5..12c5475 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -387,7 +387,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;
@@ -398,21 +398,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, &reg);
+	pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
 	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));
@@ -438,23 +470,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)
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/5] AMD L3 cache index disable fixes for .35
  2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
                   ` (4 preceding siblings ...)
  2010-04-15 16:41 ` [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches Borislav Petkov
@ 2010-04-21 20:43 ` Borislav Petkov
  5 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-21 20:43 UTC (permalink / raw)
  To: hpa; +Cc: mingo, tglx, x86, linux-kernel, Frank Arnold

From: Borislav Petkov <bp@amd64.org>
Date: Thu, Apr 15, 2010 at 06:40:58PM +0200

Ping.

It would be cool if we could sort out objections soon (in case there are
any, of course) so that the patches can have some -tip time before the
.35 merge window.

Thanks.

> From: Borislav Petkov <borislav.petkov@amd.com>
> 
> Hi,
> 
> this is a small patchset of fixes for L3 CID which have accumulated over
> the last couple of weeks. They serve as a preparation for disabling L3
> cache indices whenever an L3 MCE triggers, has been evaluated and the
> offending index thresholded and, if error rate is excessively high,
> disabled. Those patches will be coming up later though.
> 
> Patches 1,3,4 are cleanups and unifications which save us a little bit
> of percpu memory in favor of dynamic allocation. Also, we have an L3
> cache descriptor per node now instead of having this information per
> CPU.
> 
> I triggered a lockdep warning in lockdep_trace_alloc() during testing
> due to the fact that we may run with disabled interrupts that early
> in the boot process. Therefore, I have a GFP_ATOMIC in patch 3 there
> allocating the cache descriptors. I'm open for suggestions in case this
> is undesired.
> 
> Patch 2 is a fix which triggers when we run as a guest on Xen due to Xen
> not exporting CPU PCI config space to the guests.
> 
> And finally #5 is a required fix.
> 
> The patchset is also available at
> git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git l3-for-35
> 
> Please queue for .35,
> thanks.
> 

-- 
Regards/Gruss,
Boris.

--
Advanced Micro Devices, Inc.
Operating Systems Research Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node
  2010-04-15 16:41 ` [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node Borislav Petkov
@ 2010-04-21 20:46   ` H. Peter Anvin
  2010-04-21 21:05     ` Borislav Petkov
  0 siblings, 1 reply; 10+ messages in thread
From: H. Peter Anvin @ 2010-04-21 20:46 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: mingo, tglx, x86, linux-kernel, Frank Arnold, Borislav Petkov

On 04/15/2010 09:41 AM, Borislav Petkov wrote:
> +
> +/* max 8 nodes on a system */
> +static struct amd_l3_cache * __cpuinitdata l3_caches[8];
> +

This makes me very nervous.  Where does this limit come from?  It
appears completely arbitrary and seems like begging for problems in the
future.

	-hpa

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node
  2010-04-21 20:46   ` H. Peter Anvin
@ 2010-04-21 21:05     ` Borislav Petkov
  0 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-21 21:05 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: mingo, tglx, x86, linux-kernel, Frank Arnold

From: "H. Peter Anvin" <hpa@zytor.com>
Date: Wed, Apr 21, 2010 at 01:46:29PM -0700

> On 04/15/2010 09:41 AM, Borislav Petkov wrote:
> > +
> > +/* max 8 nodes on a system */
> > +static struct amd_l3_cache * __cpuinitdata l3_caches[8];
> > +
> 
> This makes me very nervous.  Where does this limit come from?  It
> appears completely arbitrary and seems like begging for problems in the
> future.

Right. So, we currently have a 3-bit field for the node id of each node,
in conjunction with the L3 cache this means one L3 cache per node. It is
located in F0x60[2:0]. This field is setup to the proper value by the
BIOS.

But yeah, I see your point. I could try initializing it dynamically
per system so that there are no out of bounds accesses. Let me cook up
something tomorrow.

-- 
Regards/Gruss,
Boris.

--
Advanced Micro Devices, Inc.
Operating Systems Research Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches
  2010-04-22 14:06 [PATCH -v2 " Borislav Petkov
@ 2010-04-22 14:07 ` Borislav Petkov
  0 siblings, 0 replies; 10+ messages in thread
From: Borislav Petkov @ 2010-04-22 14:07 UTC (permalink / raw)
  To: hpa, mingo, tglx; +Cc: x86, linux-kernel, Frank Arnold, Borislav Petkov

From: Borislav Petkov <borislav.petkov@amd.com>

When disabling an L3 cache index, make sure we disable that index in
all four subcaches of the L3. Clarify nomenclature while at it, wrt to
disable slots versus disable index and rename accordingly.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
---
 arch/x86/kernel/cpu/intel_cacheinfo.c |   60 +++++++++++++++++++++++---------
 1 files changed, 43 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 1346e9c..33eae20 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -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, &reg);
+	pci_read_config_dword(dev, 0x1BC + slot * 4, &reg);
 	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)
-- 
1.7.1.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-04-22 14:08 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-15 16:40 [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
2010-04-15 16:40 ` [PATCH 1/5] x86, cacheinfo: Unify AMD L3 cache index disable checking Borislav Petkov
2010-04-15 16:41 ` [PATCH 2/5] x86, cacheinfo: Turn off L3 cache index disable feature in virtualized environments Borislav Petkov
2010-04-15 16:41 ` [PATCH 3/5] x86, cacheinfo: Reorganize AMD L3 cache structure Borislav Petkov
2010-04-15 16:41 ` [PATCH 4/5] x86, cacheinfo: Make L3 cache info per node Borislav Petkov
2010-04-21 20:46   ` H. Peter Anvin
2010-04-21 21:05     ` Borislav Petkov
2010-04-15 16:41 ` [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches Borislav Petkov
2010-04-21 20:43 ` [PATCH 0/5] AMD L3 cache index disable fixes for .35 Borislav Petkov
2010-04-22 14:06 [PATCH -v2 " Borislav Petkov
2010-04-22 14:07 ` [PATCH 5/5] x86, cacheinfo: Disable index in all four subcaches Borislav Petkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.