| From ac8557695d5e266a42b9c6a8e8c90d3c913f9182 Mon Sep 17 00:00:00 2001 |
| From: Logan Gunthorpe <logang@deltatee.com> |
| Date: Wed, 10 Apr 2019 15:05:31 -0600 |
| Subject: 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> |
| --- |
| drivers/pci/pci.c | 19 +++++++++++++++++-- |
| 1 file changed, 17 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c |
| index 30649addc6252..61f2ef28ea1c7 100644 |
| --- a/drivers/pci/pci.c |
| +++ b/drivers/pci/pci.c |
| @@ -6135,8 +6135,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); |
| @@ -6147,3 +6146,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); |
| -- |
| 2.20.1 |
| |