From 381bd3fa8306a56b4bb8703966e6372f1b83762e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Krzysztof=20Wilczy=C5=84ski?= Date: Thu, 3 Jun 2021 00:01:09 +0000 Subject: [PATCH] PCI/sysfs: Fix 'resource_alignment' newline issues MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Bjorn Helgaas Reviewed-by: Logan Gunthorpe --- drivers/pci/pci.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5ed316ea58315..68f57d86b2439 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; } -- 2.30.2