static u32 __secure_readl(u32 addr) { u32 r; r = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ, addr); __iormb(); return r; }
static void send_q6_nmi(struct q6v3_data *drv) { /* Send NMI to QDSP6 via an SCM call. */ scm_call_atomic1(SCM_SVC_UTIL, SCM_Q6_NMI_CMD, 0x1); /* Wakeup the Q6 */ writel_relaxed(0x2000, drv->wk_base + 0x1c); /* Q6 requires atleast 100ms to dump caches etc.*/ mdelay(100); pr_info("Q6 NMI was sent.\n"); }
static void send_q6_nmi(void) { scm_call_atomic1(SCM_SVC_UTIL, SCM_Q6_NMI_CMD, 0x1); if (q6_wakeup_intr) writel_relaxed(0x2000, q6_wakeup_intr); else pr_warn("lpass-8660: Unable to send wakeup interrupt to Q6.\n"); mdelay(100); pr_info("subsystem-fatal-8x60: Q6 NMI was sent.\n"); }
static long smcmod_ioctl(struct file *file, unsigned cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int ret = 0; /* sanity check */ if (!argp) return -EINVAL; /* * The SMC instruction should only be initiated by one process * at a time, hence the critical section here. Note that this * does not prevent user space from modifying the * allocated buffer contents. Extra steps are needed to * prevent that from happening. */ mutex_lock(&ioctl_lock); ret = smcmod_ioctl_check(cmd); if (ret) goto cleanup; switch (cmd) { case SMCMOD_IOCTL_SEND_REG_CMD: { struct smcmod_reg_req req; /* copy struct from user */ if (copy_from_user((void *)&req, argp, sizeof(req))) { ret = -EFAULT; goto cleanup; } /* call the correct scm function to switch to secure * world */ if (req.num_args == 1) { req.return_val = scm_call_atomic1(req.service_id, req.command_id, req.args[0]); } else if (req.num_args == 2) { req.return_val = scm_call_atomic2(req.service_id, req.command_id, req.args[0], req.args[1]); } else { ret = -EINVAL; goto cleanup; } /* copy result back to user */ if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; /* This is an example of how to pass buffers to/from the secure * side using the ion driver. */ case SMCMOD_IOCTL_SEND_BUF_CMD: { struct smcmod_buf_req req; /* copy struct from user */ if (copy_from_user((void *)&req, argp, sizeof(req))) { ret = -EFAULT; goto cleanup; } /* send the command */ ret = smcmod_send_buf_cmd(&req); if (ret < 0) goto cleanup; /* copy result back to user */ if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; case SMCMOD_IOCTL_SEND_CIPHER_CMD: { struct smcmod_cipher_req req; /* copy struct from user */ if (copy_from_user((void *)&req, argp, sizeof(req))) { ret = -EFAULT; goto cleanup; } ret = smcmod_send_cipher_cmd(&req); if (ret < 0) goto cleanup; /* copy result back to user */ if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; case SMCMOD_IOCTL_SEND_MSG_DIGEST_CMD: { struct smcmod_msg_digest_req req; /* copy struct from user */ if (copy_from_user((void *)&req, argp, sizeof(req))) { ret = -EFAULT; goto cleanup; } ret = smcmod_send_msg_digest_cmd(&req); if (ret < 0) goto cleanup; /* copy result back to user */ if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; case SMCMOD_IOCTL_GET_VERSION: { uint32_t req; /* call scm function to switch to secure world */ req = scm_get_version(); /* copy result back to user */ if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; case SMCMOD_IOCTL_SEND_DECRYPT_CMD: { struct smcmod_decrypt_req req; if (copy_from_user((void *)&req, argp, sizeof(req))) { ret = -EFAULT; goto cleanup; } ret = smcmod_send_dec_cmd(&req); if (ret < 0) goto cleanup; if (copy_to_user(argp, (void *)&req, sizeof(req))) { ret = -EFAULT; goto cleanup; } } break; default: ret = -EINVAL; } cleanup: mutex_unlock(&ioctl_lock); return ret; }