Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/base/firmware_loader/sysfs.c
49184 views
1
// SPDX-License-Identifier: GPL-2.0
2
3
#include <linux/highmem.h>
4
#include <linux/module.h>
5
#include <linux/security.h>
6
#include <linux/slab.h>
7
#include <linux/types.h>
8
9
#include "sysfs.h"
10
11
/*
12
* sysfs support for firmware loader
13
*/
14
15
void __fw_load_abort(struct fw_priv *fw_priv)
16
{
17
/*
18
* There is a small window in which user can write to 'loading'
19
* between loading done/aborted and disappearance of 'loading'
20
*/
21
if (fw_state_is_aborted(fw_priv) || fw_state_is_done(fw_priv))
22
return;
23
24
fw_state_aborted(fw_priv);
25
}
26
27
#ifdef CONFIG_FW_LOADER_USER_HELPER
28
static ssize_t timeout_show(const struct class *class, const struct class_attribute *attr,
29
char *buf)
30
{
31
return sysfs_emit(buf, "%d\n", __firmware_loading_timeout());
32
}
33
34
/**
35
* timeout_store() - set number of seconds to wait for firmware
36
* @class: device class pointer
37
* @attr: device attribute pointer
38
* @buf: buffer to scan for timeout value
39
* @count: number of bytes in @buf
40
*
41
* Sets the number of seconds to wait for the firmware. Once
42
* this expires an error will be returned to the driver and no
43
* firmware will be provided.
44
*
45
* Note: zero means 'wait forever'.
46
**/
47
static ssize_t timeout_store(const struct class *class, const struct class_attribute *attr,
48
const char *buf, size_t count)
49
{
50
int tmp_loading_timeout;
51
52
if (kstrtoint(buf, 10, &tmp_loading_timeout))
53
return -EINVAL;
54
55
if (tmp_loading_timeout < 0)
56
tmp_loading_timeout = 0;
57
58
__fw_fallback_set_timeout(tmp_loading_timeout);
59
60
return count;
61
}
62
static CLASS_ATTR_RW(timeout);
63
64
static struct attribute *firmware_class_attrs[] = {
65
&class_attr_timeout.attr,
66
NULL,
67
};
68
ATTRIBUTE_GROUPS(firmware_class);
69
70
static int do_firmware_uevent(const struct fw_sysfs *fw_sysfs, struct kobj_uevent_env *env)
71
{
72
if (add_uevent_var(env, "FIRMWARE=%s", fw_sysfs->fw_priv->fw_name))
73
return -ENOMEM;
74
if (add_uevent_var(env, "TIMEOUT=%i", __firmware_loading_timeout()))
75
return -ENOMEM;
76
if (add_uevent_var(env, "ASYNC=%d", fw_sysfs->nowait))
77
return -ENOMEM;
78
79
return 0;
80
}
81
82
static int firmware_uevent(const struct device *dev, struct kobj_uevent_env *env)
83
{
84
const struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
85
int err = 0;
86
87
mutex_lock(&fw_lock);
88
if (fw_sysfs->fw_priv)
89
err = do_firmware_uevent(fw_sysfs, env);
90
mutex_unlock(&fw_lock);
91
return err;
92
}
93
#endif /* CONFIG_FW_LOADER_USER_HELPER */
94
95
static void fw_dev_release(struct device *dev)
96
{
97
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
98
99
if (fw_sysfs->fw_upload_priv)
100
fw_upload_free(fw_sysfs);
101
102
kfree(fw_sysfs);
103
}
104
105
static struct class firmware_class = {
106
.name = "firmware",
107
#ifdef CONFIG_FW_LOADER_USER_HELPER
108
.class_groups = firmware_class_groups,
109
.dev_uevent = firmware_uevent,
110
#endif
111
.dev_release = fw_dev_release,
112
};
113
114
int register_sysfs_loader(void)
115
{
116
int ret = class_register(&firmware_class);
117
118
if (ret != 0)
119
return ret;
120
return register_firmware_config_sysctl();
121
}
122
123
void unregister_sysfs_loader(void)
124
{
125
unregister_firmware_config_sysctl();
126
class_unregister(&firmware_class);
127
}
128
129
static ssize_t firmware_loading_show(struct device *dev,
130
struct device_attribute *attr, char *buf)
131
{
132
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
133
int loading = 0;
134
135
mutex_lock(&fw_lock);
136
if (fw_sysfs->fw_priv)
137
loading = fw_state_is_loading(fw_sysfs->fw_priv);
138
mutex_unlock(&fw_lock);
139
140
return sysfs_emit(buf, "%d\n", loading);
141
}
142
143
/**
144
* firmware_loading_store() - set value in the 'loading' control file
145
* @dev: device pointer
146
* @attr: device attribute pointer
147
* @buf: buffer to scan for loading control value
148
* @count: number of bytes in @buf
149
*
150
* The relevant values are:
151
*
152
* 1: Start a load, discarding any previous partial load.
153
* 0: Conclude the load and hand the data to the driver code.
154
* -1: Conclude the load with an error and discard any written data.
155
**/
156
static ssize_t firmware_loading_store(struct device *dev,
157
struct device_attribute *attr,
158
const char *buf, size_t count)
159
{
160
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
161
struct fw_priv *fw_priv;
162
ssize_t written = count;
163
int loading;
164
165
if (kstrtoint(buf, 10, &loading))
166
return -EINVAL;
167
168
mutex_lock(&fw_lock);
169
fw_priv = fw_sysfs->fw_priv;
170
if (fw_state_is_aborted(fw_priv) || fw_state_is_done(fw_priv))
171
goto out;
172
173
switch (loading) {
174
case 1:
175
/* discarding any previous partial load */
176
fw_free_paged_buf(fw_priv);
177
fw_state_start(fw_priv);
178
break;
179
case 0:
180
if (fw_state_is_loading(fw_priv)) {
181
int rc;
182
183
/*
184
* Several loading requests may be pending on
185
* one same firmware buf, so let all requests
186
* see the mapped 'buf->data' once the loading
187
* is completed.
188
*/
189
rc = fw_map_paged_buf(fw_priv);
190
if (rc)
191
dev_err(dev, "%s: map pages failed\n",
192
__func__);
193
else
194
rc = security_kernel_post_load_data(fw_priv->data,
195
fw_priv->size,
196
LOADING_FIRMWARE,
197
"blob");
198
199
/*
200
* Same logic as fw_load_abort, only the DONE bit
201
* is ignored and we set ABORT only on failure.
202
*/
203
if (rc) {
204
fw_state_aborted(fw_priv);
205
written = rc;
206
} else {
207
fw_state_done(fw_priv);
208
209
/*
210
* If this is a user-initiated firmware upload
211
* then start the upload in a worker thread now.
212
*/
213
rc = fw_upload_start(fw_sysfs);
214
if (rc)
215
written = rc;
216
}
217
break;
218
}
219
fallthrough;
220
default:
221
dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
222
fallthrough;
223
case -1:
224
fw_load_abort(fw_sysfs);
225
if (fw_sysfs->fw_upload_priv)
226
fw_state_init(fw_sysfs->fw_priv);
227
228
break;
229
}
230
out:
231
mutex_unlock(&fw_lock);
232
return written;
233
}
234
235
DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
236
237
static void firmware_rw_data(struct fw_priv *fw_priv, char *buffer,
238
loff_t offset, size_t count, bool read)
239
{
240
if (read)
241
memcpy(buffer, fw_priv->data + offset, count);
242
else
243
memcpy(fw_priv->data + offset, buffer, count);
244
}
245
246
static void firmware_rw(struct fw_priv *fw_priv, char *buffer,
247
loff_t offset, size_t count, bool read)
248
{
249
while (count) {
250
int page_nr = offset >> PAGE_SHIFT;
251
int page_ofs = offset & (PAGE_SIZE - 1);
252
int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count);
253
254
if (read)
255
memcpy_from_page(buffer, fw_priv->pages[page_nr],
256
page_ofs, page_cnt);
257
else
258
memcpy_to_page(fw_priv->pages[page_nr], page_ofs,
259
buffer, page_cnt);
260
261
buffer += page_cnt;
262
offset += page_cnt;
263
count -= page_cnt;
264
}
265
}
266
267
static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
268
const struct bin_attribute *bin_attr,
269
char *buffer, loff_t offset, size_t count)
270
{
271
struct device *dev = kobj_to_dev(kobj);
272
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
273
struct fw_priv *fw_priv;
274
ssize_t ret_count;
275
276
mutex_lock(&fw_lock);
277
fw_priv = fw_sysfs->fw_priv;
278
if (!fw_priv || fw_state_is_done(fw_priv)) {
279
ret_count = -ENODEV;
280
goto out;
281
}
282
if (offset > fw_priv->size) {
283
ret_count = 0;
284
goto out;
285
}
286
if (count > fw_priv->size - offset)
287
count = fw_priv->size - offset;
288
289
ret_count = count;
290
291
if (fw_priv->data)
292
firmware_rw_data(fw_priv, buffer, offset, count, true);
293
else
294
firmware_rw(fw_priv, buffer, offset, count, true);
295
296
out:
297
mutex_unlock(&fw_lock);
298
return ret_count;
299
}
300
301
static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size)
302
{
303
int err;
304
305
err = fw_grow_paged_buf(fw_sysfs->fw_priv,
306
PAGE_ALIGN(min_size) >> PAGE_SHIFT);
307
if (err)
308
fw_load_abort(fw_sysfs);
309
return err;
310
}
311
312
/**
313
* firmware_data_write() - write method for firmware
314
* @filp: open sysfs file
315
* @kobj: kobject for the device
316
* @bin_attr: bin_attr structure
317
* @buffer: buffer being written
318
* @offset: buffer offset for write in total data store area
319
* @count: buffer size
320
*
321
* Data written to the 'data' attribute will be later handed to
322
* the driver as a firmware image.
323
**/
324
static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
325
const struct bin_attribute *bin_attr,
326
char *buffer, loff_t offset, size_t count)
327
{
328
struct device *dev = kobj_to_dev(kobj);
329
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
330
struct fw_priv *fw_priv;
331
ssize_t retval;
332
333
if (!capable(CAP_SYS_RAWIO))
334
return -EPERM;
335
336
mutex_lock(&fw_lock);
337
fw_priv = fw_sysfs->fw_priv;
338
if (!fw_priv || fw_state_is_done(fw_priv)) {
339
retval = -ENODEV;
340
goto out;
341
}
342
343
if (fw_priv->data) {
344
if (offset + count > fw_priv->allocated_size) {
345
retval = -ENOMEM;
346
goto out;
347
}
348
firmware_rw_data(fw_priv, buffer, offset, count, false);
349
retval = count;
350
} else {
351
retval = fw_realloc_pages(fw_sysfs, offset + count);
352
if (retval)
353
goto out;
354
355
retval = count;
356
firmware_rw(fw_priv, buffer, offset, count, false);
357
}
358
359
fw_priv->size = max_t(size_t, offset + count, fw_priv->size);
360
out:
361
mutex_unlock(&fw_lock);
362
return retval;
363
}
364
365
static const struct bin_attribute firmware_attr_data = {
366
.attr = { .name = "data", .mode = 0644 },
367
.size = 0,
368
.read = firmware_data_read,
369
.write = firmware_data_write,
370
};
371
372
static struct attribute *fw_dev_attrs[] = {
373
&dev_attr_loading.attr,
374
#ifdef CONFIG_FW_UPLOAD
375
&dev_attr_cancel.attr,
376
&dev_attr_status.attr,
377
&dev_attr_error.attr,
378
&dev_attr_remaining_size.attr,
379
#endif
380
NULL
381
};
382
383
static const struct bin_attribute *const fw_dev_bin_attrs[] = {
384
&firmware_attr_data,
385
NULL
386
};
387
388
static const struct attribute_group fw_dev_attr_group = {
389
.attrs = fw_dev_attrs,
390
.bin_attrs = fw_dev_bin_attrs,
391
#ifdef CONFIG_FW_UPLOAD
392
.is_visible = fw_upload_is_visible,
393
#endif
394
};
395
396
static const struct attribute_group *fw_dev_attr_groups[] = {
397
&fw_dev_attr_group,
398
NULL
399
};
400
401
struct fw_sysfs *
402
fw_create_instance(struct firmware *firmware, const char *fw_name,
403
struct device *device, u32 opt_flags)
404
{
405
struct fw_sysfs *fw_sysfs;
406
struct device *f_dev;
407
408
fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL);
409
if (!fw_sysfs) {
410
fw_sysfs = ERR_PTR(-ENOMEM);
411
goto exit;
412
}
413
414
fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT);
415
fw_sysfs->fw = firmware;
416
f_dev = &fw_sysfs->dev;
417
418
device_initialize(f_dev);
419
dev_set_name(f_dev, "%s", fw_name);
420
f_dev->parent = device;
421
f_dev->class = &firmware_class;
422
f_dev->groups = fw_dev_attr_groups;
423
exit:
424
return fw_sysfs;
425
}
426
427