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