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);