diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-08 17:13:01 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-08 17:20:52 +1000 |
commit | f1067cdc0a9c8e34e4c2e57ad9dd37132b47fcb3 (patch) | |
tree | b2991f60378c2b29e860b7490d173159c95a312d /hw/fsp | |
parent | 869c7522aad98c2682e37feb8e56be7a3e975d4d (diff) | |
download | skiboot-f1067cdc0a9c8e34e4c2e57ad9dd37132b47fcb3.zip skiboot-f1067cdc0a9c8e34e4c2e57ad9dd37132b47fcb3.tar.gz skiboot-f1067cdc0a9c8e34e4c2e57ad9dd37132b47fcb3.tar.bz2 |
lock: Fix races when setting in_con_lock
When setting the flag in a lock that indicates that it's on the console
path, we need to take and release that lock to ensure that any other
processor that might have taken it before the flag was set has released
it, otherwise the lock might still be held without the console count
properly incremented, which can cause it to go negative or cause the
deadlock that we mean to avoid by that to still occur.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw/fsp')
-rw-r--r-- | hw/fsp/fsp-console.c | 3 | ||||
-rw-r--r-- | hw/fsp/fsp.c | 8 |
2 files changed, 11 insertions, 0 deletions
diff --git a/hw/fsp/fsp-console.c b/hw/fsp/fsp-console.c index d14e520..4e5803a 100644 --- a/hw/fsp/fsp-console.c +++ b/hw/fsp/fsp-console.c @@ -299,6 +299,9 @@ static void fsp_open_vserial(struct fsp_msg *msg) */ fsp_used_by_console(); fsp_con_lock.in_con_path = true; + /* See comment in fsp_used_by_console */ + lock(&fsp_con_lock); + unlock(&fsp_con_lock); set_console(&fsp_con_ops); } #endif diff --git a/hw/fsp/fsp.c b/hw/fsp/fsp.c index b87c8b3..2189bbb 100644 --- a/hw/fsp/fsp.c +++ b/hw/fsp/fsp.c @@ -2213,4 +2213,12 @@ int fsp_fetch_data_queue(uint8_t flags, uint16_t id, uint32_t sub_id, void fsp_used_by_console(void) { fsp_lock.in_con_path = true; + + /* + * Some other processor might hold it without having + * disabled the console locally so let's make sure that + * is over by taking/releasing the lock ourselves + */ + lock(&fsp_lock); + unlock(&fsp_lock); } |