Message ID | 20241114110326.1891331-7-cassel@kernel.org (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Krzysztof WilczyĆski |
Headers | show |
Series | PCI endpoint additional pci_epc_set_bar() checks | expand |
On Thu, Nov 14, 2024 at 12:03:28PM +0100, Niklas Cassel wrote: > A BAR of type BAR_FIXED has a fixed BAR size (the size cannot be changed). > > When using pci_epf_alloc_space() to allocate backing memory for a BAR, > pci_epf_alloc_space() will always set the size to the fixed BAR size if > the BAR type is BAR_FIXED (and will give an error if you the requested size > is larger than the fixed BAR size). > > However, some drivers might not call pci_epf_alloc_space() before calling > pci_epc_set_bar(), so add a check in pci_epc_set_bar() to ensure that an > EPF driver cannot set a size different from the fixed BAR size, if the BAR > type is BAR_FIXED. > > The pci_epc_function_is_valid() check is removed because this check is now > done by pci_epc_get_features(). > > Signed-off-by: Niklas Cassel <cassel@kernel.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> > --- > drivers/pci/endpoint/pci-epc-core.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c > index bed7c7d1fe3c3..c69c133701c92 100644 > --- a/drivers/pci/endpoint/pci-epc-core.c > +++ b/drivers/pci/endpoint/pci-epc-core.c > @@ -609,10 +609,17 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar); > int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, > struct pci_epf_bar *epf_bar) > { > - int ret; > + const struct pci_epc_features *epc_features; > + enum pci_barno bar = epf_bar->barno; > int flags = epf_bar->flags; > + int ret; > > - if (!pci_epc_function_is_valid(epc, func_no, vfunc_no)) > + epc_features = pci_epc_get_features(epc, func_no, vfunc_no); > + if (!epc_features) > + return -EINVAL; > + > + if (epc_features->bar[bar].type == BAR_FIXED && > + (epc_features->bar[bar].fixed_size != epf_bar->size)) > return -EINVAL; > > if ((epf_bar->barno == BAR_5 && flags & PCI_BASE_ADDRESS_MEM_TYPE_64) || > -- > 2.47.0 >
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index bed7c7d1fe3c3..c69c133701c92 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -609,10 +609,17 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar); int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, struct pci_epf_bar *epf_bar) { - int ret; + const struct pci_epc_features *epc_features; + enum pci_barno bar = epf_bar->barno; int flags = epf_bar->flags; + int ret; - if (!pci_epc_function_is_valid(epc, func_no, vfunc_no)) + epc_features = pci_epc_get_features(epc, func_no, vfunc_no); + if (!epc_features) + return -EINVAL; + + if (epc_features->bar[bar].type == BAR_FIXED && + (epc_features->bar[bar].fixed_size != epf_bar->size)) return -EINVAL; if ((epf_bar->barno == BAR_5 && flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ||
A BAR of type BAR_FIXED has a fixed BAR size (the size cannot be changed). When using pci_epf_alloc_space() to allocate backing memory for a BAR, pci_epf_alloc_space() will always set the size to the fixed BAR size if the BAR type is BAR_FIXED (and will give an error if you the requested size is larger than the fixed BAR size). However, some drivers might not call pci_epf_alloc_space() before calling pci_epc_set_bar(), so add a check in pci_epc_set_bar() to ensure that an EPF driver cannot set a size different from the fixed BAR size, if the BAR type is BAR_FIXED. The pci_epc_function_is_valid() check is removed because this check is now done by pci_epc_get_features(). Signed-off-by: Niklas Cassel <cassel@kernel.org> --- drivers/pci/endpoint/pci-epc-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)