static const char *give_pointer_location(struct nvshm_handle *handle, void *ptr) { if (!ptr) return "null"; ptr = NVSHM_B2A(handle, ptr); if (ADDR_OUTSIDE(ptr, handle->desc_base_virt, handle->desc_size) && ADDR_OUTSIDE(ptr, handle->data_base_virt, handle->data_size)) { if (ADDR_OUTSIDE(ptr, handle->ipc_base_virt, handle->ipc_size)) return "Err"; else return "BBC"; } return "AP"; }
/* Return 0 if ok or non zero otherwise */ static int inv_iob_list(struct nvshm_handle *handle, struct nvshm_iobuf *iob) { struct nvshm_iobuf *phy_list, *leaf; phy_list = iob; while (phy_list) { leaf = phy_list; while (leaf) { /* Check leaf address before any operation on it */ /* Cannot use nvshm_iobuf_check because iobuf */ /* is not invalidated so content will be wrong */ if (ADDR_OUTSIDE(leaf, handle->ipc_base_virt, handle->ipc_size)) { return -EIO; } /* Invalidate iobuf */ INV_CPU_DCACHE(leaf, sizeof(struct nvshm_iobuf)); /* Check iobuf */ if (nvshm_iobuf_check(leaf)) return -EIO; /* Invalidate associated data */ if (leaf->length) { INV_CPU_DCACHE(NVSHM_B2A(handle, (int)leaf->npduData + leaf->dataOffset), leaf->length); } if (leaf->sg_next) leaf = NVSHM_B2A(handle, leaf->sg_next); else leaf = NULL; } if (phy_list->next) phy_list = NVSHM_B2A(handle, phy_list->next); else phy_list = NULL; } return 0; }
int nvshm_iobuf_check(struct nvshm_iobuf *iob) { struct nvshm_handle *priv = nvshm_get_handle(); struct nvshm_iobuf *bbiob; int ret = 0; /* Check iobuf is in IPC space */ if (ADDR_OUTSIDE(iob, priv->ipc_base_virt, priv->ipc_size)) { pr_err("%s: iob @ check failed 0x%lx\n", __func__, (long)iob); return -1; } bbiob = NVSHM_A2B(priv, iob); if (ADDR_OUTSIDE(iob->npduData, NVSHM_IPC_BB_BASE, priv->ipc_size)) { pr_err("%s 0x%lx: npduData @ check failed 0x%lx\n", __func__, (long)bbiob, (long)iob->npduData); ret = -2; goto dump; } if (ADDR_OUTSIDE(iob->npduData + iob->dataOffset, NVSHM_IPC_BB_BASE, priv->ipc_size)) { pr_err("%s 0x%lx: npduData + offset @ check failed 0x%lx/0x%lx\n", __func__, (long)bbiob, (long)iob->npduData, (long)iob->dataOffset); ret = -3; goto dump; } if (iob->next) { if (ADDR_OUTSIDE(iob->next, NVSHM_IPC_BB_BASE, priv->ipc_size)) { pr_err("%s 0x%lx: next @ check failed 0x%lx\n", __func__, (long)bbiob, (long)iob->next); ret = -4; goto dump; } } if (iob->sg_next) { if (ADDR_OUTSIDE(iob->sg_next, NVSHM_IPC_BB_BASE, priv->ipc_size)) { pr_err("%s 0x%lx:sg_next @ check failed 0x%lx\n", __func__, (long)bbiob, (long)iob->sg_next); ret = -5; goto dump; } } if (iob->qnext) { if (ADDR_OUTSIDE(iob->qnext, NVSHM_IPC_BB_BASE, priv->ipc_size)) { pr_err("%s 0x%lx:qnext @ check failed 0x%lx\n", __func__, (long)bbiob, (long)iob->qnext); ret = -6; goto dump; } } return ret; dump: nvshm_iobuf_dump(iob); return ret; }