conf_space.c (11602B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * PCI Backend - Functions for creating a virtual configuration space for 4 * exported PCI Devices. 5 * It's dangerous to allow PCI Driver Domains to change their 6 * device's resources (memory, i/o ports, interrupts). We need to 7 * restrict changes to certain PCI Configuration registers: 8 * BARs, INTERRUPT_PIN, most registers in the header... 9 * 10 * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 11 */ 12 13#define dev_fmt(fmt) DRV_NAME ": " fmt 14 15#include <linux/kernel.h> 16#include <linux/moduleparam.h> 17#include <linux/pci.h> 18#include "pciback.h" 19#include "conf_space.h" 20#include "conf_space_quirks.h" 21 22bool xen_pcibk_permissive; 23module_param_named(permissive, xen_pcibk_permissive, bool, 0644); 24 25/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word, 26 * xen_pcibk_write_config_word, and xen_pcibk_write_config_byte are created. */ 27#define DEFINE_PCI_CONFIG(op, size, type) \ 28int xen_pcibk_##op##_config_##size \ 29(struct pci_dev *dev, int offset, type value, void *data) \ 30{ \ 31 return pci_##op##_config_##size(dev, offset, value); \ 32} 33 34DEFINE_PCI_CONFIG(read, byte, u8 *) 35DEFINE_PCI_CONFIG(read, word, u16 *) 36DEFINE_PCI_CONFIG(read, dword, u32 *) 37 38DEFINE_PCI_CONFIG(write, byte, u8) 39DEFINE_PCI_CONFIG(write, word, u16) 40DEFINE_PCI_CONFIG(write, dword, u32) 41 42static int conf_space_read(struct pci_dev *dev, 43 const struct config_field_entry *entry, 44 int offset, u32 *value) 45{ 46 int ret = 0; 47 const struct config_field *field = entry->field; 48 49 *value = 0; 50 51 switch (field->size) { 52 case 1: 53 if (field->u.b.read) 54 ret = field->u.b.read(dev, offset, (u8 *) value, 55 entry->data); 56 break; 57 case 2: 58 if (field->u.w.read) 59 ret = field->u.w.read(dev, offset, (u16 *) value, 60 entry->data); 61 break; 62 case 4: 63 if (field->u.dw.read) 64 ret = field->u.dw.read(dev, offset, value, entry->data); 65 break; 66 } 67 return ret; 68} 69 70static int conf_space_write(struct pci_dev *dev, 71 const struct config_field_entry *entry, 72 int offset, u32 value) 73{ 74 int ret = 0; 75 const struct config_field *field = entry->field; 76 77 switch (field->size) { 78 case 1: 79 if (field->u.b.write) 80 ret = field->u.b.write(dev, offset, (u8) value, 81 entry->data); 82 break; 83 case 2: 84 if (field->u.w.write) 85 ret = field->u.w.write(dev, offset, (u16) value, 86 entry->data); 87 break; 88 case 4: 89 if (field->u.dw.write) 90 ret = field->u.dw.write(dev, offset, value, 91 entry->data); 92 break; 93 } 94 return ret; 95} 96 97static inline u32 get_mask(int size) 98{ 99 if (size == 1) 100 return 0xff; 101 else if (size == 2) 102 return 0xffff; 103 else 104 return 0xffffffff; 105} 106 107static inline int valid_request(int offset, int size) 108{ 109 /* Validate request (no un-aligned requests) */ 110 if ((size == 1 || size == 2 || size == 4) && (offset % size) == 0) 111 return 1; 112 return 0; 113} 114 115static inline u32 merge_value(u32 val, u32 new_val, u32 new_val_mask, 116 int offset) 117{ 118 if (offset >= 0) { 119 new_val_mask <<= (offset * 8); 120 new_val <<= (offset * 8); 121 } else { 122 new_val_mask >>= (offset * -8); 123 new_val >>= (offset * -8); 124 } 125 val = (val & ~new_val_mask) | (new_val & new_val_mask); 126 127 return val; 128} 129 130static int xen_pcibios_err_to_errno(int err) 131{ 132 switch (err) { 133 case PCIBIOS_SUCCESSFUL: 134 return XEN_PCI_ERR_success; 135 case PCIBIOS_DEVICE_NOT_FOUND: 136 return XEN_PCI_ERR_dev_not_found; 137 case PCIBIOS_BAD_REGISTER_NUMBER: 138 return XEN_PCI_ERR_invalid_offset; 139 case PCIBIOS_FUNC_NOT_SUPPORTED: 140 return XEN_PCI_ERR_not_implemented; 141 case PCIBIOS_SET_FAILED: 142 return XEN_PCI_ERR_access_denied; 143 } 144 return err; 145} 146 147int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size, 148 u32 *ret_val) 149{ 150 int err = 0; 151 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 152 const struct config_field_entry *cfg_entry; 153 const struct config_field *field; 154 int field_start, field_end; 155 /* if read fails for any reason, return 0 156 * (as if device didn't respond) */ 157 u32 value = 0, tmp_val; 158 159 dev_dbg(&dev->dev, "read %d bytes at 0x%x\n", size, offset); 160 161 if (!valid_request(offset, size)) { 162 err = XEN_PCI_ERR_invalid_offset; 163 goto out; 164 } 165 166 /* Get the real value first, then modify as appropriate */ 167 switch (size) { 168 case 1: 169 err = pci_read_config_byte(dev, offset, (u8 *) &value); 170 break; 171 case 2: 172 err = pci_read_config_word(dev, offset, (u16 *) &value); 173 break; 174 case 4: 175 err = pci_read_config_dword(dev, offset, &value); 176 break; 177 } 178 179 list_for_each_entry(cfg_entry, &dev_data->config_fields, list) { 180 field = cfg_entry->field; 181 182 field_start = OFFSET(cfg_entry); 183 field_end = OFFSET(cfg_entry) + field->size; 184 185 if (offset + size > field_start && field_end > offset) { 186 err = conf_space_read(dev, cfg_entry, field_start, 187 &tmp_val); 188 if (err) 189 goto out; 190 191 value = merge_value(value, tmp_val, 192 get_mask(field->size), 193 field_start - offset); 194 } 195 } 196 197out: 198 dev_dbg(&dev->dev, "read %d bytes at 0x%x = %x\n", size, offset, value); 199 200 *ret_val = value; 201 return xen_pcibios_err_to_errno(err); 202} 203 204int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value) 205{ 206 int err = 0, handled = 0; 207 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 208 const struct config_field_entry *cfg_entry; 209 const struct config_field *field; 210 u32 tmp_val; 211 int field_start, field_end; 212 213 dev_dbg(&dev->dev, "write request %d bytes at 0x%x = %x\n", 214 size, offset, value); 215 216 if (!valid_request(offset, size)) 217 return XEN_PCI_ERR_invalid_offset; 218 219 list_for_each_entry(cfg_entry, &dev_data->config_fields, list) { 220 field = cfg_entry->field; 221 222 field_start = OFFSET(cfg_entry); 223 field_end = OFFSET(cfg_entry) + field->size; 224 225 if (offset + size > field_start && field_end > offset) { 226 err = conf_space_read(dev, cfg_entry, field_start, 227 &tmp_val); 228 if (err) 229 break; 230 231 tmp_val = merge_value(tmp_val, value, get_mask(size), 232 offset - field_start); 233 234 err = conf_space_write(dev, cfg_entry, field_start, 235 tmp_val); 236 237 /* handled is set true here, but not every byte 238 * may have been written! Properly detecting if 239 * every byte is handled is unnecessary as the 240 * flag is used to detect devices that need 241 * special helpers to work correctly. 242 */ 243 handled = 1; 244 } 245 } 246 247 if (!handled && !err) { 248 /* By default, anything not specificially handled above is 249 * read-only. The permissive flag changes this behavior so 250 * that anything not specifically handled above is writable. 251 * This means that some fields may still be read-only because 252 * they have entries in the config_field list that intercept 253 * the write and do nothing. */ 254 if (dev_data->permissive || xen_pcibk_permissive) { 255 switch (size) { 256 case 1: 257 err = pci_write_config_byte(dev, offset, 258 (u8) value); 259 break; 260 case 2: 261 err = pci_write_config_word(dev, offset, 262 (u16) value); 263 break; 264 case 4: 265 err = pci_write_config_dword(dev, offset, 266 (u32) value); 267 break; 268 } 269 } else if (!dev_data->warned_on_write) { 270 dev_data->warned_on_write = 1; 271 dev_warn(&dev->dev, "Driver tried to write to a " 272 "read-only configuration space field at offset" 273 " 0x%x, size %d. This may be harmless, but if " 274 "you have problems with your device:\n" 275 "1) see permissive attribute in sysfs\n" 276 "2) report problems to the xen-devel " 277 "mailing list along with details of your " 278 "device obtained from lspci.\n", offset, size); 279 } 280 } 281 282 return xen_pcibios_err_to_errno(err); 283} 284 285int xen_pcibk_get_interrupt_type(struct pci_dev *dev) 286{ 287 int err; 288 u16 val; 289 int ret = 0; 290 291 err = pci_read_config_word(dev, PCI_COMMAND, &val); 292 if (err) 293 return err; 294 if (!(val & PCI_COMMAND_INTX_DISABLE)) 295 ret |= INTERRUPT_TYPE_INTX; 296 297 /* 298 * Do not trust dev->msi(x)_enabled here, as enabling could be done 299 * bypassing the pci_*msi* functions, by the qemu. 300 */ 301 if (dev->msi_cap) { 302 err = pci_read_config_word(dev, 303 dev->msi_cap + PCI_MSI_FLAGS, 304 &val); 305 if (err) 306 return err; 307 if (val & PCI_MSI_FLAGS_ENABLE) 308 ret |= INTERRUPT_TYPE_MSI; 309 } 310 if (dev->msix_cap) { 311 err = pci_read_config_word(dev, 312 dev->msix_cap + PCI_MSIX_FLAGS, 313 &val); 314 if (err) 315 return err; 316 if (val & PCI_MSIX_FLAGS_ENABLE) 317 ret |= INTERRUPT_TYPE_MSIX; 318 } 319 return ret ?: INTERRUPT_TYPE_NONE; 320} 321 322void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev) 323{ 324 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 325 struct config_field_entry *cfg_entry, *t; 326 const struct config_field *field; 327 328 dev_dbg(&dev->dev, "free-ing dynamically allocated virtual " 329 "configuration space fields\n"); 330 if (!dev_data) 331 return; 332 333 list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) { 334 field = cfg_entry->field; 335 336 if (field->clean) { 337 field->clean((struct config_field *)field); 338 339 kfree(cfg_entry->data); 340 341 list_del(&cfg_entry->list); 342 kfree(cfg_entry); 343 } 344 345 } 346} 347 348void xen_pcibk_config_reset_dev(struct pci_dev *dev) 349{ 350 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 351 const struct config_field_entry *cfg_entry; 352 const struct config_field *field; 353 354 dev_dbg(&dev->dev, "resetting virtual configuration space\n"); 355 if (!dev_data) 356 return; 357 358 list_for_each_entry(cfg_entry, &dev_data->config_fields, list) { 359 field = cfg_entry->field; 360 361 if (field->reset) 362 field->reset(dev, OFFSET(cfg_entry), cfg_entry->data); 363 } 364} 365 366void xen_pcibk_config_free_dev(struct pci_dev *dev) 367{ 368 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 369 struct config_field_entry *cfg_entry, *t; 370 const struct config_field *field; 371 372 dev_dbg(&dev->dev, "free-ing virtual configuration space fields\n"); 373 if (!dev_data) 374 return; 375 376 list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) { 377 list_del(&cfg_entry->list); 378 379 field = cfg_entry->field; 380 381 if (field->release) 382 field->release(dev, OFFSET(cfg_entry), cfg_entry->data); 383 384 kfree(cfg_entry); 385 } 386} 387 388int xen_pcibk_config_add_field_offset(struct pci_dev *dev, 389 const struct config_field *field, 390 unsigned int base_offset) 391{ 392 int err = 0; 393 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 394 struct config_field_entry *cfg_entry; 395 void *tmp; 396 397 cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL); 398 if (!cfg_entry) { 399 err = -ENOMEM; 400 goto out; 401 } 402 403 cfg_entry->data = NULL; 404 cfg_entry->field = field; 405 cfg_entry->base_offset = base_offset; 406 407 /* silently ignore duplicate fields */ 408 err = xen_pcibk_field_is_dup(dev, OFFSET(cfg_entry)); 409 if (err) 410 goto out; 411 412 if (field->init) { 413 tmp = field->init(dev, OFFSET(cfg_entry)); 414 415 if (IS_ERR(tmp)) { 416 err = PTR_ERR(tmp); 417 goto out; 418 } 419 420 cfg_entry->data = tmp; 421 } 422 423 dev_dbg(&dev->dev, "added config field at offset 0x%02x\n", 424 OFFSET(cfg_entry)); 425 list_add_tail(&cfg_entry->list, &dev_data->config_fields); 426 427out: 428 if (err) 429 kfree(cfg_entry); 430 431 return err; 432} 433 434/* This sets up the device's virtual configuration space to keep track of 435 * certain registers (like the base address registers (BARs) so that we can 436 * keep the client from manipulating them directly. 437 */ 438int xen_pcibk_config_init_dev(struct pci_dev *dev) 439{ 440 int err = 0; 441 struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev); 442 443 dev_dbg(&dev->dev, "initializing virtual configuration space\n"); 444 445 INIT_LIST_HEAD(&dev_data->config_fields); 446 447 err = xen_pcibk_config_header_add_fields(dev); 448 if (err) 449 goto out; 450 451 err = xen_pcibk_config_capability_add_fields(dev); 452 if (err) 453 goto out; 454 455 err = xen_pcibk_config_quirks_init(dev); 456 457out: 458 return err; 459} 460 461int xen_pcibk_config_init(void) 462{ 463 return xen_pcibk_config_capability_init(); 464}