aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2025-03-01 01:07:57 +1000
committerNicholas Piggin <npiggin@gmail.com>2025-03-11 22:43:30 +1000
commit4c84a0a4a6e5c4a374493d99e7eb702def7e7eae (patch)
treee980771ca14854e19b6fdd67ea8a733c371efef3
parentb899de9a3d959652bf61d671ffa2c2ba23259b15 (diff)
downloadqemu-4c84a0a4a6e5c4a374493d99e7eb702def7e7eae.zip
qemu-4c84a0a4a6e5c4a374493d99e7eb702def7e7eae.tar.gz
qemu-4c84a0a4a6e5c4a374493d99e7eb702def7e7eae.tar.bz2
ppc/pnv: Add a PNOR address and size sanity checks
The BMC HIOMAP PNOR access protocol has certain limits on PNOR addresses and sizes. Add some sanity checks for these so we don't get strange behaviour. Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
-rw-r--r--hw/ppc/pnv_bmc.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 0c1274d..811ba3d 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -251,10 +251,38 @@ static const IPMINetfn hiomap_netfn = {
void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
{
+ uint32_t pnor_size = pnor->size;
+ uint32_t pnor_addr = PNOR_SPI_OFFSET;
+
if (!pnv_bmc_is_simulator(bmc)) {
return;
}
+ /*
+ * The HIOMAP protocol uses block units and 16-bit addressing.
+ * Prevent overflow or misalign.
+ */
+ if (pnor_addr >= 1U << (BLOCK_SHIFT + 16)) {
+ warn_report("PNOR address is larger than 2^%d, disabling PNOR",
+ BLOCK_SHIFT + 16);
+ return;
+ }
+ if (pnor_addr & ((1U << BLOCK_SHIFT) - 1)) {
+ warn_report("PNOR address is not aligned to 2^%d, disabling PNOR",
+ BLOCK_SHIFT);
+ return;
+ }
+ if (pnor_size > 1U << (BLOCK_SHIFT + 16)) {
+ warn_report("PNOR size is larger than 2^%d, disabling PNOR",
+ BLOCK_SHIFT + 16);
+ return;
+ }
+ if (pnor_size & ((1U << BLOCK_SHIFT) - 1)) {
+ warn_report("PNOR size is not aligned to 2^%d, disabling PNOR",
+ BLOCK_SHIFT);
+ return;
+ }
+
object_ref(OBJECT(pnor));
object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor));