[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251017-rn-cfi-v1-1-bf66e6ad4fcd@google.com>
Date: Fri, 17 Oct 2025 12:46:25 -0700
From: Ryan Neph <ryanneph@...gle.com>
To: Lucas De Marchi <lucas.demarchi@...el.com>,
"Thomas Hellström" <thomas.hellstrom@...ux.intel.com>, Rodrigo Vivi <rodrigo.vivi@...el.com>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>
Cc: intel-xe@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-kernel@...r.kernel.org, Ryan Neph <ryanneph@...gle.com>
Subject: [PATCH 1/2] drm/xe/sysfs: Fix additional sysfs node access CFI violations
Sysfs attribute store/show handlers expect the first passed parameter to
be of type 'struct kobject *', but Xe unintentionally abuses the fact
that a pointer to 'struct device' can decay to a kobject pointer (its
first member).
When CFI is enabled in the kernel, this is detected, resulting in an
intentional kernel crash when accessing the corresponding sysfs nodes.
This patch fixes the access handlers to take a kobject pointer instead
of device pointer, similarly to the earlier cleanup in
<https://lore.kernel.org/r/20250422171852.85558-1-jeevaka.badrappan@intel.com>
that missed some instances. Some others were added since with the same
issue.
Signed-off-by: Ryan Neph <ryanneph@...gle.com>
---
drivers/gpu/drm/xe/xe_gt_ccs_mode.c | 24 ++++++++++++------------
drivers/gpu/drm/xe/xe_survivability_mode.c | 15 ++++++++-------
drivers/gpu/drm/xe/xe_vram_freq.c | 20 ++++++++++----------
3 files changed, 30 insertions(+), 29 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c
index 50fffc9ebf62a1d0a051bbfd8698d4ec6de4d93e..6e7dc0c317f058e284203fc31dfed51f75e392ef 100644
--- a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c
+++ b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c
@@ -89,30 +89,30 @@ void xe_gt_apply_ccs_mode(struct xe_gt *gt)
}
static ssize_t
-num_cslices_show(struct device *kdev,
- struct device_attribute *attr, char *buf)
+num_cslices_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
- struct xe_gt *gt = kobj_to_gt(&kdev->kobj);
+ struct xe_gt *gt = kobj_to_gt(kobj);
return sysfs_emit(buf, "%u\n", hweight32(CCS_MASK(gt)));
}
-static DEVICE_ATTR_RO(num_cslices);
+static struct kobj_attribute attr_num_cslices = __ATTR_RO(num_cslices);
static ssize_t
-ccs_mode_show(struct device *kdev,
- struct device_attribute *attr, char *buf)
+ccs_mode_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
{
- struct xe_gt *gt = kobj_to_gt(&kdev->kobj);
+ struct xe_gt *gt = kobj_to_gt(kobj);
return sysfs_emit(buf, "%u\n", gt->ccs_mode);
}
static ssize_t
-ccs_mode_store(struct device *kdev, struct device_attribute *attr,
+ccs_mode_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buff, size_t count)
{
- struct xe_gt *gt = kobj_to_gt(&kdev->kobj);
+ struct xe_gt *gt = kobj_to_gt(kobj);
struct xe_device *xe = gt_to_xe(gt);
u32 num_engines, num_slices;
int ret;
@@ -158,11 +158,11 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR_RW(ccs_mode);
+static struct kobj_attribute attr_ccs_mode = __ATTR_RW(ccs_mode);
static const struct attribute *gt_ccs_mode_attrs[] = {
- &dev_attr_ccs_mode.attr,
- &dev_attr_num_cslices.attr,
+ &attr_ccs_mode.attr,
+ &attr_num_cslices.attr,
NULL,
};
diff --git a/drivers/gpu/drm/xe/xe_survivability_mode.c b/drivers/gpu/drm/xe/xe_survivability_mode.c
index 1662bfddd4bc9c530644c185eb929f0613eb8e30..8bfad28d269440deb6a18a95b91eccc61be1b50e 100644
--- a/drivers/gpu/drm/xe/xe_survivability_mode.c
+++ b/drivers/gpu/drm/xe/xe_survivability_mode.c
@@ -150,11 +150,11 @@ static int check_boot_failure(struct xe_device *xe)
survivability->boot_status == CRITICAL_FAILURE;
}
-static ssize_t survivability_mode_show(struct device *dev,
- struct device_attribute *attr, char *buff)
+static ssize_t survivability_mode_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buff)
{
- struct pci_dev *pdev = to_pci_dev(dev);
- struct xe_device *xe = pdev_to_xe_device(pdev);
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct xe_device *xe = pdev_to_xe_device(to_pci_dev(dev));
struct xe_survivability *survivability = &xe->survivability;
struct xe_survivability_info *info = survivability->info;
int index = 0, count = 0;
@@ -174,7 +174,8 @@ static ssize_t survivability_mode_show(struct device *dev,
return count;
}
-static DEVICE_ATTR_ADMIN_RO(survivability_mode);
+static struct kobj_attribute attr_survivability_mode =
+ __ATTR_RO_MODE(survivability_mode, 0400);
static void xe_survivability_mode_fini(void *arg)
{
@@ -182,7 +183,7 @@ static void xe_survivability_mode_fini(void *arg)
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
struct device *dev = &pdev->dev;
- sysfs_remove_file(&dev->kobj, &dev_attr_survivability_mode.attr);
+ sysfs_remove_file(&dev->kobj, &attr_survivability_mode.attr);
}
static int create_survivability_sysfs(struct pci_dev *pdev)
@@ -192,7 +193,7 @@ static int create_survivability_sysfs(struct pci_dev *pdev)
int ret;
/* create survivability mode sysfs */
- ret = sysfs_create_file(&dev->kobj, &dev_attr_survivability_mode.attr);
+ ret = sysfs_create_file(&dev->kobj, &attr_survivability_mode.attr);
if (ret) {
dev_warn(dev, "Failed to create survivability sysfs files\n");
return ret;
diff --git a/drivers/gpu/drm/xe/xe_vram_freq.c b/drivers/gpu/drm/xe/xe_vram_freq.c
index 17bc84da4cdcc9da22f44b99f63f2393ad85371a..7c1ce2602f70abd3a00c03982b25a69bacc24a25 100644
--- a/drivers/gpu/drm/xe/xe_vram_freq.c
+++ b/drivers/gpu/drm/xe/xe_vram_freq.c
@@ -25,15 +25,15 @@
* configuration.
*/
-static struct xe_tile *dev_to_tile(struct device *dev)
+static struct xe_tile *kobj_parent_to_tile(struct kobject *kobj)
{
- return kobj_to_tile(dev->kobj.parent);
+ return kobj_to_tile(kobj->parent);
}
-static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
+static ssize_t max_freq_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
- struct xe_tile *tile = dev_to_tile(dev);
+ struct xe_tile *tile = kobj_parent_to_tile(kobj);
u32 val = 0, mbox;
int err;
@@ -50,12 +50,12 @@ static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr,
return sysfs_emit(buf, "%u\n", val);
}
-static DEVICE_ATTR_RO(max_freq);
+static struct kobj_attribute attr_max_freq = __ATTR_RO(max_freq);
-static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
+static ssize_t min_freq_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
- struct xe_tile *tile = dev_to_tile(dev);
+ struct xe_tile *tile = kobj_parent_to_tile(kobj);
u32 val = 0, mbox;
int err;
@@ -72,11 +72,11 @@ static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr,
return sysfs_emit(buf, "%u\n", val);
}
-static DEVICE_ATTR_RO(min_freq);
+static struct kobj_attribute attr_min_freq = __ATTR_RO(min_freq);
static struct attribute *freq_attrs[] = {
- &dev_attr_max_freq.attr,
- &dev_attr_min_freq.attr,
+ &attr_max_freq.attr,
+ &attr_min_freq.attr,
NULL
};
--
2.51.0.858.gf9c4a03a3a-goog
Powered by blists - more mailing lists