pci: Range check address conversions
When converting between PCI bus and physical addresses, include a length
parameter that can be used to check that the entire range fits within
one of the PCI regions. This prevents an address being returned that
might be only partially valid for the range it is going to be used for.
Where the range check is not wanted, passing a length of 0 will have the
same behaviour as before this change.
Signed-off-by: Andrew Scull <ascull@google.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/include/pci.h b/include/pci.h
index 3d0356b..966b84c 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -1313,14 +1313,15 @@
u32 dm_pci_read_bar32(const struct udevice *dev, int barnum);
/**
- * dm_pci_bus_to_phys() - convert a PCI bus address to a physical address
+ * dm_pci_bus_to_phys() - convert a PCI bus address range to a physical address
*
* @dev: Device containing the PCI address
* @addr: PCI address to convert
+ * @len: Length of the address range
* @flags: Flags for the region type (PCI_REGION_...)
* Return: physical address corresponding to that PCI bus address
*/
-phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr,
+phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, size_t len,
unsigned long flags);
/**
@@ -1328,10 +1329,11 @@
*
* @dev: Device containing the bus address
* @addr: Physical address to convert
+ * @len: Length of the address range
* @flags: Flags for the region type (PCI_REGION_...)
* Return: PCI bus address corresponding to that physical address
*/
-pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr,
+pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, size_t len,
unsigned long flags);
/**
@@ -1453,19 +1455,19 @@
int dm_pci_flr(struct udevice *dev);
#define dm_pci_virt_to_bus(dev, addr, flags) \
- dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
+ dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), 0, (flags))
#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
- map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \
+ map_physmem(dm_pci_bus_to_phys(dev, (addr), (len), (flags)), \
(len), (map_flags))
#define dm_pci_phys_to_mem(dev, addr) \
- dm_pci_phys_to_bus((dev), (addr), PCI_REGION_MEM)
+ dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_MEM)
#define dm_pci_mem_to_phys(dev, addr) \
- dm_pci_bus_to_phys((dev), (addr), PCI_REGION_MEM)
+ dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_MEM)
#define dm_pci_phys_to_io(dev, addr) \
- dm_pci_phys_to_bus((dev), (addr), PCI_REGION_IO)
+ dm_pci_phys_to_bus((dev), (addr), 0, PCI_REGION_IO)
#define dm_pci_io_to_phys(dev, addr) \
- dm_pci_bus_to_phys((dev), (addr), PCI_REGION_IO)
+ dm_pci_bus_to_phys((dev), (addr), 0, PCI_REGION_IO)
#define dm_pci_virt_to_mem(dev, addr) \
dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM)