summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Gunthorpe <logang@deltatee.com>2019-04-10 15:05:31 -0600
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-25 18:22:26 +0200
commit48be4d7ced2cd62430c01c9bd62afa734540caeb (patch)
treef3503c3a0064b7b073495ba0d03a9db3e40b5d94
parentfa42fde1f8e6da596de8e0bb1e353bc8ce000bc2 (diff)
PCI: Fix issue with "pci=disable_acs_redir" parameter being ignored
[ Upstream commit d5bc73f34cc97c4b4b9202cc93182c2515076edf ] In most cases, kmalloc() will not be available early in boot when pci_setup() is called. Thus, the kstrdup() call that was added to fix the __initdata bug with the disable_acs_redir parameter usually returns NULL, so the parameter is discarded and has no effect. To fix this, store the string that's in initdata until an initcall function can allocate the memory appropriately. This way we don't need any additional static memory. Fixes: d2fd6e81912a ("PCI: Fix __initdata issue with "pci=disable_acs_redir" parameter") Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/pci/pci.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e91005d0f20c..3f77bab698ce 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -6266,8 +6266,7 @@ static int __init pci_setup(char *str)
} else if (!strncmp(str, "pcie_scan_all", 13)) {
pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
} else if (!strncmp(str, "disable_acs_redir=", 18)) {
- disable_acs_redir_param =
- kstrdup(str + 18, GFP_KERNEL);
+ disable_acs_redir_param = str + 18;
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
@@ -6278,3 +6277,19 @@ static int __init pci_setup(char *str)
return 0;
}
early_param("pci", pci_setup);
+
+/*
+ * 'disable_acs_redir_param' is initialized in pci_setup(), above, to point
+ * to data in the __initdata section which will be freed after the init
+ * sequence is complete. We can't allocate memory in pci_setup() because some
+ * architectures do not have any memory allocation service available during
+ * an early_param() call. So we allocate memory and copy the variable here
+ * before the init section is freed.
+ */
+static int __init pci_realloc_setup_params(void)
+{
+ disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL);
+
+ return 0;
+}
+pure_initcall(pci_realloc_setup_params);