diff options
author | Chalapathi V <chalapathi.v@linux.ibm.com> | 2025-03-03 08:13:28 -0600 |
---|---|---|
committer | Nicholas Piggin <npiggin@gmail.com> | 2025-03-11 22:43:31 +1000 |
commit | a613b9d321f5536943e29aa5847553df46dc2340 (patch) | |
tree | 680394a0be4da05173db7172a39d11e47647192c | |
parent | 7192d7b7fea15f2226a896f02b360bf7cfce1ab1 (diff) | |
download | qemu-a613b9d321f5536943e29aa5847553df46dc2340.zip qemu-a613b9d321f5536943e29aa5847553df46dc2340.tar.gz qemu-a613b9d321f5536943e29aa5847553df46dc2340.tar.bz2 |
hw/ssi/pnv_spi: Put a limit to RDR match failures
There is a possibility that SPI controller can get into loop due to indefinite
RDR match failures. Hence put a limit to failures and stop the sequencer.
Signed-off-by: Chalapathi V <chalapathi.v@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Message-ID: <20250303141328.23991-5-chalapathi.v@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
-rw-r--r-- | hw/ssi/pnv_spi.c | 10 | ||||
-rw-r--r-- | include/hw/ssi/pnv_spi.h | 1 |
2 files changed, 11 insertions, 0 deletions
diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index 8322160..1260703 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -20,6 +20,7 @@ #define PNV_SPI_OPCODE_LO_NIBBLE(x) (x & 0x0F) #define PNV_SPI_MASKED_OPCODE(x) (x & 0xF0) #define PNV_SPI_FIFO_SIZE 16 +#define RDR_MATCH_FAILURE_LIMIT 16 /* * Macro from include/hw/ppc/fdt.h @@ -872,18 +873,27 @@ static void operation_sequencer(PnvSpi *s) rdr_matched = does_rdr_match(s); if (rdr_matched) { trace_pnv_spi_RDR_match("success"); + s->fail_count = 0; /* A match occurred, increment the sequencer index. */ seq_index++; s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT); } else { trace_pnv_spi_RDR_match("failed"); + s->fail_count++; /* * Branch the sequencer to the index coded into the op * code. */ seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode); } + if (s->fail_count >= RDR_MATCH_FAILURE_LIMIT) { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RDR match failure" + " limit crossed %d times hence requesting " + "sequencer to stop.\n", + RDR_MATCH_FAILURE_LIMIT); + stop = true; + } /* * Regardless of where the branch ended up we want the * sequencer to continue shifting so we have to clear diff --git a/include/hw/ssi/pnv_spi.h b/include/hw/ssi/pnv_spi.h index 6adb72d..c591a06 100644 --- a/include/hw/ssi/pnv_spi.h +++ b/include/hw/ssi/pnv_spi.h @@ -40,6 +40,7 @@ typedef struct PnvSpi { MemoryRegion xscom_spic_regs; Fifo8 tx_fifo; Fifo8 rx_fifo; + uint8_t fail_count; /* RDR Match failure counter */ /* SPI object number */ uint32_t spic_num; uint32_t chip_id; |