arm64: cpuinfo: print info for all CPUs
authorMark Rutland <mark.rutland@arm.com>
Fri, 18 Jul 2014 13:57:38 +0000 (14:57 +0100)
committerWill Deacon <will.deacon@arm.com>
Fri, 18 Jul 2014 17:33:23 +0000 (18:33 +0100)
Currently reading /proc/cpuinfo will result in information being read
out of the MIDR_EL1 of the current CPU, and the information is not
associated with any particular logical CPU number.

This is problematic for systems with heterogeneous CPUs (i.e.
big.LITTLE) where MIDR fields will vary across CPUs, and the output will
differ depending on the executing CPU.

This patch reorganises the code responsible for /proc/cpuinfo to print
information per-cpu. In the process, we perform several cleanups:

* Property names are coerced to lower-case (to match "processor" as per
  glibc's expectations).
* Property names are simplified and made to match the MIDR field names.
* Revision is changed to hex as with every other field.
* The meaningless Architecture property is removed.
* The ripe-for-abuse Machine field is removed.

The features field (a human-readable representation of the hwcaps)
remains printed once, as this is expected to remain in use as the
globally support CPU features. To enable the possibility of the addition
of per-cpu HW feature information later, this is printed before any
CPU-specific information.

Comments are added to guide userspace developers in the right direction
(using the hwcaps provided in auxval). Hopefully where userspace
applications parse /proc/cpuinfo rather than using the readily available
hwcaps, they limit themselves to reading said first line.

If CPU features differ from each other, the previously installed sanity
checks will give us some advance notice with warnings and
TAINT_CPU_OUT_OF_SPEC. If we are lucky, we will never see such systems.
Rework will be required in many places to support such systems anyway.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Marcus Shawcroft <marcus.shawcroft@arm.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
[catalin.marinas@arm.com: remove machine_name as it is no longer reported]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/kernel/setup.c

index edb146d0185740b18de7d7cd365ae5d01ea1cbdc..f6f0ccf35ae67110c030d72c6c7648e04168c6e9 100644 (file)
@@ -78,7 +78,6 @@ unsigned int compat_elf_hwcap2 __read_mostly;
 #endif
 
 static const char *cpu_name;
-static const char *machine_name;
 phys_addr_t __fdt_pointer __initdata;
 
 /*
@@ -310,8 +309,6 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
                while (true)
                        cpu_relax();
        }
-
-       machine_name = of_flat_dt_get_machine_name();
 }
 
 /*
@@ -450,10 +447,21 @@ static int c_show(struct seq_file *m, void *v)
 {
        int i;
 
-       seq_printf(m, "Processor\t: %s rev %d (%s)\n",
-                  cpu_name, read_cpuid_id() & 15, ELF_PLATFORM);
+       /*
+        * Dump out the common processor features in a single line. Userspace
+        * should read the hwcaps with getauxval(AT_HWCAP) rather than
+        * attempting to parse this.
+        */
+       seq_puts(m, "features\t:");
+       for (i = 0; hwcap_str[i]; i++)
+               if (elf_hwcap & (1 << i))
+                       seq_printf(m, " %s", hwcap_str[i]);
+       seq_puts(m, "\n\n");
 
        for_each_online_cpu(i) {
+               struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+               u32 midr = cpuinfo->reg_midr;
+
                /*
                 * glibc reads /proc/cpuinfo to determine the number of
                 * online processors, looking for lines beginning with
@@ -462,25 +470,13 @@ static int c_show(struct seq_file *m, void *v)
 #ifdef CONFIG_SMP
                seq_printf(m, "processor\t: %d\n", i);
 #endif
+               seq_printf(m, "implementer\t: 0x%02x\n",
+                          MIDR_IMPLEMENTOR(midr));
+               seq_printf(m, "variant\t\t: 0x%x\n", MIDR_VARIANT(midr));
+               seq_printf(m, "partnum\t\t: 0x%03x\n", MIDR_PARTNUM(midr));
+               seq_printf(m, "revision\t: 0x%x\n\n", MIDR_REVISION(midr));
        }
 
-       /* dump out the processor features */
-       seq_puts(m, "Features\t: ");
-
-       for (i = 0; hwcap_str[i]; i++)
-               if (elf_hwcap & (1 << i))
-                       seq_printf(m, "%s ", hwcap_str[i]);
-
-       seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
-       seq_printf(m, "CPU architecture: AArch64\n");
-       seq_printf(m, "CPU variant\t: 0x%x\n", (read_cpuid_id() >> 20) & 15);
-       seq_printf(m, "CPU part\t: 0x%03x\n", (read_cpuid_id() >> 4) & 0xfff);
-       seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
-
-       seq_puts(m, "\n");
-
-       seq_printf(m, "Hardware\t: %s\n", machine_name);
-
        return 0;
 }