static int fimg2d_check_params(struct fimg2d_blit __user *u) { int w, h, i; struct fimg2d_param *p = &u->param; struct fimg2d_image *img, *buf[MAX_IMAGES] = image_table(u); struct fimg2d_scale *scl; struct fimg2d_clip *clp; struct fimg2d_rect *r; if (!u->dst) return -1; /* DST op makes no effect */ if (u->op < 0 || u->op == BLIT_OP_DST || u->op >= BLIT_OP_END) return -1; for (i = 0; i < MAX_IMAGES; i++) { img = buf[i]; if (!img) continue; w = img->width; h = img->height; r = &img->rect; /* 8000: max width & height */ if (w > 8000 || h > 8000 || r->x1 == r->x2 || r->y1 == r->y2) return -1; } scl = &p->scaling; if (scl->mode) { img = buf[ISRC]; r = &img->rect; /* src_w and src_h of scale must be the equal to src rect */ if (img->addr.type && ((rect_w(r) != scl->src_w) || (rect_h(r) != scl->src_h))) return -1; if (!scl->src_w || !scl->src_h || !scl->dst_w || !scl->dst_h) return -1; } clp = &p->clipping; if (clp->enable) { img = buf[IDST]; r = &img->rect; /* clip rect must be within dst rect */ if (clp->x1 >= r->x2 || clp->x2 <= r->x1 || clp->y1 >= r->y2 || clp->y2 <= r->y1) return -1; } return 0; }
static mlval ml_image_table(mlval argument) { argument = image_table(argument); if(argument == MLERROR) switch(errno) { case EIMPL: exn_raise_string(perv_exn_ref_save, "Image table not implemented"); case EIMAGEREAD: exn_raise_string(perv_exn_ref_save, "Error reading opened image file"); case EIMAGEOPEN: exn_raise_string(perv_exn_ref_save, "Unable to open image file"); default: exn_raise_string(perv_exn_ref_save, "Unexpected error from image_table()"); } return(argument); }
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, struct fimg2d_blit *blit) { int i, ret; struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit); struct fimg2d_bltcmd *cmd; cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; cmd->ctx = ctx; cmd->op = blit->op; cmd->sync = blit->sync; cmd->seq_no = blit->seq_no; memcpy(&cmd->param, &blit->param, sizeof(cmd->param)); for (i = 0; i < MAX_IMAGES; i++) { if (!buf[i]) continue; if (copy_from_user(&cmd->image[i], buf[i], sizeof(struct fimg2d_image))) { ret = -EFAULT; goto err_user; } } #ifdef CONFIG_VIDEO_FIMG2D_DEBUG fimg2d_dump_command(cmd); #endif if (fimg2d_check_params(info, cmd)) { printk(KERN_ERR "[%s] invalid params\n", __func__); fimg2d_dump_command(cmd); ret = -EINVAL; goto err_user; } fimg2d_fixup_params(cmd); ret = fimg2d_import_bufs(info, cmd); if (ret) goto err_user; /* add command node and increase ncmd */ spin_lock(&info->bltlock); if (atomic_read(&info->suspended)) { fimg2d_debug("fimg2d suspended, do sw fallback\n"); spin_unlock(&info->bltlock); ret = -EFAULT; goto err_user; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &info->cmd_q); fimg2d_debug("ctx %p ncmd(%d) seq_no(%u)\n", cmd->ctx, atomic_read(&ctx->ncmd), cmd->seq_no); spin_unlock(&info->bltlock); return 0; err_user: kfree(cmd); return ret; }
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, struct fimg2d_blit __user *u) { int i; struct fimg2d_bltcmd *cmd; struct fimg2d_image *buf[MAX_IMAGES] = image_table(u); #ifdef CONFIG_VIDEO_FIMG2D_DEBUG fimg2d_print_params(u); #endif if (info->err) { printk(KERN_ERR "[%s] device error, do sw fallback\n", __func__); return -EFAULT; } if (fimg2d_check_params(u)) { printk(KERN_ERR "[%s] invalid params\n", __func__); fimg2d_print_params(u); return -EINVAL; } cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM; cmd->ctx = ctx; cmd->op = u->op; cmd->seq_no = u->seq_no; cmd->sync = u->sync; if (copy_from_user(&cmd->param, &u->param, sizeof(cmd->param))) goto err_user; for (i = 0; i < MAX_IMAGES; i++) { if (!buf[i]) continue; if (copy_from_user(&cmd->image[i], buf[i], sizeof(cmd->image[i]))) goto err_user; } fimg2d_fixup_params(cmd); if (fimg2d_check_dma_sync(cmd)) goto err_user; /* add command node and increase ncmd */ spin_lock(&info->bltlock); if (atomic_read(&info->suspended)) { fimg2d_debug("fimg2d suspended, do sw fallback\n"); spin_unlock(&info->bltlock); goto err_user; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &info->cmd_q); fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n", cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd, atomic_read(&ctx->ncmd), cmd->seq_no); spin_unlock(&info->bltlock); return 0; err_user: kfree(cmd); return -EFAULT; }
int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx, struct fimg2d_blit *blit) { int i, ret; struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit); struct fimg2d_bltcmd *cmd; struct fimg2d_image dst; if (blit->dst) if (copy_from_user(&dst, (void *)blit->dst, sizeof(dst))) return -EFAULT; if ((blit->dst) && (dst.addr.type == ADDR_USER)) up_write(&page_alloc_slow_rwsem); cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if ((blit->dst) && (dst.addr.type == ADDR_USER)) down_write(&page_alloc_slow_rwsem); if (!cmd) return -ENOMEM; for (i = 0; i < MAX_IMAGES; i++) { if (!buf[i]) continue; if (copy_from_user(&cmd->image[i], buf[i], sizeof(struct fimg2d_image))) { ret = -EFAULT; goto err_user; } } cmd->ctx = ctx; cmd->op = blit->op; cmd->sync = blit->sync; cmd->seq_no = blit->seq_no; memcpy(&cmd->param, &blit->param, sizeof(cmd->param)); #ifdef CONFIG_VIDEO_FIMG2D_DEBUG fimg2d_dump_command(cmd); #endif if (fimg2d_check_params(cmd)) { printk(KERN_ERR "[%s] invalid params\n", __func__); fimg2d_dump_command(cmd); ret = -EINVAL; goto err_user; } fimg2d_fixup_params(cmd); if (fimg2d_check_dma_sync(cmd)) { ret = -EFAULT; goto err_user; } /* add command node and increase ncmd */ spin_lock(&info->bltlock); if (atomic_read(&info->suspended)) { fimg2d_debug("fimg2d suspended, do sw fallback\n"); spin_unlock(&info->bltlock); ret = -EFAULT; goto err_user; } atomic_inc(&ctx->ncmd); fimg2d_enqueue(&cmd->node, &info->cmd_q); fimg2d_debug("ctx %p pgd %p ncmd(%d) seq_no(%u)\n", cmd->ctx, (unsigned long *)cmd->ctx->mm->pgd, atomic_read(&ctx->ncmd), cmd->seq_no); spin_unlock(&info->bltlock); return 0; err_user: kfree(cmd); return ret; }