summaryrefslogtreecommitdiff
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorKrzysztof Wilczyński <kw@linux.com>2021-06-03 03:01:09 +0300
committerBjorn Helgaas <bhelgaas@google.com>2021-06-04 17:19:22 +0300
commit381bd3fa8306a56b4bb8703966e6372f1b83762e (patch)
tree2ecbd47face9ca318ede7adfb00ba2d864e22910 /drivers/pci/pci.c
parentf8cf6e513ec4f0e207f56c27d5030da429ac2cae (diff)
downloadlinux-381bd3fa8306a56b4bb8703966e6372f1b83762e.tar.xz
PCI/sysfs: Fix 'resource_alignment' newline issues
The value of the "resource_alignment" can be specified using a kernel command-line argument ("pci=resource_alignment=") or through the corresponding sysfs attribute under the /sys/bus/pci path. Previously, when the value was set via the kernel command-line argument, and then subsequently accessed through sysfs attribute, the value read back was not correct: # grep -oE 'pci=resource_alignment.+' /proc/cmdline pci=resource_alignment=20@00:1f.2 # cat /sys/bus/pci/resource_alignment 20@00:1f. This was also true when the value was set through the sysfs attribute without including a trailing newline: # echo -n 20@00:1f.2 > /sys/bus/pci/resource_alignment # cat /sys/bus/pci/resource_alignment 20@00:1f. When it was set through the sysfs attribute *including* a newline, reading it back worked as intended: # echo 20@00:1f.2 > /sys/bus/pci/resource_alignment # cat /sys/bus/pci/resource_alignment 20@00:1f.2 To fix this inconsistency, append a trailing newline in the show() function and strip the trailing line in the store() function if one is present. Also, allow for the value previously set using either a command-line argument or through the sysfs object to be cleared at run-time. [bhelgaas: fold in kfree fix from https://lore.kernel.org/linux-pci/20210604133230.983956-4-kw@linux.com] Fixes: e499081da1a2 ("PCI: Force trailing new line to resource_alignment_param in sysfs") Link: https://lore.kernel.org/r/20210603000112.703037-4-kw@linux.com Signed-off-by: Krzysztof Wilczyński <kw@linux.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 5ed316ea5831..68f57d86b243 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6439,34 +6439,40 @@ static ssize_t resource_alignment_show(struct bus_type *bus, char *buf)
spin_lock(&resource_alignment_lock);
if (resource_alignment_param)
- count = sysfs_emit(buf, "%s", resource_alignment_param);
+ count = sysfs_emit(buf, "%s\n", resource_alignment_param);
spin_unlock(&resource_alignment_lock);
- /*
- * When set by the command line, resource_alignment_param will not
- * have a trailing line feed, which is ugly. So conditionally add
- * it here.
- */
- if (count >= 2 && buf[count - 2] != '\n' && count < PAGE_SIZE - 1) {
- buf[count - 1] = '\n';
- buf[count++] = 0;
- }
-
return count;
}
static ssize_t resource_alignment_store(struct bus_type *bus,
const char *buf, size_t count)
{
- char *param = kstrndup(buf, count, GFP_KERNEL);
+ char *param, *old, *end;
+
+ if (count >= (PAGE_SIZE - 1))
+ return -EINVAL;
+ param = kstrndup(buf, count, GFP_KERNEL);
if (!param)
return -ENOMEM;
+ end = strchr(param, '\n');
+ if (end)
+ *end = '\0';
+
spin_lock(&resource_alignment_lock);
- kfree(resource_alignment_param);
- resource_alignment_param = param;
+ old = resource_alignment_param;
+ if (strlen(param)) {
+ resource_alignment_param = param;
+ } else {
+ kfree(param);
+ resource_alignment_param = NULL;
+ }
spin_unlock(&resource_alignment_lock);
+
+ kfree(old);
+
return count;
}