]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 14:49:53 +0000 (15:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 16 Jan 2023 14:49:53 +0000 (15:49 +0100)
added patches:
block-handle-bio_split_to_limits-null-return.patch
drm-i915-fix-cfi-violations-in-gt_sysfs.patch
io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch
io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch

queue-6.1/block-handle-bio_split_to_limits-null-return.patch [new file with mode: 0644]
queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch [new file with mode: 0644]
queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch [new file with mode: 0644]
queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch [new file with mode: 0644]
queue-6.1/io_uring-poll-attempt-request-issue-after-racy-poll-.patch
queue-6.1/series

diff --git a/queue-6.1/block-handle-bio_split_to_limits-null-return.patch b/queue-6.1/block-handle-bio_split_to_limits-null-return.patch
new file mode 100644 (file)
index 0000000..32b3183
--- /dev/null
@@ -0,0 +1,124 @@
+From 613b14884b8595e20b9fac4126bf627313827fbe Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Wed, 4 Jan 2023 08:51:19 -0700
+Subject: block: handle bio_split_to_limits() NULL return
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 613b14884b8595e20b9fac4126bf627313827fbe upstream.
+
+This can't happen right now, but in preparation for allowing
+bio_split_to_limits() returning NULL if it ended the bio, check for it
+in all the callers.
+
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/blk-merge.c             |    4 +++-
+ block/blk-mq.c                |    5 ++++-
+ drivers/block/drbd/drbd_req.c |    2 ++
+ drivers/block/ps3vram.c       |    2 ++
+ drivers/md/dm.c               |    2 ++
+ drivers/md/md.c               |    2 ++
+ drivers/nvme/host/multipath.c |    2 ++
+ drivers/s390/block/dcssblk.c  |    2 ++
+ 8 files changed, 19 insertions(+), 2 deletions(-)
+
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -358,11 +358,13 @@ struct bio *__bio_split_to_limits(struct
+       default:
+               split = bio_split_rw(bio, lim, nr_segs, bs,
+                               get_max_io_size(bio, lim) << SECTOR_SHIFT);
++              if (IS_ERR(split))
++                      return NULL;
+               break;
+       }
+       if (split) {
+-              /* there isn't chance to merge the splitted bio */
++              /* there isn't chance to merge the split bio */
+               split->bi_opf |= REQ_NOMERGE;
+               blkcg_bio_issue_init(split);
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -2919,8 +2919,11 @@ void blk_mq_submit_bio(struct bio *bio)
+       blk_status_t ret;
+       bio = blk_queue_bounce(bio, q);
+-      if (bio_may_exceed_limits(bio, &q->limits))
++      if (bio_may_exceed_limits(bio, &q->limits)) {
+               bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
++              if (!bio)
++                      return;
++      }
+       if (!bio_integrity_prep(bio))
+               return;
+--- a/drivers/block/drbd/drbd_req.c
++++ b/drivers/block/drbd/drbd_req.c
+@@ -1607,6 +1607,8 @@ void drbd_submit_bio(struct bio *bio)
+       struct drbd_device *device = bio->bi_bdev->bd_disk->private_data;
+       bio = bio_split_to_limits(bio);
++      if (!bio)
++              return;
+       /*
+        * what we "blindly" assume:
+--- a/drivers/block/ps3vram.c
++++ b/drivers/block/ps3vram.c
+@@ -587,6 +587,8 @@ static void ps3vram_submit_bio(struct bi
+       dev_dbg(&dev->core, "%s\n", __func__);
+       bio = bio_split_to_limits(bio);
++      if (!bio)
++              return;
+       spin_lock_irq(&priv->lock);
+       busy = !bio_list_empty(&priv->list);
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1755,6 +1755,8 @@ static void dm_split_and_process_bio(str
+                * otherwise associated queue_limits won't be imposed.
+                */
+               bio = bio_split_to_limits(bio);
++              if (!bio)
++                      return;
+       }
+       init_clone_info(&ci, md, map, bio, is_abnormal);
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -443,6 +443,8 @@ static void md_submit_bio(struct bio *bi
+       }
+       bio = bio_split_to_limits(bio);
++      if (!bio)
++              return;
+       if (mddev->ro == 1 && unlikely(rw == WRITE)) {
+               if (bio_sectors(bio) != 0)
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -351,6 +351,8 @@ static void nvme_ns_head_submit_bio(stru
+        * pool from the original queue to allocate the bvecs from.
+        */
+       bio = bio_split_to_limits(bio);
++      if (!bio)
++              return;
+       srcu_idx = srcu_read_lock(&head->srcu);
+       ns = nvme_find_path(head);
+--- a/drivers/s390/block/dcssblk.c
++++ b/drivers/s390/block/dcssblk.c
+@@ -865,6 +865,8 @@ dcssblk_submit_bio(struct bio *bio)
+       unsigned long bytes_done;
+       bio = bio_split_to_limits(bio);
++      if (!bio)
++              return;
+       bytes_done = 0;
+       dev_info = bio->bi_bdev->bd_disk->private_data;
diff --git a/queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch b/queue-6.1/drm-i915-fix-cfi-violations-in-gt_sysfs.patch
new file mode 100644 (file)
index 0000000..20ca64f
--- /dev/null
@@ -0,0 +1,912 @@
+From a8a4f0467d706fc22d286dfa973946e5944b793c Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Tue, 25 Oct 2022 21:50:15 +0200
+Subject: drm/i915: Fix CFI violations in gt_sysfs
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit a8a4f0467d706fc22d286dfa973946e5944b793c upstream.
+
+When booting with CONFIG_CFI_CLANG, there are numerous violations when
+accessing the files under
+/sys/devices/pci0000:00/0000:00:02.0/drm/card0/gt/gt0:
+
+  $ cd /sys/devices/pci0000:00/0000:00:02.0/drm/card0/gt/gt0
+
+  $ grep . *
+  id:0
+  punit_req_freq_mhz:350
+  rc6_enable:1
+  rc6_residency_ms:214934
+  rps_act_freq_mhz:1300
+  rps_boost_freq_mhz:1300
+  rps_cur_freq_mhz:350
+  rps_max_freq_mhz:1300
+  rps_min_freq_mhz:350
+  rps_RP0_freq_mhz:1300
+  rps_RP1_freq_mhz:350
+  rps_RPn_freq_mhz:350
+  throttle_reason_pl1:0
+  throttle_reason_pl2:0
+  throttle_reason_pl4:0
+  throttle_reason_prochot:0
+  throttle_reason_ratl:0
+  throttle_reason_status:0
+  throttle_reason_thermal:0
+  throttle_reason_vr_tdc:0
+  throttle_reason_vr_thermalert:0
+
+  $ sudo dmesg &| grep "CFI failure at"
+  [  214.595903] CFI failure at kobj_attr_show+0x19/0x30 (target: id_show+0x0/0x70 [i915]; expected type: 0xc527b809)
+  [  214.596064] CFI failure at kobj_attr_show+0x19/0x30 (target: punit_req_freq_mhz_show+0x0/0x40 [i915]; expected type: 0xc527b809)
+  [  214.596407] CFI failure at kobj_attr_show+0x19/0x30 (target: rc6_enable_show+0x0/0x40 [i915]; expected type: 0xc527b809)
+  [  214.596528] CFI failure at kobj_attr_show+0x19/0x30 (target: rc6_residency_ms_show+0x0/0x270 [i915]; expected type: 0xc527b809)
+  [  214.596682] CFI failure at kobj_attr_show+0x19/0x30 (target: act_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.596792] CFI failure at kobj_attr_show+0x19/0x30 (target: boost_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.596893] CFI failure at kobj_attr_show+0x19/0x30 (target: cur_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.596996] CFI failure at kobj_attr_show+0x19/0x30 (target: max_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.597099] CFI failure at kobj_attr_show+0x19/0x30 (target: min_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.597198] CFI failure at kobj_attr_show+0x19/0x30 (target: RP0_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.597301] CFI failure at kobj_attr_show+0x19/0x30 (target: RP1_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.597405] CFI failure at kobj_attr_show+0x19/0x30 (target: RPn_freq_mhz_show+0x0/0xe0 [i915]; expected type: 0xc527b809)
+  [  214.597538] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.597701] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.597836] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.597952] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.598071] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.598177] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.598307] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.598439] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+  [  214.598542] CFI failure at kobj_attr_show+0x19/0x30 (target: throttle_reason_bool_show+0x0/0x50 [i915]; expected type: 0xc527b809)
+
+With kCFI, indirect calls are validated against their expected type
+versus actual type and failures occur when the two types do not match.
+The ultimate issue is that these sysfs functions are expecting to be
+called via dev_attr_show() but they may also be called via
+kobj_attr_show(), as certain files are created under two different
+kobjects that have two different sysfs_ops in intel_gt_sysfs_register(),
+hence the warnings above. When accessing the gt_ files under
+/sys/devices/pci0000:00/0000:00:02.0/drm/card0, which are using the same
+sysfs functions, there are no violations, meaning the functions are
+being called with the proper type.
+
+To make everything work properly, adjust certain functions to match the
+type of the ->show() and ->store() members in 'struct kobj_attribute'.
+Add a macro to generate functions for that can be called via both
+dev_attr_{show,store}() or kobj_attr_{show,store}() so that they can be
+called through both kobject locations without violating kCFI and adjust
+the attribute groups to account for this.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/1716
+Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
+Reviewed-by: Andrzej Hajda <andrzej.hajda@intel.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20221013205909.1282545-1-nathan@kernel.org
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gt/intel_gt_sysfs.c    |   15 
+ drivers/gpu/drm/i915/gt/intel_gt_sysfs.h    |    2 
+ drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c |  459 ++++++++++++----------------
+ 3 files changed, 219 insertions(+), 257 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs.c
+@@ -22,11 +22,9 @@ bool is_object_gt(struct kobject *kobj)
+       return !strncmp(kobj->name, "gt", 2);
+ }
+-struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
++struct intel_gt *intel_gt_sysfs_get_drvdata(struct kobject *kobj,
+                                           const char *name)
+ {
+-      struct kobject *kobj = &dev->kobj;
+-
+       /*
+        * We are interested at knowing from where the interface
+        * has been called, whether it's called from gt/ or from
+@@ -38,6 +36,7 @@ struct intel_gt *intel_gt_sysfs_get_drvd
+        * "struct drm_i915_private *" type.
+        */
+       if (!is_object_gt(kobj)) {
++              struct device *dev = kobj_to_dev(kobj);
+               struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
+               return to_gt(i915);
+@@ -51,18 +50,18 @@ static struct kobject *gt_get_parent_obj
+       return &gt->i915->drm.primary->kdev->kobj;
+ }
+-static ssize_t id_show(struct device *dev,
+-                     struct device_attribute *attr,
++static ssize_t id_show(struct kobject *kobj,
++                     struct kobj_attribute *attr,
+                      char *buf)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       return sysfs_emit(buf, "%u\n", gt->info.id);
+ }
+-static DEVICE_ATTR_RO(id);
++static struct kobj_attribute attr_id = __ATTR_RO(id);
+ static struct attribute *id_attrs[] = {
+-      &dev_attr_id.attr,
++      &attr_id.attr,
+       NULL,
+ };
+ ATTRIBUTE_GROUPS(id);
+--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs.h
++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs.h
+@@ -30,7 +30,7 @@ static inline struct intel_gt *kobj_to_g
+ void intel_gt_sysfs_register(struct intel_gt *gt);
+ void intel_gt_sysfs_unregister(struct intel_gt *gt);
+-struct intel_gt *intel_gt_sysfs_get_drvdata(struct device *dev,
++struct intel_gt *intel_gt_sysfs_get_drvdata(struct kobject *kobj,
+                                           const char *name);
+ #endif /* SYSFS_GT_H */
+--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c
+@@ -24,14 +24,15 @@ enum intel_gt_sysfs_op {
+ };
+ static int
+-sysfs_gt_attribute_w_func(struct device *dev, struct device_attribute *attr,
++sysfs_gt_attribute_w_func(struct kobject *kobj, struct attribute *attr,
+                         int (func)(struct intel_gt *gt, u32 val), u32 val)
+ {
+       struct intel_gt *gt;
+       int ret;
+-      if (!is_object_gt(&dev->kobj)) {
++      if (!is_object_gt(kobj)) {
+               int i;
++              struct device *dev = kobj_to_dev(kobj);
+               struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
+               for_each_gt(gt, i915, i) {
+@@ -40,7 +41,7 @@ sysfs_gt_attribute_w_func(struct device
+                               break;
+               }
+       } else {
+-              gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++              gt = intel_gt_sysfs_get_drvdata(kobj, attr->name);
+               ret = func(gt, val);
+       }
+@@ -48,7 +49,7 @@ sysfs_gt_attribute_w_func(struct device
+ }
+ static u32
+-sysfs_gt_attribute_r_func(struct device *dev, struct device_attribute *attr,
++sysfs_gt_attribute_r_func(struct kobject *kobj, struct attribute *attr,
+                         u32 (func)(struct intel_gt *gt),
+                         enum intel_gt_sysfs_op op)
+ {
+@@ -57,8 +58,9 @@ sysfs_gt_attribute_r_func(struct device
+       ret = (op == INTEL_GT_SYSFS_MAX) ? 0 : (u32) -1;
+-      if (!is_object_gt(&dev->kobj)) {
++      if (!is_object_gt(kobj)) {
+               int i;
++              struct device *dev = kobj_to_dev(kobj);
+               struct drm_i915_private *i915 = kdev_minor_to_i915(dev);
+               for_each_gt(gt, i915, i) {
+@@ -77,7 +79,7 @@ sysfs_gt_attribute_r_func(struct device
+                       }
+               }
+       } else {
+-              gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++              gt = intel_gt_sysfs_get_drvdata(kobj, attr->name);
+               ret = func(gt);
+       }
+@@ -92,6 +94,76 @@ sysfs_gt_attribute_r_func(struct device
+ #define sysfs_gt_attribute_r_max_func(d, a, f) \
+               sysfs_gt_attribute_r_func(d, a, f, INTEL_GT_SYSFS_MAX)
++#define INTEL_GT_SYSFS_SHOW(_name, _attr_type)                                                        \
++      static ssize_t _name##_show_common(struct kobject *kobj,                                \
++                                         struct attribute *attr, char *buff)                  \
++      {                                                                                       \
++              u32 val = sysfs_gt_attribute_r_##_attr_type##_func(kobj, attr,                  \
++                                                                 __##_name##_show);           \
++                                                                                              \
++              return sysfs_emit(buff, "%u\n", val);                                           \
++      }                                                                                       \
++      static ssize_t _name##_show(struct kobject *kobj,                                       \
++                                  struct kobj_attribute *attr, char *buff)                    \
++      {                                                                                       \
++              return _name ##_show_common(kobj, &attr->attr, buff);                           \
++      }                                                                                       \
++      static ssize_t _name##_dev_show(struct device *dev,                                     \
++                                      struct device_attribute *attr, char *buff)              \
++      {                                                                                       \
++              return _name##_show_common(&dev->kobj, &attr->attr, buff);                      \
++      }
++
++#define INTEL_GT_SYSFS_STORE(_name, _func)                                            \
++      static ssize_t _name##_store_common(struct kobject *kobj,                       \
++                                          struct attribute *attr,                     \
++                                          const char *buff, size_t count)             \
++      {                                                                               \
++              int ret;                                                                \
++              u32 val;                                                                \
++                                                                                      \
++              ret = kstrtou32(buff, 0, &val);                                         \
++              if (ret)                                                                \
++                      return ret;                                                     \
++                                                                                      \
++              ret = sysfs_gt_attribute_w_func(kobj, attr, _func, val);                \
++                                                                                      \
++              return ret ?: count;                                                    \
++      }                                                                               \
++      static ssize_t _name##_store(struct kobject *kobj,                              \
++                                   struct kobj_attribute *attr, const char *buff,     \
++                                   size_t count)                                      \
++      {                                                                               \
++              return _name##_store_common(kobj, &attr->attr, buff, count);            \
++      }                                                                               \
++      static ssize_t _name##_dev_store(struct device *dev,                            \
++                                       struct device_attribute *attr,                 \
++                                       const char *buff, size_t count)                \
++      {                                                                               \
++              return _name##_store_common(&dev->kobj, &attr->attr, buff, count);      \
++      }
++
++#define INTEL_GT_SYSFS_SHOW_MAX(_name) INTEL_GT_SYSFS_SHOW(_name, max)
++#define INTEL_GT_SYSFS_SHOW_MIN(_name) INTEL_GT_SYSFS_SHOW(_name, min)
++
++#define INTEL_GT_ATTR_RW(_name) \
++      static struct kobj_attribute attr_##_name = __ATTR_RW(_name)
++
++#define INTEL_GT_ATTR_RO(_name) \
++      static struct kobj_attribute attr_##_name = __ATTR_RO(_name)
++
++#define INTEL_GT_DUAL_ATTR_RW(_name) \
++      static struct device_attribute dev_attr_##_name = __ATTR(_name, 0644,           \
++                                                               _name##_dev_show,      \
++                                                               _name##_dev_store);    \
++      INTEL_GT_ATTR_RW(_name)
++
++#define INTEL_GT_DUAL_ATTR_RO(_name) \
++      static struct device_attribute dev_attr_##_name = __ATTR(_name, 0444,           \
++                                                               _name##_dev_show,      \
++                                                               NULL);                 \
++      INTEL_GT_ATTR_RO(_name)
++
+ #ifdef CONFIG_PM
+ static u32 get_residency(struct intel_gt *gt, i915_reg_t reg)
+ {
+@@ -104,11 +176,8 @@ static u32 get_residency(struct intel_gt
+       return DIV_ROUND_CLOSEST_ULL(res, 1000);
+ }
+-static ssize_t rc6_enable_show(struct device *dev,
+-                             struct device_attribute *attr,
+-                             char *buff)
++static u8 get_rc6_mask(struct intel_gt *gt)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
+       u8 mask = 0;
+       if (HAS_RC6(gt->i915))
+@@ -118,37 +187,35 @@ static ssize_t rc6_enable_show(struct de
+       if (HAS_RC6pp(gt->i915))
+               mask |= BIT(2);
+-      return sysfs_emit(buff, "%x\n", mask);
++      return mask;
+ }
+-static u32 __rc6_residency_ms_show(struct intel_gt *gt)
++static ssize_t rc6_enable_show(struct kobject *kobj,
++                             struct kobj_attribute *attr,
++                             char *buff)
+ {
+-      return get_residency(gt, GEN6_GT_GFX_RC6);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
++
++      return sysfs_emit(buff, "%x\n", get_rc6_mask(gt));
+ }
+-static ssize_t rc6_residency_ms_show(struct device *dev,
+-                                   struct device_attribute *attr,
+-                                   char *buff)
++static ssize_t rc6_enable_dev_show(struct device *dev,
++                                 struct device_attribute *attr,
++                                 char *buff)
+ {
+-      u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr,
+-                                                    __rc6_residency_ms_show);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(&dev->kobj, attr->attr.name);
+-      return sysfs_emit(buff, "%u\n", rc6_residency);
++      return sysfs_emit(buff, "%x\n", get_rc6_mask(gt));
+ }
+-static u32 __rc6p_residency_ms_show(struct intel_gt *gt)
++static u32 __rc6_residency_ms_show(struct intel_gt *gt)
+ {
+-      return get_residency(gt, GEN6_GT_GFX_RC6p);
++      return get_residency(gt, GEN6_GT_GFX_RC6);
+ }
+-static ssize_t rc6p_residency_ms_show(struct device *dev,
+-                                    struct device_attribute *attr,
+-                                    char *buff)
++static u32 __rc6p_residency_ms_show(struct intel_gt *gt)
+ {
+-      u32 rc6p_residency = sysfs_gt_attribute_r_min_func(dev, attr,
+-                                              __rc6p_residency_ms_show);
+-
+-      return sysfs_emit(buff, "%u\n", rc6p_residency);
++      return get_residency(gt, GEN6_GT_GFX_RC6p);
+ }
+ static u32 __rc6pp_residency_ms_show(struct intel_gt *gt)
+@@ -156,67 +223,69 @@ static u32 __rc6pp_residency_ms_show(str
+       return get_residency(gt, GEN6_GT_GFX_RC6pp);
+ }
+-static ssize_t rc6pp_residency_ms_show(struct device *dev,
+-                                     struct device_attribute *attr,
+-                                     char *buff)
+-{
+-      u32 rc6pp_residency = sysfs_gt_attribute_r_min_func(dev, attr,
+-                                              __rc6pp_residency_ms_show);
+-
+-      return sysfs_emit(buff, "%u\n", rc6pp_residency);
+-}
+-
+ static u32 __media_rc6_residency_ms_show(struct intel_gt *gt)
+ {
+       return get_residency(gt, VLV_GT_MEDIA_RC6);
+ }
+-static ssize_t media_rc6_residency_ms_show(struct device *dev,
+-                                         struct device_attribute *attr,
+-                                         char *buff)
+-{
+-      u32 rc6_residency = sysfs_gt_attribute_r_min_func(dev, attr,
+-                                              __media_rc6_residency_ms_show);
++INTEL_GT_SYSFS_SHOW_MIN(rc6_residency_ms);
++INTEL_GT_SYSFS_SHOW_MIN(rc6p_residency_ms);
++INTEL_GT_SYSFS_SHOW_MIN(rc6pp_residency_ms);
++INTEL_GT_SYSFS_SHOW_MIN(media_rc6_residency_ms);
++
++INTEL_GT_DUAL_ATTR_RO(rc6_enable);
++INTEL_GT_DUAL_ATTR_RO(rc6_residency_ms);
++INTEL_GT_DUAL_ATTR_RO(rc6p_residency_ms);
++INTEL_GT_DUAL_ATTR_RO(rc6pp_residency_ms);
++INTEL_GT_DUAL_ATTR_RO(media_rc6_residency_ms);
+-      return sysfs_emit(buff, "%u\n", rc6_residency);
+-}
++static struct attribute *rc6_attrs[] = {
++      &attr_rc6_enable.attr,
++      &attr_rc6_residency_ms.attr,
++      NULL
++};
+-static DEVICE_ATTR_RO(rc6_enable);
+-static DEVICE_ATTR_RO(rc6_residency_ms);
+-static DEVICE_ATTR_RO(rc6p_residency_ms);
+-static DEVICE_ATTR_RO(rc6pp_residency_ms);
+-static DEVICE_ATTR_RO(media_rc6_residency_ms);
++static struct attribute *rc6p_attrs[] = {
++      &attr_rc6p_residency_ms.attr,
++      &attr_rc6pp_residency_ms.attr,
++      NULL
++};
+-static struct attribute *rc6_attrs[] = {
++static struct attribute *media_rc6_attrs[] = {
++      &attr_media_rc6_residency_ms.attr,
++      NULL
++};
++
++static struct attribute *rc6_dev_attrs[] = {
+       &dev_attr_rc6_enable.attr,
+       &dev_attr_rc6_residency_ms.attr,
+       NULL
+ };
+-static struct attribute *rc6p_attrs[] = {
++static struct attribute *rc6p_dev_attrs[] = {
+       &dev_attr_rc6p_residency_ms.attr,
+       &dev_attr_rc6pp_residency_ms.attr,
+       NULL
+ };
+-static struct attribute *media_rc6_attrs[] = {
++static struct attribute *media_rc6_dev_attrs[] = {
+       &dev_attr_media_rc6_residency_ms.attr,
+       NULL
+ };
+ static const struct attribute_group rc6_attr_group[] = {
+       { .attrs = rc6_attrs, },
+-      { .name = power_group_name, .attrs = rc6_attrs, },
++      { .name = power_group_name, .attrs = rc6_dev_attrs, },
+ };
+ static const struct attribute_group rc6p_attr_group[] = {
+       { .attrs = rc6p_attrs, },
+-      { .name = power_group_name, .attrs = rc6p_attrs, },
++      { .name = power_group_name, .attrs = rc6p_dev_attrs, },
+ };
+ static const struct attribute_group media_rc6_attr_group[] = {
+       { .attrs = media_rc6_attrs, },
+-      { .name = power_group_name, .attrs = media_rc6_attrs, },
++      { .name = power_group_name, .attrs = media_rc6_dev_attrs, },
+ };
+ static int __intel_gt_sysfs_create_group(struct kobject *kobj,
+@@ -271,104 +340,34 @@ static u32 __act_freq_mhz_show(struct in
+       return intel_rps_read_actual_frequency(&gt->rps);
+ }
+-static ssize_t act_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 actual_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                  __act_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", actual_freq);
+-}
+-
+ static u32 __cur_freq_mhz_show(struct intel_gt *gt)
+ {
+       return intel_rps_get_requested_frequency(&gt->rps);
+ }
+-static ssize_t cur_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 cur_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                               __cur_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", cur_freq);
+-}
+-
+ static u32 __boost_freq_mhz_show(struct intel_gt *gt)
+ {
+       return intel_rps_get_boost_frequency(&gt->rps);
+ }
+-static ssize_t boost_freq_mhz_show(struct device *dev,
+-                                 struct device_attribute *attr,
+-                                 char *buff)
+-{
+-      u32 boost_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                 __boost_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", boost_freq);
+-}
+-
+ static int __boost_freq_mhz_store(struct intel_gt *gt, u32 val)
+ {
+       return intel_rps_set_boost_frequency(&gt->rps, val);
+ }
+-static ssize_t boost_freq_mhz_store(struct device *dev,
+-                                  struct device_attribute *attr,
+-                                  const char *buff, size_t count)
+-{
+-      ssize_t ret;
+-      u32 val;
+-
+-      ret = kstrtou32(buff, 0, &val);
+-      if (ret)
+-              return ret;
+-
+-      return sysfs_gt_attribute_w_func(dev, attr,
+-                                       __boost_freq_mhz_store, val) ?: count;
+-}
+-
+-static u32 __rp0_freq_mhz_show(struct intel_gt *gt)
++static u32 __RP0_freq_mhz_show(struct intel_gt *gt)
+ {
+       return intel_rps_get_rp0_frequency(&gt->rps);
+ }
+-static ssize_t RP0_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 rp0_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                   __rp0_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", rp0_freq);
+-}
+-
+-static u32 __rp1_freq_mhz_show(struct intel_gt *gt)
+-{
+-      return intel_rps_get_rp1_frequency(&gt->rps);
+-}
+-
+-static ssize_t RP1_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 rp1_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                   __rp1_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", rp1_freq);
+-}
+-
+-static u32 __rpn_freq_mhz_show(struct intel_gt *gt)
++static u32 __RPn_freq_mhz_show(struct intel_gt *gt)
+ {
+       return intel_rps_get_rpn_frequency(&gt->rps);
+ }
+-static ssize_t RPn_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
++static u32 __RP1_freq_mhz_show(struct intel_gt *gt)
+ {
+-      u32 rpn_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                   __rpn_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", rpn_freq);
++      return intel_rps_get_rp1_frequency(&gt->rps);
+ }
+ static u32 __max_freq_mhz_show(struct intel_gt *gt)
+@@ -376,71 +375,21 @@ static u32 __max_freq_mhz_show(struct in
+       return intel_rps_get_max_frequency(&gt->rps);
+ }
+-static ssize_t max_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 max_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                                   __max_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", max_freq);
+-}
+-
+ static int __set_max_freq(struct intel_gt *gt, u32 val)
+ {
+       return intel_rps_set_max_frequency(&gt->rps, val);
+ }
+-static ssize_t max_freq_mhz_store(struct device *dev,
+-                                struct device_attribute *attr,
+-                                const char *buff, size_t count)
+-{
+-      int ret;
+-      u32 val;
+-
+-      ret = kstrtou32(buff, 0, &val);
+-      if (ret)
+-              return ret;
+-
+-      ret = sysfs_gt_attribute_w_func(dev, attr, __set_max_freq, val);
+-
+-      return ret ?: count;
+-}
+-
+ static u32 __min_freq_mhz_show(struct intel_gt *gt)
+ {
+       return intel_rps_get_min_frequency(&gt->rps);
+ }
+-static ssize_t min_freq_mhz_show(struct device *dev,
+-                               struct device_attribute *attr, char *buff)
+-{
+-      u32 min_freq = sysfs_gt_attribute_r_min_func(dev, attr,
+-                                                   __min_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", min_freq);
+-}
+-
+ static int __set_min_freq(struct intel_gt *gt, u32 val)
+ {
+       return intel_rps_set_min_frequency(&gt->rps, val);
+ }
+-static ssize_t min_freq_mhz_store(struct device *dev,
+-                                struct device_attribute *attr,
+-                                const char *buff, size_t count)
+-{
+-      int ret;
+-      u32 val;
+-
+-      ret = kstrtou32(buff, 0, &val);
+-      if (ret)
+-              return ret;
+-
+-      ret = sysfs_gt_attribute_w_func(dev, attr, __set_min_freq, val);
+-
+-      return ret ?: count;
+-}
+-
+ static u32 __vlv_rpe_freq_mhz_show(struct intel_gt *gt)
+ {
+       struct intel_rps *rps = &gt->rps;
+@@ -448,23 +397,31 @@ static u32 __vlv_rpe_freq_mhz_show(struc
+       return intel_gpu_freq(rps, rps->efficient_freq);
+ }
+-static ssize_t vlv_rpe_freq_mhz_show(struct device *dev,
+-                                   struct device_attribute *attr, char *buff)
+-{
+-      u32 rpe_freq = sysfs_gt_attribute_r_max_func(dev, attr,
+-                                               __vlv_rpe_freq_mhz_show);
+-
+-      return sysfs_emit(buff, "%u\n", rpe_freq);
+-}
+-
+-#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store) \
+-      static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode, _show, _store); \
+-      static struct device_attribute dev_attr_rps_##_name = __ATTR(rps_##_name, _mode, _show, _store)
+-
+-#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name)                             \
+-              INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL)
+-#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name)                             \
+-              INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store)
++INTEL_GT_SYSFS_SHOW_MAX(act_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(boost_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(cur_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(RP0_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(RP1_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(RPn_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(max_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MIN(min_freq_mhz);
++INTEL_GT_SYSFS_SHOW_MAX(vlv_rpe_freq_mhz);
++INTEL_GT_SYSFS_STORE(boost_freq_mhz, __boost_freq_mhz_store);
++INTEL_GT_SYSFS_STORE(max_freq_mhz, __set_max_freq);
++INTEL_GT_SYSFS_STORE(min_freq_mhz, __set_min_freq);
++
++#define INTEL_GT_RPS_SYSFS_ATTR(_name, _mode, _show, _store, _show_dev, _store_dev)           \
++      static struct device_attribute dev_attr_gt_##_name = __ATTR(gt_##_name, _mode,          \
++                                                                  _show_dev, _store_dev);     \
++      static struct kobj_attribute attr_rps_##_name = __ATTR(rps_##_name, _mode,              \
++                                                             _show, _store)
++
++#define INTEL_GT_RPS_SYSFS_ATTR_RO(_name)                                             \
++              INTEL_GT_RPS_SYSFS_ATTR(_name, 0444, _name##_show, NULL,                \
++                                      _name##_dev_show, NULL)
++#define INTEL_GT_RPS_SYSFS_ATTR_RW(_name)                                             \
++              INTEL_GT_RPS_SYSFS_ATTR(_name, 0644, _name##_show, _name##_store,       \
++                                      _name##_dev_show, _name##_dev_store)
+ /* The below macros generate static structures */
+ INTEL_GT_RPS_SYSFS_ATTR_RO(act_freq_mhz);
+@@ -475,32 +432,31 @@ INTEL_GT_RPS_SYSFS_ATTR_RO(RP1_freq_mhz)
+ INTEL_GT_RPS_SYSFS_ATTR_RO(RPn_freq_mhz);
+ INTEL_GT_RPS_SYSFS_ATTR_RW(max_freq_mhz);
+ INTEL_GT_RPS_SYSFS_ATTR_RW(min_freq_mhz);
++INTEL_GT_RPS_SYSFS_ATTR_RO(vlv_rpe_freq_mhz);
+-static DEVICE_ATTR_RO(vlv_rpe_freq_mhz);
+-
+-#define GEN6_ATTR(s) { \
+-              &dev_attr_##s##_act_freq_mhz.attr, \
+-              &dev_attr_##s##_cur_freq_mhz.attr, \
+-              &dev_attr_##s##_boost_freq_mhz.attr, \
+-              &dev_attr_##s##_max_freq_mhz.attr, \
+-              &dev_attr_##s##_min_freq_mhz.attr, \
+-              &dev_attr_##s##_RP0_freq_mhz.attr, \
+-              &dev_attr_##s##_RP1_freq_mhz.attr, \
+-              &dev_attr_##s##_RPn_freq_mhz.attr, \
++#define GEN6_ATTR(p, s) { \
++              &p##attr_##s##_act_freq_mhz.attr, \
++              &p##attr_##s##_cur_freq_mhz.attr, \
++              &p##attr_##s##_boost_freq_mhz.attr, \
++              &p##attr_##s##_max_freq_mhz.attr, \
++              &p##attr_##s##_min_freq_mhz.attr, \
++              &p##attr_##s##_RP0_freq_mhz.attr, \
++              &p##attr_##s##_RP1_freq_mhz.attr, \
++              &p##attr_##s##_RPn_freq_mhz.attr, \
+               NULL, \
+       }
+-#define GEN6_RPS_ATTR GEN6_ATTR(rps)
+-#define GEN6_GT_ATTR  GEN6_ATTR(gt)
++#define GEN6_RPS_ATTR GEN6_ATTR(, rps)
++#define GEN6_GT_ATTR  GEN6_ATTR(dev_, gt)
+ static const struct attribute * const gen6_rps_attrs[] = GEN6_RPS_ATTR;
+ static const struct attribute * const gen6_gt_attrs[]  = GEN6_GT_ATTR;
+-static ssize_t punit_req_freq_mhz_show(struct device *dev,
+-                                     struct device_attribute *attr,
++static ssize_t punit_req_freq_mhz_show(struct kobject *kobj,
++                                     struct kobj_attribute *attr,
+                                      char *buff)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       u32 preq = intel_rps_read_punit_req_frequency(&gt->rps);
+       return sysfs_emit(buff, "%u\n", preq);
+@@ -508,17 +464,17 @@ static ssize_t punit_req_freq_mhz_show(s
+ struct intel_gt_bool_throttle_attr {
+       struct attribute attr;
+-      ssize_t (*show)(struct device *dev, struct device_attribute *attr,
++      ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr,
+                       char *buf);
+       i915_reg_t reg32;
+       u32 mask;
+ };
+-static ssize_t throttle_reason_bool_show(struct device *dev,
+-                                       struct device_attribute *attr,
++static ssize_t throttle_reason_bool_show(struct kobject *kobj,
++                                       struct kobj_attribute *attr,
+                                        char *buff)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       struct intel_gt_bool_throttle_attr *t_attr =
+                               (struct intel_gt_bool_throttle_attr *) attr;
+       bool val = rps_read_mask_mmio(&gt->rps, t_attr->reg32, t_attr->mask);
+@@ -534,7 +490,7 @@ struct intel_gt_bool_throttle_attr attr_
+       .mask = mask__, \
+ }
+-static DEVICE_ATTR_RO(punit_req_freq_mhz);
++INTEL_GT_ATTR_RO(punit_req_freq_mhz);
+ static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_status, GT0_PERF_LIMIT_REASONS_MASK);
+ static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl1, POWER_LIMIT_1_MASK);
+ static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_pl2, POWER_LIMIT_2_MASK);
+@@ -597,8 +553,8 @@ static const struct attribute *throttle_
+ #define U8_8_VAL_MASK           0xffff
+ #define U8_8_SCALE_TO_VALUE     "0.00390625"
+-static ssize_t freq_factor_scale_show(struct device *dev,
+-                                    struct device_attribute *attr,
++static ssize_t freq_factor_scale_show(struct kobject *kobj,
++                                    struct kobj_attribute *attr,
+                                     char *buff)
+ {
+       return sysfs_emit(buff, "%s\n", U8_8_SCALE_TO_VALUE);
+@@ -610,11 +566,11 @@ static u32 media_ratio_mode_to_factor(u3
+       return !mode ? mode : 256 / mode;
+ }
+-static ssize_t media_freq_factor_show(struct device *dev,
+-                                    struct device_attribute *attr,
++static ssize_t media_freq_factor_show(struct kobject *kobj,
++                                    struct kobj_attribute *attr,
+                                     char *buff)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+       intel_wakeref_t wakeref;
+       u32 mode;
+@@ -641,11 +597,11 @@ static ssize_t media_freq_factor_show(st
+       return sysfs_emit(buff, "%u\n", media_ratio_mode_to_factor(mode));
+ }
+-static ssize_t media_freq_factor_store(struct device *dev,
+-                                     struct device_attribute *attr,
++static ssize_t media_freq_factor_store(struct kobject *kobj,
++                                     struct kobj_attribute *attr,
+                                      const char *buff, size_t count)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       struct intel_guc_slpc *slpc = &gt->uc.guc.slpc;
+       u32 factor, mode;
+       int err;
+@@ -670,11 +626,11 @@ static ssize_t media_freq_factor_store(s
+       return err ?: count;
+ }
+-static ssize_t media_RP0_freq_mhz_show(struct device *dev,
+-                                     struct device_attribute *attr,
++static ssize_t media_RP0_freq_mhz_show(struct kobject *kobj,
++                                     struct kobj_attribute *attr,
+                                      char *buff)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       u32 val;
+       int err;
+@@ -691,11 +647,11 @@ static ssize_t media_RP0_freq_mhz_show(s
+       return sysfs_emit(buff, "%u\n", val);
+ }
+-static ssize_t media_RPn_freq_mhz_show(struct device *dev,
+-                                     struct device_attribute *attr,
++static ssize_t media_RPn_freq_mhz_show(struct kobject *kobj,
++                                     struct kobj_attribute *attr,
+                                      char *buff)
+ {
+-      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(dev, attr->attr.name);
++      struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
+       u32 val;
+       int err;
+@@ -712,17 +668,17 @@ static ssize_t media_RPn_freq_mhz_show(s
+       return sysfs_emit(buff, "%u\n", val);
+ }
+-static DEVICE_ATTR_RW(media_freq_factor);
+-static struct device_attribute dev_attr_media_freq_factor_scale =
++INTEL_GT_ATTR_RW(media_freq_factor);
++static struct kobj_attribute attr_media_freq_factor_scale =
+       __ATTR(media_freq_factor.scale, 0444, freq_factor_scale_show, NULL);
+-static DEVICE_ATTR_RO(media_RP0_freq_mhz);
+-static DEVICE_ATTR_RO(media_RPn_freq_mhz);
++INTEL_GT_ATTR_RO(media_RP0_freq_mhz);
++INTEL_GT_ATTR_RO(media_RPn_freq_mhz);
+ static const struct attribute *media_perf_power_attrs[] = {
+-      &dev_attr_media_freq_factor.attr,
+-      &dev_attr_media_freq_factor_scale.attr,
+-      &dev_attr_media_RP0_freq_mhz.attr,
+-      &dev_attr_media_RPn_freq_mhz.attr,
++      &attr_media_freq_factor.attr,
++      &attr_media_freq_factor_scale.attr,
++      &attr_media_RP0_freq_mhz.attr,
++      &attr_media_RPn_freq_mhz.attr,
+       NULL
+ };
+@@ -754,20 +710,29 @@ static const struct attribute * const rp
+       NULL
+ };
+-static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj,
+-                              const struct attribute * const *attrs)
++static int intel_sysfs_rps_init(struct intel_gt *gt, struct kobject *kobj)
+ {
++      const struct attribute * const *attrs;
++      struct attribute *vlv_attr;
+       int ret;
+       if (GRAPHICS_VER(gt->i915) < 6)
+               return 0;
++      if (is_object_gt(kobj)) {
++              attrs = gen6_rps_attrs;
++              vlv_attr = &attr_rps_vlv_rpe_freq_mhz.attr;
++      } else {
++              attrs = gen6_gt_attrs;
++              vlv_attr = &dev_attr_gt_vlv_rpe_freq_mhz.attr;
++      }
++
+       ret = sysfs_create_files(kobj, attrs);
+       if (ret)
+               return ret;
+       if (IS_VALLEYVIEW(gt->i915) || IS_CHERRYVIEW(gt->i915))
+-              ret = sysfs_create_file(kobj, &dev_attr_vlv_rpe_freq_mhz.attr);
++              ret = sysfs_create_file(kobj, vlv_attr);
+       return ret;
+ }
+@@ -778,9 +743,7 @@ void intel_gt_sysfs_pm_init(struct intel
+       intel_sysfs_rc6_init(gt, kobj);
+-      ret = is_object_gt(kobj) ?
+-            intel_sysfs_rps_init(gt, kobj, gen6_rps_attrs) :
+-            intel_sysfs_rps_init(gt, kobj, gen6_gt_attrs);
++      ret = intel_sysfs_rps_init(gt, kobj);
+       if (ret)
+               drm_warn(&gt->i915->drm,
+                        "failed to create gt%u RPS sysfs files (%pe)",
+@@ -790,7 +753,7 @@ void intel_gt_sysfs_pm_init(struct intel
+       if (!is_object_gt(kobj))
+               return;
+-      ret = sysfs_create_file(kobj, &dev_attr_punit_req_freq_mhz.attr);
++      ret = sysfs_create_file(kobj, &attr_punit_req_freq_mhz.attr);
+       if (ret)
+               drm_warn(&gt->i915->drm,
+                        "failed to create gt%u punit_req_freq_mhz sysfs (%pe)",
diff --git a/queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch b/queue-6.1/io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch
new file mode 100644 (file)
index 0000000..f753aff
--- /dev/null
@@ -0,0 +1,34 @@
+From af82425c6a2d2f347c79b63ce74fca6dc6be157f Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 2 Jan 2023 16:49:46 -0700
+Subject: io_uring/io-wq: free worker if task_work creation is canceled
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit af82425c6a2d2f347c79b63ce74fca6dc6be157f upstream.
+
+If we cancel the task_work, the worker will never come into existance.
+As this is the last reference to it, ensure that we get it freed
+appropriately.
+
+Cc: stable@vger.kernel.org
+Reported-by: 진호 <wnwlsgh98@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io-wq.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -1230,6 +1230,7 @@ static void io_wq_cancel_tw_create(struc
+               worker = container_of(cb, struct io_worker, create_work);
+               io_worker_cancel_cb(worker);
++              kfree(worker);
+       }
+ }
diff --git a/queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch b/queue-6.1/io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch
new file mode 100644 (file)
index 0000000..0caf72f
--- /dev/null
@@ -0,0 +1,38 @@
+From e6db6f9398dadcbc06318a133d4c44a2d3844e61 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Sun, 8 Jan 2023 10:39:17 -0700
+Subject: io_uring/io-wq: only free worker if it was allocated for creation
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit e6db6f9398dadcbc06318a133d4c44a2d3844e61 upstream.
+
+We have two types of task_work based creation, one is using an existing
+worker to setup a new one (eg when going to sleep and we have no free
+workers), and the other is allocating a new worker. Only the latter
+should be freed when we cancel task_work creation for a new worker.
+
+Fixes: af82425c6a2d ("io_uring/io-wq: free worker if task_work creation is canceled")
+Reported-by: syzbot+d56ec896af3637bdb7e4@syzkaller.appspotmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ io_uring/io-wq.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/io_uring/io-wq.c
++++ b/io_uring/io-wq.c
+@@ -1230,7 +1230,12 @@ static void io_wq_cancel_tw_create(struc
+               worker = container_of(cb, struct io_worker, create_work);
+               io_worker_cancel_cb(worker);
+-              kfree(worker);
++              /*
++               * Only the worker continuation helper has worker allocated and
++               * hence needs freeing.
++               */
++              if (cb->func == create_worker_cont)
++                      kfree(worker);
+       }
+ }
index e7356e2354a0bee933f830e4108e05a2ab78c11e..a9fef1e85ba5e1c7e4f8ebf0fb829555df457022 100644 (file)
@@ -28,11 +28,9 @@ Fixes: eb0089d629ba ("io_uring: single shot poll removal optimisation")
 Signed-off-by: Jens Axboe <axboe@kernel.dk>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
 ---
- io_uring/poll.c | 33 ++++++++++++++++++++++-----------
+ io_uring/poll.c |   33 ++++++++++++++++++++++-----------
  1 file changed, 22 insertions(+), 11 deletions(-)
 
-diff --git a/io_uring/poll.c b/io_uring/poll.c
-index df42fd8a6ab0..f2f9f174fc62 100644
 --- a/io_uring/poll.c
 +++ b/io_uring/poll.c
 @@ -223,22 +223,23 @@ enum {
@@ -65,7 +63,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644
  
        /* req->task == current here, checking PF_EXITING is safe */
        if (unlikely(req->task->flags & PF_EXITING))
-@@ -274,10 +275,15 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+@@ -274,10 +275,15 @@ static int io_poll_check_events(struct i
                if (!req->cqe.res) {
                        struct poll_table_struct pt = { ._key = req->apoll_events };
                        req->cqe.res = vfs_poll(req->file, &pt) & req->apoll_events;
@@ -84,7 +82,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644
                if (req->apoll_events & EPOLLONESHOT)
                        return IOU_POLL_DONE;
                if (io_is_uring_fops(req->file))
-@@ -294,7 +300,7 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
+@@ -294,7 +300,7 @@ static int io_poll_check_events(struct i
                                return IOU_POLL_REMOVE_POLL_USE_RES;
                        }
                } else {
@@ -93,7 +91,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644
                        if (ret == IOU_STOP_MULTISHOT)
                                return IOU_POLL_REMOVE_POLL_USE_RES;
                        if (ret < 0)
-@@ -325,6 +331,11 @@ static void io_poll_task_func(struct io_kiocb *req, bool *locked)
+@@ -325,6 +331,11 @@ static void io_poll_task_func(struct io_
        if (ret == IOU_POLL_DONE) {
                struct io_poll *poll = io_kiocb_to_cmd(req, struct io_poll);
                req->cqe.res = mangle_poll(req->cqe.res & poll->events);
@@ -105,7 +103,7 @@ index df42fd8a6ab0..f2f9f174fc62 100644
        } else if (ret != IOU_POLL_REMOVE_POLL_USE_RES) {
                req->cqe.res = ret;
                req_set_fail(req);
-@@ -350,7 +361,7 @@ static void io_apoll_task_func(struct io_kiocb *req, bool *locked)
+@@ -350,7 +361,7 @@ static void io_apoll_task_func(struct io
  
        if (ret == IOU_POLL_REMOVE_POLL_USE_RES)
                io_req_complete_post(req);
@@ -114,6 +112,3 @@ index df42fd8a6ab0..f2f9f174fc62 100644
                io_req_task_submit(req, locked);
        else
                io_req_complete_failed(req, ret);
--- 
-2.35.1
-
index 25f18e5969fb0668e97945a163dde499c5bc3618..a934165a5b3616f506f060b013d01f1e5075d673 100644 (file)
@@ -175,3 +175,7 @@ alsa-usb-audio-fix-possible-null-pointer-dereference.patch
 efi-fix-null-deref-in-init-error-path.patch
 io_uring-lock-overflowing-for-iopoll.patch
 io_uring-poll-attempt-request-issue-after-racy-poll-.patch
+drm-i915-fix-cfi-violations-in-gt_sysfs.patch
+io_uring-io-wq-free-worker-if-task_work-creation-is-canceled.patch
+io_uring-io-wq-only-free-worker-if-it-was-allocated-for-creation.patch
+block-handle-bio_split_to_limits-null-return.patch