diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2013-12-23 07:16:58 -0500 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2014-01-03 17:35:42 -0500 |
commit | dd360393f4d948eb518372316e52101cf3b44212 (patch) | |
tree | 7b664120f6ea4de3adb75acc9d05fbf15356f1cc /arch/x86/kernel/cpu | |
parent | 802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff) |
x86, cpu: Detect more TLB configuration
The Intel Software Developer’s Manual covers few more TLB
configurations exposed as CPUID 2 descriptors:
61H Instruction TLB: 4 KByte pages, fully associative, 48 entries
63H Data TLB: 1 GByte pages, 4-way set associative, 4 entries
76H Instruction TLB: 2M/4M pages, fully associative, 8 entries
B5H Instruction TLB: 4KByte pages, 8-way set associative, 64 entries
B6H Instruction TLB: 4KByte pages, 8-way set associative, 128 entries
C1H Shared 2nd-Level TLB: 4 KByte/2MByte pages, 8-way associative, 1024 entries
C2H DTLB DTLB: 2 MByte/$MByte pages, 4-way associative, 16 entries
Let's detect them as well.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Link: http://lkml.kernel.org/r/1387801018-14499-1-git-send-email-kirill.shutemov@linux.intel.com
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 26 |
2 files changed, 30 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6abc172b8258..24b6fd10625a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -472,6 +472,7 @@ u16 __read_mostly tlb_lli_4m[NR_INFO]; | |||
472 | u16 __read_mostly tlb_lld_4k[NR_INFO]; | 472 | u16 __read_mostly tlb_lld_4k[NR_INFO]; |
473 | u16 __read_mostly tlb_lld_2m[NR_INFO]; | 473 | u16 __read_mostly tlb_lld_2m[NR_INFO]; |
474 | u16 __read_mostly tlb_lld_4m[NR_INFO]; | 474 | u16 __read_mostly tlb_lld_4m[NR_INFO]; |
475 | u16 __read_mostly tlb_lld_1g[NR_INFO]; | ||
475 | 476 | ||
476 | /* | 477 | /* |
477 | * tlb_flushall_shift shows the balance point in replacing cr3 write | 478 | * tlb_flushall_shift shows the balance point in replacing cr3 write |
@@ -486,13 +487,13 @@ void cpu_detect_tlb(struct cpuinfo_x86 *c) | |||
486 | if (this_cpu->c_detect_tlb) | 487 | if (this_cpu->c_detect_tlb) |
487 | this_cpu->c_detect_tlb(c); | 488 | this_cpu->c_detect_tlb(c); |
488 | 489 | ||
489 | printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | 490 | printk(KERN_INFO "Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n" |
490 | "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d\n" \ | 491 | "Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d, 1GB %d\n" |
491 | "tlb_flushall_shift: %d\n", | 492 | "tlb_flushall_shift: %d\n", |
492 | tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], | 493 | tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES], |
493 | tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], | 494 | tlb_lli_4m[ENTRIES], tlb_lld_4k[ENTRIES], |
494 | tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], | 495 | tlb_lld_2m[ENTRIES], tlb_lld_4m[ENTRIES], |
495 | tlb_flushall_shift); | 496 | tlb_lld_1g[ENTRIES], tlb_flushall_shift); |
496 | } | 497 | } |
497 | 498 | ||
498 | void detect_ht(struct cpuinfo_x86 *c) | 499 | void detect_ht(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index ea04b342c026..5eb7ea5fae15 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -506,6 +506,7 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
506 | #define TLB_DATA0_2M_4M 0x23 | 506 | #define TLB_DATA0_2M_4M 0x23 |
507 | 507 | ||
508 | #define STLB_4K 0x41 | 508 | #define STLB_4K 0x41 |
509 | #define STLB_4K_2M 0x42 | ||
509 | 510 | ||
510 | static const struct _tlb_table intel_tlb_table[] = { | 511 | static const struct _tlb_table intel_tlb_table[] = { |
511 | { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, | 512 | { 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" }, |
@@ -526,13 +527,20 @@ static const struct _tlb_table intel_tlb_table[] = { | |||
526 | { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, | 527 | { 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" }, |
527 | { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, | 528 | { 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" }, |
528 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, | 529 | { 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" }, |
530 | { 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" }, | ||
531 | { 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" }, | ||
532 | { 0x76, TLB_INST_2M_4M, 8, " TLB_INST 2-MByte or 4-MByte pages, fully associative" }, | ||
529 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, | 533 | { 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" }, |
530 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, | 534 | { 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" }, |
531 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, | 535 | { 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" }, |
532 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, | 536 | { 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" }, |
533 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, | 537 | { 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" }, |
538 | { 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | ||
539 | { 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set ssociative" }, | ||
534 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, | 540 | { 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" }, |
535 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, | 541 | { 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" }, |
542 | { 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" }, | ||
543 | { 0xc2, TLB_DATA_2M_4M, 16, " DTLB 2 MByte/4MByte pages, 4-way associative" }, | ||
536 | { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, | 544 | { 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" }, |
537 | { 0x00, 0, 0 } | 545 | { 0x00, 0, 0 } |
538 | }; | 546 | }; |
@@ -558,6 +566,20 @@ static void intel_tlb_lookup(const unsigned char desc) | |||
558 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | 566 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) |
559 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | 567 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; |
560 | break; | 568 | break; |
569 | case STLB_4K_2M: | ||
570 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
571 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
572 | if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries) | ||
573 | tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries; | ||
574 | if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
575 | tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
576 | if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries) | ||
577 | tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries; | ||
578 | if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
579 | tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
580 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | ||
581 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | ||
582 | break; | ||
561 | case TLB_INST_ALL: | 583 | case TLB_INST_ALL: |
562 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) | 584 | if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries) |
563 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; | 585 | tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries; |
@@ -603,6 +625,10 @@ static void intel_tlb_lookup(const unsigned char desc) | |||
603 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) | 625 | if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries) |
604 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; | 626 | tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries; |
605 | break; | 627 | break; |
628 | case TLB_DATA_1G: | ||
629 | if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries) | ||
630 | tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries; | ||
631 | break; | ||
606 | } | 632 | } |
607 | } | 633 | } |
608 | 634 | ||