diff --git a/drivers/devfreq/devfreq_spdm.h b/drivers/devfreq/devfreq_spdm.h index 4f7fd1cd8ef4..9db5c1187f3f 100644 --- a/drivers/devfreq/devfreq_spdm.h +++ b/drivers/devfreq/devfreq_spdm.h @@ -79,6 +79,8 @@ struct spdm_data { struct list_head list; struct dentry *debugfs_dir; + + bool enabled; }; extern void spdm_init_debugfs(struct device *dev); diff --git a/drivers/devfreq/devfreq_spdm_debugfs.c b/drivers/devfreq/devfreq_spdm_debugfs.c index f80c56d6766e..94e94f3bbc1c 100644 --- a/drivers/devfreq/devfreq_spdm_debugfs.c +++ b/drivers/devfreq/devfreq_spdm_debugfs.c @@ -13,9 +13,11 @@ #include #include #include +#include #include #include #include "devfreq_spdm.h" +#include "governor.h" static int spdm_open(struct inode *inode, struct file *file) { @@ -23,25 +25,99 @@ static int spdm_open(struct inode *inode, struct file *file) return 0; } -static ssize_t pl_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) +static char buf[PAGE_SIZE]; + +static ssize_t enable_write(struct file *file, const char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i; + int next_idx; + + if (size > sizeof(buf)) + return -EINVAL; + + if (copy_from_user(buf, data, size)) { + goto err; + size = -EINVAL; + } + + if (sscanf(buf, "%u\n", &i) != 1) { + size = -EINVAL; + goto err; + } + i = !!i; + + if (i == spdm_data->enabled) + goto out; + + spdm_data->devfreq->governor->event_handler(spdm_data->devfreq, + i ? DEVFREQ_GOV_START : + DEVFREQ_GOV_STOP, NULL); + + if (!i) { + next_idx = spdm_data->cur_idx + 1; + next_idx = next_idx % 2; + + for (i = 0; i < spdm_data->pdata->usecase[next_idx].num_paths; + i++) + spdm_data->pdata->usecase[next_idx].vectors[i].ab = 0; + + spdm_data->cur_idx = next_idx; + msm_bus_scale_client_update_request + (spdm_data->bus_scale_client_id, spdm_data->cur_idx); + } + +out: + *offset += size; +err: + memset(buf, 0, sizeof(buf)); + return size; +} + +static ssize_t enable_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int len = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + len = scnprintf(buf, size, "%u\n", spdm_data->enabled); + len = simple_read_from_buffer(data, size, offset, buf, len); + + memset(buf, 0, sizeof(buf)); + return len; +} + +static const struct file_operations enable_fops = { + .open = spdm_open, + .write = enable_write, + .read = enable_read, +}; + +static ssize_t pl_write(struct file *file, const char __user *data, + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; int i; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.pl_freqs[0], - &spdm_data->config_data.pl_freqs[1]); + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.pl_freqs[0], + &spdm_data->config_data.pl_freqs[1]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_PL; desc.arg[1] = spdm_data->spdm_client; @@ -52,32 +128,55 @@ static ssize_t pl_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; + +} + +static ssize_t pl_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", spdm_data->config_data.pl_freqs[0], + spdm_data->config_data.pl_freqs[1]); + i = simple_read_from_buffer(data, size, offset, buf, i); + + memset(buf, 0, sizeof(buf)); + return i; } static const struct file_operations pl_fops = { .open = spdm_open, .write = pl_write, + .read = pl_read, }; static ssize_t rejrate_low_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[0], - &spdm_data->config_data.reject_rate[1]); + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[0], + &spdm_data->config_data.reject_rate[1]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_REJRATE_LOW; desc.arg[1] = spdm_data->spdm_client; @@ -88,31 +187,55 @@ static ssize_t rejrate_low_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t rejrate_low_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.reject_rate[0], + spdm_data->config_data.reject_rate[1]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rrl_fops = { .open = spdm_open, .write = rejrate_low_write, + .read = rejrate_low_read, }; static ssize_t rejrate_med_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[2], - &spdm_data->config_data.reject_rate[3]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[2], + &spdm_data->config_data.reject_rate[3]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_REJRATE_MED; desc.arg[1] = spdm_data->spdm_client; @@ -123,31 +246,54 @@ static ssize_t rejrate_med_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t rejrate_med_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.reject_rate[2], + spdm_data->config_data.reject_rate[3]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rrm_fops = { .open = spdm_open, .write = rejrate_med_write, + .read = rejrate_med_read, }; static ssize_t rejrate_high_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[4], - &spdm_data->config_data.reject_rate[5]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.reject_rate[4], + &spdm_data->config_data.reject_rate[5]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_REJRATE_HIGH; desc.arg[1] = spdm_data->spdm_client; @@ -158,31 +304,54 @@ static ssize_t rejrate_high_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t rejrate_high_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.reject_rate[4], + spdm_data->config_data.reject_rate[5]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rrh_fops = { .open = spdm_open, .write = rejrate_high_write, + .read = rejrate_high_read, }; static ssize_t resptime_low_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[0], - &spdm_data->config_data.response_time_us[1]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[0], + &spdm_data->config_data.response_time_us[1]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_RESPTIME_LOW; desc.arg[1] = spdm_data->spdm_client; @@ -193,31 +362,54 @@ static ssize_t resptime_low_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t resptime_low_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.response_time_us[0], + spdm_data->config_data.response_time_us[1]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rtl_fops = { .open = spdm_open, .write = resptime_low_write, + .read = resptime_low_read, }; static ssize_t resptime_med_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[2], - &spdm_data->config_data.response_time_us[3]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[2], + &spdm_data->config_data.response_time_us[3]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_RESPTIME_MED; desc.arg[1] = spdm_data->spdm_client; @@ -228,31 +420,54 @@ static ssize_t resptime_med_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t resptime_med_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.response_time_us[2], + spdm_data->config_data.response_time_us[3]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rtm_fops = { .open = spdm_open, .write = resptime_med_write, + .read = resptime_med_read, }; static ssize_t resptime_high_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[4], - &spdm_data->config_data.response_time_us[5]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", &spdm_data->config_data.response_time_us[4], + &spdm_data->config_data.response_time_us[5]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_RESPTIME_HIGH; desc.arg[1] = spdm_data->spdm_client; @@ -263,31 +478,56 @@ static ssize_t resptime_high_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t resptime_high_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.response_time_us[4], + spdm_data->config_data.response_time_us[5]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations rth_fops = { .open = spdm_open, .write = resptime_high_write, + .read = resptime_high_read, }; -static ssize_t cciresptime_low_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) +static ssize_t cciresptime_low_write(struct file *file, + const char __user *data, size_t size, + loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[0], - &spdm_data->config_data.cci_response_time_us[1]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", + &spdm_data->config_data.cci_response_time_us[0], + &spdm_data->config_data.cci_response_time_us[1]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_LOW; desc.arg[1] = spdm_data->spdm_client; @@ -298,31 +538,56 @@ static ssize_t cciresptime_low_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t cciresptime_low_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.cci_response_time_us[0], + spdm_data->config_data.cci_response_time_us[1]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations ccil_fops = { .open = spdm_open, .write = cciresptime_low_write, + .read = cciresptime_low_read, }; -static ssize_t cciresptime_med_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) +static ssize_t cciresptime_med_write(struct file *file, + const char __user *data, size_t size, + loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[2], - &spdm_data->config_data.cci_response_time_us[3]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", + &spdm_data->config_data.cci_response_time_us[2], + &spdm_data->config_data.cci_response_time_us[3]) != 2) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_MED; desc.arg[1] = spdm_data->spdm_client; @@ -333,13 +598,33 @@ static ssize_t cciresptime_med_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t cciresptime_med_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.cci_response_time_us[2], + spdm_data->config_data.cci_response_time_us[3]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations ccim_fops = { .open = spdm_open, .write = cciresptime_med_write, + .read = cciresptime_med_read, }; static ssize_t cciresptime_high_write(struct file *file, @@ -347,18 +632,22 @@ static ssize_t cciresptime_high_write(struct file *file, size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u\n", &spdm_data->config_data.cci_response_time_us[4], - &spdm_data->config_data.cci_response_time_us[5]); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u\n", + &spdm_data->config_data.cci_response_time_us[4], + &spdm_data->config_data.cci_response_time_us[5]) != 2){ + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_CCIRESPTIME_HIGH; desc.arg[1] = spdm_data->spdm_client; @@ -369,30 +658,53 @@ static ssize_t cciresptime_high_write(struct file *file, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t cciresptime_high_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u\n", + spdm_data->config_data.cci_response_time_us[4], + spdm_data->config_data.cci_response_time_us[5]); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations ccih_fops = { .open = spdm_open, .write = cciresptime_high_write, + .read = cciresptime_high_read, }; static ssize_t cci_max_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u\n", &spdm_data->config_data.max_cci_freq); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u\n", &spdm_data->config_data.max_cci_freq) != 1) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_MAXCCI; desc.arg[1] = spdm_data->spdm_client; @@ -402,33 +714,54 @@ static ssize_t cci_max_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t cci_max_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u\n", spdm_data->config_data.max_cci_freq); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations ccimax_fops = { .open = spdm_open, .write = cci_max_write, + .read = cci_max_read, }; static ssize_t vote_cfg_write(struct file *file, const char __user *data, - size_t size, loff_t *offset) + size_t size, loff_t *offset) { struct spdm_data *spdm_data = file->private_data; - char *buf; struct spdm_args desc = { { 0 } }; int ext_status = 0; - buf = kzalloc(size, GFP_KERNEL); - - if (!buf) - return -ENOMEM; - if (copy_from_user(buf, data, size)) + if (size > sizeof(buf)) return -EINVAL; - sscanf(buf, "%u %u %u %u\n", &spdm_data->config_data.upstep, - &spdm_data->config_data.downstep, - &spdm_data->config_data.max_vote, - &spdm_data->config_data.up_step_multp); + + if (copy_from_user(buf, data, size)) { + size = -EINVAL; + goto out; + } + if (sscanf(buf, "%u %u %u %u\n", &spdm_data->config_data.upstep, + &spdm_data->config_data.downstep, + &spdm_data->config_data.max_vote, + &spdm_data->config_data.up_step_multp) != 4) { + size = -EINVAL; + goto out; + } desc.arg[0] = SPDM_CMD_CFG_VOTES; desc.arg[1] = spdm_data->spdm_client; @@ -441,13 +774,35 @@ static ssize_t vote_cfg_write(struct file *file, const char __user *data, pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); *offset += size; - kfree(buf); +out: + memset(buf, 0, sizeof(buf)); return size; } +static ssize_t vote_cfg_read(struct file *file, char __user *data, + size_t size, loff_t *offset) +{ + struct spdm_data *spdm_data = file->private_data; + int i = 32; + + if (size > sizeof(buf)) + return -EINVAL; + + i = scnprintf(buf, size, "%u %u %u %u\n", + spdm_data->config_data.upstep, + spdm_data->config_data.downstep, + spdm_data->config_data.max_vote, + spdm_data->config_data.up_step_multp); + + i = simple_read_from_buffer(data, size, offset, buf, i); + memset(buf, 0, sizeof(buf)); + return i; +} + static const struct file_operations vote_fops = { .open = spdm_open, .write = vote_cfg_write, + .read = vote_cfg_read, }; void spdm_init_debugfs(struct device *dev) @@ -457,6 +812,8 @@ void spdm_init_debugfs(struct device *dev) data = dev_get_drvdata(dev); data->debugfs_dir = debugfs_create_dir(dev_name(dev), NULL); + debugfs_create_file("enable", 0600, data->debugfs_dir, data, + &enable_fops); debugfs_create_file("pl_freqs", 0600, data->debugfs_dir, data, &pl_fops); debugfs_create_file("rej_rate_low", 0600, data->debugfs_dir, data, @@ -476,11 +833,11 @@ void spdm_init_debugfs(struct device *dev) debugfs_create_file("cci_resp_time_med", 0600, data->debugfs_dir, data, &ccim_fops); debugfs_create_file("cci_resp_time_high", 0600, data->debugfs_dir, - data, &ccih_fops); + data, &ccih_fops); debugfs_create_file("cci_max", 0600, data->debugfs_dir, data, - &ccimax_fops); + &ccimax_fops); debugfs_create_file("vote_cfg", 0600, data->debugfs_dir, data, - &vote_fops); + &vote_fops); } void spdm_remove_debugfs(struct spdm_data *data) diff --git a/drivers/devfreq/governor_spdm_bw_hyp.c b/drivers/devfreq/governor_spdm_bw_hyp.c index a97d0425926f..575621606100 100644 --- a/drivers/devfreq/governor_spdm_bw_hyp.c +++ b/drivers/devfreq/governor_spdm_bw_hyp.c @@ -296,6 +296,7 @@ static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event, mutex_unlock(&devfreqs_lock); return -EINVAL; } + spdm_data->enabled = true; devfreq_monitor_start(devfreq); break; @@ -313,6 +314,7 @@ static int gov_spdm_hyp_eh(struct devfreq *devfreq, unsigned int event, if (ext_status) pr_err("External command %u failed with error %u", (int)desc.arg[0], ext_status); + spdm_data->enabled = false; break; case DEVFREQ_GOV_INTERVAL: