Skip to content

Commit 4ea5127

Browse files
JeevakaPraburodrigovivi
authored andcommitted
drm/xe: Fix CFI violation when accessing sysfs files
When an attribute group is created with sysfs_create_group() or sysfs_create_files() the ->sysfs_ops() callback is set to kobj_sysfs_ops, which sets the ->show() callback to kobj_attr_show(). kobj_attr_show() uses container_of() to get the ->show() callback from the attribute it was passed, meaning the ->show() callback needs to be the same type as the ->show() callback in 'struct kobj_attribute'. However, cur_freq_show() has the type of the ->show() callback in 'struct device_attribute', which causes a CFI violation when opening the 'id' sysfs node under gtidle/freq/throttle. This happens to work because the layout of 'struct kobj_attribute' and 'struct device_attribute' are the same, so the container_of() cast happens to allow the ->show() callback to still work. Changed the type of cur_freq_show() and few more functions to match the ->show() callback in 'struct kobj_attributes' to resolve the CFI violation. CFI failure seen while accessing sysfs files under /sys/class/drm/card0/device/tile0/gt*/gtidle/* /sys/class/drm/card0/device/tile0/gt*/freq0/* /sys/class/drm/card0/device/tile0/gt*/freq0/throttle/* [ 2599.618075] RIP: 0010:__cfi_cur_freq_show+0xd/0x10 [xe] [ 2599.624452] Code: 44 c1 44 89 fa e8 03 95 39 f2 48 98 5b 41 5e 41 5f 5d c3 c9 [ 2599.646638] RSP: 0018:ffffbe438ead7d10 EFLAGS: 00010286 [ 2599.652823] RAX: ffff9f7d8b3845d8 RBX: ffff9f7dee8c95d8 RCX: 0000000000000000 [ 2599.661246] RDX: ffff9f7e6f439000 RSI: ffffffffc13ada30 RDI: ffff9f7d975d4b00 [ 2599.669669] RBP: ffffbe438ead7d18 R08: 0000000000001000 R09: ffff9f7e6f439000 [ 2599.678092] R10: 00000000e07304a6 R11: ffffffffc1241ca0 R12: ffffffffb4836ea0 [ 2599.688435] R13: ffff9f7e45fb1180 R14: ffff9f7d975d4b00 R15: ffff9f7e6f439000 [ 2599.696860] FS: 000076b02b66cfc0(0000) GS:ffff9f80ef400000(0000) knlGS:00000 [ 2599.706412] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2599.713196] CR2: 00005f80d94641a9 CR3: 00000001e44ec006 CR4: 0000000100f72ef0 [ 2599.721618] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 2599.730041] DR3: 0000000000000000 DR6: 00000000ffff07f0 DR7: 0000000000000400 [ 2599.738464] PKRU: 55555554 [ 2599.741655] Call Trace: [ 2599.744541] <TASK> [ 2599.747017] ? __die_body+0x69/0xb0 [ 2599.751151] ? die+0xa9/0xd0 [ 2599.754548] ? do_trap+0x89/0x160 [ 2599.758476] ? __cfi_cur_freq_show+0xd/0x10 [xe b37985c94829727668bd7c5b33c1] [ 2599.768315] ? handle_invalid_op+0x69/0x90 [ 2599.773167] ? __cfi_cur_freq_show+0xd/0x10 [xe b37985c94829727668bd7c5b33c1] [ 2599.783010] ? exc_invalid_op+0x36/0x60 [ 2599.787552] ? fred_hwexc+0x123/0x1a0 [ 2599.791873] ? fred_entry_from_kernel+0x7b/0xd0 [ 2599.797219] ? asm_fred_entrypoint_kernel+0x45/0x70 [ 2599.802976] ? act_freq_show+0x70/0x70 [xe b37985c94829727668bd7c5b33c1d9998] [ 2599.812301] ? __cfi_cur_freq_show+0xd/0x10 [xe b37985c94829727668bd7c5b33c1] [ 2599.822137] ? __kmalloc_node_noprof+0x1f3/0x420 [ 2599.827594] ? __kvmalloc_node_noprof+0xcb/0x180 [ 2599.833045] ? kobj_attr_show+0x22/0x40 [ 2599.837571] sysfs_kf_seq_show+0xa8/0x110 [ 2599.842302] kernfs_seq_show+0x38/0x50 Signed-off-by: Jeevaka Prabu Badrappan <jeevaka.badrappan@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://lore.kernel.org/r/20250422171852.85558-1-jeevaka.badrappan@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent 7e3f4a3 commit 4ea5127

3 files changed

Lines changed: 107 additions & 93 deletions

File tree

drivers/gpu/drm/xe/xe_gt_freq.c

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ dev_to_xe(struct device *dev)
5656
return gt_to_xe(kobj_to_gt(dev->kobj.parent));
5757
}
5858

59-
static ssize_t act_freq_show(struct device *dev,
60-
struct device_attribute *attr, char *buf)
59+
static ssize_t act_freq_show(struct kobject *kobj,
60+
struct kobj_attribute *attr, char *buf)
6161
{
62+
struct device *dev = kobj_to_dev(kobj);
6263
struct xe_guc_pc *pc = dev_to_pc(dev);
6364
u32 freq;
6465

@@ -68,11 +69,12 @@ static ssize_t act_freq_show(struct device *dev,
6869

6970
return sysfs_emit(buf, "%d\n", freq);
7071
}
71-
static DEVICE_ATTR_RO(act_freq);
72+
static struct kobj_attribute attr_act_freq = __ATTR_RO(act_freq);
7273

73-
static ssize_t cur_freq_show(struct device *dev,
74-
struct device_attribute *attr, char *buf)
74+
static ssize_t cur_freq_show(struct kobject *kobj,
75+
struct kobj_attribute *attr, char *buf)
7576
{
77+
struct device *dev = kobj_to_dev(kobj);
7678
struct xe_guc_pc *pc = dev_to_pc(dev);
7779
u32 freq;
7880
ssize_t ret;
@@ -85,11 +87,12 @@ static ssize_t cur_freq_show(struct device *dev,
8587

8688
return sysfs_emit(buf, "%d\n", freq);
8789
}
88-
static DEVICE_ATTR_RO(cur_freq);
90+
static struct kobj_attribute attr_cur_freq = __ATTR_RO(cur_freq);
8991

90-
static ssize_t rp0_freq_show(struct device *dev,
91-
struct device_attribute *attr, char *buf)
92+
static ssize_t rp0_freq_show(struct kobject *kobj,
93+
struct kobj_attribute *attr, char *buf)
9294
{
95+
struct device *dev = kobj_to_dev(kobj);
9396
struct xe_guc_pc *pc = dev_to_pc(dev);
9497
u32 freq;
9598

@@ -99,11 +102,12 @@ static ssize_t rp0_freq_show(struct device *dev,
99102

100103
return sysfs_emit(buf, "%d\n", freq);
101104
}
102-
static DEVICE_ATTR_RO(rp0_freq);
105+
static struct kobj_attribute attr_rp0_freq = __ATTR_RO(rp0_freq);
103106

104-
static ssize_t rpe_freq_show(struct device *dev,
105-
struct device_attribute *attr, char *buf)
107+
static ssize_t rpe_freq_show(struct kobject *kobj,
108+
struct kobj_attribute *attr, char *buf)
106109
{
110+
struct device *dev = kobj_to_dev(kobj);
107111
struct xe_guc_pc *pc = dev_to_pc(dev);
108112
u32 freq;
109113

@@ -113,11 +117,12 @@ static ssize_t rpe_freq_show(struct device *dev,
113117

114118
return sysfs_emit(buf, "%d\n", freq);
115119
}
116-
static DEVICE_ATTR_RO(rpe_freq);
120+
static struct kobj_attribute attr_rpe_freq = __ATTR_RO(rpe_freq);
117121

118-
static ssize_t rpa_freq_show(struct device *dev,
119-
struct device_attribute *attr, char *buf)
122+
static ssize_t rpa_freq_show(struct kobject *kobj,
123+
struct kobj_attribute *attr, char *buf)
120124
{
125+
struct device *dev = kobj_to_dev(kobj);
121126
struct xe_guc_pc *pc = dev_to_pc(dev);
122127
u32 freq;
123128

@@ -127,20 +132,22 @@ static ssize_t rpa_freq_show(struct device *dev,
127132

128133
return sysfs_emit(buf, "%d\n", freq);
129134
}
130-
static DEVICE_ATTR_RO(rpa_freq);
135+
static struct kobj_attribute attr_rpa_freq = __ATTR_RO(rpa_freq);
131136

132-
static ssize_t rpn_freq_show(struct device *dev,
133-
struct device_attribute *attr, char *buf)
137+
static ssize_t rpn_freq_show(struct kobject *kobj,
138+
struct kobj_attribute *attr, char *buf)
134139
{
140+
struct device *dev = kobj_to_dev(kobj);
135141
struct xe_guc_pc *pc = dev_to_pc(dev);
136142

137143
return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpn_freq(pc));
138144
}
139-
static DEVICE_ATTR_RO(rpn_freq);
145+
static struct kobj_attribute attr_rpn_freq = __ATTR_RO(rpn_freq);
140146

141-
static ssize_t min_freq_show(struct device *dev,
142-
struct device_attribute *attr, char *buf)
147+
static ssize_t min_freq_show(struct kobject *kobj,
148+
struct kobj_attribute *attr, char *buf)
143149
{
150+
struct device *dev = kobj_to_dev(kobj);
144151
struct xe_guc_pc *pc = dev_to_pc(dev);
145152
u32 freq;
146153
ssize_t ret;
@@ -154,9 +161,10 @@ static ssize_t min_freq_show(struct device *dev,
154161
return sysfs_emit(buf, "%d\n", freq);
155162
}
156163

157-
static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
158-
const char *buff, size_t count)
164+
static ssize_t min_freq_store(struct kobject *kobj,
165+
struct kobj_attribute *attr, const char *buff, size_t count)
159166
{
167+
struct device *dev = kobj_to_dev(kobj);
160168
struct xe_guc_pc *pc = dev_to_pc(dev);
161169
u32 freq;
162170
ssize_t ret;
@@ -173,11 +181,12 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
173181

174182
return count;
175183
}
176-
static DEVICE_ATTR_RW(min_freq);
184+
static struct kobj_attribute attr_min_freq = __ATTR_RW(min_freq);
177185

178-
static ssize_t max_freq_show(struct device *dev,
179-
struct device_attribute *attr, char *buf)
186+
static ssize_t max_freq_show(struct kobject *kobj,
187+
struct kobj_attribute *attr, char *buf)
180188
{
189+
struct device *dev = kobj_to_dev(kobj);
181190
struct xe_guc_pc *pc = dev_to_pc(dev);
182191
u32 freq;
183192
ssize_t ret;
@@ -191,9 +200,10 @@ static ssize_t max_freq_show(struct device *dev,
191200
return sysfs_emit(buf, "%d\n", freq);
192201
}
193202

194-
static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
195-
const char *buff, size_t count)
203+
static ssize_t max_freq_store(struct kobject *kobj,
204+
struct kobj_attribute *attr, const char *buff, size_t count)
196205
{
206+
struct device *dev = kobj_to_dev(kobj);
197207
struct xe_guc_pc *pc = dev_to_pc(dev);
198208
u32 freq;
199209
ssize_t ret;
@@ -210,17 +220,17 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
210220

211221
return count;
212222
}
213-
static DEVICE_ATTR_RW(max_freq);
223+
static struct kobj_attribute attr_max_freq = __ATTR_RW(max_freq);
214224

215225
static const struct attribute *freq_attrs[] = {
216-
&dev_attr_act_freq.attr,
217-
&dev_attr_cur_freq.attr,
218-
&dev_attr_rp0_freq.attr,
219-
&dev_attr_rpa_freq.attr,
220-
&dev_attr_rpe_freq.attr,
221-
&dev_attr_rpn_freq.attr,
222-
&dev_attr_min_freq.attr,
223-
&dev_attr_max_freq.attr,
226+
&attr_act_freq.attr,
227+
&attr_cur_freq.attr,
228+
&attr_rp0_freq.attr,
229+
&attr_rpa_freq.attr,
230+
&attr_rpe_freq.attr,
231+
&attr_rpn_freq.attr,
232+
&attr_min_freq.attr,
233+
&attr_max_freq.attr,
224234
NULL
225235
};
226236

drivers/gpu/drm/xe/xe_gt_idle.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,10 @@ int xe_gt_idle_pg_print(struct xe_gt *gt, struct drm_printer *p)
249249
return 0;
250250
}
251251

252-
static ssize_t name_show(struct device *dev,
253-
struct device_attribute *attr, char *buff)
252+
static ssize_t name_show(struct kobject *kobj,
253+
struct kobj_attribute *attr, char *buff)
254254
{
255+
struct device *dev = kobj_to_dev(kobj);
255256
struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
256257
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
257258
ssize_t ret;
@@ -262,11 +263,12 @@ static ssize_t name_show(struct device *dev,
262263

263264
return ret;
264265
}
265-
static DEVICE_ATTR_RO(name);
266+
static struct kobj_attribute name_attr = __ATTR_RO(name);
266267

267-
static ssize_t idle_status_show(struct device *dev,
268-
struct device_attribute *attr, char *buff)
268+
static ssize_t idle_status_show(struct kobject *kobj,
269+
struct kobj_attribute *attr, char *buff)
269270
{
271+
struct device *dev = kobj_to_dev(kobj);
270272
struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
271273
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
272274
enum xe_gt_idle_state state;
@@ -277,6 +279,7 @@ static ssize_t idle_status_show(struct device *dev,
277279

278280
return sysfs_emit(buff, "%s\n", gt_idle_state_to_string(state));
279281
}
282+
static struct kobj_attribute idle_status_attr = __ATTR_RO(idle_status);
280283

281284
u64 xe_gt_idle_residency_msec(struct xe_gt_idle *gtidle)
282285
{
@@ -291,10 +294,11 @@ u64 xe_gt_idle_residency_msec(struct xe_gt_idle *gtidle)
291294
return residency;
292295
}
293296

294-
static DEVICE_ATTR_RO(idle_status);
295-
static ssize_t idle_residency_ms_show(struct device *dev,
296-
struct device_attribute *attr, char *buff)
297+
298+
static ssize_t idle_residency_ms_show(struct kobject *kobj,
299+
struct kobj_attribute *attr, char *buff)
297300
{
301+
struct device *dev = kobj_to_dev(kobj);
298302
struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
299303
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
300304
u64 residency;
@@ -305,12 +309,12 @@ static ssize_t idle_residency_ms_show(struct device *dev,
305309

306310
return sysfs_emit(buff, "%llu\n", residency);
307311
}
308-
static DEVICE_ATTR_RO(idle_residency_ms);
312+
static struct kobj_attribute idle_residency_attr = __ATTR_RO(idle_residency_ms);
309313

310314
static const struct attribute *gt_idle_attrs[] = {
311-
&dev_attr_name.attr,
312-
&dev_attr_idle_status.attr,
313-
&dev_attr_idle_residency_ms.attr,
315+
&name_attr.attr,
316+
&idle_status_attr.attr,
317+
&idle_residency_attr.attr,
314318
NULL,
315319
};
316320

0 commit comments

Comments
 (0)