1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCI Resizable BAR Extended Capability handling. 4 */ 5 6 #include <linux/bits.h> 7 #include <linux/bitfield.h> 8 #include <linux/bitops.h> 9 #include <linux/errno.h> 10 #include <linux/export.h> 11 #include <linux/ioport.h> 12 #include <linux/log2.h> 13 #include <linux/pci.h> 14 #include <linux/sizes.h> 15 #include <linux/types.h> 16 17 #include "pci.h" 18 19 #define PCI_REBAR_MIN_SIZE ((resource_size_t)SZ_1M) 20 21 /** 22 * pci_rebar_bytes_to_size - Convert size in bytes to PCI BAR Size 23 * @bytes: size in bytes 24 * 25 * Convert size in bytes to encoded BAR Size in Resizable BAR Capability 26 * (PCIe r6.2, sec. 7.8.6.3). 27 * 28 * Return: encoded BAR Size as defined in the PCIe spec (0=1MB, 31=128TB) 29 */ 30 int pci_rebar_bytes_to_size(u64 bytes) 31 { 32 int rebar_minsize = ilog2(PCI_REBAR_MIN_SIZE); 33 34 bytes = roundup_pow_of_two(bytes); 35 36 return max(ilog2(bytes), rebar_minsize) - rebar_minsize; 37 } 38 EXPORT_SYMBOL_GPL(pci_rebar_bytes_to_size); 39 40 /** 41 * pci_rebar_size_to_bytes - Convert encoded BAR Size to size in bytes 42 * @size: encoded BAR Size as defined in the PCIe spec (0=1MB, 31=128TB) 43 * 44 * Return: BAR size in bytes 45 */ 46 resource_size_t pci_rebar_size_to_bytes(int size) 47 { 48 return 1ULL << (size + ilog2(PCI_REBAR_MIN_SIZE)); 49 } 50 EXPORT_SYMBOL_GPL(pci_rebar_size_to_bytes); 51 52 void pci_rebar_init(struct pci_dev *pdev) 53 { 54 pdev->rebar_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR); 55 } 56 57 /** 58 * pci_rebar_find_pos - find position of resize control reg for BAR 59 * @pdev: PCI device 60 * @bar: BAR to find 61 * 62 * Helper to find the position of the control register for a BAR. 63 * 64 * Return: 65 * * %-ENOTSUPP if resizable BARs are not supported at all, 66 * * %-ENOENT if no control register for the BAR could be found. 67 */ 68 static int pci_rebar_find_pos(struct pci_dev *pdev, int bar) 69 { 70 unsigned int pos, nbars, i; 71 u32 ctrl; 72 73 if (pci_resource_is_iov(bar)) { 74 pos = pci_iov_vf_rebar_cap(pdev); 75 bar = pci_resource_num_to_vf_bar(bar); 76 } else { 77 pos = pdev->rebar_cap; 78 } 79 80 if (!pos) 81 return -ENOTSUPP; 82 83 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 84 nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl); 85 86 for (i = 0; i < nbars; i++, pos += 8) { 87 int bar_idx; 88 89 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 90 bar_idx = FIELD_GET(PCI_REBAR_CTRL_BAR_IDX, ctrl); 91 if (bar_idx == bar) 92 return pos; 93 } 94 95 return -ENOENT; 96 } 97 98 /** 99 * pci_rebar_get_possible_sizes - get possible sizes for Resizable BAR 100 * @pdev: PCI device 101 * @bar: BAR to query 102 * 103 * Get the possible sizes of a resizable BAR as bitmask. 104 * 105 * Return: A bitmask of possible sizes (bit 0=1MB, bit 31=128TB), or %0 if 106 * BAR isn't resizable. 107 */ 108 u64 pci_rebar_get_possible_sizes(struct pci_dev *pdev, int bar) 109 { 110 int pos; 111 u32 cap; 112 113 pos = pci_rebar_find_pos(pdev, bar); 114 if (pos < 0) 115 return 0; 116 117 pci_read_config_dword(pdev, pos + PCI_REBAR_CAP, &cap); 118 cap = FIELD_GET(PCI_REBAR_CAP_SIZES, cap); 119 120 /* Sapphire RX 5600 XT Pulse has an invalid cap dword for BAR 0 */ 121 if (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x731f && 122 bar == 0 && cap == 0x700) 123 return 0x3f00; 124 125 return cap; 126 } 127 EXPORT_SYMBOL(pci_rebar_get_possible_sizes); 128 129 /** 130 * pci_rebar_size_supported - check if size is supported for BAR 131 * @pdev: PCI device 132 * @bar: BAR to check 133 * @size: encoded size as defined in the PCIe spec (0=1MB, 31=128TB) 134 * 135 * Return: %true if @bar is resizable and @size is supported, otherwise 136 * %false. 137 */ 138 bool pci_rebar_size_supported(struct pci_dev *pdev, int bar, int size) 139 { 140 u64 sizes = pci_rebar_get_possible_sizes(pdev, bar); 141 142 if (size < 0 || size > ilog2(SZ_128T) - ilog2(PCI_REBAR_MIN_SIZE)) 143 return false; 144 145 return BIT(size) & sizes; 146 } 147 EXPORT_SYMBOL_GPL(pci_rebar_size_supported); 148 149 /** 150 * pci_rebar_get_max_size - get the maximum supported size of a BAR 151 * @pdev: PCI device 152 * @bar: BAR to query 153 * 154 * Get the largest supported size of a resizable BAR as a size. 155 * 156 * Return: the encoded maximum BAR size as defined in the PCIe spec 157 * (0=1MB, 31=128TB), or %-NOENT on error. 158 */ 159 int pci_rebar_get_max_size(struct pci_dev *pdev, int bar) 160 { 161 u64 sizes; 162 163 sizes = pci_rebar_get_possible_sizes(pdev, bar); 164 if (!sizes) 165 return -ENOENT; 166 167 return __fls(sizes); 168 } 169 EXPORT_SYMBOL_GPL(pci_rebar_get_max_size); 170 171 /** 172 * pci_rebar_get_current_size - get the current size of a Resizable BAR 173 * @pdev: PCI device 174 * @bar: BAR to get the size from 175 * 176 * Read the current size of a BAR from the Resizable BAR config. 177 * 178 * Return: BAR Size if @bar is resizable (0=1MB, 31=128TB), or negative on 179 * error. 180 */ 181 int pci_rebar_get_current_size(struct pci_dev *pdev, int bar) 182 { 183 int pos; 184 u32 ctrl; 185 186 pos = pci_rebar_find_pos(pdev, bar); 187 if (pos < 0) 188 return pos; 189 190 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 191 return FIELD_GET(PCI_REBAR_CTRL_BAR_SIZE, ctrl); 192 } 193 194 /** 195 * pci_rebar_set_size - set a new size for a Resizable BAR 196 * @pdev: PCI device 197 * @bar: BAR to set size to 198 * @size: new size as defined in the PCIe spec (0=1MB, 31=128TB) 199 * 200 * Set the new size of a BAR as defined in the spec. 201 * 202 * Return: %0 if resizing was successful, or negative on error. 203 */ 204 int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size) 205 { 206 int pos; 207 u32 ctrl; 208 209 pos = pci_rebar_find_pos(pdev, bar); 210 if (pos < 0) 211 return pos; 212 213 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 214 ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; 215 ctrl |= FIELD_PREP(PCI_REBAR_CTRL_BAR_SIZE, size); 216 pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); 217 218 if (pci_resource_is_iov(bar)) 219 pci_iov_resource_set_size(pdev, bar, size); 220 221 return 0; 222 } 223 224 void pci_restore_rebar_state(struct pci_dev *pdev) 225 { 226 unsigned int pos, nbars, i; 227 u32 ctrl; 228 229 pos = pdev->rebar_cap; 230 if (!pos) 231 return; 232 233 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 234 nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl); 235 236 for (i = 0; i < nbars; i++, pos += 8) { 237 struct resource *res; 238 int bar_idx, size; 239 240 pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl); 241 bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX; 242 res = pci_resource_n(pdev, bar_idx); 243 size = pci_rebar_bytes_to_size(resource_size(res)); 244 ctrl &= ~PCI_REBAR_CTRL_BAR_SIZE; 245 ctrl |= FIELD_PREP(PCI_REBAR_CTRL_BAR_SIZE, size); 246 pci_write_config_dword(pdev, pos + PCI_REBAR_CTRL, ctrl); 247 } 248 } 249 250 static bool pci_resize_is_memory_decoding_enabled(struct pci_dev *dev, 251 int resno) 252 { 253 u16 cmd; 254 255 if (pci_resource_is_iov(resno)) 256 return pci_iov_is_memory_decoding_enabled(dev); 257 258 pci_read_config_word(dev, PCI_COMMAND, &cmd); 259 260 return cmd & PCI_COMMAND_MEMORY; 261 } 262 263 void pci_resize_resource_set_size(struct pci_dev *dev, int resno, int size) 264 { 265 resource_size_t res_size = pci_rebar_size_to_bytes(size); 266 struct resource *res = pci_resource_n(dev, resno); 267 268 if (pci_resource_is_iov(resno)) 269 res_size *= pci_sriov_get_totalvfs(dev); 270 271 resource_set_size(res, res_size); 272 } 273 274 /** 275 * pci_resize_resource - reconfigure a Resizable BAR and resources 276 * @dev: the PCI device 277 * @resno: index of the BAR to be resized 278 * @size: new size as defined in the spec (0=1MB, 31=128TB) 279 * @exclude_bars: a mask of BARs that should not be released 280 * 281 * Reconfigure @resno to @size and re-run resource assignment algorithm 282 * with the new size. 283 * 284 * Prior to resize, release @dev resources that share a bridge window with 285 * @resno. This unpins the bridge window resource to allow changing it. 286 * 287 * The caller may prevent releasing a particular BAR by providing 288 * @exclude_bars mask, but this may result in the resize operation failing 289 * due to insufficient space. 290 * 291 * Return: 0 on success, or negative on error. In case of an error, the 292 * resources are restored to their original places. 293 */ 294 int pci_resize_resource(struct pci_dev *dev, int resno, int size, 295 int exclude_bars) 296 { 297 struct pci_host_bridge *host; 298 int old, ret; 299 300 /* Check if we must preserve the firmware's resource assignment */ 301 host = pci_find_host_bridge(dev->bus); 302 if (host->preserve_config) 303 return -ENOTSUPP; 304 305 if (pci_resize_is_memory_decoding_enabled(dev, resno)) 306 return -EBUSY; 307 308 if (!pci_rebar_size_supported(dev, resno, size)) 309 return -EINVAL; 310 311 old = pci_rebar_get_current_size(dev, resno); 312 if (old < 0) 313 return old; 314 315 ret = pci_rebar_set_size(dev, resno, size); 316 if (ret) 317 return ret; 318 319 ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars); 320 if (ret) 321 goto error_resize; 322 return 0; 323 324 error_resize: 325 pci_rebar_set_size(dev, resno, old); 326 return ret; 327 } 328 EXPORT_SYMBOL(pci_resize_resource); 329