linux/drivers/xen/xen-pciback/conf_space.c
<<
>>
Prefs
   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/module.h>
  14#include <linux/pci.h>
  15#include "pciback.h"
  16#include "conf_space.h"
  17#include "conf_space_quirks.h"
  18
  19static bool permissive;
  20module_param(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)                       \
  25int 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
  31DEFINE_PCI_CONFIG(read, byte, u8 *)
  32DEFINE_PCI_CONFIG(read, word, u16 *)
  33DEFINE_PCI_CONFIG(read, dword, u32 *)
  34
  35DEFINE_PCI_CONFIG(write, byte, u8)
  36DEFINE_PCI_CONFIG(write, word, u16)
  37DEFINE_PCI_CONFIG(write, dword, u32)
  38
  39static 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
  67static 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
  94static 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
 104static 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
 112static 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
 127static 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
 144int 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 req_start, req_end, 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                req_start = offset;
 182                req_end = offset + size;
 183                field_start = OFFSET(cfg_entry);
 184                field_end = OFFSET(cfg_entry) + field->size;
 185
 186                if ((req_start >= field_start && req_start < field_end)
 187                    || (req_end > field_start && req_end <= field_end)) {
 188                        err = conf_space_read(dev, cfg_entry, field_start,
 189                                              &tmp_val);
 190                        if (err)
 191                                goto out;
 192
 193                        value = merge_value(value, tmp_val,
 194                                            get_mask(field->size),
 195                                            field_start - req_start);
 196                }
 197        }
 198
 199out:
 200        if (unlikely(verbose_request))
 201                printk(KERN_DEBUG DRV_NAME ": %s: read %d bytes at 0x%x = %x\n",
 202                       pci_name(dev), size, offset, value);
 203
 204        *ret_val = value;
 205        return xen_pcibios_err_to_errno(err);
 206}
 207
 208int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)
 209{
 210        int err = 0, handled = 0;
 211        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 212        const struct config_field_entry *cfg_entry;
 213        const struct config_field *field;
 214        u32 tmp_val;
 215        int req_start, req_end, field_start, field_end;
 216
 217        if (unlikely(verbose_request))
 218                printk(KERN_DEBUG
 219                       DRV_NAME ": %s: write request %d bytes at 0x%x = %x\n",
 220                       pci_name(dev), size, offset, value);
 221
 222        if (!valid_request(offset, size))
 223                return XEN_PCI_ERR_invalid_offset;
 224
 225        list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
 226                field = cfg_entry->field;
 227
 228                req_start = offset;
 229                req_end = offset + size;
 230                field_start = OFFSET(cfg_entry);
 231                field_end = OFFSET(cfg_entry) + field->size;
 232
 233                if ((req_start >= field_start && req_start < field_end)
 234                    || (req_end > field_start && req_end <= field_end)) {
 235                        tmp_val = 0;
 236
 237                        err = xen_pcibk_config_read(dev, field_start,
 238                                                  field->size, &tmp_val);
 239                        if (err)
 240                                break;
 241
 242                        tmp_val = merge_value(tmp_val, value, get_mask(size),
 243                                              req_start - field_start);
 244
 245                        err = conf_space_write(dev, cfg_entry, field_start,
 246                                               tmp_val);
 247
 248                        /* handled is set true here, but not every byte
 249                         * may have been written! Properly detecting if
 250                         * every byte is handled is unnecessary as the
 251                         * flag is used to detect devices that need
 252                         * special helpers to work correctly.
 253                         */
 254                        handled = 1;
 255                }
 256        }
 257
 258        if (!handled && !err) {
 259                /* By default, anything not specificially handled above is
 260                 * read-only. The permissive flag changes this behavior so
 261                 * that anything not specifically handled above is writable.
 262                 * This means that some fields may still be read-only because
 263                 * they have entries in the config_field list that intercept
 264                 * the write and do nothing. */
 265                if (dev_data->permissive || permissive) {
 266                        switch (size) {
 267                        case 1:
 268                                err = pci_write_config_byte(dev, offset,
 269                                                            (u8) value);
 270                                break;
 271                        case 2:
 272                                err = pci_write_config_word(dev, offset,
 273                                                            (u16) value);
 274                                break;
 275                        case 4:
 276                                err = pci_write_config_dword(dev, offset,
 277                                                             (u32) value);
 278                                break;
 279                        }
 280                } else if (!dev_data->warned_on_write) {
 281                        dev_data->warned_on_write = 1;
 282                        dev_warn(&dev->dev, "Driver tried to write to a "
 283                                 "read-only configuration space field at offset"
 284                                 " 0x%x, size %d. This may be harmless, but if "
 285                                 "you have problems with your device:\n"
 286                                 "1) see permissive attribute in sysfs\n"
 287                                 "2) report problems to the xen-devel "
 288                                 "mailing list along with details of your "
 289                                 "device obtained from lspci.\n", offset, size);
 290                }
 291        }
 292
 293        return xen_pcibios_err_to_errno(err);
 294}
 295
 296void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev)
 297{
 298        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 299        struct config_field_entry *cfg_entry, *t;
 300        const struct config_field *field;
 301
 302        dev_dbg(&dev->dev, "free-ing dynamically allocated virtual "
 303                           "configuration space fields\n");
 304        if (!dev_data)
 305                return;
 306
 307        list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
 308                field = cfg_entry->field;
 309
 310                if (field->clean) {
 311                        field->clean((struct config_field *)field);
 312
 313                        kfree(cfg_entry->data);
 314
 315                        list_del(&cfg_entry->list);
 316                        kfree(cfg_entry);
 317                }
 318
 319        }
 320}
 321
 322void xen_pcibk_config_reset_dev(struct pci_dev *dev)
 323{
 324        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 325        const struct config_field_entry *cfg_entry;
 326        const struct config_field *field;
 327
 328        dev_dbg(&dev->dev, "resetting virtual configuration space\n");
 329        if (!dev_data)
 330                return;
 331
 332        list_for_each_entry(cfg_entry, &dev_data->config_fields, list) {
 333                field = cfg_entry->field;
 334
 335                if (field->reset)
 336                        field->reset(dev, OFFSET(cfg_entry), cfg_entry->data);
 337        }
 338}
 339
 340void xen_pcibk_config_free_dev(struct pci_dev *dev)
 341{
 342        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 343        struct config_field_entry *cfg_entry, *t;
 344        const struct config_field *field;
 345
 346        dev_dbg(&dev->dev, "free-ing virtual configuration space fields\n");
 347        if (!dev_data)
 348                return;
 349
 350        list_for_each_entry_safe(cfg_entry, t, &dev_data->config_fields, list) {
 351                list_del(&cfg_entry->list);
 352
 353                field = cfg_entry->field;
 354
 355                if (field->release)
 356                        field->release(dev, OFFSET(cfg_entry), cfg_entry->data);
 357
 358                kfree(cfg_entry);
 359        }
 360}
 361
 362int xen_pcibk_config_add_field_offset(struct pci_dev *dev,
 363                                    const struct config_field *field,
 364                                    unsigned int base_offset)
 365{
 366        int err = 0;
 367        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 368        struct config_field_entry *cfg_entry;
 369        void *tmp;
 370
 371        cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL);
 372        if (!cfg_entry) {
 373                err = -ENOMEM;
 374                goto out;
 375        }
 376
 377        cfg_entry->data = NULL;
 378        cfg_entry->field = field;
 379        cfg_entry->base_offset = base_offset;
 380
 381        /* silently ignore duplicate fields */
 382        err = xen_pcibk_field_is_dup(dev, OFFSET(cfg_entry));
 383        if (err)
 384                goto out;
 385
 386        if (field->init) {
 387                tmp = field->init(dev, OFFSET(cfg_entry));
 388
 389                if (IS_ERR(tmp)) {
 390                        err = PTR_ERR(tmp);
 391                        goto out;
 392                }
 393
 394                cfg_entry->data = tmp;
 395        }
 396
 397        dev_dbg(&dev->dev, "added config field at offset 0x%02x\n",
 398                OFFSET(cfg_entry));
 399        list_add_tail(&cfg_entry->list, &dev_data->config_fields);
 400
 401out:
 402        if (err)
 403                kfree(cfg_entry);
 404
 405        return err;
 406}
 407
 408/* This sets up the device's virtual configuration space to keep track of
 409 * certain registers (like the base address registers (BARs) so that we can
 410 * keep the client from manipulating them directly.
 411 */
 412int xen_pcibk_config_init_dev(struct pci_dev *dev)
 413{
 414        int err = 0;
 415        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
 416
 417        dev_dbg(&dev->dev, "initializing virtual configuration space\n");
 418
 419        INIT_LIST_HEAD(&dev_data->config_fields);
 420
 421        err = xen_pcibk_config_header_add_fields(dev);
 422        if (err)
 423                goto out;
 424
 425        err = xen_pcibk_config_capability_add_fields(dev);
 426        if (err)
 427                goto out;
 428
 429        err = xen_pcibk_config_quirks_init(dev);
 430
 431out:
 432        return err;
 433}
 434
 435int xen_pcibk_config_init(void)
 436{
 437        return xen_pcibk_config_capability_init();
 438}
 439