soc: qcom: spss_utils: protect from event signaled twice
avoid event signaled twice. add ioctl to check if event was signaled. Change-Id: Ie75b9db86f2badddc08d65eee30ecd6a15795256 Signed-off-by: Amir Samuelov <amirs@codeaurora.org>
This commit is contained in:
committed by
Gerrit - the friendly Code Review server
parent
80fded8cc1
commit
86d0cd334f
@@ -93,7 +93,11 @@ static phys_addr_t cmac_mem_addr;
|
|||||||
#define SPU_PRESENT_IN_EMULATION BIT(2)
|
#define SPU_PRESENT_IN_EMULATION BIT(2)
|
||||||
|
|
||||||
/* Events notification */
|
/* Events notification */
|
||||||
struct completion spss_events[SPSS_NUM_EVENTS];
|
static struct completion spss_events[SPSS_NUM_EVENTS];
|
||||||
|
static bool spss_events_signaled[SPSS_NUM_EVENTS];
|
||||||
|
|
||||||
|
/* Protect from ioctl signal func called by multiple-proc at the same time */
|
||||||
|
static struct mutex event_lock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct device state
|
* struct device state
|
||||||
@@ -418,6 +422,8 @@ static int spss_wait_for_event(struct spss_ioc_wait_for_event *req)
|
|||||||
pr_err("wait for event [%d] interrupted. ret [%d]\n",
|
pr_err("wait for event [%d] interrupted. ret [%d]\n",
|
||||||
event_id, ret);
|
event_id, ret);
|
||||||
req->status = EVENT_STATUS_ABORTED;
|
req->status = EVENT_STATUS_ABORTED;
|
||||||
|
if (ret == -ERESTARTSYS) /* handle LPM event */
|
||||||
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
pr_debug("wait for event [%d] completed.\n", event_id);
|
pr_debug("wait for event [%d] completed.\n", event_id);
|
||||||
req->status = EVENT_STATUS_SIGNALED;
|
req->status = EVENT_STATUS_SIGNALED;
|
||||||
@@ -430,16 +436,52 @@ static int spss_signal_event(struct spss_ioc_signal_event *req)
|
|||||||
{
|
{
|
||||||
uint32_t event_id;
|
uint32_t event_id;
|
||||||
|
|
||||||
|
mutex_lock(&event_lock);
|
||||||
|
|
||||||
event_id = req->event_id;
|
event_id = req->event_id;
|
||||||
|
|
||||||
if (event_id >= SPSS_NUM_EVENTS) {
|
if (event_id >= SPSS_NUM_EVENTS) {
|
||||||
pr_err("event_id [%d] invalid\n", event_id);
|
pr_err("event_id [%d] invalid\n", event_id);
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spss_events_signaled[event_id]) {
|
||||||
|
pr_err("event_id [%d] already signaled\n", event_id);
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_debug("signal event [%d]\n", event_id);
|
pr_debug("signal event [%d]\n", event_id);
|
||||||
complete_all(&spss_events[event_id]);
|
complete_all(&spss_events[event_id]);
|
||||||
req->status = EVENT_STATUS_SIGNALED;
|
req->status = EVENT_STATUS_SIGNALED;
|
||||||
|
spss_events_signaled[event_id] = true;
|
||||||
|
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spss_is_event_signaled(struct spss_ioc_is_signaled *req)
|
||||||
|
{
|
||||||
|
uint32_t event_id;
|
||||||
|
|
||||||
|
mutex_lock(&event_lock);
|
||||||
|
|
||||||
|
event_id = req->event_id;
|
||||||
|
|
||||||
|
if (event_id >= SPSS_NUM_EVENTS) {
|
||||||
|
pr_err("event_id [%d] invalid\n", event_id);
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spss_events_signaled[event_id])
|
||||||
|
req->status = EVENT_STATUS_SIGNALED;
|
||||||
|
else
|
||||||
|
req->status = EVENT_STATUS_NOT_SIGNALED;
|
||||||
|
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -454,10 +496,7 @@ static long spss_utils_ioctl(struct file *file,
|
|||||||
u32 i = 0;
|
u32 i = 0;
|
||||||
/* Saved cmacs of spu firmware and UEFI loaded spu apps */
|
/* Saved cmacs of spu firmware and UEFI loaded spu apps */
|
||||||
u32 fw_and_apps_cmacs[FW_AND_APPS_CMAC_SIZE];
|
u32 fw_and_apps_cmacs[FW_AND_APPS_CMAC_SIZE];
|
||||||
struct spss_ioc_wait_for_event *wait_req =
|
void *req = (void *) data;
|
||||||
(struct spss_ioc_wait_for_event *) data;
|
|
||||||
struct spss_ioc_signal_event *signal_req =
|
|
||||||
(struct spss_ioc_signal_event *) data;
|
|
||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
pr_err("invalid ioctl arg\n");
|
pr_err("invalid ioctl arg\n");
|
||||||
@@ -518,10 +557,10 @@ static long spss_utils_ioctl(struct file *file,
|
|||||||
pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size);
|
pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ret = spss_wait_for_event(wait_req);
|
ret = spss_wait_for_event(req);
|
||||||
|
copy_to_user((void __user *)arg, data, size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
copy_to_user((void __user *)arg, data, size);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPSS_IOC_SIGNAL_EVENT:
|
case SPSS_IOC_SIGNAL_EVENT:
|
||||||
@@ -530,10 +569,22 @@ static long spss_utils_ioctl(struct file *file,
|
|||||||
pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size);
|
pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ret = spss_signal_event(signal_req);
|
ret = spss_signal_event(req);
|
||||||
|
copy_to_user((void __user *)arg, data, size);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPSS_IOC_IS_EVENT_SIGNALED:
|
||||||
|
/* check input params */
|
||||||
|
if (size != sizeof(struct spss_ioc_is_signaled)) {
|
||||||
|
pr_err("cmd [0x%x] invalid size [0x%x]\n", cmd, size);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ret = spss_is_event_signaled(req);
|
||||||
copy_to_user((void __user *)arg, data, size);
|
copy_to_user((void __user *)arg, data, size);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1010,22 +1061,56 @@ static int spss_utils_pil_callback(struct notifier_block *nb,
|
|||||||
unsigned long code,
|
unsigned long code,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
int i;
|
int i, event_id;
|
||||||
|
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case SUBSYS_BEFORE_SHUTDOWN:
|
case SUBSYS_BEFORE_SHUTDOWN:
|
||||||
pr_debug("[SUBSYS_BEFORE_SHUTDOWN] event.\n");
|
pr_debug("[SUBSYS_BEFORE_SHUTDOWN] event.\n");
|
||||||
|
mutex_lock(&event_lock);
|
||||||
|
/* Reset NVM-ready and SPU-ready events */
|
||||||
|
for (i = SPSS_EVENT_ID_NVM_READY;
|
||||||
|
i <= SPSS_EVENT_ID_SPU_READY; i++) {
|
||||||
|
reinit_completion(&spss_events[i]);
|
||||||
|
spss_events_signaled[i] = false;
|
||||||
|
}
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
pr_debug("reset spss events.\n");
|
||||||
break;
|
break;
|
||||||
case SUBSYS_AFTER_SHUTDOWN:
|
case SUBSYS_AFTER_SHUTDOWN:
|
||||||
pr_debug("[SUBSYS_AFTER_SHUTDOWN] event.\n");
|
pr_debug("[SUBSYS_AFTER_SHUTDOWN] event.\n");
|
||||||
|
mutex_lock(&event_lock);
|
||||||
|
event_id = SPSS_EVENT_ID_SPU_POWER_DOWN;
|
||||||
|
complete_all(&spss_events[event_id]);
|
||||||
|
spss_events_signaled[event_id] = true;
|
||||||
|
|
||||||
|
event_id = SPSS_EVENT_ID_SPU_POWER_UP;
|
||||||
|
reinit_completion(&spss_events[event_id]);
|
||||||
|
spss_events_signaled[event_id] = false;
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
break;
|
break;
|
||||||
case SUBSYS_BEFORE_POWERUP:
|
case SUBSYS_BEFORE_POWERUP:
|
||||||
pr_debug("[SUBSYS_BEFORE_POWERUP] event.\n");
|
pr_debug("[SUBSYS_BEFORE_POWERUP] event.\n");
|
||||||
for (i = 0 ; i < SPSS_NUM_EVENTS; i++)
|
|
||||||
reinit_completion(&spss_events[i]);
|
|
||||||
break;
|
break;
|
||||||
case SUBSYS_AFTER_POWERUP:
|
case SUBSYS_AFTER_POWERUP:
|
||||||
pr_debug("[SUBSYS_AFTER_POWERUP] event.\n");
|
pr_debug("[SUBSYS_AFTER_POWERUP] event.\n");
|
||||||
|
mutex_lock(&event_lock);
|
||||||
|
event_id = SPSS_EVENT_ID_SPU_POWER_UP;
|
||||||
|
complete_all(&spss_events[event_id]);
|
||||||
|
spss_events_signaled[event_id] = true;
|
||||||
|
|
||||||
|
event_id = SPSS_EVENT_ID_SPU_POWER_DOWN;
|
||||||
|
reinit_completion(&spss_events[event_id]);
|
||||||
|
spss_events_signaled[event_id] = false;
|
||||||
|
mutex_unlock(&event_lock);
|
||||||
|
break;
|
||||||
|
case SUBSYS_RAMDUMP_NOTIFICATION:
|
||||||
|
pr_debug("[SUBSYS_RAMDUMP_NOTIFICATION] event.\n");
|
||||||
|
break;
|
||||||
|
case SUBSYS_PROXY_VOTE:
|
||||||
|
pr_debug("[SUBSYS_PROXY_VOTE] event.\n");
|
||||||
|
break;
|
||||||
|
case SUBSYS_PROXY_UNVOTE:
|
||||||
|
pr_debug("[SUBSYS_PROXY_UNVOTE] event.\n");
|
||||||
break;
|
break;
|
||||||
case SUBSYS_BEFORE_AUTH_AND_RESET:
|
case SUBSYS_BEFORE_AUTH_AND_RESET:
|
||||||
/* do nothing if IAR is not active */
|
/* do nothing if IAR is not active */
|
||||||
@@ -1132,8 +1217,11 @@ static int spss_probe(struct platform_device *pdev)
|
|||||||
kfree(iar_nb);
|
kfree(iar_nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < SPSS_NUM_EVENTS; i++)
|
for (i = 0 ; i < SPSS_NUM_EVENTS; i++) {
|
||||||
init_completion(&spss_events[i]);
|
init_completion(&spss_events[i]);
|
||||||
|
spss_events_signaled[i] = false;
|
||||||
|
}
|
||||||
|
mutex_init(&event_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,22 +19,37 @@
|
|||||||
#define SPSS_IOC_MAGIC 'S'
|
#define SPSS_IOC_MAGIC 'S'
|
||||||
|
|
||||||
/* ---------- set fw cmac --------------------------------- */
|
/* ---------- set fw cmac --------------------------------- */
|
||||||
#define NUM_SPU_UEFI_APPS 3
|
#define NUM_SPU_UEFI_APPS 3
|
||||||
|
#define CMAC_SIZE_IN_WORDS 4
|
||||||
|
|
||||||
struct spss_ioc_set_fw_cmac {
|
struct spss_ioc_set_fw_cmac {
|
||||||
uint32_t cmac[4];
|
uint32_t cmac[CMAC_SIZE_IN_WORDS];
|
||||||
uint32_t app_cmacs[NUM_SPU_UEFI_APPS][4];
|
uint32_t app_cmacs[NUM_SPU_UEFI_APPS][CMAC_SIZE_IN_WORDS];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define SPSS_IOC_SET_FW_CMAC \
|
#define SPSS_IOC_SET_FW_CMAC \
|
||||||
_IOWR(SPSS_IOC_MAGIC, 1, struct spss_ioc_set_fw_cmac)
|
_IOWR(SPSS_IOC_MAGIC, 1, struct spss_ioc_set_fw_cmac)
|
||||||
|
|
||||||
/* ---------- wait for event ------------------------------ */
|
/* ---------- wait for event ------------------------------ */
|
||||||
#define SPSS_NUM_EVENTS 8
|
enum _spss_event_id {
|
||||||
|
/* signaled from user */
|
||||||
|
SPSS_EVENT_ID_PIL_CALLED = 0,
|
||||||
|
SPSS_EVENT_ID_NVM_READY = 1,
|
||||||
|
SPSS_EVENT_ID_SPU_READY = 2,
|
||||||
|
SPSS_NUM_USER_EVENTS,
|
||||||
|
|
||||||
#define EVENT_STATUS_SIGNALED 0xAAAA
|
/* signaled from kernel */
|
||||||
#define EVENT_STATUS_TIMEOUT 0xEEE1
|
SPSS_EVENT_ID_SPU_POWER_DOWN = 6,
|
||||||
#define EVENT_STATUS_ABORTED 0xEEE2
|
SPSS_EVENT_ID_SPU_POWER_UP = 7,
|
||||||
|
SPSS_NUM_EVENTS,
|
||||||
|
} spss_event_id;
|
||||||
|
|
||||||
|
enum _spss_event_status {
|
||||||
|
EVENT_STATUS_SIGNALED = 0xAAAA,
|
||||||
|
EVENT_STATUS_NOT_SIGNALED = 0xFFFF,
|
||||||
|
EVENT_STATUS_TIMEOUT = 0xEEE1,
|
||||||
|
EVENT_STATUS_ABORTED = 0xEEE2,
|
||||||
|
} spss_event_status;
|
||||||
|
|
||||||
struct spss_ioc_wait_for_event {
|
struct spss_ioc_wait_for_event {
|
||||||
uint32_t event_id; /* input */
|
uint32_t event_id; /* input */
|
||||||
@@ -54,4 +69,13 @@ struct spss_ioc_signal_event {
|
|||||||
#define SPSS_IOC_SIGNAL_EVENT \
|
#define SPSS_IOC_SIGNAL_EVENT \
|
||||||
_IOWR(SPSS_IOC_MAGIC, 3, struct spss_ioc_signal_event)
|
_IOWR(SPSS_IOC_MAGIC, 3, struct spss_ioc_signal_event)
|
||||||
|
|
||||||
|
/* ---------- is event isgnaled ------------------------------ */
|
||||||
|
struct spss_ioc_is_signaled {
|
||||||
|
uint32_t event_id; /* input */
|
||||||
|
uint32_t status; /* output */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define SPSS_IOC_IS_EVENT_SIGNALED \
|
||||||
|
_IOWR(SPSS_IOC_MAGIC, 4, struct spss_ioc_is_signaled)
|
||||||
|
|
||||||
#endif /* _UAPI_SPSS_UTILS_H_ */
|
#endif /* _UAPI_SPSS_UTILS_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user