]>
Commit | Line | Data |
---|---|---|
7381a876 GKH |
1 | From 048a8774ca43488d78605031f11cc206d7a2682a Mon Sep 17 00:00:00 2001 |
2 | From: Borislav Petkov <borislav.petkov@amd.com> | |
3 | Date: Fri, 22 Jan 2010 16:01:07 +0100 | |
4 | Subject: x86, cacheinfo: Calculate L3 indices | |
5 | ||
6 | From: Borislav Petkov <borislav.petkov@amd.com> | |
7 | ||
8 | commit 048a8774ca43488d78605031f11cc206d7a2682a upstream. | |
9 | ||
10 | We need to know the valid L3 indices interval when disabling them over | |
11 | /sysfs. Do that when the core is brought online and add boundary checks | |
12 | to the sysfs .store attribute. | |
13 | ||
14 | Signed-off-by: Borislav Petkov <borislav.petkov@amd.com> | |
15 | LKML-Reference: <1264172467-25155-6-git-send-email-bp@amd64.org> | |
16 | Signed-off-by: H. Peter Anvin <hpa@zytor.com> | |
17 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
18 | ||
19 | --- | |
20 | arch/x86/kernel/cpu/intel_cacheinfo.c | 35 ++++++++++++++++++++++++++++++---- | |
21 | 1 file changed, 31 insertions(+), 4 deletions(-) | |
22 | ||
23 | --- a/arch/x86/kernel/cpu/intel_cacheinfo.c | |
24 | +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |
25 | @@ -151,7 +151,8 @@ struct _cpuid4_info { | |
26 | union _cpuid4_leaf_ebx ebx; | |
27 | union _cpuid4_leaf_ecx ecx; | |
28 | unsigned long size; | |
29 | - unsigned long can_disable; | |
30 | + bool can_disable; | |
31 | + unsigned int l3_indices; | |
32 | DECLARE_BITMAP(shared_cpu_map, NR_CPUS); | |
33 | }; | |
34 | ||
35 | @@ -161,7 +162,8 @@ struct _cpuid4_info_regs { | |
36 | union _cpuid4_leaf_ebx ebx; | |
37 | union _cpuid4_leaf_ecx ecx; | |
38 | unsigned long size; | |
39 | - unsigned long can_disable; | |
40 | + bool can_disable; | |
41 | + unsigned int l3_indices; | |
42 | }; | |
43 | ||
44 | unsigned short num_cache_leaves; | |
45 | @@ -291,6 +293,29 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_ | |
46 | (ebx->split.ways_of_associativity + 1) - 1; | |
47 | } | |
48 | ||
49 | +static unsigned int __cpuinit amd_calc_l3_indices(void) | |
50 | +{ | |
51 | + /* | |
52 | + * We're called over smp_call_function_single() and therefore | |
53 | + * are on the correct cpu. | |
54 | + */ | |
55 | + int cpu = smp_processor_id(); | |
56 | + int node = cpu_to_node(cpu); | |
57 | + struct pci_dev *dev = node_to_k8_nb_misc(node); | |
58 | + unsigned int sc0, sc1, sc2, sc3; | |
59 | + u32 val; | |
60 | + | |
61 | + pci_read_config_dword(dev, 0x1C4, &val); | |
62 | + | |
63 | + /* calculate subcache sizes */ | |
64 | + sc0 = !(val & BIT(0)); | |
65 | + sc1 = !(val & BIT(4)); | |
66 | + sc2 = !(val & BIT(8)) + !(val & BIT(9)); | |
67 | + sc3 = !(val & BIT(12)) + !(val & BIT(13)); | |
68 | + | |
69 | + return (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1; | |
70 | +} | |
71 | + | |
72 | static void __cpuinit | |
73 | amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) | |
74 | { | |
75 | @@ -306,7 +331,8 @@ amd_check_l3_disable(int index, struct _ | |
76 | (boot_cpu_data.x86_mask < 0x1))) | |
77 | return; | |
78 | ||
79 | - this_leaf->can_disable = 1; | |
80 | + this_leaf->can_disable = true; | |
81 | + this_leaf->l3_indices = amd_calc_l3_indices(); | |
82 | } | |
83 | ||
84 | static int | |
85 | @@ -780,7 +806,8 @@ static ssize_t store_cache_disable(struc | |
86 | return -EINVAL; | |
87 | ||
88 | /* do not allow writes outside of allowed bits */ | |
89 | - if (val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) | |
90 | + if ((val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) || | |
91 | + ((val & SUBCACHE_INDEX) > this_leaf->l3_indices)) | |
92 | return -EINVAL; | |
93 | ||
94 | val |= BIT(30); |