From 5f3cec21f6d57336a2cbfa9ee428ac66c77a7211 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 29 Aug 2025 20:46:01 +0300 Subject: overflow: add range_overflows() and range_end_overflows() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the range_overflows() and range_end_overflows() along with the _t variants over from drm/i915 and drm/buddy to overflow.h. Cc: Kees Cook Cc: "Gustavo A. R. Silva" Cc: linux-hardening@vger.kernel.org Reviewed-by: Kees Cook Reviewed-by: Jouni Högander Acked-by: Thomas Zimmermann Link: https://lore.kernel.org/r/20250829174601.2163064-3-jani.nikula@intel.com Signed-off-by: Jani Nikula --- include/drm/drm_buddy.h | 9 ------- include/linux/overflow.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 9689a7c5dd36..236971681514 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -13,15 +13,6 @@ #include -#define range_overflows(start, size, max) ({ \ - typeof(start) start__ = (start); \ - typeof(size) size__ = (size); \ - typeof(max) max__ = (max); \ - (void)(&start__ == &size__); \ - (void)(&start__ == &max__); \ - start__ >= max__ || size__ > max__ - start__; \ -}) - #define DRM_BUDDY_RANGE_ALLOCATION BIT(0) #define DRM_BUDDY_TOPDOWN_ALLOCATION BIT(1) #define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 154ed0dbb43f..725f95f7e416 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -238,6 +238,76 @@ static inline bool __must_check __must_check_overflow(bool overflow) __overflows_type_constexpr(n, T), \ __overflows_type(n, T)) +/** + * range_overflows() - Check if a range is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * A strict check to determine if the range [@start, @start + @size) is + * invalid with respect to the allowable range [0, @max). Any range + * starting at or beyond @max is considered an overflow, even if @size is 0. + * + * Returns: true if the range is out of bounds. + */ +#define range_overflows(start, size, max) ({ \ + typeof(start) start__ = (start); \ + typeof(size) size__ = (size); \ + typeof(max) max__ = (max); \ + (void)(&start__ == &size__); \ + (void)(&start__ == &max__); \ + start__ >= max__ || size__ > max__ - start__; \ +}) + +/** + * range_overflows_t() - Check if a range is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_overflows() but forcing the parameters to @type. + * + * Returns: true if the range is out of bounds. + */ +#define range_overflows_t(type, start, size, max) \ + range_overflows((type)(start), (type)(size), (type)(max)) + +/** + * range_end_overflows() - Check if a range's endpoint is out of bounds + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Checks only if the endpoint of a range (@start + @size) exceeds @max. + * Unlike range_overflows(), a zero-sized range at the boundary (@start == @max) + * is not considered an overflow. Useful for iterator-style checks. + * + * Returns: true if the endpoint exceeds the boundary. + */ +#define range_end_overflows(start, size, max) ({ \ + typeof(start) start__ = (start); \ + typeof(size) size__ = (size); \ + typeof(max) max__ = (max); \ + (void)(&start__ == &size__); \ + (void)(&start__ == &max__); \ + start__ > max__ || size__ > max__ - start__; \ +}) + +/** + * range_end_overflows_t() - Check if a range's endpoint is out of bounds + * @type: Data type to use. + * @start: Start of the range. + * @size: Size of the range. + * @max: Exclusive upper boundary. + * + * Same as range_end_overflows() but forcing the parameters to @type. + * + * Returns: true if the endpoint exceeds the boundary. + */ +#define range_end_overflows_t(type, start, size, max) \ + range_end_overflows((type)(start), (type)(size), (type)(max)) + /** * castable_to_type - like __same_type(), but also allows for casted literals * -- cgit v1.2.3 From 86a9fe82e9b1f43e6d2bc867bf96bb40660d8719 Mon Sep 17 00:00:00 2001 From: Luiz Otavio Mello Date: Mon, 8 Sep 2025 09:15:09 -0400 Subject: drm/i915: Move struct_mutex to drm_i915_private Move legacy BKL struct_mutex from drm_device to drm_i915_private, which is the last remaining user. Signed-off-by: Luiz Otavio Mello Reviewed-by: Rodrigo Vivi Link: https://lore.kernel.org/r/20250908131518.36625-2-luiz.mello@estudante.ufscar.br Acked-by: Thomas Zimmermann Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_drv.c | 2 -- drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 4 ++-- drivers/gpu/drm/i915/i915_driver.c | 2 ++ drivers/gpu/drm/i915/i915_drv.h | 11 +++++++++++ drivers/gpu/drm/i915/i915_irq.c | 4 ++-- include/drm/drm_device.h | 10 ---------- 6 files changed, 17 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 02556363e918..287cf4a09101 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -697,7 +697,6 @@ static void drm_dev_init_release(struct drm_device *dev, void *res) mutex_destroy(&dev->master_mutex); mutex_destroy(&dev->clientlist_mutex); mutex_destroy(&dev->filelist_mutex); - mutex_destroy(&dev->struct_mutex); } static int drm_dev_init(struct drm_device *dev, @@ -738,7 +737,6 @@ static int drm_dev_init(struct drm_device *dev, INIT_LIST_HEAD(&dev->vblank_event_list); spin_lock_init(&dev->event_lock); - mutex_init(&dev->struct_mutex); mutex_init(&dev->filelist_mutex); mutex_init(&dev->clientlist_mutex); mutex_init(&dev->master_mutex); diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c index e8a04e476c57..7135fdb0ebb4 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c @@ -678,7 +678,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) if (level < GUC_LOG_LEVEL_DISABLED || level > GUC_LOG_LEVEL_MAX) return -EINVAL; - mutex_lock(&i915->drm.struct_mutex); + mutex_lock(&i915->struct_mutex); if (log->level == level) goto out_unlock; @@ -696,7 +696,7 @@ int intel_guc_log_set_level(struct intel_guc_log *log, u32 level) log->level = level; out_unlock: - mutex_unlock(&i915->drm.struct_mutex); + mutex_unlock(&i915->struct_mutex); return ret; } diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index a28c3710c4d5..2677c39a3246 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -235,6 +235,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_sbi_init(display); vlv_iosf_sb_init(dev_priv); + mutex_init(&dev_priv->struct_mutex); mutex_init(&dev_priv->sb_lock); i915_memcpy_init_early(dev_priv); @@ -293,6 +294,7 @@ static void i915_driver_late_release(struct drm_i915_private *dev_priv) i915_workqueues_cleanup(dev_priv); mutex_destroy(&dev_priv->sb_lock); + mutex_destroy(&dev_priv->struct_mutex); vlv_iosf_sb_fini(dev_priv); intel_sbi_fini(display); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f76d138df0af..55f13cb2c395 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -224,6 +224,17 @@ struct drm_i915_private { bool irqs_enabled; + /* + * Currently, struct_mutex is only used by the i915 driver as a replacement + * for BKL. + * + * For this reason, it is no longer part of struct drm_device. + */ + struct mutex struct_mutex; + + /* LPT/WPT IOSF sideband protection */ + struct mutex sbi_lock; + /* VLV/CHV IOSF sideband */ struct { struct mutex lock; /* protect sideband access */ diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a5fa40ab5de2..5916a648efbb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -167,7 +167,7 @@ static void ivb_parity_work(struct work_struct *work) * In order to prevent a get/put style interface, acquire struct mutex * any time we access those registers. */ - mutex_lock(&dev_priv->drm.struct_mutex); + mutex_lock(&dev_priv->struct_mutex); /* If we've screwed up tracking, just let the interrupt fire again */ if (drm_WARN_ON(&dev_priv->drm, !dev_priv->l3_parity.which_slice)) @@ -225,7 +225,7 @@ out: gen5_gt_enable_irq(gt, GT_PARITY_ERROR(dev_priv)); spin_unlock_irq(gt->irq_lock); - mutex_unlock(&dev_priv->drm.struct_mutex); + mutex_unlock(&dev_priv->struct_mutex); } static irqreturn_t valleyview_irq_handler(int irq, void *arg) diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h index 08b3b2467c4c..cb16fd47e075 100644 --- a/include/drm/drm_device.h +++ b/include/drm/drm_device.h @@ -186,16 +186,6 @@ struct drm_device { /** @unique: Unique name of the device */ char *unique; - /** - * @struct_mutex: - * - * Lock for others (not &drm_minor.master and &drm_file.is_master) - * - * TODO: This lock used to be the BKL of the DRM subsystem. Move the - * lock into i915, which is the only remaining user. - */ - struct mutex struct_mutex; - /** * @master_mutex: * -- cgit v1.2.3