aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2022-05-24 19:16:37 +1000
committerReza Arbab <arbab@linux.ibm.com>2022-06-13 09:57:42 -0500
commit2ab647c894e8525a94c7837db2df91afacb65951 (patch)
treec497748ec7766bdf4a15a9272935d4dfd71e9911 /core
parent5133e1efc9470781fb5ccf553460ecb8b3dccbc7 (diff)
downloadskiboot-2ab647c894e8525a94c7837db2df91afacb65951.zip
skiboot-2ab647c894e8525a94c7837db2df91afacb65951.tar.gz
skiboot-2ab647c894e8525a94c7837db2df91afacb65951.tar.bz2
core: detect LPAR-per-core mode and report in dt
Some firmware configurations boot in LPAR-per-core mode, which is not compatible with KVM on POWER9 and later machines. Detect which LPAR mode the boot core is in (all others will be set the same way), and if booted in LPAR-per-core mode then print a warning and add a device-tree entry that the OS can test for. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/init.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/core/init.c b/core/init.c
index a1fd5f2..005ecf3 100644
--- a/core/init.c
+++ b/core/init.c
@@ -48,6 +48,7 @@
#include <debug_descriptor.h>
#include <occ.h>
#include <opal-dump.h>
+#include <xscom-p9-regs.h>
#include <xscom-p10-regs.h>
enum proc_gen proc_gen;
@@ -1026,6 +1027,40 @@ static void mask_pc_system_xstop(void)
}
}
+bool lpar_per_core = false;
+
+static void probe_lpar_per_core(void)
+{
+ struct cpu_thread *cpu = this_cpu();
+ uint32_t chip_id = pir_to_chip_id(cpu->pir);
+ uint32_t core_id = pir_to_core_id(cpu->pir);
+ uint64_t addr;
+ uint64_t core_thread_state;
+ int rc;
+
+ if (chip_quirk(QUIRK_MAMBO_CALLOUTS) || chip_quirk(QUIRK_AWAN))
+ return;
+
+ if (proc_gen == proc_gen_p9)
+ addr = XSCOM_ADDR_P9_EC(core_id, P9_CORE_THREAD_STATE);
+ else if (proc_gen == proc_gen_p10)
+ addr = XSCOM_ADDR_P10_EC(core_id, P10_EC_CORE_THREAD_STATE);
+ else
+ return;
+
+ rc = xscom_read(chip_id, addr, &core_thread_state);
+ if (rc) {
+ prerror("Error reading CORE_THREAD_STATE rc:%d on PIR:%x\n",
+ rc, cpu->pir);
+ return;
+ }
+
+ if (core_thread_state & PPC_BIT(62)) {
+ lpar_per_core = true;
+ prlog(PR_WARNING, "LPAR-per-core mode detected. KVM may not be usable.");
+ }
+}
+
/* Called from head.S, thus no prototype. */
void __noreturn __nomcount main_cpu_entry(const void *fdt);
@@ -1211,6 +1246,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Once all CPU are up apply this workaround */
mask_pc_system_xstop();
+ /* P9/10 may be in LPAR-per-core mode, which is incompatible with KVM */
+ probe_lpar_per_core();
+
/* Add the /opal node to the device-tree */
add_opal_node();