]>
Commit | Line | Data |
---|---|---|
e6832405 SL |
1 | From 61b682be17b429c09e24c50bcf4429bd352275d8 Mon Sep 17 00:00:00 2001 |
2 | From: Logan Gunthorpe <logang@deltatee.com> | |
3 | Date: Wed, 10 Apr 2019 15:05:31 -0600 | |
4 | Subject: PCI: Fix issue with "pci=disable_acs_redir" parameter being ignored | |
5 | ||
6 | [ Upstream commit d5bc73f34cc97c4b4b9202cc93182c2515076edf ] | |
7 | ||
8 | In most cases, kmalloc() will not be available early in boot when | |
9 | pci_setup() is called. Thus, the kstrdup() call that was added to fix the | |
10 | __initdata bug with the disable_acs_redir parameter usually returns NULL, | |
11 | so the parameter is discarded and has no effect. | |
12 | ||
13 | To fix this, store the string that's in initdata until an initcall function | |
14 | can allocate the memory appropriately. This way we don't need any | |
15 | additional static memory. | |
16 | ||
17 | Fixes: d2fd6e81912a ("PCI: Fix __initdata issue with "pci=disable_acs_redir" parameter") | |
18 | Signed-off-by: Logan Gunthorpe <logang@deltatee.com> | |
19 | Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> | |
20 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
21 | --- | |
22 | drivers/pci/pci.c | 19 +++++++++++++++++-- | |
23 | 1 file changed, 17 insertions(+), 2 deletions(-) | |
24 | ||
25 | diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c | |
26 | index e91005d0f20c7..3f77bab698ced 100644 | |
27 | --- a/drivers/pci/pci.c | |
28 | +++ b/drivers/pci/pci.c | |
29 | @@ -6266,8 +6266,7 @@ static int __init pci_setup(char *str) | |
30 | } else if (!strncmp(str, "pcie_scan_all", 13)) { | |
31 | pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS); | |
32 | } else if (!strncmp(str, "disable_acs_redir=", 18)) { | |
33 | - disable_acs_redir_param = | |
34 | - kstrdup(str + 18, GFP_KERNEL); | |
35 | + disable_acs_redir_param = str + 18; | |
36 | } else { | |
37 | printk(KERN_ERR "PCI: Unknown option `%s'\n", | |
38 | str); | |
39 | @@ -6278,3 +6277,19 @@ static int __init pci_setup(char *str) | |
40 | return 0; | |
41 | } | |
42 | early_param("pci", pci_setup); | |
43 | + | |
44 | +/* | |
45 | + * 'disable_acs_redir_param' is initialized in pci_setup(), above, to point | |
46 | + * to data in the __initdata section which will be freed after the init | |
47 | + * sequence is complete. We can't allocate memory in pci_setup() because some | |
48 | + * architectures do not have any memory allocation service available during | |
49 | + * an early_param() call. So we allocate memory and copy the variable here | |
50 | + * before the init section is freed. | |
51 | + */ | |
52 | +static int __init pci_realloc_setup_params(void) | |
53 | +{ | |
54 | + disable_acs_redir_param = kstrdup(disable_acs_redir_param, GFP_KERNEL); | |
55 | + | |
56 | + return 0; | |
57 | +} | |
58 | +pure_initcall(pci_realloc_setup_params); | |
59 | -- | |
60 | 2.20.1 | |
61 |