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