* [PATCH v5 0/3] Fix find_first_zero_bit() usage
@ 2017-12-14 13:01 Niklas Cassel
2017-12-14 13:01 ` [PATCH v5 1/3] PCI: designware-ep: " Niklas Cassel
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Niklas Cassel @ 2017-12-14 13:01 UTC (permalink / raw)
To: linux-pci; +Cc: kishon, Niklas Cassel, linux-kernel
find_first_zero_bit()'s parameter 'size' is defined in bits,
not in bytes.
Calling find_first_zero_bit() with the wrong size unit
will lead to insidious bugs.
Fix all uses of find_first_zero_bit() called with
sizeof() as size argument in drivers/pci.
Niklas Cassel (3):
PCI: designware-ep: Fix find_first_zero_bit() usage
PCI: endpoint: Populate func_no before calling pci_epc_add_epf()
PCI: endpoint: Fix find_first_zero_bit() usage
drivers/pci/dwc/pcie-designware-ep.c | 34 ++++++++++++++++++++++++++--------
drivers/pci/dwc/pcie-designware.h | 8 ++++++--
drivers/pci/endpoint/pci-ep-cfs.c | 19 ++++++++++---------
3 files changed, 42 insertions(+), 19 deletions(-)
--
2.14.2
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH v5 1/3] PCI: designware-ep: Fix find_first_zero_bit() usage 2017-12-14 13:01 [PATCH v5 0/3] Fix find_first_zero_bit() usage Niklas Cassel @ 2017-12-14 13:01 ` Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() Niklas Cassel ` (2 subsequent siblings) 3 siblings, 0 replies; 7+ messages in thread From: Niklas Cassel @ 2017-12-14 13:01 UTC (permalink / raw) To: Jingoo Han, Joao Pinto, Lorenzo Pieralisi, Bjorn Helgaas Cc: kishon, Niklas Cassel, linux-pci, linux-kernel find_first_zero_bit()'s parameter 'size' is defined in bits, not in bytes. find_first_zero_bit() is called with size in bytes rather than bits, which thus defines a too low upper limit, causing dw_pcie_ep_inbound_atu() to assign iatu index #4 to both bar 4 and bar 5, which makes bar 5 overwrite the settings set by bar 4. Since the sizes of the bitmaps are known, dynamically allocate the bitmaps, and use the correct size when calling find_first_zero_bit(). Additionally, make sure that ep->num_ob_windows and ep->num_ib_windows, which are obtained from device tree, are smaller than the maximum number of iATUs (MAX_IATU_IN/MAX_IATU_OUT). Fixes: f8aed6ec624f ("PCI: dwc: designware: Add EP mode support") Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> --- drivers/pci/dwc/pcie-designware-ep.c | 34 ++++++++++++++++++++++++++-------- drivers/pci/dwc/pcie-designware.h | 8 ++++++-- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index d53d5f168363..d5eb143040e3 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -70,8 +70,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar, u32 free_win; struct dw_pcie *pci = to_dw_pcie_from_ep(ep); - free_win = find_first_zero_bit(&ep->ib_window_map, - sizeof(ep->ib_window_map)); + free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows); if (free_win >= ep->num_ib_windows) { dev_err(pci->dev, "no free inbound window\n"); return -EINVAL; @@ -85,7 +84,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar, } ep->bar_to_atu[bar] = free_win; - set_bit(free_win, &ep->ib_window_map); + set_bit(free_win, ep->ib_window_map); return 0; } @@ -96,8 +95,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, u32 free_win; struct dw_pcie *pci = to_dw_pcie_from_ep(ep); - free_win = find_first_zero_bit(&ep->ob_window_map, - sizeof(ep->ob_window_map)); + free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows); if (free_win >= ep->num_ob_windows) { dev_err(pci->dev, "no free outbound window\n"); return -EINVAL; @@ -106,7 +104,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM, phys_addr, pci_addr, size); - set_bit(free_win, &ep->ob_window_map); + set_bit(free_win, ep->ob_window_map); ep->outbound_addr[free_win] = phys_addr; return 0; @@ -121,7 +119,7 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) dw_pcie_ep_reset_bar(pci, bar); dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND); - clear_bit(atu_index, &ep->ib_window_map); + clear_bit(atu_index, ep->ib_window_map); } static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, @@ -175,7 +173,7 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) return; dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND); - clear_bit(atu_index, &ep->ob_window_map); + clear_bit(atu_index, ep->ob_window_map); } static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, @@ -298,12 +296,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep) dev_err(dev, "unable to read *num-ib-windows* property\n"); return ret; } + if (ep->num_ib_windows > MAX_IATU_IN) { + dev_err(dev, "invalid *num-ib-windows*\n"); + return -EINVAL; + } ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows); if (ret < 0) { dev_err(dev, "unable to read *num-ob-windows* property\n"); return ret; } + if (ep->num_ob_windows > MAX_IATU_OUT) { + dev_err(dev, "invalid *num-ob-windows*\n"); + return -EINVAL; + } + + ep->ib_window_map = devm_kzalloc(dev, sizeof(long) * + BITS_TO_LONGS(ep->num_ib_windows), + GFP_KERNEL); + if (!ep->ib_window_map) + return -ENOMEM; + + ep->ob_window_map = devm_kzalloc(dev, sizeof(long) * + BITS_TO_LONGS(ep->num_ob_windows), + GFP_KERNEL); + if (!ep->ob_window_map) + return -ENOMEM; addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows, GFP_KERNEL); diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h index e5d9d77b778e..e6fd0b024b21 100644 --- a/drivers/pci/dwc/pcie-designware.h +++ b/drivers/pci/dwc/pcie-designware.h @@ -113,6 +113,10 @@ #define MAX_MSI_IRQS 32 #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) +/* Maximum number of inbound/outbound iATUs */ +#define MAX_IATU_IN 256 +#define MAX_IATU_OUT 256 + struct pcie_port; struct dw_pcie; struct dw_pcie_ep; @@ -192,8 +196,8 @@ struct dw_pcie_ep { size_t page_size; u8 bar_to_atu[6]; phys_addr_t *outbound_addr; - unsigned long ib_window_map; - unsigned long ob_window_map; + unsigned long *ib_window_map; + unsigned long *ob_window_map; u32 num_ib_windows; u32 num_ob_windows; }; -- 2.14.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() 2017-12-14 13:01 [PATCH v5 0/3] Fix find_first_zero_bit() usage Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 1/3] PCI: designware-ep: " Niklas Cassel @ 2017-12-14 13:01 ` Niklas Cassel 2017-12-14 13:13 ` Kishon Vijay Abraham I 2017-12-14 13:01 ` [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage Niklas Cassel 2017-12-15 13:25 ` [PATCH v5 0/3] " Lorenzo Pieralisi 3 siblings, 1 reply; 7+ messages in thread From: Niklas Cassel @ 2017-12-14 13:01 UTC (permalink / raw) To: Kishon Vijay Abraham I, Lorenzo Pieralisi, Bjorn Helgaas Cc: Niklas Cassel, linux-pci, linux-kernel func_no is a member of struct pci_epf. struct pci_epf is used as an argument to pci_epc_add_epf(), therefore func_no should be populated before calling pci_epc_add_epf(). Fixes: d74679911610 ("PCI: endpoint: Introduce configfs entry for configuring EP functions") Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> Suggested-by: Kishon Vijay Abraham I <kishon@ti.com> --- drivers/pci/endpoint/pci-ep-cfs.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 4f74386c1ced..e8f65eb51c1a 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -97,22 +97,20 @@ static int pci_epc_epf_link(struct config_item *epc_item, { int ret; u32 func_no = 0; - struct pci_epc *epc; - struct pci_epf *epf; struct pci_epf_group *epf_group = to_pci_epf_group(epf_item); struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); - - epc = epc_group->epc; - epf = epf_group->epf; - ret = pci_epc_add_epf(epc, epf); - if (ret) - goto err_add_epf; + struct pci_epc *epc = epc_group->epc; + struct pci_epf *epf = epf_group->epf; func_no = find_first_zero_bit(&epc_group->function_num_map, sizeof(epc_group->function_num_map)); set_bit(func_no, &epc_group->function_num_map); epf->func_no = func_no; + ret = pci_epc_add_epf(epc, epf); + if (ret) + goto err_add_epf; + ret = pci_epf_bind(epf); if (ret) goto err_epf_bind; -- 2.14.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() 2017-12-14 13:01 ` [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() Niklas Cassel @ 2017-12-14 13:13 ` Kishon Vijay Abraham I 0 siblings, 0 replies; 7+ messages in thread From: Kishon Vijay Abraham I @ 2017-12-14 13:13 UTC (permalink / raw) To: Niklas Cassel, Lorenzo Pieralisi, Bjorn Helgaas Cc: Niklas Cassel, linux-pci, linux-kernel On Thursday 14 December 2017 06:31 PM, Niklas Cassel wrote: > func_no is a member of struct pci_epf. > struct pci_epf is used as an argument to pci_epc_add_epf(), > therefore func_no should be populated before calling pci_epc_add_epf(). > > Fixes: d74679911610 ("PCI: endpoint: Introduce configfs entry for configuring EP functions") > Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> > Suggested-by: Kishon Vijay Abraham I <kishon@ti.com> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> > --- > drivers/pci/endpoint/pci-ep-cfs.c | 14 ++++++-------- > 1 file changed, 6 insertions(+), 8 deletions(-) > > diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c > index 4f74386c1ced..e8f65eb51c1a 100644 > --- a/drivers/pci/endpoint/pci-ep-cfs.c > +++ b/drivers/pci/endpoint/pci-ep-cfs.c > @@ -97,22 +97,20 @@ static int pci_epc_epf_link(struct config_item *epc_item, > { > int ret; > u32 func_no = 0; > - struct pci_epc *epc; > - struct pci_epf *epf; > struct pci_epf_group *epf_group = to_pci_epf_group(epf_item); > struct pci_epc_group *epc_group = to_pci_epc_group(epc_item); > - > - epc = epc_group->epc; > - epf = epf_group->epf; > - ret = pci_epc_add_epf(epc, epf); > - if (ret) > - goto err_add_epf; > + struct pci_epc *epc = epc_group->epc; > + struct pci_epf *epf = epf_group->epf; > > func_no = find_first_zero_bit(&epc_group->function_num_map, > sizeof(epc_group->function_num_map)); > set_bit(func_no, &epc_group->function_num_map); > epf->func_no = func_no; > > + ret = pci_epc_add_epf(epc, epf); > + if (ret) > + goto err_add_epf; > + > ret = pci_epf_bind(epf); > if (ret) > goto err_epf_bind; > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage 2017-12-14 13:01 [PATCH v5 0/3] Fix find_first_zero_bit() usage Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 1/3] PCI: designware-ep: " Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() Niklas Cassel @ 2017-12-14 13:01 ` Niklas Cassel 2017-12-14 13:13 ` Kishon Vijay Abraham I 2017-12-15 13:25 ` [PATCH v5 0/3] " Lorenzo Pieralisi 3 siblings, 1 reply; 7+ messages in thread From: Niklas Cassel @ 2017-12-14 13:01 UTC (permalink / raw) To: Kishon Vijay Abraham I, Lorenzo Pieralisi, Bjorn Helgaas Cc: Niklas Cassel, linux-pci, linux-kernel find_first_zero_bit()'s parameter 'size' is defined in bits, not in bytes. Calling find_first_zero_bit() with the wrong size unit will lead to insidious bugs. Fix this by calling find_first_zero_bit() with size BITS_PER_LONG, rather than sizeof() and add missing find_first_zero_bit() return handling. Fixes: d74679911610 ("PCI: endpoint: Introduce configfs entry for configuring EP functions") Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> --- drivers/pci/endpoint/pci-ep-cfs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index e8f65eb51c1a..c9a2fb9dd49d 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -103,7 +103,10 @@ static int pci_epc_epf_link(struct config_item *epc_item, struct pci_epf *epf = epf_group->epf; func_no = find_first_zero_bit(&epc_group->function_num_map, - sizeof(epc_group->function_num_map)); + BITS_PER_LONG); + if (func_no >= BITS_PER_LONG) + return -EINVAL; + set_bit(func_no, &epc_group->function_num_map); epf->func_no = func_no; -- 2.14.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage 2017-12-14 13:01 ` [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage Niklas Cassel @ 2017-12-14 13:13 ` Kishon Vijay Abraham I 0 siblings, 0 replies; 7+ messages in thread From: Kishon Vijay Abraham I @ 2017-12-14 13:13 UTC (permalink / raw) To: Niklas Cassel, Lorenzo Pieralisi, Bjorn Helgaas Cc: Niklas Cassel, linux-pci, linux-kernel On Thursday 14 December 2017 06:31 PM, Niklas Cassel wrote: > find_first_zero_bit()'s parameter 'size' is defined in bits, > not in bytes. > > Calling find_first_zero_bit() with the wrong size unit > will lead to insidious bugs. > > Fix this by calling find_first_zero_bit() with size BITS_PER_LONG, > rather than sizeof() and add missing find_first_zero_bit() return > handling. > > Fixes: d74679911610 ("PCI: endpoint: Introduce configfs entry for configuring EP functions") > Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> > --- > drivers/pci/endpoint/pci-ep-cfs.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c > index e8f65eb51c1a..c9a2fb9dd49d 100644 > --- a/drivers/pci/endpoint/pci-ep-cfs.c > +++ b/drivers/pci/endpoint/pci-ep-cfs.c > @@ -103,7 +103,10 @@ static int pci_epc_epf_link(struct config_item *epc_item, > struct pci_epf *epf = epf_group->epf; > > func_no = find_first_zero_bit(&epc_group->function_num_map, > - sizeof(epc_group->function_num_map)); > + BITS_PER_LONG); > + if (func_no >= BITS_PER_LONG) > + return -EINVAL; > + > set_bit(func_no, &epc_group->function_num_map); > epf->func_no = func_no; > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 0/3] Fix find_first_zero_bit() usage 2017-12-14 13:01 [PATCH v5 0/3] Fix find_first_zero_bit() usage Niklas Cassel ` (2 preceding siblings ...) 2017-12-14 13:01 ` [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage Niklas Cassel @ 2017-12-15 13:25 ` Lorenzo Pieralisi 3 siblings, 0 replies; 7+ messages in thread From: Lorenzo Pieralisi @ 2017-12-15 13:25 UTC (permalink / raw) To: Niklas Cassel; +Cc: linux-pci, kishon, Niklas Cassel, linux-kernel On Thu, Dec 14, 2017 at 02:01:43PM +0100, Niklas Cassel wrote: > find_first_zero_bit()'s parameter 'size' is defined in bits, > not in bytes. > > Calling find_first_zero_bit() with the wrong size unit > will lead to insidious bugs. > > Fix all uses of find_first_zero_bit() called with > sizeof() as size argument in drivers/pci. > > Niklas Cassel (3): > PCI: designware-ep: Fix find_first_zero_bit() usage > PCI: endpoint: Populate func_no before calling pci_epc_add_epf() > PCI: endpoint: Fix find_first_zero_bit() usage > > drivers/pci/dwc/pcie-designware-ep.c | 34 ++++++++++++++++++++++++++-------- > drivers/pci/dwc/pcie-designware.h | 8 ++++++-- > drivers/pci/endpoint/pci-ep-cfs.c | 19 ++++++++++--------- > 3 files changed, 42 insertions(+), 19 deletions(-) Applied to pci/endpoint for v4.16 (updated some commit logs) with Kishon's ACKs. Thanks, Lorenzo ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-12-15 13:24 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-12-14 13:01 [PATCH v5 0/3] Fix find_first_zero_bit() usage Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 1/3] PCI: designware-ep: " Niklas Cassel 2017-12-14 13:01 ` [PATCH v5 2/3] PCI: endpoint: Populate func_no before calling pci_epc_add_epf() Niklas Cassel 2017-12-14 13:13 ` Kishon Vijay Abraham I 2017-12-14 13:01 ` [PATCH v5 3/3] PCI: endpoint: Fix find_first_zero_bit() usage Niklas Cassel 2017-12-14 13:13 ` Kishon Vijay Abraham I 2017-12-15 13:25 ` [PATCH v5 0/3] " Lorenzo Pieralisi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome