aboutsummaryrefslogtreecommitdiff
path: root/hw/imc.c
diff options
context:
space:
mode:
authorMadhavan Srinivasan <maddy@linux.vnet.ibm.com>2017-12-04 04:57:28 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-05 01:01:55 -0600
commit3647e9850660206f862cecad5abe62943ea727a1 (patch)
treee9bf57e6b424ff081d6334b655291dffebf46bab /hw/imc.c
parent631ed5f2e06a0c55268b61cfaf89c833cef14ae1 (diff)
downloadskiboot-3647e9850660206f862cecad5abe62943ea727a1.zip
skiboot-3647e9850660206f862cecad5abe62943ea727a1.tar.gz
skiboot-3647e9850660206f862cecad5abe62943ea727a1.tar.bz2
hw/imc: Check ucode state before exposing units to Linux
disable_unavailable_units() checks whether the ucode is in the running state before enabling the nest units in the device tree. From a recent debug, it is found that on some system boot, ucode is not loaded and running in all the chips in the system. And this caused a fail in OPAL_IMC_COUNTERS_STOP call where we check for ucode state on each chip. Bug here is that disable_unavailable_units() checks the state of the ucode only in boot cpu chip. Patch adds a condition in disable_unavailable_units() to check for the ucode state in all the chip before enabling the nest units in the device tree node. Fixes: f98d59958db19 ('skiboot: Find the IMC DTB') Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> [stewart: clarify with comment and better variable name] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/imc.c')
-rw-r--r--hw/imc.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/hw/imc.c b/hw/imc.c
index 765c40f..df29e6d 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -356,13 +356,34 @@ static void disable_unavailable_units(struct dt_node *dev)
struct imc_chip_cb *cb;
struct dt_node *target;
int i;
+ bool disable_all_nests = false;
+ struct proc_chip *chip;
+
+ /*
+ * Check the state of ucode in all the chip.
+ * Disable the nest unit if ucode is not initialized
+ * in any of the chip.
+ */
+ for_each_chip(chip) {
+ cb = get_imc_cb(chip->id);
+ if (!cb) {
+ /*
+ * At least currently, if one chip isn't functioning,
+ * none of the IMC Nest units will be functional.
+ * So while you may *think* this should be per chip,
+ * it isn't.
+ */
+ disable_all_nests = true;
+ break;
+ }
+ }
/* Add a property to "exports" node in opal_node */
imc_dt_exports_prop_add(dev);
/* Fetch the IMC control block structure */
cb = get_imc_cb(this_cpu()->chip_id);
- if (cb)
+ if (cb && !disable_all_nests)
avl_vec = be64_to_cpu(cb->imc_chip_avl_vector);
else {
avl_vec = 0; /* Remove only nest imc device nodes */