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