cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sysfs.c (10039B)


      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
     15void __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
     28static 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 **/
     47static 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}
     59static CLASS_ATTR_RW(timeout);
     60
     61static struct attribute *firmware_class_attrs[] = {
     62	&class_attr_timeout.attr,
     63	NULL,
     64};
     65ATTRIBUTE_GROUPS(firmware_class);
     66
     67static 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
     79static 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
     92static 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
    103static 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
    112int 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
    121void unregister_sysfs_loader(void)
    122{
    123	unregister_firmware_config_sysctl();
    124	class_unregister(&firmware_class);
    125}
    126
    127static 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 **/
    154static 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	}
    225out:
    226	mutex_unlock(&fw_lock);
    227	return written;
    228}
    229
    230DEVICE_ATTR(loading, 0644, firmware_loading_show, firmware_loading_store);
    231
    232static 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
    241static void firmware_rw(struct fw_priv *fw_priv, char *buffer,
    242			loff_t offset, size_t count, bool read)
    243{
    244	while (count) {
    245		void *page_data;
    246		int page_nr = offset >> PAGE_SHIFT;
    247		int page_ofs = offset & (PAGE_SIZE - 1);
    248		int page_cnt = min_t(size_t, PAGE_SIZE - page_ofs, count);
    249
    250		page_data = kmap(fw_priv->pages[page_nr]);
    251
    252		if (read)
    253			memcpy(buffer, page_data + page_ofs, page_cnt);
    254		else
    255			memcpy(page_data + page_ofs, buffer, page_cnt);
    256
    257		kunmap(fw_priv->pages[page_nr]);
    258		buffer += page_cnt;
    259		offset += page_cnt;
    260		count -= page_cnt;
    261	}
    262}
    263
    264static ssize_t firmware_data_read(struct file *filp, struct kobject *kobj,
    265				  struct bin_attribute *bin_attr,
    266				  char *buffer, loff_t offset, size_t count)
    267{
    268	struct device *dev = kobj_to_dev(kobj);
    269	struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
    270	struct fw_priv *fw_priv;
    271	ssize_t ret_count;
    272
    273	mutex_lock(&fw_lock);
    274	fw_priv = fw_sysfs->fw_priv;
    275	if (!fw_priv || fw_state_is_done(fw_priv)) {
    276		ret_count = -ENODEV;
    277		goto out;
    278	}
    279	if (offset > fw_priv->size) {
    280		ret_count = 0;
    281		goto out;
    282	}
    283	if (count > fw_priv->size - offset)
    284		count = fw_priv->size - offset;
    285
    286	ret_count = count;
    287
    288	if (fw_priv->data)
    289		firmware_rw_data(fw_priv, buffer, offset, count, true);
    290	else
    291		firmware_rw(fw_priv, buffer, offset, count, true);
    292
    293out:
    294	mutex_unlock(&fw_lock);
    295	return ret_count;
    296}
    297
    298static int fw_realloc_pages(struct fw_sysfs *fw_sysfs, int min_size)
    299{
    300	int err;
    301
    302	err = fw_grow_paged_buf(fw_sysfs->fw_priv,
    303				PAGE_ALIGN(min_size) >> PAGE_SHIFT);
    304	if (err)
    305		fw_load_abort(fw_sysfs);
    306	return err;
    307}
    308
    309/**
    310 * firmware_data_write() - write method for firmware
    311 * @filp: open sysfs file
    312 * @kobj: kobject for the device
    313 * @bin_attr: bin_attr structure
    314 * @buffer: buffer being written
    315 * @offset: buffer offset for write in total data store area
    316 * @count: buffer size
    317 *
    318 *	Data written to the 'data' attribute will be later handed to
    319 *	the driver as a firmware image.
    320 **/
    321static ssize_t firmware_data_write(struct file *filp, struct kobject *kobj,
    322				   struct bin_attribute *bin_attr,
    323				   char *buffer, loff_t offset, size_t count)
    324{
    325	struct device *dev = kobj_to_dev(kobj);
    326	struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
    327	struct fw_priv *fw_priv;
    328	ssize_t retval;
    329
    330	if (!capable(CAP_SYS_RAWIO))
    331		return -EPERM;
    332
    333	mutex_lock(&fw_lock);
    334	fw_priv = fw_sysfs->fw_priv;
    335	if (!fw_priv || fw_state_is_done(fw_priv)) {
    336		retval = -ENODEV;
    337		goto out;
    338	}
    339
    340	if (fw_priv->data) {
    341		if (offset + count > fw_priv->allocated_size) {
    342			retval = -ENOMEM;
    343			goto out;
    344		}
    345		firmware_rw_data(fw_priv, buffer, offset, count, false);
    346		retval = count;
    347	} else {
    348		retval = fw_realloc_pages(fw_sysfs, offset + count);
    349		if (retval)
    350			goto out;
    351
    352		retval = count;
    353		firmware_rw(fw_priv, buffer, offset, count, false);
    354	}
    355
    356	fw_priv->size = max_t(size_t, offset + count, fw_priv->size);
    357out:
    358	mutex_unlock(&fw_lock);
    359	return retval;
    360}
    361
    362static struct bin_attribute firmware_attr_data = {
    363	.attr = { .name = "data", .mode = 0644 },
    364	.size = 0,
    365	.read = firmware_data_read,
    366	.write = firmware_data_write,
    367};
    368
    369static struct attribute *fw_dev_attrs[] = {
    370	&dev_attr_loading.attr,
    371#ifdef CONFIG_FW_UPLOAD
    372	&dev_attr_cancel.attr,
    373	&dev_attr_status.attr,
    374	&dev_attr_error.attr,
    375	&dev_attr_remaining_size.attr,
    376#endif
    377	NULL
    378};
    379
    380static struct bin_attribute *fw_dev_bin_attrs[] = {
    381	&firmware_attr_data,
    382	NULL
    383};
    384
    385static const struct attribute_group fw_dev_attr_group = {
    386	.attrs = fw_dev_attrs,
    387	.bin_attrs = fw_dev_bin_attrs,
    388#ifdef CONFIG_FW_UPLOAD
    389	.is_visible = fw_upload_is_visible,
    390#endif
    391};
    392
    393static const struct attribute_group *fw_dev_attr_groups[] = {
    394	&fw_dev_attr_group,
    395	NULL
    396};
    397
    398struct fw_sysfs *
    399fw_create_instance(struct firmware *firmware, const char *fw_name,
    400		   struct device *device, u32 opt_flags)
    401{
    402	struct fw_sysfs *fw_sysfs;
    403	struct device *f_dev;
    404
    405	fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL);
    406	if (!fw_sysfs) {
    407		fw_sysfs = ERR_PTR(-ENOMEM);
    408		goto exit;
    409	}
    410
    411	fw_sysfs->nowait = !!(opt_flags & FW_OPT_NOWAIT);
    412	fw_sysfs->fw = firmware;
    413	f_dev = &fw_sysfs->dev;
    414
    415	device_initialize(f_dev);
    416	dev_set_name(f_dev, "%s", fw_name);
    417	f_dev->parent = device;
    418	f_dev->class = &firmware_class;
    419	f_dev->groups = fw_dev_attr_groups;
    420exit:
    421	return fw_sysfs;
    422}