From patchwork Fri Apr 10 08:42:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Praveen Paneri X-Patchwork-Id: 6192951 Return-Path: X-Original-To: patchwork-intel-gfx@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 89D109F725 for ; Fri, 10 Apr 2015 08:39:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 354D2203C4 for ; Fri, 10 Apr 2015 08:39:26 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6983720351 for ; Fri, 10 Apr 2015 08:39:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B657E6E8E2; Fri, 10 Apr 2015 01:39:23 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id E40536E8E2 for ; Fri, 10 Apr 2015 01:39:20 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 10 Apr 2015 01:39:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,555,1422950400"; d="scan'208";a="706745155" Received: from intel-desktop.iind.intel.com ([10.223.82.37]) by fmsmga002.fm.intel.com with ESMTP; 10 Apr 2015 01:39:19 -0700 From: Praveen Paneri To: intel-gfx@lists.freedesktop.org Date: Fri, 10 Apr 2015 14:12:54 +0530 Message-Id: <1428655383-26087-3-git-send-email-praveen.paneri@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1428655383-26087-1-git-send-email-praveen.paneri@intel.com> References: <1428655383-26087-1-git-send-email-praveen.paneri@intel.com> Cc: Praveen Paneri Subject: [Intel-gfx] [PATCH 02/11] intel: Validate output of realloc() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 realloc will return NULL if failed to allocate the extra memory requested. Return -ENOMEM from the function if it fails. v2: Modifications to propagate relloc failure to caller functions and skip the execbuffer ioctl. (Chris) Signed-off-by: Praveen Paneri --- intel/intel_bufmgr_gem.c | 96 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 27 deletions(-) diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c index 5a67f53..91320ca 100644 --- a/intel/intel_bufmgr_gem.c +++ b/intel/intel_bufmgr_gem.c @@ -427,15 +427,17 @@ drm_intel_gem_bo_reference(drm_intel_bo *bo) * with the intersection of the memory type flags and the union of the * access flags. */ -static void +static int drm_intel_add_validate_buffer(drm_intel_bo *bo) { drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *) bo->bufmgr; drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; int index; + struct drm_i915_gem_exec_object *exec_objects; + drm_intel_bo **exec_bos; if (bo_gem->validate_index != -1) - return; + return 0; /* Extend the array of validation entries as necessary. */ if (bufmgr_gem->exec_count == bufmgr_gem->exec_size) { @@ -444,12 +446,22 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo) if (new_size == 0) new_size = 5; - bufmgr_gem->exec_objects = - realloc(bufmgr_gem->exec_objects, - sizeof(*bufmgr_gem->exec_objects) * new_size); - bufmgr_gem->exec_bos = - realloc(bufmgr_gem->exec_bos, + exec_objects = realloc(bufmgr_gem->exec_objects, + sizeof(*bufmgr_gem->exec_objects) * new_size); + if (!exec_objects) { + return -ENOMEM; + } + + bufmgr_gem->exec_objects = exec_objects; + + exec_bos = realloc(bufmgr_gem->exec_bos, sizeof(*bufmgr_gem->exec_bos) * new_size); + if (!exec_bos) { + return -ENOMEM; + } + + bufmgr_gem->exec_bos = exec_bos; + bufmgr_gem->exec_size = new_size; } @@ -463,20 +475,23 @@ drm_intel_add_validate_buffer(drm_intel_bo *bo) bufmgr_gem->exec_objects[index].offset = 0; bufmgr_gem->exec_bos[index] = bo; bufmgr_gem->exec_count++; + return 0; } -static void +static int drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence) { drm_intel_bufmgr_gem *bufmgr_gem = (drm_intel_bufmgr_gem *)bo->bufmgr; drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; int index; + struct drm_i915_gem_exec_object2 *exec2_objects; + drm_intel_bo **exec_bos; if (bo_gem->validate_index != -1) { if (need_fence) bufmgr_gem->exec2_objects[bo_gem->validate_index].flags |= EXEC_OBJECT_NEEDS_FENCE; - return; + return 0; } /* Extend the array of validation entries as necessary. */ @@ -486,12 +501,19 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence) if (new_size == 0) new_size = 5; - bufmgr_gem->exec2_objects = - realloc(bufmgr_gem->exec2_objects, + exec2_objects = realloc(bufmgr_gem->exec2_objects, sizeof(*bufmgr_gem->exec2_objects) * new_size); - bufmgr_gem->exec_bos = - realloc(bufmgr_gem->exec_bos, + if (!exec2_objects) + return -ENOMEM; + + bufmgr_gem->exec2_objects = exec2_objects; + + exec_bos = realloc(bufmgr_gem->exec_bos, sizeof(*bufmgr_gem->exec_bos) * new_size); + if (!exec_bos) + return -ENOMEM; + + bufmgr_gem->exec_bos = exec_bos; bufmgr_gem->exec_size = new_size; } @@ -512,6 +534,7 @@ drm_intel_add_validate_buffer2(drm_intel_bo *bo, int need_fence) EXEC_OBJECT_NEEDS_FENCE; } bufmgr_gem->exec_count++; + return 0; } #define RELOC_BUF_SIZE(x) ((I915_RELOC_HEADER + x * I915_RELOC0_STRIDE) * \ @@ -1931,14 +1954,14 @@ drm_intel_gem_bo_clear_relocs(drm_intel_bo *bo, int start) * validations to be performed and update the relocation buffers with * index values into the validation list. */ -static void +static int drm_intel_gem_bo_process_reloc(drm_intel_bo *bo) { drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo; - int i; + int i, ret = 0; if (bo_gem->relocs == NULL) - return; + return 0; for (i = 0; i < bo_gem->reloc_count; i++) { drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo; @@ -1949,21 +1972,26 @@ drm_intel_gem_bo_process_reloc(drm_intel_bo *bo) drm_intel_gem_bo_mark_mmaps_incoherent(bo); /* Continue walking the tree depth-first. */ - drm_intel_gem_bo_process_reloc(target_bo); + ret = drm_intel_gem_bo_process_reloc(target_bo); + if (ret) + break; /* Add the target to the validate list */ - drm_intel_add_validate_buffer(target_bo); + ret = drm_intel_add_validate_buffer(target_bo); + if (ret) + break; } + return ret; } -static void +static int drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo) { drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo; - int i; + int i, ret = 0; if (bo_gem->relocs == NULL) - return; + return 0; for (i = 0; i < bo_gem->reloc_count; i++) { drm_intel_bo *target_bo = bo_gem->reloc_target_info[i].bo; @@ -1975,14 +2003,19 @@ drm_intel_gem_bo_process_reloc2(drm_intel_bo *bo) drm_intel_gem_bo_mark_mmaps_incoherent(bo); /* Continue walking the tree depth-first. */ - drm_intel_gem_bo_process_reloc2(target_bo); + ret = drm_intel_gem_bo_process_reloc2(target_bo); + if (ret) + break; need_fence = (bo_gem->reloc_target_info[i].flags & DRM_INTEL_RELOC_FENCE); /* Add the target to the validate list */ - drm_intel_add_validate_buffer2(target_bo, need_fence); + ret = drm_intel_add_validate_buffer2(target_bo, need_fence); + if (ret) + break; } + return ret; } @@ -2334,12 +2367,16 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used, pthread_mutex_lock(&bufmgr_gem->lock); /* Update indices and set up the validate list. */ - drm_intel_gem_bo_process_reloc(bo); + ret = drm_intel_gem_bo_process_reloc(bo); + if (ret) + goto skip_execution; /* Add the batch buffer to the validation list. There are no * relocations pointing to it. */ - drm_intel_add_validate_buffer(bo); + ret = drm_intel_add_validate_buffer(bo); + if (ret) + goto skip_execution; memclear(execbuf); execbuf.buffers_ptr = (uintptr_t) bufmgr_gem->exec_objects; @@ -2370,6 +2407,7 @@ drm_intel_gem_bo_exec(drm_intel_bo *bo, int used, } drm_intel_update_buffer_offsets(bufmgr_gem); +skip_execution: if (bufmgr_gem->bufmgr.debug) drm_intel_gem_dump_validation_list(bufmgr_gem); @@ -2421,12 +2459,16 @@ do_exec2(drm_intel_bo *bo, int used, drm_intel_context *ctx, pthread_mutex_lock(&bufmgr_gem->lock); /* Update indices and set up the validate list. */ - drm_intel_gem_bo_process_reloc2(bo); + ret = drm_intel_gem_bo_process_reloc2(bo); + if (ret) + goto skip_execution; /* Add the batch buffer to the validation list. There are no relocations * pointing to it. */ - drm_intel_add_validate_buffer2(bo, 0); + ret = drm_intel_add_validate_buffer2(bo, 0); + if (ret) + goto skip_execution; memclear(execbuf); execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec2_objects;