From patchwork Wed Jun 3 10:36:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 6533981 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2C8149F1CC for ; Wed, 3 Jun 2015 10:36:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2184D205E2 for ; Wed, 3 Jun 2015 10:36:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 39E41206AC for ; Wed, 3 Jun 2015 10:36:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751701AbbFCKgk (ORCPT ); Wed, 3 Jun 2015 06:36:40 -0400 Received: from mailout3.w1.samsung.com ([210.118.77.13]:57415 "EHLO mailout3.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751395AbbFCKgi (ORCPT ); Wed, 3 Jun 2015 06:36:38 -0400 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0NPD00LWL6SZ3R80@mailout3.w1.samsung.com> for linux-media@vger.kernel.org; Wed, 03 Jun 2015 11:36:35 +0100 (BST) X-AuditID: cbfec7f4-f79c56d0000012ee-93-556ed8b3eb6a Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id BA.DB.04846.3B8DE655; Wed, 3 Jun 2015 11:36:35 +0100 (BST) Received: from amdc1339.digital.local ([106.116.147.30]) by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0NPD008726SV6X80@eusync3.samsung.com>; Wed, 03 Jun 2015 11:36:35 +0100 (BST) From: Marek Szyprowski To: linux-media@vger.kernel.org Cc: Marek Szyprowski , Sylwester Nawrocki Subject: [PATCH 2/2] media: s5p-mfc: add additional check for incorrect memory configuration Date: Wed, 03 Jun 2015 12:36:23 +0200 Message-id: <1433327783-29552-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.9.2 In-reply-to: <1433327783-29552-1-git-send-email-m.szyprowski@samsung.com> References: <1433327783-29552-1-git-send-email-m.szyprowski@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrOJMWRmVeSWpSXmKPExsVy+t/xq7qbb+SFGrRPsLCYeaKd1aJnw1ZW i7VH7rJbHH7TzurA4tG3ZRWjx+dNch5XjjSyBzBHcdmkpOZklqUW6dslcGUsa5vHXPBer+Jz s2ED4wH1LkYODgkBE4kfd3i7GDmBTDGJC/fWs4HYQgJLGSX6N3J0MXIB2U1MEhPaXjKDJNgE DCW63naBFYkIyEs86b0BZjMLxEn0HX0GViMMZP9a95wJxGYRUJX4vKyLBcTmFfCQeLXqKzvE MjmJ/y9XgNVwCnhKXLrdwghyjxBQzc3ZahMYeRcwMqxiFE0tTS4oTkrPNdQrTswtLs1L10vO z93ECAmOLzsYFx+zOsQowMGoxMM7IyIvVIg1say4MvcQowQHs5II762zQCHelMTKqtSi/Pii 0pzU4kOM0hwsSuK8c3e9DxESSE8sSc1OTS1ILYLJMnFwSjUwNv0TqCq5UtkZ/CgvadnNCbmr b5h/O7PrW9Qp4bz9lf7394ffO2LV5uQ+a3lf8+WQBpXV7rXyk49u2PqFP/qdVsNEAaaeZK4J Tg/f2C8Qnnlm33aR1+9ZLW7V/3YQmWBcvezrldDzT93i7CfOnlg91S9810njd2mJGhbrnJqW pBrP8hbzXnnQT4mlOCPRUIu5qDgRAKlw2iwKAgAA Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP MFC hardware is known to trash random memory if one tries to use a buffer buffer, which has lower DMA addresses than the configured DMA base address. This patch adds a check for this case and proper error handling. Signed-off-by: Marek Szyprowski Acked-by: Kamil Debski --- drivers/media/platform/s5p-mfc/s5p_mfc_opr.c | 11 +++++++++-- drivers/media/platform/s5p-mfc/s5p_mfc_opr.h | 2 +- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c | 12 +++++++----- drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c | 8 +++++--- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c index 00a1d8b..8d27f88 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.c @@ -37,10 +37,9 @@ void s5p_mfc_init_regs(struct s5p_mfc_dev *dev) dev->mfc_regs = s5p_mfc_init_regs_v6_plus(dev); } -int s5p_mfc_alloc_priv_buf(struct device *dev, +int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, struct s5p_mfc_priv_buf *b) { - mfc_debug(3, "Allocating priv: %zu\n", b->size); b->virt = dma_alloc_coherent(dev, b->size, &b->dma, GFP_KERNEL); @@ -50,6 +49,14 @@ int s5p_mfc_alloc_priv_buf(struct device *dev, return -ENOMEM; } + if (b->dma < base) { + mfc_err("Invaling memory configuration!\n"); + mfc_err("Allocated buffer (%pad) is lower than memory base addres (%pad)\n", + &b->dma, &base); + dma_free_coherent(dev, b->size, b->virt, b->dma); + return -ENOMEM; + } + mfc_debug(3, "Allocated addr %p %pad\n", b->virt, &b->dma); return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h index 22dfb3e..77a08b1 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr.h @@ -334,7 +334,7 @@ struct s5p_mfc_hw_ops { void s5p_mfc_init_hw_ops(struct s5p_mfc_dev *dev); void s5p_mfc_init_regs(struct s5p_mfc_dev *dev); -int s5p_mfc_alloc_priv_buf(struct device *dev, +int s5p_mfc_alloc_priv_buf(struct device *dev, dma_addr_t base, struct s5p_mfc_priv_buf *b); void s5p_mfc_release_priv_buf(struct device *dev, struct s5p_mfc_priv_buf *b); diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index c7adc3d..b3f6700 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -41,7 +41,7 @@ static int s5p_mfc_alloc_dec_temp_buffers_v5(struct s5p_mfc_ctx *ctx) int ret; ctx->dsc.size = buf_size->dsc; - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->dsc); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->dsc); if (ret) { mfc_err("Failed to allocate temporary buffer\n"); return ret; @@ -172,7 +172,8 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) /* Allocate only if memory from bank 1 is necessary */ if (ctx->bank1.size > 0) { - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->bank1); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, + &ctx->bank1); if (ret) { mfc_err("Failed to allocate Bank1 temporary buffer\n"); return ret; @@ -181,7 +182,8 @@ static int s5p_mfc_alloc_codec_buffers_v5(struct s5p_mfc_ctx *ctx) } /* Allocate only if memory from bank 2 is necessary */ if (ctx->bank2.size > 0) { - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_r, &ctx->bank2); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_r, dev->bank2, + &ctx->bank2); if (ret) { mfc_err("Failed to allocate Bank2 temporary buffer\n"); s5p_mfc_release_priv_buf(ctx->dev->mem_dev_l, &ctx->bank1); @@ -212,7 +214,7 @@ static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) else ctx->ctx.size = buf_size->non_h264_ctx; - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->ctx); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->ctx); if (ret) { mfc_err("Failed to allocate instance buffer\n"); return ret; @@ -225,7 +227,7 @@ static int s5p_mfc_alloc_instance_buffer_v5(struct s5p_mfc_ctx *ctx) /* Initialize shared memory */ ctx->shm.size = buf_size->shm; - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->shm); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->shm); if (ret) { mfc_err("Failed to allocate shared memory buffer\n"); s5p_mfc_release_priv_buf(dev->mem_dev_l, &ctx->ctx); diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index cefad18..ed6b14c 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -239,7 +239,8 @@ static int s5p_mfc_alloc_codec_buffers_v6(struct s5p_mfc_ctx *ctx) /* Allocate only if memory from bank 1 is necessary */ if (ctx->bank1.size > 0) { - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->bank1); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, + &ctx->bank1); if (ret) { mfc_err("Failed to allocate Bank1 memory\n"); return ret; @@ -291,7 +292,7 @@ static int s5p_mfc_alloc_instance_buffer_v6(struct s5p_mfc_ctx *ctx) break; } - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &ctx->ctx); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, &ctx->ctx); if (ret) { mfc_err("Failed to allocate instance buffer\n"); return ret; @@ -320,7 +321,8 @@ static int s5p_mfc_alloc_dev_context_buffer_v6(struct s5p_mfc_dev *dev) mfc_debug_enter(); dev->ctx_buf.size = buf_size->dev_ctx; - ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, &dev->ctx_buf); + ret = s5p_mfc_alloc_priv_buf(dev->mem_dev_l, dev->bank1, + &dev->ctx_buf); if (ret) { mfc_err("Failed to allocate device context buffer\n"); return ret;