]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 Jan 2024 23:07:05 +0000 (15:07 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 27 Jan 2024 23:07:05 +0000 (15:07 -0800)
added patches:
platform-x86-intel-uncore-freq-fix-types-in-sysfs-callbacks.patch

queue-6.1/platform-x86-intel-uncore-freq-fix-types-in-sysfs-callbacks.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/platform-x86-intel-uncore-freq-fix-types-in-sysfs-callbacks.patch b/queue-6.1/platform-x86-intel-uncore-freq-fix-types-in-sysfs-callbacks.patch
new file mode 100644 (file)
index 0000000..cea4c73
--- /dev/null
@@ -0,0 +1,216 @@
+From 416de0246f35f43d871a57939671fe814f4455ee Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Thu, 4 Jan 2024 15:59:03 -0700
+Subject: platform/x86: intel-uncore-freq: Fix types in sysfs callbacks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 416de0246f35f43d871a57939671fe814f4455ee upstream.
+
+When booting a kernel with CONFIG_CFI_CLANG, there is a CFI failure when
+accessing any of the values under
+/sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00:
+
+  $ cat /sys/devices/system/cpu/intel_uncore_frequency/package_00_die_00/max_freq_khz
+  fish: Job 1, 'cat /sys/devices/system/cpu/int…' terminated by signal SIGSEGV (Address boundary error)
+
+  $ sudo dmesg &| grep 'CFI failure'
+  [  170.953925] CFI failure at kobj_attr_show+0x19/0x30 (target: show_max_freq_khz+0x0/0xc0 [intel_uncore_frequency_common]; expected type: 0xd34078c5
+
+The sysfs callback functions such as show_domain_id() are written as if
+they are going to be called by dev_attr_show() but as the above message
+shows, they are instead called by kobj_attr_show(). kCFI checks that the
+destination of an indirect jump has the exact same type as the prototype
+of the function pointer it is called through and fails when they do not.
+
+These callbacks are called through kobj_attr_show() because
+uncore_root_kobj was initialized with kobject_create_and_add(), which
+means uncore_root_kobj has a ->sysfs_ops of kobj_sysfs_ops from
+kobject_create(), which uses kobj_attr_show() as its ->show() value.
+
+The only reason there has not been a more noticeable problem until this
+point is that 'struct kobj_attribute' and 'struct device_attribute' have
+the same layout, so getting the callback from container_of() works the
+same with either value.
+
+Change all the callbacks and their uses to be compatible with
+kobj_attr_show() and kobj_attr_store(), which resolves the kCFI failure
+and allows the sysfs files to work properly.
+
+Closes: https://github.com/ClangBuiltLinux/linux/issues/1974
+Fixes: ae7b2ce57851 ("platform/x86/intel/uncore-freq: Use sysfs API to create attributes")
+Cc: stable@vger.kernel.org
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://lore.kernel.org/r/20240104-intel-uncore-freq-kcfi-fix-v1-1-bf1e8939af40@kernel.org
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+[nathan: Fix conflicts due to lack of 9b8dea80e3cb in 6.1]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c |   64 +++++-----
+ drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h |   20 +--
+ 2 files changed, 42 insertions(+), 42 deletions(-)
+
+--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
++++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c
+@@ -74,30 +74,30 @@ static ssize_t show_perf_status_freq_khz
+ }
+ #define store_uncore_min_max(name, min_max)                           \
+-      static ssize_t store_##name(struct device *dev,         \
+-                                   struct device_attribute *attr,     \
++      static ssize_t store_##name(struct kobject *kobj,               \
++                                   struct kobj_attribute *attr,       \
+                                    const char *buf, size_t count)     \
+       {                                                               \
+-              struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
++              struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
+                                                                       \
+               return store_min_max_freq_khz(data, buf, count, \
+                                             min_max);         \
+       }
+ #define show_uncore_min_max(name, min_max)                            \
+-      static ssize_t show_##name(struct device *dev,          \
+-                                  struct device_attribute *attr, char *buf)\
++      static ssize_t show_##name(struct kobject *kobj,                \
++                                  struct kobj_attribute *attr, char *buf)\
+       {                                                               \
+-              struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
++              struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
+                                                                       \
+               return show_min_max_freq_khz(data, buf, min_max);       \
+       }
+ #define show_uncore_perf_status(name)                                 \
+-      static ssize_t show_##name(struct device *dev,          \
+-                                 struct device_attribute *attr, char *buf)\
++      static ssize_t show_##name(struct kobject *kobj,                \
++                                 struct kobj_attribute *attr, char *buf)\
+       {                                                               \
+-              struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\
++              struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\
+                                                                       \
+               return show_perf_status_freq_khz(data, buf); \
+       }
+@@ -111,11 +111,11 @@ show_uncore_min_max(max_freq_khz, 1);
+ show_uncore_perf_status(current_freq_khz);
+ #define show_uncore_data(member_name)                                 \
+-      static ssize_t show_##member_name(struct device *dev,   \
+-                                         struct device_attribute *attr, char *buf)\
++      static ssize_t show_##member_name(struct kobject *kobj, \
++                                         struct kobj_attribute *attr, char *buf)\
+       {                                                               \
+               struct uncore_data *data = container_of(attr, struct uncore_data,\
+-                                                        member_name##_dev_attr);\
++                                                        member_name##_kobj_attr);\
+                                                                       \
+               return sysfs_emit(buf, "%u\n",                          \
+                                data->member_name);                    \
+@@ -126,29 +126,29 @@ show_uncore_data(initial_max_freq_khz);
+ #define init_attribute_rw(_name)                                      \
+       do {                                                            \
+-              sysfs_attr_init(&data->_name##_dev_attr.attr);  \
+-              data->_name##_dev_attr.show = show_##_name;             \
+-              data->_name##_dev_attr.store = store_##_name;           \
+-              data->_name##_dev_attr.attr.name = #_name;              \
+-              data->_name##_dev_attr.attr.mode = 0644;                \
++              sysfs_attr_init(&data->_name##_kobj_attr.attr); \
++              data->_name##_kobj_attr.show = show_##_name;            \
++              data->_name##_kobj_attr.store = store_##_name;          \
++              data->_name##_kobj_attr.attr.name = #_name;             \
++              data->_name##_kobj_attr.attr.mode = 0644;               \
+       } while (0)
+ #define init_attribute_ro(_name)                                      \
+       do {                                                            \
+-              sysfs_attr_init(&data->_name##_dev_attr.attr);  \
+-              data->_name##_dev_attr.show = show_##_name;             \
+-              data->_name##_dev_attr.store = NULL;                    \
+-              data->_name##_dev_attr.attr.name = #_name;              \
+-              data->_name##_dev_attr.attr.mode = 0444;                \
++              sysfs_attr_init(&data->_name##_kobj_attr.attr); \
++              data->_name##_kobj_attr.show = show_##_name;            \
++              data->_name##_kobj_attr.store = NULL;                   \
++              data->_name##_kobj_attr.attr.name = #_name;             \
++              data->_name##_kobj_attr.attr.mode = 0444;               \
+       } while (0)
+ #define init_attribute_root_ro(_name)                                 \
+       do {                                                            \
+-              sysfs_attr_init(&data->_name##_dev_attr.attr);  \
+-              data->_name##_dev_attr.show = show_##_name;             \
+-              data->_name##_dev_attr.store = NULL;                    \
+-              data->_name##_dev_attr.attr.name = #_name;              \
+-              data->_name##_dev_attr.attr.mode = 0400;                \
++              sysfs_attr_init(&data->_name##_kobj_attr.attr); \
++              data->_name##_kobj_attr.show = show_##_name;            \
++              data->_name##_kobj_attr.store = NULL;                   \
++              data->_name##_kobj_attr.attr.name = #_name;             \
++              data->_name##_kobj_attr.attr.mode = 0400;               \
+       } while (0)
+ static int create_attr_group(struct uncore_data *data, char *name)
+@@ -161,14 +161,14 @@ static int create_attr_group(struct unco
+       init_attribute_ro(initial_max_freq_khz);
+       init_attribute_root_ro(current_freq_khz);
+-      data->uncore_attrs[index++] = &data->max_freq_khz_dev_attr.attr;
+-      data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr;
+-      data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr;
+-      data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr;
++      data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr;
++      data->uncore_attrs[index++] = &data->min_freq_khz_kobj_attr.attr;
++      data->uncore_attrs[index++] = &data->initial_min_freq_khz_kobj_attr.attr;
++      data->uncore_attrs[index++] = &data->initial_max_freq_khz_kobj_attr.attr;
+       ret = uncore_read_freq(data, &freq);
+       if (!ret)
+-              data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr;
++              data->uncore_attrs[index++] = &data->current_freq_khz_kobj_attr.attr;
+       data->uncore_attrs[index] = NULL;
+--- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
++++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h
+@@ -23,11 +23,11 @@
+  * @die_id:           Die id for this instance
+  * @name:             Sysfs entry name for this instance
+  * @uncore_attr_group:        Attribute group storage
+- * @max_freq_khz_dev_attr: Storage for device attribute max_freq_khz
+- * @mix_freq_khz_dev_attr: Storage for device attribute min_freq_khz
+- * @initial_max_freq_khz_dev_attr: Storage for device attribute initial_max_freq_khz
+- * @initial_min_freq_khz_dev_attr: Storage for device attribute initial_min_freq_khz
+- * @current_freq_khz_dev_attr: Storage for device attribute current_freq_khz
++ * @max_freq_khz_dev_attr: Storage for kobject attribute max_freq_khz
++ * @mix_freq_khz_dev_attr: Storage for kobject attribute min_freq_khz
++ * @initial_max_freq_khz_dev_attr: Storage for kobject attribute initial_max_freq_khz
++ * @initial_min_freq_khz_dev_attr: Storage for kobject attribute initial_min_freq_khz
++ * @current_freq_khz_dev_attr: Storage for kobject attribute current_freq_khz
+  * @uncore_attrs:     Attribute storage for group creation
+  *
+  * This structure is used to encapsulate all data related to uncore sysfs
+@@ -44,11 +44,11 @@ struct uncore_data {
+       char name[32];
+       struct attribute_group uncore_attr_group;
+-      struct device_attribute max_freq_khz_dev_attr;
+-      struct device_attribute min_freq_khz_dev_attr;
+-      struct device_attribute initial_max_freq_khz_dev_attr;
+-      struct device_attribute initial_min_freq_khz_dev_attr;
+-      struct device_attribute current_freq_khz_dev_attr;
++      struct kobj_attribute max_freq_khz_kobj_attr;
++      struct kobj_attribute min_freq_khz_kobj_attr;
++      struct kobj_attribute initial_max_freq_khz_kobj_attr;
++      struct kobj_attribute initial_min_freq_khz_kobj_attr;
++      struct kobj_attribute current_freq_khz_kobj_attr;
+       struct attribute *uncore_attrs[6];
+ };
index 41fa5fff155eda6292fd9980199b2fe69d6999e3..fb8ad869424b920486c398d7cac1da6ef8652125 100644 (file)
@@ -137,3 +137,4 @@ drm-don-t-unref-the-same-fb-many-times-by-mistake-due-to-deadlock-handling.patch
 drm-bridge-nxp-ptn3460-fix-i2c_master_send-error-checking.patch
 drm-tidss-fix-atomic_flush-check.patch
 drm-amd-display-disable-psr-su-on-parade-0803-tcon-again.patch
+platform-x86-intel-uncore-freq-fix-types-in-sysfs-callbacks.patch