diff options
| -rw-r--r-- | 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 1346e9c23fc4..33eae2062cf5 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) | |||
| 397 | } | 397 | } |
| 398 | 398 | ||
| 399 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, | 399 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, |
| 400 | unsigned int index) | 400 | unsigned int slot) |
| 401 | { | 401 | { |
| 402 | struct pci_dev *dev = this_leaf->l3->dev; | 402 | struct pci_dev *dev = this_leaf->l3->dev; |
| 403 | unsigned int reg = 0; | 403 | unsigned int reg = 0; |
| @@ -408,21 +408,53 @@ static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf, | |||
| 408 | if (!dev) | 408 | if (!dev) |
| 409 | return -EINVAL; | 409 | return -EINVAL; |
| 410 | 410 | ||
| 411 | pci_read_config_dword(dev, 0x1BC + index * 4, ®); | 411 | pci_read_config_dword(dev, 0x1BC + slot * 4, ®); |
| 412 | return sprintf(buf, "0x%08x\n", reg); | 412 | return sprintf(buf, "0x%08x\n", reg); |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | #define SHOW_CACHE_DISABLE(index) \ | 415 | #define SHOW_CACHE_DISABLE(slot) \ |
| 416 | static ssize_t \ | 416 | static ssize_t \ |
| 417 | show_cache_disable_##index(struct _cpuid4_info *this_leaf, char *buf) \ | 417 | show_cache_disable_##slot(struct _cpuid4_info *this_leaf, char *buf) \ |
| 418 | { \ | 418 | { \ |
| 419 | return show_cache_disable(this_leaf, buf, index); \ | 419 | return show_cache_disable(this_leaf, buf, slot); \ |
| 420 | } | 420 | } |
| 421 | SHOW_CACHE_DISABLE(0) | 421 | SHOW_CACHE_DISABLE(0) |
| 422 | SHOW_CACHE_DISABLE(1) | 422 | SHOW_CACHE_DISABLE(1) |
| 423 | 423 | ||
| 424 | static void amd_l3_disable_index(struct amd_l3_cache *l3, int cpu, | ||
| 425 | unsigned slot, unsigned long idx) | ||
| 426 | { | ||
| 427 | int i; | ||
| 428 | |||
| 429 | idx |= BIT(30); | ||
| 430 | |||
| 431 | /* | ||
| 432 | * disable index in all 4 subcaches | ||
| 433 | */ | ||
| 434 | for (i = 0; i < 4; i++) { | ||
| 435 | u32 reg = idx | (i << 20); | ||
| 436 | |||
| 437 | if (!l3->subcaches[i]) | ||
| 438 | continue; | ||
| 439 | |||
| 440 | pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg); | ||
| 441 | |||
| 442 | /* | ||
| 443 | * We need to WBINVD on a core on the node containing the L3 | ||
| 444 | * cache which indices we disable therefore a simple wbinvd() | ||
| 445 | * is not sufficient. | ||
| 446 | */ | ||
| 447 | wbinvd_on_cpu(cpu); | ||
| 448 | |||
| 449 | reg |= BIT(31); | ||
| 450 | pci_write_config_dword(l3->dev, 0x1BC + slot * 4, reg); | ||
| 451 | } | ||
| 452 | } | ||
| 453 | |||
| 454 | |||
| 424 | static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, | 455 | static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, |
| 425 | const char *buf, size_t count, unsigned int index) | 456 | const char *buf, size_t count, |
| 457 | unsigned int slot) | ||
| 426 | { | 458 | { |
| 427 | struct pci_dev *dev = this_leaf->l3->dev; | 459 | struct pci_dev *dev = this_leaf->l3->dev; |
| 428 | int cpu = cpumask_first(to_cpumask(this_leaf->shared_cpu_map)); | 460 | 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, | |||
| 448 | ((val & SUBCACHE_INDEX) > this_leaf->l3->indices)) | 480 | ((val & SUBCACHE_INDEX) > this_leaf->l3->indices)) |
| 449 | return -EINVAL; | 481 | return -EINVAL; |
| 450 | 482 | ||
| 451 | val |= BIT(30); | 483 | amd_l3_disable_index(this_leaf->l3, cpu, slot, val); |
| 452 | pci_write_config_dword(dev, 0x1BC + index * 4, val); | 484 | |
| 453 | /* | ||
| 454 | * We need to WBINVD on a core on the node containing the L3 cache which | ||
| 455 | * indices we disable therefore a simple wbinvd() is not sufficient. | ||
| 456 | */ | ||
| 457 | wbinvd_on_cpu(cpu); | ||
| 458 | pci_write_config_dword(dev, 0x1BC + index * 4, val | BIT(31)); | ||
| 459 | return count; | 485 | return count; |
| 460 | } | 486 | } |
| 461 | 487 | ||
| 462 | #define STORE_CACHE_DISABLE(index) \ | 488 | #define STORE_CACHE_DISABLE(slot) \ |
| 463 | static ssize_t \ | 489 | static ssize_t \ |
| 464 | store_cache_disable_##index(struct _cpuid4_info *this_leaf, \ | 490 | store_cache_disable_##slot(struct _cpuid4_info *this_leaf, \ |
| 465 | const char *buf, size_t count) \ | 491 | const char *buf, size_t count) \ |
| 466 | { \ | 492 | { \ |
| 467 | return store_cache_disable(this_leaf, buf, count, index); \ | 493 | return store_cache_disable(this_leaf, buf, count, slot); \ |
| 468 | } | 494 | } |
| 469 | STORE_CACHE_DISABLE(0) | 495 | STORE_CACHE_DISABLE(0) |
| 470 | STORE_CACHE_DISABLE(1) | 496 | STORE_CACHE_DISABLE(1) |
