osd: risk coverity bugs in osd module
authorpengcheng chen <pengcheng.chen@amlogic.com>
Mon, 11 Jun 2018 03:00:08 +0000 (11:00 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Mon, 2 Jul 2018 08:26:33 +0000 (01:26 -0700)
PD#168947: osd: risk coverity bugs in osd module

Change-Id: Ia593f55c1debbd5dca271461336edb29123fae00
Signed-off-by: pengcheng chen <pengcheng.chen@amlogic.com>
drivers/amlogic/media/osd/osd_drm.c
drivers/amlogic/media/osd/osd_fb.c
drivers/amlogic/media/osd/osd_hw.c
drivers/amlogic/media/osd/osd_rdma.c

index fc6f7cd..6d6c6e9 100644 (file)
@@ -61,6 +61,8 @@ static int parse_para(const char *para, int para_num, int *result)
        params = kstrdup(para, GFP_KERNEL);
        params_base = params;
        token = params;
+       if (!token)
+               return 0;
        len = strlen(token);
        do {
                token = strsep(&params, " ");
@@ -74,6 +76,8 @@ static int parse_para(const char *para, int para_num, int *result)
                ret = kstrtoint(token, 0, &res);
                if (ret < 0)
                        break;
+               if (!token)
+                       return 0;
                len = strlen(token);
                *out++ = res;
                count++;
@@ -217,7 +221,7 @@ static ssize_t free_scale_read_file(struct file *file, char __user *userbuf,
        unsigned int free_scale_enable;
 
        osd_get_free_scale_enable_hw(osd_id, &free_scale_enable);
-       len = snprintf(buf, PAGE_SIZE, "free_scale_enable:[0x%x]\n",
+       len = snprintf(buf, 128, "free_scale_enable:[0x%x]\n",
                        free_scale_enable);
        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
 }
@@ -697,9 +701,10 @@ void osd_drm_debugfs_add(
 
        plane_osd_id[osd_id] = osd_id;
        *plane_debugfs_dir = debugfs_create_dir(name, osd_debugfs_root);
-       if (!plane_debugfs_dir)
+       if (!*plane_debugfs_dir) {
                osd_log_info("debugfs_create_dir failed: name=%s\n", name);
-
+               return;
+       }
        for (i = 0; i < ARRAY_SIZE(osd_drm_debugfs_files); i++) {
                ent = debugfs_create_file(osd_drm_debugfs_files[i].name,
                        osd_drm_debugfs_files[i].mode,
index 35b7511..7422400 100644 (file)
@@ -728,7 +728,7 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
        u32 block_windows[8] = {0};
        u32 block_mode;
        u32 hwc_enable;
-       int ret;
+       int ret = 0;
        s32 vsync_timestamp;
        s64 vsync_timestamp_64;
        u32 flush_rate;
@@ -1021,6 +1021,8 @@ static int osd_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
        case FBIOGET_OSD_DMABUF:
 #ifdef CONFIG_ION
                if (osd_get_afbc(info->node)) {
+                       if (dmaexp.buffer_idx > OSD_MAX_BUF_NUM - 1)
+                               dmaexp.buffer_idx = OSD_MAX_BUF_NUM - 1;
                        dmaexp.fd =
                                ion_share_dma_buf_fd(
                                fb_ion_client,
@@ -1444,7 +1446,8 @@ static int malloc_osd_memory(struct fb_info *info)
 
 static int osd_open(struct fb_info *info, int arg)
 {
-       u32 fb_index, logo_index;
+       u32 fb_index;
+       int logo_index;
        struct osd_fb_dev_s *fbdev;
        struct fb_fix_screeninfo *fix = NULL;
        int ret = 0;
@@ -2014,6 +2017,8 @@ static int parse_para(const char *para, int para_num, int *result)
        params = kstrdup(para, GFP_KERNEL);
        params_base = params;
        token = params;
+       if (!token)
+               return 0;
        len = strlen(token);
        do {
                token = strsep(&params, " ");
@@ -2027,6 +2032,8 @@ static int parse_para(const char *para, int para_num, int *result)
                ret = kstrtoint(token, 0, &res);
                if (ret < 0)
                        break;
+               if (!token)
+                       return 0;
                len = strlen(token);
                *out++ = res;
                count++;
@@ -2447,29 +2454,6 @@ static ssize_t store_antiflicker(struct device *device,
        return count;
 }
 
-static ssize_t show_update_freescale(struct device *device,
-                                    struct device_attribute *attr,
-                                    char *buf)
-{
-       unsigned int update_state = 0;
-
-       return snprintf(buf, PAGE_SIZE, "update_state:[%s]\n",
-                       update_state ? "TRUE" : "FALSE");
-}
-
-static ssize_t store_update_freescale(struct device *device,
-                                     struct device_attribute *attr,
-                                     const char *buf, size_t count)
-{
-       unsigned int update_state = 0;
-       int res = 0;
-       int ret = 0;
-
-       ret = kstrtoint(buf, 0, &res);
-       update_state = res;
-       return count;
-}
-
 static ssize_t show_ver_clone(struct device *device,
                              struct device_attribute *attr,
                              char *buf)
@@ -3073,8 +3057,6 @@ static struct device_attribute osd_attrs[] = {
                        show_osd_reverse, store_osd_reverse),
        __ATTR(osd_antiflicker, 0644,
                        show_antiflicker, store_antiflicker),
-       __ATTR(update_freescale, 0644,
-                       show_update_freescale, store_update_freescale),
        __ATTR(ver_clone, 0644,
                        show_ver_clone, store_ver_clone),
        __ATTR(ver_update_pan, 0220,
@@ -3639,6 +3621,8 @@ static int osd_probe(struct platform_device *pdev)
        vinfo = get_current_vinfo();
        for (index = 0; index < osd_meson_dev.osd_count; index++) {
                /* register frame buffer memory */
+               if (index > OSD_COUNT - 1)
+                       break;
                if (!fb_memsize[index + 1])
                        continue;
                fbi = framebuffer_alloc(sizeof(struct osd_fb_dev_s),
@@ -3784,6 +3768,8 @@ static int osd_remove(struct platform_device *pdev)
        for (i = 0; i < osd_meson_dev.osd_count; i++) {
                int j;
 
+               if (i > OSD_COUNT - 1)
+                       break;
                if (gp_fbdev_list[i]) {
                        struct osd_fb_dev_s *fbdev = gp_fbdev_list[i];
 
@@ -3800,7 +3786,7 @@ static int osd_remove(struct platform_device *pdev)
                        }
                        iounmap(fbdev->fb_mem_vaddr);
                        if (osd_get_afbc(i)) {
-                               for (j = 1; j < OSD_MAX_BUF_NUM; j++)
+                               for (j = 0; j < OSD_MAX_BUF_NUM; j++)
                                        iounmap(fbdev->fb_mem_afbc_vaddr[j]);
                        }
                        kfree(fbi->pseudo_palette);
index e2be8f7..97666f9 100644 (file)
@@ -911,14 +911,14 @@ static int sync_render_single_fence(u32 index, u32 yres,
        int out_fence_fd = -1;
        int buf_num = 0;
        u32 xoffset, yoffset;
-       struct osd_fence_map_s *fence_map =
-               kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL);
+       struct osd_fence_map_s *fence_map =  NULL;
 
        if (index > OSD1)
                return -1;
        xoffset = request->xoffset;
        yoffset = request->yoffset;
        buf_num = find_buf_num(yres, yoffset);
+       fence_map = kzalloc(sizeof(struct osd_fence_map_s), GFP_KERNEL);
        if (!fence_map) {
                osd_log_err("could not allocate osd_fence_map\n");
                return -ENOMEM;
@@ -1448,9 +1448,10 @@ void walk_through_update_list(void)
 
        for (i = 0; i < HW_OSD_COUNT; i++) {
                j = 0;
-               while (osd_hw.updated[i] && j < 32) {
+               while (osd_hw.updated[i] && j < HW_REG_INDEX_MAX) {
                        if (osd_hw.updated[i] & (1 << j)) {
-                               osd_hw.reg[j].update_func(i);
+                               if (osd_hw.reg[j].update_func)
+                                       osd_hw.reg[j].update_func(i);
                                remove_from_update_list(i, j);
                        }
                        j++;
@@ -1488,9 +1489,22 @@ static u32 osd_get_hw_reset_flag(void)
                /* same bit, but gxm only reset hardware, not top reg*/
                if (osd_hw.osd_afbcd[OSD1].enable)
                        hw_reset_flag |= HW_RESET_AFBCD_HARDWARE;
-#ifndef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
+               if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001)
+                       != 0x0) ||
+                       ((hdr_osd_reg.viu_osd1_eotf_ctl & 0x80000000)
+                       != 0) ||
+                       ((hdr_osd_reg.viu_osd1_oetf_ctl & 0xe0000000)
+                       != 0)) {
+                       hw_reset_flag |= HW_RESET_OSD1_REGS;
+                       osd_hdr_on = true;
+               } else if (osd_hdr_on) {
+                       hw_reset_flag |= HW_RESET_OSD1_REGS;
+                       osd_hdr_on = false;
+               }
+#endif
                break;
-#else
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM
        case __MESON_CPU_MAJOR_ID_GXL:
        case __MESON_CPU_MAJOR_ID_TXL:
                if (((hdr_osd_reg.viu_osd1_matrix_ctrl & 0x00000001)
@@ -1699,8 +1713,10 @@ void osd_set_afbc(u32 index, u32 enable)
 u32 osd_get_afbc(u32 index)
 {
        u32 afbc_type = 0;
+       u32 afbc_enalbe;
 
-       if (osd_hw.osd_afbcd[index].enable) {
+       afbc_enalbe = osd_hw.osd_afbcd[index].enable;
+       if (afbc_enalbe) {
                if (osd_hw.osd_meson_dev.cpu_id ==
                        __MESON_CPU_MAJOR_ID_GXM)
                        afbc_type = 1;
@@ -2557,20 +2573,24 @@ void osd_get_flush_rate_hw(u32 *break_rate)
 
 void osd_set_antiflicker_hw(u32 index, struct vinfo_s *vinfo, u32 yres)
 {
+#ifdef NEED_ANTIFLICKER
        bool osd_need_antiflicker = false;
 
        if (is_interlaced(vinfo))
                osd_need_antiflicker = false;
+       else
+               osd_need_antiflicker = true;
        if (osd_need_antiflicker) {
                osd_hw.antiflicker_mode = 1;
                osd_antiflicker_task_start();
                osd_antiflicker_enable(1);
                osd_antiflicker_update_pan(osd_hw.pandata[index].y_start, yres);
-       } else {
-               if (osd_hw.antiflicker_mode)
-                       osd_antiflicker_task_stop();
-               osd_hw.antiflicker_mode = 0;
        }
+#else
+       if (osd_hw.antiflicker_mode)
+               osd_antiflicker_task_stop();
+       osd_hw.antiflicker_mode = 0;
+#endif
 }
 
 void osd_get_antiflicker_hw(u32 index, u32 *on_off)
@@ -4872,16 +4892,15 @@ static int check_order_continuous(u32 *order)
 }
 
 
-static int blend_din_to_osd(
+static u32 blend_din_to_osd(
        u32 blend_din_index, struct hw_osd_blending_s *blending)
 {
        u32 osd_index = 0;
 
        osd_index =
                blending->osd_to_bdin_table[blend_din_index];
-       if ((osd_index > OSD3)
-               || (osd_index < OSD1))
-               return -1;
+       if (osd_index > OSD3)
+               return OSD_MAX;
        else
                return osd_index;
 }
@@ -4940,7 +4959,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending)
                break;
        case 2:
        {
-               int temp_index[2];
+               int temp_index[2] = {0};
                int j = 0;
 
                for (i = 0; i < osd_count; i++) {
@@ -5061,51 +5080,7 @@ static void generate_blend_din_table(struct hw_osd_blending_s *blending)
                blending->osd_to_bdin_table[3]);
        blending->blend_reg.din_reoder_sel =
                blending->din_reoder_sel;
-       osd_log_dbg("blend_din1 == osd%d\n",
-               blend_din_to_osd(BLEND_DIN1, blending) + 1);
-       osd_log_dbg("blend_din3 == osd%d\n",
-               blend_din_to_osd(BLEND_DIN3, blending) + 1);
-       osd_log_dbg("blend_din4 == osd%d\n",
-               blend_din_to_osd(BLEND_DIN4, blending) + 1);
-}
-
-#if 0
-static void adjust_blend_din_table(struct hw_osd_blending_s *blending)
-{
-       int i = 0;
-
-       /* adjust osd_to_bdin_table */
-       /* reorder[i] = osd[i]'s display layer */
-       /* tow osd_x input to vpp, default osd2 is top */
-       blending->din_reoder_sel = 0;
-       for (i = 0; i < osd_hw.osd_meson_dev.osd_count - 1; i++) {
-               switch (blending->reorder[i]) {
-               /* blend_din1 is top, blend_din(3 4) is bottom layer */
-               case LAYER_1:
-                       blending->din_reoder_sel |= (i + 1) << 8;//blend_din3
-                       blending->osd_to_bdin_table[2] = i;//blend_din3 -- osdx
-                       break;
-               case LAYER_2:
-                       blending->din_reoder_sel |= (i + 1) << 0;//blend_din1
-                       blending->osd_to_bdin_table[0] = i;//blend_din4 -- osdx
-                       break;
-               case LAYER_3:
-                       blending->din_reoder_sel |= (i + 1) << 12;//blend_din4
-                       blending->osd_to_bdin_table[3] = i;//blend_din4 -- osdx
-                       break;
-               }
-       }
-       osd_log_dbg("osd_to_bdin_table[i]=[%x,%x,%x,%x]\n",
-               blending->osd_to_bdin_table[0],
-               blending->osd_to_bdin_table[1],
-               blending->osd_to_bdin_table[2],
-               blending->osd_to_bdin_table[3]);
-       osd_log_dbg("blending->din_reoder_sel=%d\n",
-               blending->din_reoder_sel);
-       blending->blend_reg.din_reoder_sel =
-               blending->din_reoder_sel;
 }
-#endif
 
 static bool is_freescale_para_changed(u32 index)
 {
@@ -5349,6 +5324,8 @@ static void osd_setting_blend0(struct hw_osd_blending_s *blending)
        if (layer_blend->input1 != BLEND_NO_DIN) {
                /* calculate osd blend din scope */
                index = blend_din_to_osd(layer_blend->input1, blending);
+               if (index >= OSD_MAX)
+                       return;
                bld_osd_h_start =
                        layer_blend->input1_data.x;
                bld_osd_h_end =
@@ -5426,6 +5403,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
 
        if (layer_blend->input1 != BLEND_NO_DIN) {
                index = blend_din_to_osd(layer_blend->input1, blending);
+               if (index >= OSD_MAX)
+                       return;
                /* calculate osd blend din scope */
                bld_osd_h_start =
                        layer_blend->input1_data.x;
@@ -5450,6 +5429,8 @@ static void osd_setting_blend1(struct hw_osd_blending_s *blending)
        }
        if (layer_blend->input2 != BLEND_NO_DIN) {
                index = blend_din_to_osd(layer_blend->input2, blending);
+               if (index >= OSD_MAX)
+                       return;
                /* calculate osd blend din scope */
                bld_osd_h_start =
                        layer_blend->input2_data.x;
@@ -5844,6 +5825,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        layer_blend->input1 |= BYPASS_DIN;
                layer_blend->input2 = BLEND_NO_DIN;
                index = blend_din_to_osd(BLEND_DIN1, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_setting_blend0_input(index, blending);
                osd_setting_blend0(blending);
 
@@ -5903,6 +5886,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                layer_blend->input1 = input1;
                layer_blend->input2 = BLEND_NO_DIN;
                index = blend_din_to_osd(input1, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_setting_blend0_input(index, blending);
                if (index != OSD1) {
                        /* here used freescale osd1/osd2 */
@@ -5916,6 +5901,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        sizeof(struct dispdata_s));
 
                index = blend_din_to_osd(input2, blending);
+               if (index >= OSD_MAX)
+                       return;
                if (index != OSD1) {
                        osd_log_dbg("before blend1: set osd%d freescale\n",
                                index);
@@ -5978,6 +5965,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        layer_blend->input1 |= BYPASS_DIN;
                layer_blend->input2 = BLEND_NO_DIN;
                index = blend_din_to_osd(BLEND_DIN1, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_setting_blend0_input(index, blending);
                osd_setting_blend0(blending);
 
@@ -6007,6 +5996,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        osd_hw.free_dst_data[index].y_start + 1;
 
                index = blend_din_to_osd(BLEND_DIN4, blending);
+               if (index >= OSD_MAX)
+                       return;
                /* here freescale osd1/osd2 used */
                osd_log_dbg("before blend1: set osd%d freescale\n", index);
                osd_set_freescale(index, blending->background_w,
@@ -6063,6 +6054,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                layer_blend->input1 = input1;
                layer_blend->input2 = BLEND_NO_DIN;
                index = blend_din_to_osd(input1, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_setting_blend0_input(index, blending);
                if (index != OSD1)
                        osd_log_err("not support case!!!\n");
@@ -6090,6 +6083,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        osd_hw.free_dst_data[index].y_end -
                        osd_hw.free_dst_data[index].y_start + 1;
                index = blend_din_to_osd(layer_blend->input2, blending);
+               if (index >= OSD_MAX)
+                       return;
                if (index != OSD1) {
                        osd_log_dbg("before blend1: set osd%d freescale\n",
                                index);
@@ -6139,6 +6134,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        layer_blend->input1 |= BYPASS_DIN;
                layer_blend->input2 = BLEND_NO_DIN;
                index = blend_din_to_osd(BLEND_DIN1, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_setting_blend0_input(index, blending);
                osd_setting_blend0(blending);
 
@@ -6168,6 +6165,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        osd_hw.free_dst_data[index].y_start + 1;
 
                index = blend_din_to_osd(BLEND_DIN3, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_log_dbg("before blend1: set osd%d freescale\n", index);
                osd_set_freescale(index, blending->background_w,
                        blending->background_h, blending);
@@ -6183,6 +6182,8 @@ static void set_blend_path(struct hw_osd_blending_s *blending)
                        osd_hw.free_dst_data[index].y_start + 1;
 
                index = blend_din_to_osd(BLEND_DIN4, blending);
+               if (index >= OSD_MAX)
+                       return;
                osd_log_dbg("before blend1: set osd%d freescale\n", index);
                osd_set_freescale(index, blending->background_w,
                        blending->background_h, blending);
index 03cab43..e383a2d 100644 (file)
@@ -62,7 +62,6 @@ int rdma_reset_tigger_flag;
 static DEFINE_SPINLOCK(rdma_lock);
 static struct rdma_table_item *rdma_table;
 static struct device *osd_rdma_dev;
-static struct page *table_pages;
 static void *osd_rdma_table_virt;
 static dma_addr_t osd_rdma_table_phy;
 static u32 table_paddr;
@@ -1338,7 +1337,6 @@ static int osd_rdma_init(void)
                goto error1;
        }
        of_dma_configure(osd_rdma_dev, osd_rdma_dev->of_node);
-       table_pages = dma_alloc_from_contiguous(osd_rdma_dev, 1, 4);
        osd_rdma_table_virt = dma_alloc_coherent(osd_rdma_dev, PAGE_SIZE,
                                        &osd_rdma_table_phy, GFP_KERNEL);