On Wed 15 Jul 16:43 PDT 2015, Stephen Boyd wrote: > On 07/15, Bjorn Andersson wrote: > > This adds the Peripheral Authentication Service (PAS) interface to the > > Qualcomm SCM interface. The API is used to authenticate and boot a range > > of external processors in various Qualcomm platforms. > > > > Signed-off-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxxxxxx> > > --- > > > > Changes since v1: > > - Big endian compatibility > > Did you try out a big endian kernel? > No, you're still the only one. > > diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c > > index 1bd6f9c34331..81d9c59f3ccc 100644 > > --- a/drivers/firmware/qcom_scm-32.c > > +++ b/drivers/firmware/qcom_scm-32.c > > @@ -501,3 +502,95 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) > > return qcom_scm_call(QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, > > req, req_cnt * sizeof(*req), resp, sizeof(*resp)); > > } > > + > > +bool __qcom_scm_pas_supported(u32 peripheral) > > +{ > > + u32 ret_val; > > I guess we don't have to care about __le32 here because it's just > a zero or non-zero value? > Right, but could be fixed up for completeness. > > + int ret; > > + > > + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_IS_SUPPORTED_CMD, > > + &peripheral, sizeof(peripheral), > > Peripheral needs cpu_to_le32() treatment. > Sorry, missed that one. > > + &ret_val, sizeof(ret_val)); > > + > > + return ret ? false : !!ret_val; > > +} > > + > > +int __qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size) > > +{ > > + dma_addr_t mdata_phys; > > + void *mdata_buf; > > + __le32 scm_ret; > > + int ret; > > + struct pas_init_image_req { > > + __le32 proc; > > + __le32 image_addr; > > + } request; > > + > > + /* > > + * During the scm call memory protection will be enabled for the meta > > + * data blob, so make sure it's physically contiguous, 4K aligned and > > + * non-cachable to avoid XPU violations. > > + */ > > + mdata_buf = dma_alloc_coherent(NULL, size, &mdata_phys, GFP_KERNEL); > > This should pass a device pointer instead of NULL here. Please > make struct device an argument of this function and pass > something there besides NULL in the calling driver. Or we should > make SCM into a platform device driver with a node in DT (named > firmware?). Then if we need to do anything special for DMA to the > firmware, etc. we have a struct device that can describe that. > I think making scm into a platform driver seems very much overkill, passing the callers device * sounds reasonable. My only concern would be if associating this dma allocation with the client has any further implications, but I'll have to read up a little bit on how that works. > Also, dma_alloc_coherent() doesn't do enough to prevent XPU > violations because memory returned from that function on ARM is > not guaranteed to be device memory and so we could speculatively > access the locked down metadata region. This is why we added the > strongly ordered mapping property and pass that to > dma_alloc_attrs in the downstream code so we can change the page > table attributes of the mapping to be device memory. Not doing > this can lead to random crashes when some read speculates on the > metadata and the secure world intercepts it and shuts the system > down. > The code is taken verbatim from msm-3.4 and the comment is picked from the git log, sorry to hear that this is not enough. > I was going to say we could try to use the carveout/reserved > memory code but that doesn't look fool proof. From what I can > tell CMA doesn't use the same page table attributes for the > mapping that dma-coherent does, so if we use dma-coherent it will > use ioremap and work but if we use CMA it won't (at least it > looks like bufferable memory there). Can we add a way to request > memory doesn't allow speculatioan through the DMA APIs? > I haven't looked enough at dma allocations, but this is what worries me when using the clients dev pointer (I'm under the impression that these choices follow the dev*). > > + if (!mdata_buf) { > > + pr_err("Allocation of metadata buffer failed.\n"); > > + return -ENOMEM; > > + } > > + memcpy(mdata_buf, metadata, size); > > + > > + request.proc = cpu_to_le32(peripheral); > > + request.image_addr = cpu_to_le32(mdata_phys); > > + > > + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD, > > + &request, sizeof(request), > > + &scm_ret, sizeof(scm_ret)); > > + > > + dma_free_coherent(NULL, size, mdata_buf, mdata_phys); > > + > > + return ret ? : le32_to_cpu(scm_ret); > > +} > > + > > +int __qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) > > +{ > > + __le32 scm_ret; > > + int ret; > > + struct pas_init_image_req { > > I thought this was going to be an unnamed structure? > > struct { > __le32 proc; > __le32 addr; > __le32 len; > } cmd; > It was, sorry about that. > > + __le32 proc; > > + __le32 addr; > > + __le32 len; > > + } request; > > + > > + request.proc = cpu_to_le32(peripheral); > > + request.addr = cpu_to_le32(addr); > > + request.len = cpu_to_le32(size); > > + > > + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD, > > + &request, sizeof(request), > > + &scm_ret, sizeof(scm_ret)); > > + > > + return ret ? : le32_to_cpu(scm_ret); > > +} > > + > > +int __qcom_scm_pas_auth_and_reset(u32 peripheral) > > +{ > > + __le32 scm_ret; > > + int ret; > > + > > + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_AUTH_AND_RESET_CMD, > > + &peripheral, sizeof(peripheral), > > peripheral needs cpu_to_le32() treatment. > Sorry, missed these. > > + &scm_ret, sizeof(scm_ret)); > > + > > + return ret ? : le32_to_cpu(scm_ret); > > +} > > + > > +int __qcom_scm_pas_shutdown(u32 peripheral) > > +{ > > + __le32 scm_ret; > > + int ret; > > + > > + ret = qcom_scm_call(QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD, > > + &peripheral, sizeof(peripheral), > > peripheral needs cpu_to_le32() treatment. > Ditto > > + &scm_ret, sizeof(scm_ret)); > > + > > + return ret ? : le32_to_cpu(scm_ret); > > +} Regards, Bjorn -- To unsubscribe from this list: send the line "unsubscribe linux-soc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html