From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01F95C00140 for ; Sat, 13 Aug 2022 01:09:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237471AbiHMBI7 (ORCPT ); Fri, 12 Aug 2022 21:08:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237399AbiHMBI6 (ORCPT ); Fri, 12 Aug 2022 21:08:58 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B837373304 for ; Fri, 12 Aug 2022 18:08:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352937; x=1691888937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Zi/lCjUXpkF6B8O4jozC9jJ60/Hc8bXroWDXph0b3Rk=; b=AWYrgkwdwqh+Te1oqwBBwk5+9RyG5cWoqSg/FL+2lXoh/+Sqblcs5RGE q6lI5qd/ZwUaRIDIcBy757pAiIcuyyr42BZftsHnZ0ZXO7ql0Niqb7xHP +p55qeq2P6reSvKtMSn4isjYmn/v2aoeVbn+Sla6DjPmu7sFYq3cGuskT ySCcfBQqKSwdcI/OE+wKYuhX/ygPk2G/tVZ8gxzJNlIlGUScCXdS4lguN Voj1N904uyCKsSqFsdHv0crHqWEnpavcGzoP7VlZUNOTUibrCWkUMiCPj LnmZnFyfLyEDE/dVADfFhVBO6svcvhtdlAUrA6PjBBBuqYP8LSrSbceD6 Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488706" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488706" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:08:57 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038333" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:08:54 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 1/8] overflow: Move and add few utility macros into overflow Date: Sat, 13 Aug 2022 04:08:50 +0300 Message-Id: <20220813010857.4043956-2-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It moves overflows_type utility macro into overflow header from i915_utils header. The overflows_type can be used to catch the truncation between data types. And it adds safe_conversion() macro which performs a type conversion (cast) of an source value into a new variable, checking that the destination is large enough to hold the source value. And the functionality of overflows_type has been improved to handle the signbit. The is_unsigned_type macro has been added to check the sign bit of the built-in type. v3: Add is_type_unsigned() macro (Mauro) Modify overflows_type() macro to consider signed data types (Mauro) Fix the problem that safe_conversion() macro always returns true v4: Fix kernel-doc markups v6: Move macro addition location so that it can be used by other than drm subsystem (Jani, Mauro, Andi) Change is_type_unsigned to is_unsigned_type to have the same name form as is_signed_type macro Signed-off-by: Gwan-gyeong Mun Cc: Thomas Hellstr=C3=B6m Cc: Matthew Auld Cc: Nirmoy Das Cc: Jani Nikula Cc: Andi Shyti Reviewed-by: Mauro Carvalho Chehab (v5) --- drivers/gpu/drm/i915/i915_utils.h | 5 +-- include/linux/overflow.h | 54 +++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_= utils.h index c10d68cdc3ca..eb0ded23fa9c 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -32,6 +32,7 @@ #include #include #include +#include =20 #ifdef CONFIG_X86 #include @@ -111,10 +112,6 @@ bool i915_error_injected(void); #define range_overflows_end_t(type, start, size, max) \ range_overflows_end((type)(start), (type)(size), (type)(max)) =20 -/* Note we don't consider signbits :| */ -#define overflows_type(x, T) \ - (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T)) - #define ptr_mask_bits(ptr, n) ({ \ unsigned long __v =3D (unsigned long)(ptr); \ (typeof(ptr))(__v & -BIT(n)); \ diff --git a/include/linux/overflow.h b/include/linux/overflow.h index f1221d11f8e5..462a03454377 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -35,6 +35,60 @@ #define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) #define type_min(T) ((T)((T)-type_max(T)-(T)1)) =20 +/** + * is_unsigned_type - helper for checking data type which is an unsigned d= ata + * type or not + * @x: The data type to check + * + * Returns: + * True if the data type is an unsigned data type, false otherwise. + */ +#define is_unsigned_type(x) ((typeof(x))-1 >=3D (typeof(x))0) + +/** + * overflows_type - helper for checking the truncation between data types + * @x: Source for overflow type comparison + * @T: Destination for overflow type comparison + * + * It compares the values and size of each data type between the first and + * second argument to check whether truncation can occur when assigning the + * first argument to the variable of the second argument. + * Source and Destination can be used with or without sign bit. + * Composite data structures such as union and structure are not considere= d. + * Enum data types are not considered. + * Floating point data types are not considered. + * + * Returns: + * True if truncation can occur, false otherwise. + */ +#define overflows_type(x, T) \ + (is_unsigned_type(x) ? \ + is_unsigned_type(T) ? \ + (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T)) ? 1 : 0 \ + : (sizeof(x) >=3D sizeof(T) && (x) >> (BITS_PER_TYPE(T) - 1)) ? 1 : 0 \ + : is_unsigned_type(T) ? \ + ((x) < 0) ? 1 : (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T)) ? 1 := 0 \ + : (sizeof(x) > sizeof(T)) ? \ + ((x) < 0) ? (((x) * -1) >> BITS_PER_TYPE(T)) ? 1 : 0 \ + : ((x) >> BITS_PER_TYPE(T)) ? 1 : 0 \ + : 0) + +/** + * safe_conversion - perform a type conversion (cast) of an source value i= nto + * a new variable, checking that the destination is large enough to hold t= he + * source value. + * @ptr: Destination pointer address + * @value: Source value + * + * Returns: + * If the value would overflow the destination, it returns false. + */ +#define safe_conversion(ptr, value) ({ \ + typeof(value) __v =3D (value); \ + typeof(ptr) __ptr =3D (ptr); \ + overflows_type(__v, *__ptr) ? 0 : ((*__ptr =3D (typeof(*__ptr))__v), 1); \ +}) + /* * Avoids triggering -Wtype-limits compilation warning, * while using unsigned data types to check a < 0. --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C217C00140 for ; Sat, 13 Aug 2022 01:09:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235950AbiHMBJK (ORCPT ); Fri, 12 Aug 2022 21:09:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237585AbiHMBJB (ORCPT ); Fri, 12 Aug 2022 21:09:01 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDE5E7333B for ; Fri, 12 Aug 2022 18:09:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352940; x=1691888940; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=htBXzFuj58kSVBgpeaRLCDJaLlWQVrwWv47Dz051D/g=; b=iUfuIuIKeGi7G4MXOuqOnCWRKZEZJ1a1MS/JvW3tE/czdnZrBmzcFT4y /RaIkmFCue2JKlaJ6iotByD+AKGfT9rAOgPttB6Hg7vgG/z35gAdXNhEu RuBzi8OMDnnyZuYEx8x5nnyOHJJh9A/H4prOQEds8Px/3DAE2bX7bC74O Ib7m4DLLe6BGDegrA+O3s6C9rheAIwmOWyXtHx1LdXC96cG5ecEFdRokd 7cen3Ik6KiorOOgiA0COWjEml8Tkjd5l5GIbHyUdj4S76hPL2PlZzbEVi JbkUGHZttFwOE5f/zYnnNlWcTbxy2b2pVPiKNDyF1t1sAE84Jeu6E7BXY Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488712" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488712" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:00 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038345" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:08:57 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 2/8] util_macros: Add exact_type macro to catch type mis-match while compiling Date: Sat, 13 Aug 2022 04:08:51 +0300 Message-Id: <20220813010857.4043956-3-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org It adds exact_type and exactly_pgoff_t macro to catch type mis-match while compiling. The existing typecheck() macro outputs build warnings, but the newly added exact_type() macro uses the BUILD_BUG_ON() macro to generate a build break when the types are different and can be used to detect explicit build errors. v6: Move macro addition location so that it can be used by other than drm subsystem (Jani, Mauro, Andi) Signed-off-by: Gwan-gyeong Mun Cc: Thomas Hellstr=C3=B6m Cc: Matthew Auld Cc: Nirmoy Das Cc: Jani Nikula Cc: Andi Shyti Cc: Mauro Carvalho Chehab --- include/linux/util_macros.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/linux/util_macros.h b/include/linux/util_macros.h index 72299f261b25..b6624b275257 100644 --- a/include/linux/util_macros.h +++ b/include/linux/util_macros.h @@ -2,6 +2,9 @@ #ifndef _LINUX_HELPER_MACROS_H_ #define _LINUX_HELPER_MACROS_H_ =20 +#include +#include + #define __find_closest(x, a, as, op) \ ({ \ typeof(as) __fc_i, __fc_as =3D (as) - 1; \ @@ -38,4 +41,26 @@ */ #define find_closest_descending(x, a, as) __find_closest(x, a, as, >=3D) =20 +/** + * exact_type - break compile if source type and destination value's type = are + * not the same + * @T: Source type + * @n: Destination value + * + * It is a helper macro for a poor man's -Wconversion: only allow variable= s of + * an exact type. It determines whether the source type and destination va= lue's + * type are the same while compiling, and it breaks compile if two types a= re + * not the same + */ +#define exact_type(T, n) \ + BUILD_BUG_ON(!__builtin_constant_p(n) && !__builtin_types_compatible_p(T,= typeof(n))) + +/** + * exactly_pgoff_t - helper to check if the type of a value is pgoff_t + * @n: value to compare pgoff_t type + * + * It breaks compile if the argument value's type is not pgoff_t type. + */ +#define exactly_pgoff_t(n) exact_type(pgoff_t, n) + #endif --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9110AC00140 for ; Sat, 13 Aug 2022 01:09:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236842AbiHMBJT (ORCPT ); Fri, 12 Aug 2022 21:09:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237698AbiHMBJJ (ORCPT ); Fri, 12 Aug 2022 21:09:09 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01595A8CD6 for ; Fri, 12 Aug 2022 18:09:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352944; x=1691888944; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Jz4G4Bh+G9hkJSxOZhLjhOWAWEO1ybZ8FBgK2ABpa4k=; b=Fn12sQ1VA+FSql21JpdmHSZIGkURLcCWkz+wf8j6ACBtViZ/YIDILilj 8gbrR1Ddy+vToExOHsRmjTXosbv+8hLpYNfQV45H4PDXU/cy0efAQS2Yh jxhhMTzIG2rT6VuOAUeMNdURrNKdCeE9JwPXNXe4GlGaXuL1BMx41WGBV i9sRzil6iUbjZYAHQ0wjwB+pUnic88CBN4H80l/y6xbz/T+rksaO9pJWY YyGz1ZYlU8J0alXIGttMcLEXteuOKgzFa52F5zJGTPtcFTP0NOVJs70y3 LupFAZ9Md7pCtR5nX2dofQhlSQT+1I0eQr/6fVTpiAR8tjDhh/7wlkjGF w==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488723" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488723" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:04 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038365" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:01 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 3/8] drm/i915/gem: Typecheck page lookups Date: Sat, 13 Aug 2022 04:08:52 +0300 Message-Id: <20220813010857.4043956-4-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chris Wilson We need to check that we avoid integer overflows when looking up a page, and so fix all the instances where we have mistakenly used a plain integer instead of a more suitable long. Be pedantic and add integer typechecking to the lookup so that we can be sure that we are safe. And it also uses pgoff_t as our page lookups must remain compatible with the page cache, pgoff_t is currently exactly unsigned long. v2: Move added i915_utils's macro into drm_util header (Jani N) v3: Make not use the same macro name on a function. (Mauro) For kernel-doc, macros and functions are handled in the same namespace, the same macro name on a function prevents ever adding documentation for it. v4: Add kernel-doc markups to the kAPI functions and macros (Mauoro) v5: Fix an alignment to match open parenthesis v6: Rebase Signed-off-by: Chris Wilson Signed-off-by: Gwan-gyeong Mun Cc: Tvrtko Ursulin Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Reviewed-by: Nirmoy Das Reviewed-by: Mauro Carvalho Chehab Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/gem/i915_gem_object.c | 7 +- drivers/gpu/drm/i915/gem/i915_gem_object.h | 293 ++++++++++++++++-- drivers/gpu/drm/i915/gem/i915_gem_pages.c | 27 +- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 2 +- .../drm/i915/gem/selftests/i915_gem_context.c | 12 +- .../drm/i915/gem/selftests/i915_gem_mman.c | 8 +- .../drm/i915/gem/selftests/i915_gem_object.c | 8 +- drivers/gpu/drm/i915/i915_gem.c | 18 +- drivers/gpu/drm/i915/i915_utils.h | 1 + drivers/gpu/drm/i915/i915_vma.c | 8 +- 10 files changed, 323 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i= 915/gem/i915_gem_object.c index 389e9f157ca5..b3861739c1eb 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c @@ -413,10 +413,11 @@ void __i915_gem_object_invalidate_frontbuffer(struct = drm_i915_gem_object *obj, static void i915_gem_object_read_from_page_kmap(struct drm_i915_gem_object *obj, u64 o= ffset, void *dst, int size) { + pgoff_t idx =3D offset >> PAGE_SHIFT; void *src_map; void *src_ptr; =20 - src_map =3D kmap_atomic(i915_gem_object_get_page(obj, offset >> PAGE_SHIF= T)); + src_map =3D kmap_atomic(i915_gem_object_get_page(obj, idx)); =20 src_ptr =3D src_map + offset_in_page(offset); if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) @@ -429,9 +430,10 @@ i915_gem_object_read_from_page_kmap(struct drm_i915_ge= m_object *obj, u64 offset, static void i915_gem_object_read_from_page_iomap(struct drm_i915_gem_object *obj, u64 = offset, void *dst, int size) { + pgoff_t idx =3D offset >> PAGE_SHIFT; + dma_addr_t dma =3D i915_gem_object_get_dma_address(obj, idx); void __iomem *src_map; void __iomem *src_ptr; - dma_addr_t dma =3D i915_gem_object_get_dma_address(obj, offset >> PAGE_SH= IFT); =20 src_map =3D io_mapping_map_wc(&obj->mm.region->iomap, dma - obj->mm.region->region.start, @@ -460,6 +462,7 @@ i915_gem_object_read_from_page_iomap(struct drm_i915_ge= m_object *obj, u64 offset */ int i915_gem_object_read_from_page(struct drm_i915_gem_object *obj, u64 of= fset, void *dst, int size) { + GEM_BUG_ON(overflows_type(offset >> PAGE_SHIFT, pgoff_t)); GEM_BUG_ON(offset >=3D obj->base.size); GEM_BUG_ON(offset_in_page(offset) > PAGE_SIZE - size); GEM_BUG_ON(!i915_gem_object_has_pinned_pages(obj)); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i= 915/gem/i915_gem_object.h index 6f0a3ce35567..5da872afc4ba 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -27,8 +27,10 @@ enum intel_region_id; * spot such a local variable, please consider fixing! * * Aside from our own locals (for which we have no excuse!): - * - sg_table embeds unsigned int for num_pages - * - get_user_pages*() mixed ints with longs + * - sg_table embeds unsigned int for nents + * + * We can check for invalidly typed locals with typecheck(), see for examp= le + * i915_gem_object_get_sg(). */ #define GEM_CHECK_SIZE_OVERFLOW(sz) \ GEM_WARN_ON((sz) >> PAGE_SHIFT > INT_MAX) @@ -363,44 +365,289 @@ i915_gem_object_get_tile_row_size(const struct drm_i= 915_gem_object *obj) int i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, unsigned int tiling, unsigned int stride); =20 +/** + * __i915_gem_object_page_iter_get_sg - helper to find the target scatterl= ist + * pointer and the target page position using pgoff_t n input argument and + * i915_gem_object_page_iter + * @obj: i915 GEM buffer object + * @iter: i915 GEM buffer object page iterator + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * Context: Takes and releases the mutex lock of the i915_gem_object_page_= iter. + * Takes and releases the RCU lock to search the radix_tree of + * i915_gem_object_page_iter. + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * Recommended to use wrapper macro: i915_gem_object_page_iter_get_sg() + */ struct scatterlist * -__i915_gem_object_get_sg(struct drm_i915_gem_object *obj, - struct i915_gem_object_page_iter *iter, - unsigned int n, - unsigned int *offset, bool dma); +__i915_gem_object_page_iter_get_sg(struct drm_i915_gem_object *obj, + struct i915_gem_object_page_iter *iter, + pgoff_t n, + unsigned int *offset); =20 +/** + * i915_gem_object_page_iter_get_sg - wrapper macro for + * __i915_gem_object_page_iter_get_sg() + * @obj: i915 GEM buffer object + * @it: i915 GEM buffer object page iterator + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * Context: Takes and releases the mutex lock of the i915_gem_object_page_= iter. + * Takes and releases the RCU lock to search the radix_tree of + * i915_gem_object_page_iter. + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_page_iter_get_sg(). + */ +#define i915_gem_object_page_iter_get_sg(obj, it, n, offset) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_page_iter_get_sg(obj, it, n, offset); \ +}) + +/** + * __i915_gem_object_get_sg - helper to find the target scatterlist + * pointer and the target page position using pgoff_t n input argument and + * drm_i915_gem_object. It uses an internal shmem scatterlist lookup funct= ion. + * @obj: i915 GEM buffer object + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * It uses drm_i915_gem_object's internal shmem scatterlist lookup functio= n as + * i915_gem_object_page_iter and calls __i915_gem_object_page_iter_get_sg(= ). + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * Recommended to use wrapper macro: i915_gem_object_get_sg() + * See also __i915_gem_object_page_iter_get_sg() + */ static inline struct scatterlist * -i915_gem_object_get_sg(struct drm_i915_gem_object *obj, - unsigned int n, - unsigned int *offset) +__i915_gem_object_get_sg(struct drm_i915_gem_object *obj, pgoff_t n, + unsigned int *offset) { - return __i915_gem_object_get_sg(obj, &obj->mm.get_page, n, offset, false); + return __i915_gem_object_page_iter_get_sg(obj, &obj->mm.get_page, n, offs= et); } =20 +/** + * i915_gem_object_get_sg - wrapper macro for __i915_gem_object_get_sg() + * @obj: i915 GEM buffer object + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_sg(). + * See also __i915_gem_object_page_iter_get_sg() + */ +#define i915_gem_object_get_sg(obj, n, offset) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_sg(obj, n, offset); \ +}) + +/** + * __i915_gem_object_get_sg_dma - helper to find the target scatterlist + * pointer and the target page position using pgoff_t n input argument and + * drm_i915_gem_object. It uses an internal DMA mapped scatterlist lookup = function + * @obj: i915 GEM buffer object + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * It uses drm_i915_gem_object's internal DMA mapped scatterlist lookup fu= nction + * as i915_gem_object_page_iter and calls __i915_gem_object_page_iter_get_= sg(). + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * Recommended to use wrapper macro: i915_gem_object_get_sg_dma() + * See also __i915_gem_object_page_iter_get_sg() + */ static inline struct scatterlist * -i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj, - unsigned int n, - unsigned int *offset) +__i915_gem_object_get_sg_dma(struct drm_i915_gem_object *obj, pgoff_t n, + unsigned int *offset) { - return __i915_gem_object_get_sg(obj, &obj->mm.get_dma_page, n, offset, tr= ue); + return __i915_gem_object_page_iter_get_sg(obj, &obj->mm.get_dma_page, n, = offset); } =20 +/** + * i915_gem_object_get_sg_dma - wrapper macro for __i915_gem_object_get_sg= _dma() + * @obj: i915 GEM buffer object + * @n: page offset + * @offset: searched physical offset, + * it will be used for returning physical page offset value + * + * Returns: + * The target scatterlist pointer and the target page position. + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_sg_dma(). + * See also __i915_gem_object_page_iter_get_sg() + */ +#define i915_gem_object_get_sg_dma(obj, n, offset) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_sg_dma(obj, n, offset); \ +}) + +/** + * __i915_gem_object_get_page - helper to find the target page with a page= offset + * @obj: i915 GEM buffer object + * @n: page offset + * + * It uses drm_i915_gem_object's internal shmem scatterlist lookup functio= n as + * i915_gem_object_page_iter and calls __i915_gem_object_page_iter_get_sg() + * internally. + * + * Returns: + * The target page pointer. + * + * Recommended to use wrapper macro: i915_gem_object_get_page() + * See also __i915_gem_object_page_iter_get_sg() + */ struct page * -i915_gem_object_get_page(struct drm_i915_gem_object *obj, - unsigned int n); +__i915_gem_object_get_page(struct drm_i915_gem_object *obj, pgoff_t n); =20 +/** + * i915_gem_object_get_page - wrapper macro for __i915_gem_object_get_page + * @obj: i915 GEM buffer object + * @n: page offset + * + * Returns: + * The target page pointer. + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_page(). + * See also __i915_gem_object_page_iter_get_sg() + */ +#define i915_gem_object_get_page(obj, n) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_page(obj, n); \ +}) + +/** + * __i915_gem_object_get_dirty_page - helper to find the target page with = a page + * offset + * @obj: i915 GEM buffer object + * @n: page offset + * + * It works like i915_gem_object_get_page(), but it marks the returned pag= e dirty. + * + * Returns: + * The target page pointer. + * + * Recommended to use wrapper macro: i915_gem_object_get_dirty_page() + * See also __i915_gem_object_page_iter_get_sg() and __i915_gem_object_get= _page() + */ struct page * -i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, - unsigned int n); +__i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, pgoff_t = n); + +/** + * i915_gem_object_get_dirty_page - wrapper macro for __i915_gem_object_ge= t_dirty_page + * @obj: i915 GEM buffer object + * @n: page offset + * + * Returns: + * The target page pointer. + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_dirty_page(). + * See also __i915_gem_object_page_iter_get_sg() and __i915_gem_object_get= _page() + */ +#define i915_gem_object_get_dirty_page(obj, n) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_dirty_page(obj, n); \ +}) =20 +/** + * __i915_gem_object_get_dma_address_len - helper to get bus addresses of + * targeted DMA mapped scatterlist from i915 GEM buffer object and it's le= ngth + * @obj: i915 GEM buffer object + * @n: page offset + * @len: DMA mapped scatterlist's DMA bus addresses length to return + * + * Returns: + * Bus addresses of targeted DMA mapped scatterlist + * + * Recommended to use wrapper macro: i915_gem_object_get_dma_address_len() + * See also __i915_gem_object_page_iter_get_sg() and __i915_gem_object_get= _sg_dma() + */ dma_addr_t -i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, - unsigned long n, - unsigned int *len); +__i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, pgo= ff_t n, + unsigned int *len); =20 +/** + * i915_gem_object_get_dma_address_len - wrapper macro for + * __i915_gem_object_get_dma_address_len + * @obj: i915 GEM buffer object + * @n: page offset + * @len: DMA mapped scatterlist's DMA bus addresses length to return + * + * Returns: + * Bus addresses of targeted DMA mapped scatterlist + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_dma_address_len(). + * See also __i915_gem_object_page_iter_get_sg() and + * __i915_gem_object_get_dma_address_len() + */ +#define i915_gem_object_get_dma_address_len(obj, n, len) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_dma_address_len(obj, n, len); \ +}) + +/** + * __i915_gem_object_get_dma_address - helper to get bus addresses of + * targeted DMA mapped scatterlist from i915 GEM buffer object + * @obj: i915 GEM buffer object + * @n: page offset + * + * Returns: + * Bus addresses of targeted DMA mapped scatterlis + * + * Recommended to use wrapper macro: i915_gem_object_get_dma_address() + * See also __i915_gem_object_page_iter_get_sg() and __i915_gem_object_get= _sg_dma() + */ dma_addr_t -i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, - unsigned long n); +__i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, pgoff_t= n); + +/** + * i915_gem_object_get_dma_address - wrapper macro for + * __i915_gem_object_get_dma_address + * @obj: i915 GEM buffer object + * @n: page offset + * + * Returns: + * Bus addresses of targeted DMA mapped scatterlist + * + * In order to avoid the truncation of the input parameter, it checks the = page + * offset n's type from the input parameter before calling + * __i915_gem_object_get_dma_address(). + * See also __i915_gem_object_page_iter_get_sg() and + * __i915_gem_object_get_dma_address() + */ +#define i915_gem_object_get_dma_address(obj, n) ({ \ + exactly_pgoff_t(n); \ + __i915_gem_object_get_dma_address(obj, n); \ +}) =20 void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, struct sg_table *pages, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i9= 15/gem/i915_gem_pages.c index 8357dbdcab5c..4d925202cae1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -510,14 +510,16 @@ void __i915_gem_object_release_map(struct drm_i915_ge= m_object *obj) } =20 struct scatterlist * -__i915_gem_object_get_sg(struct drm_i915_gem_object *obj, - struct i915_gem_object_page_iter *iter, - unsigned int n, - unsigned int *offset, - bool dma) +__i915_gem_object_page_iter_get_sg(struct drm_i915_gem_object *obj, + struct i915_gem_object_page_iter *iter, + pgoff_t n, + unsigned int *offset) + { - struct scatterlist *sg; + const bool dma =3D iter =3D=3D &obj->mm.get_dma_page || + iter =3D=3D &obj->ttm.get_io_page; unsigned int idx, count; + struct scatterlist *sg; =20 might_sleep(); GEM_BUG_ON(n >=3D obj->base.size >> PAGE_SHIFT); @@ -625,7 +627,7 @@ __i915_gem_object_get_sg(struct drm_i915_gem_object *ob= j, } =20 struct page * -i915_gem_object_get_page(struct drm_i915_gem_object *obj, unsigned int n) +__i915_gem_object_get_page(struct drm_i915_gem_object *obj, pgoff_t n) { struct scatterlist *sg; unsigned int offset; @@ -638,8 +640,7 @@ i915_gem_object_get_page(struct drm_i915_gem_object *ob= j, unsigned int n) =20 /* Like i915_gem_object_get_page(), but mark the returned page dirty */ struct page * -i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, - unsigned int n) +__i915_gem_object_get_dirty_page(struct drm_i915_gem_object *obj, pgoff_t = n) { struct page *page; =20 @@ -651,9 +652,8 @@ i915_gem_object_get_dirty_page(struct drm_i915_gem_obje= ct *obj, } =20 dma_addr_t -i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, - unsigned long n, - unsigned int *len) +__i915_gem_object_get_dma_address_len(struct drm_i915_gem_object *obj, + pgoff_t n, unsigned int *len) { struct scatterlist *sg; unsigned int offset; @@ -667,8 +667,7 @@ i915_gem_object_get_dma_address_len(struct drm_i915_gem= _object *obj, } =20 dma_addr_t -i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, - unsigned long n) +__i915_gem_object_get_dma_address(struct drm_i915_gem_object *obj, pgoff_t= n) { return i915_gem_object_get_dma_address_len(obj, n, NULL); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915= /gem/i915_gem_ttm.c index 5a5cf332d8a5..52c4c1fac7f9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -724,7 +724,7 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buf= fer_object *bo, GEM_WARN_ON(bo->ttm); =20 base =3D obj->mm.region->iomap.base - obj->mm.region->region.start; - sg =3D __i915_gem_object_get_sg(obj, &obj->ttm.get_io_page, page_offset, = &ofs, true); + sg =3D i915_gem_object_page_iter_get_sg(obj, &obj->ttm.get_io_page, page_= offset, &ofs); =20 return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; } diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/driver= s/gpu/drm/i915/gem/selftests/i915_gem_context.c index c6ad67b90e8a..a18a890e681f 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -455,7 +455,8 @@ static int gpu_fill(struct intel_context *ce, static int cpu_fill(struct drm_i915_gem_object *obj, u32 value) { const bool has_llc =3D HAS_LLC(to_i915(obj->base.dev)); - unsigned int n, m, need_flush; + unsigned int need_flush; + unsigned long n, m; int err; =20 i915_gem_object_lock(obj, NULL); @@ -485,7 +486,8 @@ static int cpu_fill(struct drm_i915_gem_object *obj, u3= 2 value) static noinline int cpu_check(struct drm_i915_gem_object *obj, unsigned int idx, unsigned int max) { - unsigned int n, m, needs_flush; + unsigned int needs_flush; + unsigned long n; int err; =20 i915_gem_object_lock(obj, NULL); @@ -494,7 +496,7 @@ static noinline int cpu_check(struct drm_i915_gem_objec= t *obj, goto out_unlock; =20 for (n =3D 0; n < real_page_count(obj); n++) { - u32 *map; + u32 *map, m; =20 map =3D kmap_atomic(i915_gem_object_get_page(obj, n)); if (needs_flush & CLFLUSH_BEFORE) @@ -502,7 +504,7 @@ static noinline int cpu_check(struct drm_i915_gem_objec= t *obj, =20 for (m =3D 0; m < max; m++) { if (map[m] !=3D m) { - pr_err("%pS: Invalid value at object %d page %d/%ld, offset %d/%d: fou= nd %x expected %x\n", + pr_err("%pS: Invalid value at object %d page %ld/%ld, offset %d/%d: fo= und %x expected %x\n", __builtin_return_address(0), idx, n, real_page_count(obj), m, max, map[m], m); @@ -513,7 +515,7 @@ static noinline int cpu_check(struct drm_i915_gem_objec= t *obj, =20 for (; m < DW_PER_PAGE; m++) { if (map[m] !=3D STACK_MAGIC) { - pr_err("%pS: Invalid value at object %d page %d, offset %d: found %x e= xpected %x (uninitialised)\n", + pr_err("%pS: Invalid value at object %d page %ld, offset %d: found %x = expected %x (uninitialised)\n", __builtin_return_address(0), idx, n, m, map[m], STACK_MAGIC); err =3D -EINVAL; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/g= pu/drm/i915/gem/selftests/i915_gem_mman.c index 3ced9948a331..86e435d42546 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -95,11 +95,11 @@ static int check_partial_mapping(struct drm_i915_gem_ob= ject *obj, struct drm_i915_private *i915 =3D to_i915(obj->base.dev); struct i915_ggtt_view view; struct i915_vma *vma; + unsigned long offset; unsigned long page; u32 __iomem *io; struct page *p; unsigned int n; - u64 offset; u32 *cpu; int err; =20 @@ -156,7 +156,7 @@ static int check_partial_mapping(struct drm_i915_gem_ob= ject *obj, cpu =3D kmap(p) + offset_in_page(offset); drm_clflush_virt_range(cpu, sizeof(*cpu)); if (*cpu !=3D (u32)page) { - pr_err("Partial view for %lu [%u] (offset=3D%llu, size=3D%u [%llu, row s= ize %u], fence=3D%d, tiling=3D%d, stride=3D%d) misalignment, expected write= to page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n", + pr_err("Partial view for %lu [%u] (offset=3D%llu, size=3D%u [%llu, row s= ize %u], fence=3D%d, tiling=3D%d, stride=3D%d) misalignment, expected write= to page (%lu + %u [0x%lx]) of 0x%x, found 0x%x\n", page, n, view.partial.offset, view.partial.size, @@ -212,10 +212,10 @@ static int check_partial_mappings(struct drm_i915_gem= _object *obj, for_each_prime_number_from(page, 1, npages) { struct i915_ggtt_view view =3D compute_partial_view(obj, page, MIN_CHUNK_PAGES); + unsigned long offset; u32 __iomem *io; struct page *p; unsigned int n; - u64 offset; u32 *cpu; =20 GEM_BUG_ON(view.partial.size > nreal); @@ -252,7 +252,7 @@ static int check_partial_mappings(struct drm_i915_gem_o= bject *obj, cpu =3D kmap(p) + offset_in_page(offset); drm_clflush_virt_range(cpu, sizeof(*cpu)); if (*cpu !=3D (u32)page) { - pr_err("Partial view for %lu [%u] (offset=3D%llu, size=3D%u [%llu, row = size %u], fence=3D%d, tiling=3D%d, stride=3D%d) misalignment, expected writ= e to page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n", + pr_err("Partial view for %lu [%u] (offset=3D%llu, size=3D%u [%llu, row = size %u], fence=3D%d, tiling=3D%d, stride=3D%d) misalignment, expected writ= e to page (%lu + %u [0x%lx]) of 0x%x, found 0x%x\n", page, n, view.partial.offset, view.partial.size, diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c b/drivers= /gpu/drm/i915/gem/selftests/i915_gem_object.c index fe0a890775e2..bf30763ee6bc 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_object.c @@ -33,10 +33,10 @@ static int igt_gem_object(void *arg) =20 static int igt_gem_huge(void *arg) { - const unsigned int nreal =3D 509; /* just to be awkward */ + const unsigned long nreal =3D 509; /* just to be awkward */ struct drm_i915_private *i915 =3D arg; struct drm_i915_gem_object *obj; - unsigned int n; + unsigned long n; int err; =20 /* Basic sanitycheck of our huge fake object allocation */ @@ -49,7 +49,7 @@ static int igt_gem_huge(void *arg) =20 err =3D i915_gem_object_pin_pages_unlocked(obj); if (err) { - pr_err("Failed to allocate %u pages (%lu total), err=3D%d\n", + pr_err("Failed to allocate %lu pages (%lu total), err=3D%d\n", nreal, obj->base.size / PAGE_SIZE, err); goto out; } @@ -57,7 +57,7 @@ static int igt_gem_huge(void *arg) for (n =3D 0; n < obj->base.size / PAGE_SIZE; n++) { if (i915_gem_object_get_page(obj, n) !=3D i915_gem_object_get_page(obj, n % nreal)) { - pr_err("Page lookup mismatch at index %u [%u]\n", + pr_err("Page lookup mismatch at index %lu [%lu]\n", n, n % nreal); err =3D -EINVAL; goto out_unpin; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_ge= m.c index 702e5b89be22..dba58a3c3238 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -229,8 +229,9 @@ i915_gem_shmem_pread(struct drm_i915_gem_object *obj, struct drm_i915_gem_pread *args) { unsigned int needs_clflush; - unsigned int idx, offset; char __user *user_data; + unsigned long offset; + pgoff_t idx; u64 remain; int ret; =20 @@ -383,13 +384,17 @@ i915_gem_gtt_pread(struct drm_i915_gem_object *obj, { struct drm_i915_private *i915 =3D to_i915(obj->base.dev); struct i915_ggtt *ggtt =3D to_gt(i915)->ggtt; + unsigned long remain, offset; intel_wakeref_t wakeref; struct drm_mm_node node; void __user *user_data; struct i915_vma *vma; - u64 remain, offset; int ret =3D 0; =20 + if (overflows_type(args->size, remain) || + overflows_type(args->offset, offset)) + return -EINVAL; + wakeref =3D intel_runtime_pm_get(&i915->runtime_pm); =20 vma =3D i915_gem_gtt_prepare(obj, &node, false); @@ -540,13 +545,17 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *= obj, struct drm_i915_private *i915 =3D to_i915(obj->base.dev); struct i915_ggtt *ggtt =3D to_gt(i915)->ggtt; struct intel_runtime_pm *rpm =3D &i915->runtime_pm; + unsigned long remain, offset; intel_wakeref_t wakeref; struct drm_mm_node node; struct i915_vma *vma; - u64 remain, offset; void __user *user_data; int ret =3D 0; =20 + if (overflows_type(args->size, remain) || + overflows_type(args->offset, offset)) + return -EINVAL; + if (i915_gem_object_has_struct_page(obj)) { /* * Avoid waking the device up if we can fallback, as @@ -654,8 +663,9 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, { unsigned int partial_cacheline_write; unsigned int needs_clflush; - unsigned int offset, idx; void __user *user_data; + unsigned long offset; + pgoff_t idx; u64 remain; int ret; =20 diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_= utils.h index eb0ded23fa9c..b325b48a66ec 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -33,6 +33,7 @@ #include #include #include +#include =20 #ifdef CONFIG_X86 #include diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vm= a.c index 260371716490..1dd8a0f51aeb 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -909,7 +909,7 @@ rotate_pages(struct drm_i915_gem_object *obj, unsigned = int offset, struct sg_table *st, struct scatterlist *sg) { unsigned int column, row; - unsigned int src_idx; + pgoff_t src_idx; =20 for (column =3D 0; column < width; column++) { unsigned int left; @@ -1015,7 +1015,7 @@ add_padding_pages(unsigned int count, =20 static struct scatterlist * remap_tiled_color_plane_pages(struct drm_i915_gem_object *obj, - unsigned int offset, unsigned int alignment_pad, + unsigned long offset, unsigned int alignment_pad, unsigned int width, unsigned int height, unsigned int src_stride, unsigned int dst_stride, struct sg_table *st, struct scatterlist *sg, @@ -1074,7 +1074,7 @@ remap_tiled_color_plane_pages(struct drm_i915_gem_obj= ect *obj, =20 static struct scatterlist * remap_contiguous_pages(struct drm_i915_gem_object *obj, - unsigned int obj_offset, + pgoff_t obj_offset, unsigned int count, struct sg_table *st, struct scatterlist *sg) { @@ -1107,7 +1107,7 @@ remap_contiguous_pages(struct drm_i915_gem_object *ob= j, =20 static struct scatterlist * remap_linear_color_plane_pages(struct drm_i915_gem_object *obj, - unsigned int obj_offset, unsigned int alignment_pad, + pgoff_t obj_offset, unsigned int alignment_pad, unsigned int size, struct sg_table *st, struct scatterlist *sg, unsigned int *gtt_offset) --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DBFFFC00140 for ; Sat, 13 Aug 2022 01:09:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238443AbiHMBJZ (ORCPT ); Fri, 12 Aug 2022 21:09:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55448 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237781AbiHMBJK (ORCPT ); Fri, 12 Aug 2022 21:09:10 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48B99A98FC for ; Fri, 12 Aug 2022 18:09:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352948; x=1691888948; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ev6wtaUfoDW/dHUWZxpi1sfMa9FY+2lWdbJ8IokImqU=; b=LMwvfi5sXJ5h+eIOfUTBeyaImJQWMCiUb1T0/Z1Mn4uF7GrzSVR5I8Lb SQo+0i7drsYiTZ9FScEFoOqmUMsR0IQ/7aJd7aLudl0Gkr9QHsr9ff13k z0Jpw/I7cPCWDthXh9QWp2hdaO7w/vZiku2GTJK6cBeUamXNvGz9xK/Ru x+6qjN4wFATPYxid4EdrlH/XXgElEuBjyh0rb2+Ite3DEbpOhrVSPOn9U iUEmhSpG0jVS5YnzIuIaZCbfp/FkLNAVeY61fTztvjtLH6klwAoc3tkqX kderHOMQIOvUB5jR3VxpRBwBFJPC0UebvlXE6xkN71qOjI6mVC0Jrf/Zx Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488727" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488727" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:08 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038372" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:04 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 4/8] drm/i915: Check for integer truncation on scatterlist creation Date: Sat, 13 Aug 2022 04:08:53 +0300 Message-Id: <20220813010857.4043956-5-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chris Wilson There is an impedance mismatch between the scatterlist API using unsigned int and our memory/page accounting in unsigned long. That is we may try to create a scatterlist for a large object that overflows returning a small table into which we try to fit very many pages. As the object size is under control of userspace, we have to be prudent and catch the conversion errors. To catch the implicit truncation as we switch from unsigned long into the scatterlist's unsigned int, we use overflows_type check and report E2BIG prior to the operation. This is already used in our create ioctls to indicate if the uABI request is simply too large for the backing store. Failing that type check, we have a second check at sg_alloc_table time to make sure the values we are passing into the scatterlist API are not truncated. It uses pgoff_t for locals that are dealing with page indices, in this case, the page count is the limit of the page index. And it uses safe_conversion() macro which performs a type conversion (cast) of an integer value into a new variable, checking that the destination is large enough to hold the source value. v2: Move added i915_utils's macro into drm_util header (Jani N) v5: Fix macros to be enclosed in parentheses for complex values Fix too long line warning Signed-off-by: Chris Wilson Signed-off-by: Gwan-gyeong Mun Cc: Tvrtko Ursulin Cc: Brian Welty Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Reviewed-by: Nirmoy Das Reviewed-by: Mauro Carvalho Chehab Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/gem/i915_gem_internal.c | 6 ++++-- drivers/gpu/drm/i915/gem/i915_gem_object.h | 3 --- drivers/gpu/drm/i915/gem/i915_gem_phys.c | 4 ++++ drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 5 ++++- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 4 ++++ drivers/gpu/drm/i915/gem/i915_gem_userptr.c | 5 ++++- drivers/gpu/drm/i915/gvt/dmabuf.c | 9 +++++---- drivers/gpu/drm/i915/i915_scatterlist.h | 11 +++++++++++ 8 files changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm= /i915/gem/i915_gem_internal.c index c698f95af15f..ff2e6e780631 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -37,10 +37,13 @@ static int i915_gem_object_get_pages_internal(struct dr= m_i915_gem_object *obj) struct sg_table *st; struct scatterlist *sg; unsigned int sg_page_sizes; - unsigned int npages; + pgoff_t npages; /* restricted by sg_alloc_table */ int max_order; gfp_t gfp; =20 + if (!safe_conversion(&npages, obj->base.size >> PAGE_SHIFT)) + return -E2BIG; + max_order =3D MAX_ORDER; #ifdef CONFIG_SWIOTLB if (is_swiotlb_active(obj->base.dev->dev)) { @@ -67,7 +70,6 @@ static int i915_gem_object_get_pages_internal(struct drm_= i915_gem_object *obj) if (!st) return -ENOMEM; =20 - npages =3D obj->base.size / PAGE_SIZE; if (sg_alloc_table(st, npages, GFP_KERNEL)) { kfree(st); return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i= 915/gem/i915_gem_object.h index 5da872afc4ba..0cf31adbfd41 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -26,9 +26,6 @@ enum intel_region_id; * this and catch if we ever need to fix it. In the meantime, if you do * spot such a local variable, please consider fixing! * - * Aside from our own locals (for which we have no excuse!): - * - sg_table embeds unsigned int for nents - * * We can check for invalidly typed locals with typecheck(), see for examp= le * i915_gem_object_get_sg(). */ diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i91= 5/gem/i915_gem_phys.c index 0d0e46dae559..88ba7266a3a5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -28,6 +28,10 @@ static int i915_gem_object_get_pages_phys(struct drm_i91= 5_gem_object *obj) void *dst; int i; =20 + /* Contiguous chunk, with a single scatterlist element */ + if (overflows_type(obj->base.size, sg->length)) + return -E2BIG; + if (GEM_WARN_ON(i915_gem_object_needs_bit17_swizzle(obj))) return -EINVAL; =20 diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i9= 15/gem/i915_gem_shmem.c index f42ca1179f37..4cb35808e431 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -193,13 +193,16 @@ static int shmem_get_pages(struct drm_i915_gem_object= *obj) struct drm_i915_private *i915 =3D to_i915(obj->base.dev); struct intel_memory_region *mem =3D obj->mm.region; struct address_space *mapping =3D obj->base.filp->f_mapping; - const unsigned long page_count =3D obj->base.size / PAGE_SIZE; unsigned int max_segment =3D i915_sg_segment_size(); struct sg_table *st; struct sgt_iter sgt_iter; + pgoff_t page_count; struct page *page; int ret; =20 + if (!safe_conversion(&page_count, obj->base.size >> PAGE_SHIFT)) + return -E2BIG; + /* * Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915= /gem/i915_gem_ttm.c index 52c4c1fac7f9..9f2be1892b6c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -822,6 +822,10 @@ static int i915_ttm_get_pages(struct drm_i915_gem_obje= ct *obj) { struct ttm_place requested, busy[I915_TTM_MAX_PLACEMENTS]; struct ttm_placement placement; + pgoff_t num_pages; + + if (!safe_conversion(&num_pages, obj->base.size >> PAGE_SHIFT)) + return -E2BIG; =20 GEM_BUG_ON(obj->mm.n_placements > I915_TTM_MAX_PLACEMENTS); =20 diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/= i915/gem/i915_gem_userptr.c index 094f06b4ce33..25785c3a0083 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -128,13 +128,16 @@ static void i915_gem_object_userptr_drop_ref(struct d= rm_i915_gem_object *obj) =20 static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) { - const unsigned long num_pages =3D obj->base.size >> PAGE_SHIFT; unsigned int max_segment =3D i915_sg_segment_size(); struct sg_table *st; unsigned int sg_page_sizes; struct page **pvec; + pgoff_t num_pages; /* limited by sg_alloc_table_from_pages_segment */ int ret; =20 + if (!safe_conversion(&num_pages, obj->base.size >> PAGE_SHIFT)) + return -E2BIG; + st =3D kmalloc(sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/d= mabuf.c index 01e54b45c5c1..795270cb4ec2 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -42,8 +42,7 @@ =20 #define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12)) =20 -static int vgpu_gem_get_pages( - struct drm_i915_gem_object *obj) +static int vgpu_gem_get_pages(struct drm_i915_gem_object *obj) { struct drm_i915_private *dev_priv =3D to_i915(obj->base.dev); struct intel_vgpu *vgpu; @@ -52,7 +51,10 @@ static int vgpu_gem_get_pages( int i, j, ret; gen8_pte_t __iomem *gtt_entries; struct intel_vgpu_fb_info *fb_info; - u32 page_num; + pgoff_t page_num; + + if (!safe_conversion(&page_num, obj->base.size >> PAGE_SHIFT)) + return -E2BIG; =20 fb_info =3D (struct intel_vgpu_fb_info *)obj->gvt_info; if (drm_WARN_ON(&dev_priv->drm, !fb_info)) @@ -66,7 +68,6 @@ static int vgpu_gem_get_pages( if (unlikely(!st)) return -ENOMEM; =20 - page_num =3D obj->base.size >> PAGE_SHIFT; ret =3D sg_alloc_table(st, page_num, GFP_KERNEL); if (ret) { kfree(st); diff --git a/drivers/gpu/drm/i915/i915_scatterlist.h b/drivers/gpu/drm/i915= /i915_scatterlist.h index 9ddb3e743a3e..1d1802beb42b 100644 --- a/drivers/gpu/drm/i915/i915_scatterlist.h +++ b/drivers/gpu/drm/i915/i915_scatterlist.h @@ -220,4 +220,15 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(s= truct ttm_resource *res, u64 region_start, u32 page_alignment); =20 +/* Wrap scatterlist.h to sanity check for integer truncation */ +typedef unsigned int __sg_size_t; /* see linux/scatterlist.h */ +#define sg_alloc_table(sgt, nents, gfp) \ + overflows_type(nents, __sg_size_t) ? -E2BIG \ + : ((sg_alloc_table)(sgt, (__sg_size_t)(nents), gfp)) + +#define sg_alloc_table_from_pages_segment(sgt, pages, npages, offset, size= , max_segment, gfp) \ + overflows_type(npages, __sg_size_t) ? -E2BIG \ + : ((sg_alloc_table_from_pages_segment)(sgt, pages, (__sg_size_t)(npages)= , offset, \ + size, max_segment, gfp)) + #endif --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A1D4C282E7 for ; Sat, 13 Aug 2022 01:09:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238475AbiHMBJ2 (ORCPT ); Fri, 12 Aug 2022 21:09:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55592 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238008AbiHMBJM (ORCPT ); Fri, 12 Aug 2022 21:09:12 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F27AA9269 for ; Fri, 12 Aug 2022 18:09:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352951; x=1691888951; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+iAHdiE53eJhFbUBHHSk44M7dSlJIiKyoBbOUgFS8F4=; b=MIcn1EKKP43ef5//8RHg79PiAiA5G6LZQP21rX0GV6hTVOUF9URBq27U D8krwkqo81vhjM+hVHqnerqAfULr2Vmd14xOABdE2qZD5dCKJCQR/9cv+ koUZLqi6p0Bw3kQ+1xKW8sif+IsfHXJ2l4udt8bTd7i2zwFcrZu1Ylg9u /YZDvnGmpimqyA67FBo6ykPhIRRswlV2Q+MPq+lA8T0X8gfvHNA+JbKSZ jsIJEQuwfwggO533hR/qfSbRrFslgtt3vKPhvbURja62meaZ3b6xxEwqv 2ZWojCWA5I9IbbpHjLEI5zUdje9L+oG5tUyUggP7Rex0Y8HIX7ynrhE8O Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488733" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488733" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:11 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038376" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:08 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 5/8] drm/i915: Check for integer truncation on the configuration of ttm place Date: Sat, 13 Aug 2022 04:08:54 +0300 Message-Id: <20220813010857.4043956-6-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There is an impedance mismatch between the first/last valid page frame number of ttm place in unsigned and our memory/page accounting in unsigned long. As the object size is under the control of userspace, we have to be prudent and catch the conversion errors. To catch the implicit truncation as we switch from unsigned long to unsigned, we use overflows_type check and report E2BIG or overflow_type prior to the operation. v3: Not to change execution inside a macro. (Mauro) Add safe_conversion_gem_bug_on() macro and remove temporal SAFE_CONVERSION() macro. v4: Fix unhandled GEM_BUG_ON() macro call from safe_conversion_gem_bug_on() v6: Fix to follow general use case for GEM_BUG_ON(). (Jani) Signed-off-by: Gwan-gyeong Mun Cc: Chris Wilson Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Cc: Jani Nikula Reviewed-by: Nirmoy Das (v2) Reviewed-by: Mauro Carvalho Chehab (v3) Reported-by: kernel test robot Reviewed-by: Andrzej Hajda (v5) --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 6 +++--- drivers/gpu/drm/i915/intel_region_ttm.c | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915= /gem/i915_gem_ttm.c index 9f2be1892b6c..30f488712abe 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -140,14 +140,14 @@ i915_ttm_place_from_region(const struct intel_memory_= region *mr, if (flags & I915_BO_ALLOC_CONTIGUOUS) place->flags |=3D TTM_PL_FLAG_CONTIGUOUS; if (offset !=3D I915_BO_INVALID_OFFSET) { - place->fpfn =3D offset >> PAGE_SHIFT; - place->lpfn =3D place->fpfn + (size >> PAGE_SHIFT); + GEM_BUG_ON(!safe_conversion(&place->fpfn, offset >> PAGE_SHIFT)); + GEM_BUG_ON(!safe_conversion(&place->lpfn, place->fpfn + (size >> PAGE_SH= IFT))); } else if (mr->io_size && mr->io_size < mr->total) { if (flags & I915_BO_ALLOC_GPU_ONLY) { place->flags |=3D TTM_PL_FLAG_TOPDOWN; } else { place->fpfn =3D 0; - place->lpfn =3D mr->io_size >> PAGE_SHIFT; + GEM_BUG_ON(!safe_conversion(&place->lpfn, mr->io_size >> PAGE_SHIFT)); } } } diff --git a/drivers/gpu/drm/i915/intel_region_ttm.c b/drivers/gpu/drm/i915= /intel_region_ttm.c index 575d67bc6ffe..c480b0b50bcc 100644 --- a/drivers/gpu/drm/i915/intel_region_ttm.c +++ b/drivers/gpu/drm/i915/intel_region_ttm.c @@ -209,14 +209,28 @@ intel_region_ttm_resource_alloc(struct intel_memory_r= egion *mem, if (flags & I915_BO_ALLOC_CONTIGUOUS) place.flags |=3D TTM_PL_FLAG_CONTIGUOUS; if (offset !=3D I915_BO_INVALID_OFFSET) { - place.fpfn =3D offset >> PAGE_SHIFT; - place.lpfn =3D place.fpfn + (size >> PAGE_SHIFT); + if (!safe_conversion(&place.fpfn, offset >> PAGE_SHIFT)) { + GEM_BUG_ON(!safe_conversion(&place.fpfn,offset >> PAGE_SHIFT)); + ret =3D -E2BIG; + goto out; + } + if (!safe_conversion(&place.lpfn, place.fpfn + (size >> PAGE_SHIFT))) { + GEM_BUG_ON(!safe_conversion(&place.lpfn, + place.fpfn + (size >> PAGE_SHIFT))); + ret =3D -E2BIG; + goto out; + } } else if (mem->io_size && mem->io_size < mem->total) { if (flags & I915_BO_ALLOC_GPU_ONLY) { place.flags |=3D TTM_PL_FLAG_TOPDOWN; } else { place.fpfn =3D 0; - place.lpfn =3D mem->io_size >> PAGE_SHIFT; + if (!safe_conversion(&place.lpfn, mem->io_size >> PAGE_SHIFT)) { + GEM_BUG_ON(!safe_conversion(&place.lpfn, + mem->io_size >> PAGE_SHIFT)); + ret =3D -E2BIG; + goto out; + } } } =20 @@ -224,6 +238,8 @@ intel_region_ttm_resource_alloc(struct intel_memory_reg= ion *mem, mock_bo.bdev =3D &mem->i915->bdev; =20 ret =3D man->func->alloc(man, &mock_bo, &place, &res); + +out: if (ret =3D=3D -ENOSPC) ret =3D -ENXIO; if (!ret) --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA69BC00140 for ; Sat, 13 Aug 2022 01:09:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238372AbiHMBJv (ORCPT ); Fri, 12 Aug 2022 21:09:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238223AbiHMBJS (ORCPT ); Fri, 12 Aug 2022 21:09:18 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88332AB067 for ; Fri, 12 Aug 2022 18:09:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352954; x=1691888954; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uGkMdALCNhPir9OCf7HNUlcXk+ktqw6h9jb2//vd0mQ=; b=JwwC1HvwD54pIIstFMRWMKu3ob2Y7L77ehqeDwOAQSgzTx8iFuc9PONQ KdPovY82AL7eRMzIIsuH84KTxOCBkDW0UAPbBmpLiyTg1SDmgjWo3RX4H mlhwDq4E4X5Zz3RzDexAlSV3g8RT6um/S+GeBKXnLVdqU9Rjahs6aMxrV JZcFNPEahIC/5BSVOzXsbRSKqSvGIcfT/XLhBLcGhTQYGDMalMmhedUpE aokD4WbIK2i1ctBUp2d/eSQpCOwH5TS5v/eU1Cx2XzCCGrJoc6c91EYtS LnCnKiohrW+I+8biMslnRUgEmT0df0Ew9eyXQU9Iu3DjQEghWgOGzEgLC Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488740" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488740" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:14 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038387" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:11 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 6/8] drm/i915: Check if the size is too big while creating shmem file Date: Sat, 13 Aug 2022 04:08:55 +0300 Message-Id: <20220813010857.4043956-7-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The __shmem_file_setup() function returns -EINVAL if size is greater than MAX_LFS_FILESIZE. To handle the same error as other code that returns -E2BIG when the size is too large, it add a code that returns -E2BIG when the size is larger than the size that can be handled. v4: If BITS_PER_LONG is 32, size > MAX_LFS_FILESIZE is always false, so it checks only when BITS_PER_LONG is 64. Signed-off-by: Gwan-gyeong Mun Cc: Chris Wilson Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Reviewed-by: Nirmoy Das Reviewed-by: Mauro Carvalho Chehab Reported-by: kernel test robot Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i9= 15/gem/i915_gem_shmem.c index 4cb35808e431..4a7a6d65fc7a 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -541,6 +541,20 @@ static int __create_shmem(struct drm_i915_private *i91= 5, =20 drm_gem_private_object_init(&i915->drm, obj, size); =20 + /* XXX: The __shmem_file_setup() function returns -EINVAL if size is + * greater than MAX_LFS_FILESIZE. + * To handle the same error as other code that returns -E2BIG when + * the size is too large, we add a code that returns -E2BIG when the + * size is larger than the size that can be handled. + * If BITS_PER_LONG is 32, size > MAX_LFS_FILESIZE is always false, + * so we only needs to check when BITS_PER_LONG is 64. + * If BITS_PER_LONG is 32, E2BIG checks are processed when + * i915_gem_object_size_2big() is called before init_object() callback + * is called. + */ + if (BITS_PER_LONG =3D=3D 64 && size > MAX_LFS_FILESIZE) + return -E2BIG; + if (i915->mm.gemfs) filp =3D shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size, flags); --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C268C25B0F for ; Sat, 13 Aug 2022 01:09:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237975AbiHMBJz (ORCPT ); Fri, 12 Aug 2022 21:09:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237719AbiHMBJT (ORCPT ); Fri, 12 Aug 2022 21:09:19 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84A1CAB4CF for ; Fri, 12 Aug 2022 18:09:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352958; x=1691888958; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vEK0tzq7uuacMBMuweRipGqfsHJFichiQ6peAPc4yRA=; b=Kq5kK2qEkjl+QQ0mMTwyBn3p042k73SHW/lJ3v+6vTsQED+4xcGymBqQ bsrGEp/pcac0kCKnVvqPAM90/VW2c3TcAnVEEdueYlZ8RE2uT7MkDzFkR yqWuxQsMwETyr6mph1oO0jFkisup3aL/8uRiZZEQ0MMME7Pf1oSEME49/ HUZbTQLue9cBErfSGAhgJxczI6wY4GH4MupcsAq2n+nOmgpsb1dw9K5dm W2NtBySP9n5h65BTE4a48CrCG4qidLvl8yS+wIFfo4cge64+Ca351mqja TD0HYWlYMvLFRE4ms1GOnjI08NG5Kx4XUtME66Cx7CyhNPf1ftLAXb3ky A==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488746" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488746" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:18 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038397" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:14 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 7/8] drm/i915: Use error code as -E2BIG when the size of gem ttm object is too large Date: Sat, 13 Aug 2022 04:08:56 +0300 Message-Id: <20220813010857.4043956-8-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The ttm_bo_init_reserved() functions returns -ENOSPC if the size is too big to add vma. The direct function that returns -ENOSPC is drm_mm_insert_node_= in_range(). To handle the same error as other code returning -E2BIG when the size is too large, it converts return value to -E2BIG. Signed-off-by: Gwan-gyeong Mun Cc: Chris Wilson Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Reviewed-by: Nirmoy Das Reviewed-by: Mauro Carvalho Chehab Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915= /gem/i915_gem_ttm.c index 30f488712abe..88d1bfd11f1d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -1249,6 +1249,17 @@ int __i915_gem_ttm_object_init(struct intel_memory_r= egion *mem, ret =3D ttm_bo_init_reserved(&i915->bdev, i915_gem_to_ttm(obj), bo_type, &i915_sys_placement, page_size >> PAGE_SHIFT, &ctx, NULL, NULL, i915_ttm_bo_destroy); + + /* + * XXX: The ttm_bo_init_reserved() functions returns -ENOSPC if the size + * is too big to add vma. The direct function that returns -ENOSPC is + * drm_mm_insert_node_in_range(). To handle the same error as other code + * that returns -E2BIG when the size is too large, it converts -ENOSPC to + * -E2BIG. + */ + if (size >> PAGE_SHIFT > INT_MAX && ret =3D=3D -ENOSPC) + ret =3D -E2BIG; + if (ret) return i915_ttm_err_to_gem(ret); =20 --=20 2.34.1 From nobody Sat Apr 11 09:23:04 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD383C00140 for ; Sat, 13 Aug 2022 01:10:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237732AbiHMBKG (ORCPT ); Fri, 12 Aug 2022 21:10:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238560AbiHMBJn (ORCPT ); Fri, 12 Aug 2022 21:09:43 -0400 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0922ABD4A for ; Fri, 12 Aug 2022 18:09:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1660352961; x=1691888961; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=feUjbyPzk1hzgECdJlMvMWye5xjHwhOw5XjgA5LI53c=; b=AizS0sVXJKhBxP2p9g2W96YQVgX882sz0e7YBvGy30VhFVRsrR6AxbCU k4iwGvAIeo3fpYSNlKeM/ulj8jpqWjkKkt/XaHgEXkkpXxip4tokz2NvQ JH9IIjniUYqjDlpbOy2MKfGjM0l/ssUoukJzURRP9kNs6IlJuFxoKVOju SV5ItV8PH32gAVgNKHbqIwSYBt4yveQW8Kt7WpS78lc7EnNgMyJTZXMDZ 3pePnDbc79QBm1StoOkOPZDImdkyo882Q7B86SGPRyyfpmYAUWCPkWves uWIy7o4UdMLOqvxWIjhJb77pw+YF/p2dy3xjl6BHjsWu3yDbPxNS/U9PA g==; X-IronPort-AV: E=McAfee;i="6400,9594,10437"; a="271488748" X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="271488748" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:21 -0700 X-IronPort-AV: E=Sophos;i="5.93,233,1654585200"; d="scan'208";a="666038402" Received: from akoska-mobl1.ger.corp.intel.com (HELO hades.ger.corp.intel.com) ([10.252.36.156]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Aug 2022 18:09:18 -0700 From: Gwan-gyeong Mun To: intel-gfx@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, mchehab@kernel.org, chris@chris-wilson.co.uk, matthew.auld@intel.com, thomas.hellstrom@linux.intel.com, jani.nikula@intel.com, nirmoy.das@intel.com, airlied@linux.ie, daniel@ffwll.ch, andi.shyti@linux.intel.com, andrzej.hajda@intel.com Subject: [PATCH v6 8/8] drm/i915: Remove truncation warning for large objects Date: Sat, 13 Aug 2022 04:08:57 +0300 Message-Id: <20220813010857.4043956-9-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> References: <20220813010857.4043956-1-gwan-gyeong.mun@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Chris Wilson Having addressed the issues surrounding incorrect types for local variables and potential integer truncation in using the scatterlist API, we have closed all the loop holes we had previously identified with dangerously large object creation. As such, we can eliminate the warning put in place to remind us to complete the review. Signed-off-by: Chris Wilson Signed-off-by: Gwan-gyeong Mun Cc: Tvrtko Ursulin Cc: Brian Welty Cc: Matthew Auld Cc: Thomas Hellstr=C3=B6m Testcase: igt@gem_create@create-massive Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4991 Reviewed-by: Nirmoy Das Reviewed-by: Mauro Carvalho Chehab Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/i915/gem/i915_gem_object.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i= 915/gem/i915_gem_object.h index 0cf31adbfd41..dd2762da332f 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -20,25 +20,10 @@ =20 enum intel_region_id; =20 -/* - * XXX: There is a prevalence of the assumption that we fit the - * object's page count inside a 32bit _signed_ variable. Let's document - * this and catch if we ever need to fix it. In the meantime, if you do - * spot such a local variable, please consider fixing! - * - * We can check for invalidly typed locals with typecheck(), see for examp= le - * i915_gem_object_get_sg(). - */ -#define GEM_CHECK_SIZE_OVERFLOW(sz) \ - GEM_WARN_ON((sz) >> PAGE_SHIFT > INT_MAX) - static inline bool i915_gem_object_size_2big(u64 size) { struct drm_i915_gem_object *obj; =20 - if (GEM_CHECK_SIZE_OVERFLOW(size)) - return true; - if (overflows_type(size, obj->base.size)) return true; =20 --=20 2.34.1