diff options
| -rw-r--r-- | arch/x86/kernel/cpu/intel_cacheinfo.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index fc6c8ef92dcc..08c91abc4d32 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <asm/processor.h> | 18 | #include <asm/processor.h> |
| 19 | #include <linux/smp.h> | 19 | #include <linux/smp.h> |
| 20 | #include <asm/k8.h> | 20 | #include <asm/k8.h> |
| 21 | #include <asm/smp.h> | ||
| 21 | 22 | ||
| 22 | #define LVL_1_INST 1 | 23 | #define LVL_1_INST 1 |
| 23 | #define LVL_1_DATA 2 | 24 | #define LVL_1_DATA 2 |
| @@ -299,8 +300,10 @@ amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) | |||
| 299 | if (boot_cpu_data.x86 == 0x11) | 300 | if (boot_cpu_data.x86 == 0x11) |
| 300 | return; | 301 | return; |
| 301 | 302 | ||
| 302 | /* see erratum #382 */ | 303 | /* see errata #382 and #388 */ |
| 303 | if ((boot_cpu_data.x86 == 0x10) && (boot_cpu_data.x86_model < 0x8)) | 304 | if ((boot_cpu_data.x86 == 0x10) && |
| 305 | ((boot_cpu_data.x86_model < 0x9) || | ||
| 306 | (boot_cpu_data.x86_mask < 0x1))) | ||
| 304 | return; | 307 | return; |
| 305 | 308 | ||
| 306 | this_leaf->can_disable = 1; | 309 | this_leaf->can_disable = 1; |
| @@ -726,12 +729,12 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, | |||
| 726 | return -EINVAL; | 729 | return -EINVAL; |
| 727 | 730 | ||
| 728 | pci_read_config_dword(dev, 0x1BC + index * 4, ®); | 731 | pci_read_config_dword(dev, 0x1BC + index * 4, ®); |
| 729 | return sprintf(buf, "%x\n", reg); | 732 | return sprintf(buf, "0x%08x\n", reg); |
| 730 | } | 733 | } |
| 731 | 734 | ||
| 732 | #define SHOW_CACHE_DISABLE(index) \ | 735 | #define SHOW_CACHE_DISABLE(index) \ |
| 733 | static ssize_t \ | 736 | static ssize_t \ |
| 734 | show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ | 737 | show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ |
| 735 | { \ | 738 | { \ |
| 736 | return show_cache_disable(this_leaf, buf, index); \ | 739 | return show_cache_disable(this_leaf, buf, index); \ |
| 737 | } | 740 | } |
| @@ -745,7 +748,9 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, | |||
| 745 | int node = cpu_to_node(cpu); | 748 | int node = cpu_to_node(cpu); |
| 746 | struct pci_dev *dev = node_to_k8_nb_misc(node); | 749 | struct pci_dev *dev = node_to_k8_nb_misc(node); |
| 747 | unsigned long val = 0; | 750 | unsigned long val = 0; |
| 748 | unsigned int scrubber = 0; | 751 | |
| 752 | #define SUBCACHE_MASK (3UL << 20) | ||
| 753 | #define SUBCACHE_INDEX 0xfff | ||
| 749 | 754 | ||
| 750 | if (!this_leaf->can_disable) | 755 | if (!this_leaf->can_disable) |
| 751 | return -EINVAL; | 756 | return -EINVAL; |
| @@ -759,21 +764,24 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, | |||
| 759 | if (strict_strtoul(buf, 10, &val) < 0) | 764 | if (strict_strtoul(buf, 10, &val) < 0) |
| 760 | return -EINVAL; | 765 | return -EINVAL; |
| 761 | 766 | ||
| 762 | val |= 0xc0000000; | 767 | /* do not allow writes outside of allowed bits */ |
| 763 | 768 | if (val & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) | |
| 764 | pci_read_config_dword(dev, 0x58, &scrubber); | 769 | return -EINVAL; |
| 765 | scrubber &= ~0x1f000000; | ||
| 766 | pci_write_config_dword(dev, 0x58, scrubber); | ||
| 767 | 770 | ||
| 768 | pci_write_config_dword(dev, 0x1BC + index * 4, val & ~0x40000000); | 771 | val |= BIT(30); |
| 769 | wbinvd(); | ||
| 770 | pci_write_config_dword(dev, 0x1BC + index * 4, val); | 772 | pci_write_config_dword(dev, 0x1BC + index * 4, val); |
| 773 | /* | ||
| 774 | * We need to WBINVD on a core on the node containing the L3 cache which | ||
| 775 | * indices we disable therefore a simple wbinvd() is not sufficient. | ||
| 776 | */ | ||
| 777 | wbinvd_on_cpu(cpu); | ||
| 778 | pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31)); | ||
| 771 | return count; | 779 | return count; |
| 772 | } | 780 | } |
| 773 | 781 | ||
| 774 | #define STORE_CACHE_DISABLE(index) \ | 782 | #define STORE_CACHE_DISABLE(index) \ |
| 775 | static ssize_t \ | 783 | static ssize_t \ |
| 776 | store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ | 784 | store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ |
| 777 | const char *buf, size_t count) \ | 785 | const char *buf, size_t count) \ |
| 778 | { \ | 786 | { \ |
| 779 | return store_cache_disable(this_leaf, buf, count, index); \ | 787 | return store_cache_disable(this_leaf, buf, count, index); \ |
