Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI/P2PDMA: Provide an access to pci_p2pdma_map_type() function

Provide an access to pci_p2pdma_map_type() function to allow subsystems
to determine the appropriate mapping type for P2PDMA transfers between
a provider and target device.

The pci_p2pdma_map_type() function is the core P2P layer version of
the existing public, but struct page focused, pci_p2pdma_state()
function. It returns the same result. It is required to use the p2p
subsystem from drivers that don't use the struct page layer.

Like __pci_p2pdma_update_state() it is not an exported function. The
idea is that only subsystem code will implement mapping helpers for
taking in phys_addr_t lists, this is deliberately not made accessible
to every driver to prevent abuse.

Following patches will use this function to implement a shared DMA
mapping helper for DMABUF.

Tested-by: Alex Mastro <amastro@fb.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Acked-by: Ankit Agrawal <ankita@nvidia.com>
Link: https://lore.kernel.org/r/20251120-dmabuf-vfio-v9-4-d7f71607f371@nvidia.com
Signed-off-by: Alex Williamson <alex@shazbot.org>

authored by

Leon Romanovsky and committed by
Alex Williamson
395698bd 372d6d1b

+58 -41
+12 -2
drivers/pci/p2pdma.c
··· 1060 1060 } 1061 1061 EXPORT_SYMBOL_GPL(pci_p2pmem_publish); 1062 1062 1063 - static enum pci_p2pdma_map_type 1064 - pci_p2pdma_map_type(struct p2pdma_provider *provider, struct device *dev) 1063 + /** 1064 + * pci_p2pdma_map_type - Determine the mapping type for P2PDMA transfers 1065 + * @provider: P2PDMA provider structure 1066 + * @dev: Target device for the transfer 1067 + * 1068 + * Determines how peer-to-peer DMA transfers should be mapped between 1069 + * the provider and the target device. The mapping type indicates whether 1070 + * the transfer can be done directly through PCI switches or must go 1071 + * through the host bridge. 1072 + */ 1073 + enum pci_p2pdma_map_type pci_p2pdma_map_type(struct p2pdma_provider *provider, 1074 + struct device *dev) 1065 1075 { 1066 1076 enum pci_p2pdma_map_type type = PCI_P2PDMA_MAP_NOT_SUPPORTED; 1067 1077 struct pci_dev *pdev = to_pci_dev(provider->owner);
+46 -39
include/linux/pci-p2pdma.h
··· 26 26 u64 bus_offset; 27 27 }; 28 28 29 + enum pci_p2pdma_map_type { 30 + /* 31 + * PCI_P2PDMA_MAP_UNKNOWN: Used internally as an initial state before 32 + * the mapping type has been calculated. Exported routines for the API 33 + * will never return this value. 34 + */ 35 + PCI_P2PDMA_MAP_UNKNOWN = 0, 36 + 37 + /* 38 + * Not a PCI P2PDMA transfer. 39 + */ 40 + PCI_P2PDMA_MAP_NONE, 41 + 42 + /* 43 + * PCI_P2PDMA_MAP_NOT_SUPPORTED: Indicates the transaction will 44 + * traverse the host bridge and the host bridge is not in the 45 + * allowlist. DMA Mapping routines should return an error when 46 + * this is returned. 47 + */ 48 + PCI_P2PDMA_MAP_NOT_SUPPORTED, 49 + 50 + /* 51 + * PCI_P2PDMA_MAP_BUS_ADDR: Indicates that two devices can talk to 52 + * each other directly through a PCI switch and the transaction will 53 + * not traverse the host bridge. Such a mapping should program 54 + * the DMA engine with PCI bus addresses. 55 + */ 56 + PCI_P2PDMA_MAP_BUS_ADDR, 57 + 58 + /* 59 + * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE: Indicates two devices can talk 60 + * to each other, but the transaction traverses a host bridge on the 61 + * allowlist. In this case, a normal mapping either with CPU physical 62 + * addresses (in the case of dma-direct) or IOVA addresses (in the 63 + * case of IOMMUs) should be used to program the DMA engine. 64 + */ 65 + PCI_P2PDMA_MAP_THRU_HOST_BRIDGE, 66 + }; 67 + 29 68 #ifdef CONFIG_PCI_P2PDMA 30 69 int pcim_p2pdma_init(struct pci_dev *pdev); 31 70 struct p2pdma_provider *pcim_p2pdma_provider(struct pci_dev *pdev, int bar); ··· 84 45 bool *use_p2pdma); 85 46 ssize_t pci_p2pdma_enable_show(char *page, struct pci_dev *p2p_dev, 86 47 bool use_p2pdma); 48 + enum pci_p2pdma_map_type pci_p2pdma_map_type(struct p2pdma_provider *provider, 49 + struct device *dev); 87 50 #else /* CONFIG_PCI_P2PDMA */ 88 51 static inline int pcim_p2pdma_init(struct pci_dev *pdev) 89 52 { ··· 147 106 { 148 107 return sprintf(page, "none\n"); 149 108 } 109 + static inline enum pci_p2pdma_map_type 110 + pci_p2pdma_map_type(struct p2pdma_provider *provider, struct device *dev) 111 + { 112 + return PCI_P2PDMA_MAP_NOT_SUPPORTED; 113 + } 150 114 #endif /* CONFIG_PCI_P2PDMA */ 151 115 152 116 ··· 165 119 { 166 120 return pci_p2pmem_find_many(&client, 1); 167 121 } 168 - 169 - enum pci_p2pdma_map_type { 170 - /* 171 - * PCI_P2PDMA_MAP_UNKNOWN: Used internally as an initial state before 172 - * the mapping type has been calculated. Exported routines for the API 173 - * will never return this value. 174 - */ 175 - PCI_P2PDMA_MAP_UNKNOWN = 0, 176 - 177 - /* 178 - * Not a PCI P2PDMA transfer. 179 - */ 180 - PCI_P2PDMA_MAP_NONE, 181 - 182 - /* 183 - * PCI_P2PDMA_MAP_NOT_SUPPORTED: Indicates the transaction will 184 - * traverse the host bridge and the host bridge is not in the 185 - * allowlist. DMA Mapping routines should return an error when 186 - * this is returned. 187 - */ 188 - PCI_P2PDMA_MAP_NOT_SUPPORTED, 189 - 190 - /* 191 - * PCI_P2PDMA_MAP_BUS_ADDR: Indicates that two devices can talk to 192 - * each other directly through a PCI switch and the transaction will 193 - * not traverse the host bridge. Such a mapping should program 194 - * the DMA engine with PCI bus addresses. 195 - */ 196 - PCI_P2PDMA_MAP_BUS_ADDR, 197 - 198 - /* 199 - * PCI_P2PDMA_MAP_THRU_HOST_BRIDGE: Indicates two devices can talk 200 - * to each other, but the transaction traverses a host bridge on the 201 - * allowlist. In this case, a normal mapping either with CPU physical 202 - * addresses (in the case of dma-direct) or IOVA addresses (in the 203 - * case of IOMMUs) should be used to program the DMA engine. 204 - */ 205 - PCI_P2PDMA_MAP_THRU_HOST_BRIDGE, 206 - }; 207 122 208 123 struct pci_p2pdma_map_state { 209 124 struct p2pdma_provider *mem;