aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Mendoza-Jonas <sam@mendozajonas.com>2016-06-28 13:07:06 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-07-15 14:48:38 +1000
commit7116c948ee63019ceda7dc3b7334e6c25e291eeb (patch)
tree918b3f92142841056c595a215063484f7c99d9d7
parent65e436ad726aac81fe8acca55868afdf9d5f3161 (diff)
downloadskiboot-7116c948ee63019ceda7dc3b7334e6c25e291eeb.zip
skiboot-7116c948ee63019ceda7dc3b7334e6c25e291eeb.tar.gz
skiboot-7116c948ee63019ceda7dc3b7334e6c25e291eeb.tar.bz2
fsp/console: Ignore data on unresponsive consoles
Linux kernels from v4.1 onwards will try to request an irq for each hvc console using OPAL_EVENT_CONSOLE_INPUT, however because the IRQF_SHARED flag is not set any console after the first will fail. If there is data on one of these failed consoles OPAL will set OPAL_EVENT_CONSOLE_INPUT every time fsp_console_read is called, leading to RCU stalls in the kernel. As a workaround for unpatched kernels, cease setting OPAL_EVENT_CONSOLE_INPUT for consoles that we have noticed are not being read. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com> (cherry picked from commit fd6b71fcc6912611ce81f455b4805f0531699d5e) Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/fsp/fsp-console.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/hw/fsp/fsp-console.c b/hw/fsp/fsp-console.c
index 2a25e1c..87e509d 100644
--- a/hw/fsp/fsp-console.c
+++ b/hw/fsp/fsp-console.c
@@ -54,6 +54,7 @@ struct fsp_serial {
struct fsp_serbuf_hdr *in_buf;
struct fsp_serbuf_hdr *out_buf;
struct fsp_msg *poke_msg;
+ u8 waiting;
};
#define SER_BUFFER_SIZE 0x00040000UL
@@ -653,6 +654,8 @@ static int64_t fsp_console_read(int64_t term_number, int64_t *length,
unlock(&fsp_con_lock);
return OPAL_CLOSED;
}
+ if (fs->waiting)
+ fs->waiting = 0;
sb = fs->in_buf;
old_nin = sb->next_in;
lwsync();
@@ -687,8 +690,19 @@ static int64_t fsp_console_read(int64_t term_number, int64_t *length,
if (fs->log_port || !fs->open)
continue;
- if (sb->next_out != sb->next_in)
- pending = true;
+ if (sb->next_out != sb->next_in) {
+ /*
+ * HACK: Some kernels (4.1+) may fail to properly
+ * register hvc1 and will never read it. This can lead
+ * to RCU stalls, so if we notice this console is not
+ * being read, do not set OPAL_EVENT_CONSOLE_INPUT even
+ * if it has data
+ */
+ if (fs->waiting < 5) {
+ pending = true;
+ fs->waiting++;
+ }
+ }
}
if (!pending)
opal_update_pending_evt(OPAL_EVENT_CONSOLE_INPUT, 0);