[ERD][RAMEN9610-20560][MODAP-47871][COMMON] chub: check ipc index and run status
authorBoojin Kim <boojin.kim@samsung.com>
Fri, 11 Oct 2019 03:43:27 +0000 (12:43 +0900)
committerCosmin Tanislav <demonsingur@gmail.com>
Mon, 22 Apr 2024 17:23:37 +0000 (20:23 +0300)
This patch checks the ipc index and the run status of chub.

Change-Id: I9165b1374641520965567493317c918a245e1d8d
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
drivers/staging/nanohub/chub.c
drivers/staging/nanohub/chub_ipc.c

index 1053804539058e58d2969a9b16e4aac21fd83cb2..7b518099936f32b8d8f4349df18969da91558718 100644 (file)
@@ -528,6 +528,11 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le
                                 "fails to get read ret:%d timeout:%d\n", ret, timeout);
        }
 
+       if (__raw_readl(&ipc->chub_status) != CHUB_ST_RUN) {
+               dev_warn(ipc->dev, "%s: chub isn't run:%d\n", __raw_readl(&ipc->chub_status));
+               return 0;
+       }
+
        if (contexthub_get_token(ipc)) {
                dev_warn(ipc->dev, "no-active: read fails\n");
                return 0;
@@ -559,6 +564,11 @@ int contexthub_ipc_write(struct contexthub_ipc_info *ipc,
 {
        int ret;
 
+       if (__raw_readl(&ipc->chub_status) != CHUB_ST_RUN) {
+               dev_warn(ipc->dev, "%s: chub isn't run:%d\n", __raw_readl(&ipc->chub_status));
+               return 0;
+       }
+
        if (contexthub_get_token(ipc)) {
                dev_warn(ipc->dev, "no-active: write fails\n");
                return 0;
index 76c2826b06bdeaf729a8d0757db06ceffa8dd65c..6bcd4b45caf6798b0e86e3eba0d00309ebc6ae72 100644 (file)
@@ -434,6 +434,11 @@ static inline bool __ipc_evt_queue_full(struct ipc_evt_ctrl *ipc_evt)
        return (((ipc_evt->eq + 1) % IPC_EVT_NUM) == ipc_evt->dq);
 }
 
+static inline bool __ipc_evt_queue_index_check(struct ipc_evt_ctrl *ipc_evt)
+{
+       return ((ipc_evt->eq > IPC_EVT_NUM) || (ipc_evt->dq > IPC_EVT_NUM));
+}
+
 struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evtq)
 {
        struct ipc_evt *ipc_evt = &ipc_map->evt[evtq];
@@ -442,6 +447,11 @@ struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evtq)
        bool retried = 0;
 #endif
 
+       if (__ipc_evt_queue_index_check(&ipc_evt->ctrl)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return NULL;
+       }
+
 retry:
        /* only called by isr DISABLE_IRQ(); */
        if (!__ipc_evt_queue_empty(&ipc_evt->ctrl)) {
@@ -473,6 +483,11 @@ static inline int __ipc_evt_wait_full(struct ipc_evt *ipc_evt)
        int trycnt = 0;
        u64 time = CUR_TIME();
 
+       if (__ipc_evt_queue_index_check(&ipc_evt->ctrl)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return -1;
+       }
+
        /* don't sleep on ap */
        do {
                pass = __ipc_evt_queue_full(&ipc_evt->ctrl);
@@ -511,6 +526,11 @@ int ipc_add_evt(enum ipc_evt_list evtq, enum irq_evt_chub evt)
                return -EINVAL;
        }
 
+       if (__ipc_evt_queue_index_check(&ipc_evt->ctrl)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return -EINVAL;
+       }
+
 retry:
        DISABLE_IRQ(LOCK_ADD_EVT, &flag);
        if (!__ipc_evt_queue_full(&ipc_evt->ctrl)) {
@@ -582,12 +602,22 @@ static inline bool __ipc_queue_full(struct ipc_buf *ipc_data)
        return (((ipc_data->eq + 1) % IPC_CH_BUF_NUM) == __raw_readl(&ipc_data->dq));
 }
 
+static inline bool __ipc_queue_index_check(struct ipc_buf *ipc_data)
+{
+       return ((ipc_data->eq > IPC_CH_BUF_NUM) || (ipc_data->dq > IPC_CH_BUF_NUM));
+}
+
 static inline int __ipc_data_wait_full(struct ipc_buf *ipc_data)
 {
        volatile u32 pass;
        int trycnt = 0;
        u64 time = CUR_TIME();
 
+       if (__ipc_queue_index_check(ipc_data)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return -EINVAL;
+       }
+
        /* don't sleep on ap */
        do {
                pass = __ipc_queue_full(ipc_data);
@@ -615,6 +645,11 @@ int ipc_write_data(enum ipc_data_list dir, void *tx, u16 length)
        int trycnt = 0;
        unsigned long flag;
 
+       if (__ipc_queue_index_check(ipc_data)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return -EINVAL;
+       }
+
        if (length <= PACKET_SIZE_MAX) {
 retry:
                DISABLE_IRQ(LOCK_WT_DATA, &flag);
@@ -671,6 +706,11 @@ void *ipc_read_data(enum ipc_data_list dir, u32 *len)
        struct ipc_buf *ipc_data = ipc_get_base(reg);
        void *buf = NULL;
 
+       if (__ipc_queue_index_check(ipc_data)) {
+               CSP_PRINTF_ERROR("%s:%s: failed by ipc index corrupt\n", NAME_PREFIX, __func__);
+               return NULL;
+       }
+
        DISABLE_IRQ(LOCK_RD_DATA, NULL);
 retry:
        if (!__ipc_queue_empty(ipc_data)) {