hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/acpi/pptt.c
....@@ -98,11 +98,11 @@
9898 *
9999 * Return: The cache structure and the level we terminated with.
100100 */
101
-static int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
102
- int local_level,
103
- struct acpi_subtable_header *res,
104
- struct acpi_pptt_cache **found,
105
- int level, int type)
101
+static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr,
102
+ unsigned int local_level,
103
+ struct acpi_subtable_header *res,
104
+ struct acpi_pptt_cache **found,
105
+ unsigned int level, int type)
106106 {
107107 struct acpi_pptt_cache *cache;
108108
....@@ -119,7 +119,7 @@
119119 if (*found != NULL && cache != *found)
120120 pr_warn("Found duplicate cache level/type unable to determine uniqueness\n");
121121
122
- pr_debug("Found cache @ level %d\n", level);
122
+ pr_debug("Found cache @ level %u\n", level);
123123 *found = cache;
124124 /*
125125 * continue looking at this node's resource list
....@@ -132,16 +132,17 @@
132132 return local_level;
133133 }
134134
135
-static struct acpi_pptt_cache *acpi_find_cache_level(struct acpi_table_header *table_hdr,
136
- struct acpi_pptt_processor *cpu_node,
137
- int *starting_level, int level,
138
- int type)
135
+static struct acpi_pptt_cache *
136
+acpi_find_cache_level(struct acpi_table_header *table_hdr,
137
+ struct acpi_pptt_processor *cpu_node,
138
+ unsigned int *starting_level, unsigned int level,
139
+ int type)
139140 {
140141 struct acpi_subtable_header *res;
141
- int number_of_levels = *starting_level;
142
+ unsigned int number_of_levels = *starting_level;
142143 int resource = 0;
143144 struct acpi_pptt_cache *ret = NULL;
144
- int local_level;
145
+ unsigned int local_level;
145146
146147 /* walk down from processor node */
147148 while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) {
....@@ -164,7 +165,7 @@
164165 }
165166
166167 /**
167
- * acpi_count_levels() - Given a PPTT table, and a cpu node, count the caches
168
+ * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches
168169 * @table_hdr: Pointer to the head of the PPTT table
169170 * @cpu_node: processor node we wish to count caches for
170171 *
....@@ -209,6 +210,9 @@
209210 struct acpi_pptt_processor *cpu_node;
210211 u32 proc_sz;
211212
213
+ if (table_hdr->revision > 1)
214
+ return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE);
215
+
212216 table_end = (unsigned long)table_hdr + table_hdr->length;
213217 node_entry = ACPI_PTR_DIFF(node, table_hdr);
214218 entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr,
....@@ -232,7 +236,7 @@
232236 /**
233237 * acpi_find_processor_node() - Given a PPTT table find the requested processor
234238 * @table_hdr: Pointer to the head of the PPTT table
235
- * @acpi_cpu_id: cpu we are searching for
239
+ * @acpi_cpu_id: CPU we are searching for
236240 *
237241 * Find the subtable entry describing the provided processor.
238242 * This is done by iterating the PPTT table looking for processor nodes
....@@ -318,12 +322,12 @@
318322 unsigned int level,
319323 struct acpi_pptt_processor **node)
320324 {
321
- int total_levels = 0;
325
+ unsigned int total_levels = 0;
322326 struct acpi_pptt_cache *found = NULL;
323327 struct acpi_pptt_processor *cpu_node;
324328 u8 acpi_type = acpi_cache_type(type);
325329
326
- pr_debug("Looking for CPU %d's level %d cache type %d\n",
330
+ pr_debug("Looking for CPU %d's level %u cache type %d\n",
327331 acpi_cpu_id, level, acpi_type);
328332
329333 cpu_node = acpi_find_processor_node(table_hdr, acpi_cpu_id);
....@@ -429,17 +433,40 @@
429433 }
430434 }
431435
436
+static bool flag_identical(struct acpi_table_header *table_hdr,
437
+ struct acpi_pptt_processor *cpu)
438
+{
439
+ struct acpi_pptt_processor *next;
440
+
441
+ /* heterogeneous machines must use PPTT revision > 1 */
442
+ if (table_hdr->revision < 2)
443
+ return false;
444
+
445
+ /* Locate the last node in the tree with IDENTICAL set */
446
+ if (cpu->flags & ACPI_PPTT_ACPI_IDENTICAL) {
447
+ next = fetch_pptt_node(table_hdr, cpu->parent);
448
+ if (!(next && next->flags & ACPI_PPTT_ACPI_IDENTICAL))
449
+ return true;
450
+ }
451
+
452
+ return false;
453
+}
454
+
432455 /* Passing level values greater than this will result in search termination */
433456 #define PPTT_ABORT_PACKAGE 0xFF
434457
435
-static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_table_header *table_hdr,
436
- struct acpi_pptt_processor *cpu,
437
- int level, int flag)
458
+static struct acpi_pptt_processor *acpi_find_processor_tag(struct acpi_table_header *table_hdr,
459
+ struct acpi_pptt_processor *cpu,
460
+ int level, int flag)
438461 {
439462 struct acpi_pptt_processor *prev_node;
440463
441464 while (cpu && level) {
442
- if (cpu->flags & flag)
465
+ /* special case the identical flag to find last identical */
466
+ if (flag == ACPI_PPTT_ACPI_IDENTICAL) {
467
+ if (flag_identical(table_hdr, cpu))
468
+ break;
469
+ } else if (cpu->flags & flag)
443470 break;
444471 pr_debug("level %d\n", level);
445472 prev_node = fetch_pptt_node(table_hdr, cpu->parent);
....@@ -451,18 +478,23 @@
451478 return cpu;
452479 }
453480
481
+static void acpi_pptt_warn_missing(void)
482
+{
483
+ pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n");
484
+}
485
+
454486 /**
455487 * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature
456488 * @table: Pointer to the head of the PPTT table
457
- * @cpu: Kernel logical cpu number
489
+ * @cpu: Kernel logical CPU number
458490 * @level: A level that terminates the search
459491 * @flag: A flag which terminates the search
460492 *
461
- * Get a unique value given a cpu, and a topology level, that can be
493
+ * Get a unique value given a CPU, and a topology level, that can be
462494 * matched to determine which cpus share common topological features
463495 * at that level.
464496 *
465
- * Return: Unique value, or -ENOENT if unable to locate cpu
497
+ * Return: Unique value, or -ENOENT if unable to locate CPU
466498 */
467499 static int topology_get_acpi_cpu_tag(struct acpi_table_header *table,
468500 unsigned int cpu, int level, int flag)
....@@ -472,8 +504,8 @@
472504
473505 cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
474506 if (cpu_node) {
475
- cpu_node = acpi_find_processor_package_id(table, cpu_node,
476
- level, flag);
507
+ cpu_node = acpi_find_processor_tag(table, cpu_node,
508
+ level, flag);
477509 /*
478510 * As per specification if the processor structure represents
479511 * an actual processor, then ACPI processor ID must be valid.
....@@ -498,11 +530,11 @@
498530
499531 status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
500532 if (ACPI_FAILURE(status)) {
501
- pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n");
533
+ acpi_pptt_warn_missing();
502534 return -ENOENT;
503535 }
504536 retval = topology_get_acpi_cpu_tag(table, cpu, level, flag);
505
- pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n",
537
+ pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n",
506538 cpu, level, retval);
507539 acpi_put_table(table);
508540
....@@ -532,7 +564,7 @@
532564
533565 status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
534566 if (ACPI_FAILURE(status)) {
535
- pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n");
567
+ acpi_pptt_warn_missing();
536568 return ret;
537569 }
538570
....@@ -549,9 +581,9 @@
549581
550582 /**
551583 * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
552
- * @cpu: Kernel logical cpu number
584
+ * @cpu: Kernel logical CPU number
553585 *
554
- * Given a logical cpu number, returns the number of levels of cache represented
586
+ * Given a logical CPU number, returns the number of levels of cache represented
555587 * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0
556588 * indicating we didn't find any cache levels.
557589 *
....@@ -564,12 +596,12 @@
564596 int number_of_levels = 0;
565597 acpi_status status;
566598
567
- pr_debug("Cache Setup find last level cpu=%d\n", cpu);
599
+ pr_debug("Cache Setup find last level CPU=%d\n", cpu);
568600
569601 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
570602 status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
571603 if (ACPI_FAILURE(status)) {
572
- pr_warn_once("No PPTT table found, cache topology may be inaccurate\n");
604
+ acpi_pptt_warn_missing();
573605 } else {
574606 number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id);
575607 acpi_put_table(table);
....@@ -581,14 +613,14 @@
581613
582614 /**
583615 * cache_setup_acpi() - Override CPU cache topology with data from the PPTT
584
- * @cpu: Kernel logical cpu number
616
+ * @cpu: Kernel logical CPU number
585617 *
586618 * Updates the global cache info provided by cpu_get_cacheinfo()
587619 * when there are valid properties in the acpi_pptt_cache nodes. A
588620 * successful parse may not result in any updates if none of the
589
- * cache levels have any valid flags set. Futher, a unique value is
621
+ * cache levels have any valid flags set. Further, a unique value is
590622 * associated with each known CPU cache entry. This unique value
591
- * can be used to determine whether caches are shared between cpus.
623
+ * can be used to determine whether caches are shared between CPUs.
592624 *
593625 * Return: -ENOENT on failure to find table, or 0 on success
594626 */
....@@ -597,11 +629,11 @@
597629 struct acpi_table_header *table;
598630 acpi_status status;
599631
600
- pr_debug("Cache Setup ACPI cpu %d\n", cpu);
632
+ pr_debug("Cache Setup ACPI CPU %d\n", cpu);
601633
602634 status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
603635 if (ACPI_FAILURE(status)) {
604
- pr_warn_once("No PPTT table found, cache topology may be inaccurate\n");
636
+ acpi_pptt_warn_missing();
605637 return -ENOENT;
606638 }
607639
....@@ -626,8 +658,8 @@
626658 }
627659
628660 /**
629
- * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu
630
- * @cpu: Kernel logical cpu number
661
+ * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU
662
+ * @cpu: Kernel logical CPU number
631663 * @level: The topological level for which we would like a unique ID
632664 *
633665 * Determine a topology unique ID for each thread/core/cluster/mc_grouping
....@@ -640,7 +672,7 @@
640672 * other levels beyond this use a generated value to uniquely identify
641673 * a topological feature.
642674 *
643
- * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
675
+ * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
644676 * Otherwise returns a value which represents a unique topological feature.
645677 */
646678 int find_acpi_cpu_topology(unsigned int cpu, int level)
....@@ -650,12 +682,12 @@
650682
651683 /**
652684 * find_acpi_cpu_cache_topology() - Determine a unique cache topology value
653
- * @cpu: Kernel logical cpu number
685
+ * @cpu: Kernel logical CPU number
654686 * @level: The cache level for which we would like a unique ID
655687 *
656688 * Determine a unique ID for each unified cache in the system
657689 *
658
- * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
690
+ * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
659691 * Otherwise returns a value which represents a unique topological feature.
660692 */
661693 int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
....@@ -669,7 +701,7 @@
669701
670702 status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
671703 if (ACPI_FAILURE(status)) {
672
- pr_warn_once("No PPTT table found, topology may be inaccurate\n");
704
+ acpi_pptt_warn_missing();
673705 return -ENOENT;
674706 }
675707
....@@ -685,22 +717,47 @@
685717 return ret;
686718 }
687719
688
-
689720 /**
690
- * find_acpi_cpu_topology_package() - Determine a unique cpu package value
691
- * @cpu: Kernel logical cpu number
721
+ * find_acpi_cpu_topology_package() - Determine a unique CPU package value
722
+ * @cpu: Kernel logical CPU number
692723 *
693
- * Determine a topology unique package ID for the given cpu.
724
+ * Determine a topology unique package ID for the given CPU.
694725 * This ID can then be used to group peers, which will have matching ids.
695726 *
696727 * The search terminates when either a level is found with the PHYSICAL_PACKAGE
697728 * flag set or we reach a root node.
698729 *
699
- * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found.
700
- * Otherwise returns a value which represents the package for this cpu.
730
+ * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
731
+ * Otherwise returns a value which represents the package for this CPU.
701732 */
702733 int find_acpi_cpu_topology_package(unsigned int cpu)
703734 {
704735 return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
705736 ACPI_PPTT_PHYSICAL_PACKAGE);
706737 }
738
+
739
+/**
740
+ * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag
741
+ * @cpu: Kernel logical CPU number
742
+ *
743
+ * Determine a unique heterogeneous tag for the given CPU. CPUs with the same
744
+ * implementation should have matching tags.
745
+ *
746
+ * The returned tag can be used to group peers with identical implementation.
747
+ *
748
+ * The search terminates when a level is found with the identical implementation
749
+ * flag set or we reach a root node.
750
+ *
751
+ * Due to limitations in the PPTT data structure, there may be rare situations
752
+ * where two cores in a heterogeneous machine may be identical, but won't have
753
+ * the same tag.
754
+ *
755
+ * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found.
756
+ * Otherwise returns a value which represents a group of identical cores
757
+ * similar to this CPU.
758
+ */
759
+int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
760
+{
761
+ return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE,
762
+ ACPI_PPTT_ACPI_IDENTICAL);
763
+}