summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mailbox/pcc.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index d96b8b54e77e..8dfa80b0a90f 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -345,6 +345,26 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p)
return IRQ_HANDLED;
}
+static int pcc_mbox_validate_signature(struct pcc_mbox_chan *pcc_mchan,
+ int subspace_id)
+{
+ u32 expected_signature = PCC_SIGNATURE | subspace_id;
+ u32 signature;
+
+ if (pcc_mchan->shmem_size < sizeof(signature)) {
+ pr_err("PCC subspace %d shared memory is too small\n",
+ subspace_id);
+ return -EINVAL;
+ }
+
+ signature = ioread32(pcc_mchan->shmem);
+ if (signature != expected_signature)
+ pr_warn("PCC subspace %d invalid signature %#x expected %#x\n",
+ subspace_id, signature, expected_signature);
+
+ return 0;
+}
+
/**
* pcc_mbox_request_channel - PCC clients call this function to
* request a pointer to their PCC subspace, from which they
@@ -381,14 +401,20 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id)
if (!pcc_mchan->shmem)
return ERR_PTR(-ENXIO);
+ rc = pcc_mbox_validate_signature(pcc_mchan, subspace_id);
+ if (rc)
+ goto err_unmap_shmem;
+
rc = mbox_bind_client(chan, cl);
- if (rc) {
- iounmap(pcc_mchan->shmem);
- pcc_mchan->shmem = NULL;
- return ERR_PTR(rc);
- }
+ if (rc)
+ goto err_unmap_shmem;
return pcc_mchan;
+
+err_unmap_shmem:
+ iounmap(pcc_mchan->shmem);
+ pcc_mchan->shmem = NULL;
+ return ERR_PTR(rc);
}
EXPORT_SYMBOL_GPL(pcc_mbox_request_channel);