diff options
author | Tom Rini <trini@konsulko.com> | 2022-05-03 18:33:46 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-05-03 18:33:46 -0400 |
commit | 46eb29201c17e1273d1cabeafde378b0759c0d7d (patch) | |
tree | 8c0241b1adb7345fe8df34da06ff1dac83f74e4f /include | |
parent | f8e7670f8b2a5ba8f25682eee56039fa5f0a20ca (diff) | |
parent | 3b920186752518fe669cb337c433a69ee021bc30 (diff) |
Merge branch '2022-05-03-virtio-pci-add-and-fix-consistency-checks'
To quote the author:
The virtio PCI drivers forgo a number of consistency checks,
particularly around pointer validation and bounds checking. This series
focuses on the modern driver to add those checks.
The start of the series adds and fixes some basic bounds checks. Later
patches ensure PCI addresses fall within the expected regions rather
than any arbitrary address. This is acheived by introducing range
parameters to a few of the dm_pci_* functions that allow the ranges to
be checked.
The series also adds a few new configs to allow parts of virtio and PCI
to be disabled where the features may be unused and the current
implementations don't have the needed consistencty checks.
Diffstat (limited to 'include')
-rw-r--r-- | include/pci.h | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/include/pci.h b/include/pci.h index 5dbdcb0672a..d7ed35dd523 100644 --- a/include/pci.h +++ b/include/pci.h @@ -1313,26 +1313,30 @@ void dm_pci_write_bar32(struct udevice *dev, int barnum, u32 addr); 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 + * @mask: Mask to match flags for the region type * @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, - unsigned long flags); +phys_addr_t dm_pci_bus_to_phys(struct udevice *dev, pci_addr_t addr, size_t len, + unsigned long mask, unsigned long flags); /** * dm_pci_phys_to_bus() - convert a physical address to a PCI bus address * * @dev: Device containing the bus address * @addr: Physical address to convert + * @len: Length of the address range + * @mask: Mask to match flags for the region type * @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, - unsigned long flags); +pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, size_t len, + unsigned long mask, unsigned long flags); /** * dm_pci_map_bar() - get a virtual address associated with a BAR region @@ -1346,10 +1350,14 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, phys_addr_t addr, * * @dev: Device to check * @bar: Bar register offset (PCI_BASE_ADDRESS_...) + * @offset: Offset from the base to map + * @len: Length to map + * @mask: Mask to match flags for the region type * @flags: Flags for the region type (PCI_REGION_...) * @return: pointer to the virtual address to use or 0 on error */ -void *dm_pci_map_bar(struct udevice *dev, int bar, int flags); +void *dm_pci_map_bar(struct udevice *dev, int bar, size_t offset, size_t len, + unsigned long mask, unsigned long flags); /** * dm_pci_find_next_capability() - find a capability starting from an offset @@ -1453,28 +1461,34 @@ int dm_pci_find_ext_capability(struct udevice *dev, int cap); 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)) -#define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \ - map_physmem(dm_pci_bus_to_phys(dev, (addr), (flags)), \ - (len), (map_flags)) + dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), 0, PCI_REGION_TYPE, (flags)) +#define dm_pci_bus_to_virt(dev, addr, len, mask, flags, map_flags) \ +({ \ + size_t _len = (len); \ + phys_addr_t phys_addr = dm_pci_bus_to_phys((dev), (addr), _len, \ + (mask), (flags)); \ + map_physmem(phys_addr, _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_TYPE, 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_TYPE, 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_TYPE, 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_TYPE, PCI_REGION_IO) #define dm_pci_virt_to_mem(dev, addr) \ dm_pci_virt_to_bus((dev), (addr), PCI_REGION_MEM) #define dm_pci_mem_to_virt(dev, addr, len, map_flags) \ - dm_pci_bus_to_virt((dev), (addr), PCI_REGION_MEM, (len), (map_flags)) + dm_pci_bus_to_virt((dev), (addr), (len), PCI_REGION_TYPE, \ + PCI_REGION_MEM, (map_flags)) #define dm_pci_virt_to_io(dev, addr) \ dm_pci_virt_to_bus((dev), (addr), PCI_REGION_IO) #define dm_pci_io_to_virt(dev, addr, len, map_flags) \ - dm_pci_bus_to_virt((dev), (addr), PCI_REGION_IO, (len), (map_flags)) + dm_pci_bus_to_virt((dev), (addr), (len), PCI_REGION_TYPE, \ + PCI_REGION_IO, (map_flags)) /** * dm_pci_find_device() - find a device by vendor/device ID |