linux/drivers/xen/xen-pciback/conf_space_header.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * PCI Backend - Handles the virtual fields in the configuration space headers.
   4 *
   5 * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9#define dev_fmt pr_fmt
  10
  11#include <linux/kernel.h>
  12#include <linux/pci.h>
  13#include "pciback.h"
  14#include "conf_space.h"
  15
  16struct pci_cmd_info {
  17        u16 val;
  18};
  19
  20struct pci_bar_info {
  21        u32 val;
  22        u32 len_val;
  23        int which;
  24};
  25
  26#define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
  27#define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
  28
  29/* Bits guests are allowed to control in permissive mode. */
  30#define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
  31                           PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
  32                           PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
  33
  34static void *command_init(struct pci_dev *dev, int offset)
  35{
  36        struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
  37        int err;
  38
  39        if (!cmd)
  40                return ERR_PTR(-ENOMEM);
  41
  42        err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
  43        if (err) {
  44                kfree(cmd);
  45                return ERR_PTR(err);
  46        }
  47
  48        return cmd;
  49}
  50
  51static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
  52{
  53        int ret = pci_read_config_word(dev, offset, value);
  54        const struct pci_cmd_info *cmd = data;
  55
  56        *value &= PCI_COMMAND_GUEST;
  57        *value |= cmd->val & ~PCI_COMMAND_GUEST;
  58
  59        return ret;
  60}
  61
  62static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
  63{
  64        struct xen_pcibk_dev_data *dev_data;
  65        int err;
  66        u16 val;
  67        struct pci_cmd_info *cmd = data;
  68
  69        dev_data = pci_get_drvdata(dev);
  70        if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
  71                dev_dbg(&dev->dev, "enable\n");
  72                err = pci_enable_device(dev);
  73                if (err)
  74                        return err;
  75                if (dev_data)
  76                        dev_data->enable_intx = 1;
  77        } else if (pci_is_enabled(dev) && !is_enable_cmd(value)) {
  78                dev_dbg(&dev->dev, "disable\n");
  79                pci_disable_device(dev);
  80                if (dev_data)
  81                        dev_data->enable_intx = 0;
  82        }
  83
  84        if (!dev->is_busmaster && is_master_cmd(value)) {
  85                dev_dbg(&dev->dev, "set bus master\n");
  86                pci_set_master(dev);
  87        } else if (dev->is_busmaster && !is_master_cmd(value)) {
  88                dev_dbg(&dev->dev, "clear bus master\n");
  89                pci_clear_master(dev);
  90        }
  91
  92        if (!(cmd->val & PCI_COMMAND_INVALIDATE) &&
  93            (value & PCI_COMMAND_INVALIDATE)) {
  94                dev_dbg(&dev->dev, "enable memory-write-invalidate\n");
  95                err = pci_set_mwi(dev);
  96                if (err) {
  97                        dev_warn(&dev->dev, "cannot enable memory-write-invalidate (%d)\n",
  98                                err);
  99                        value &= ~PCI_COMMAND_INVALIDATE;
 100                }
 101        } else if ((cmd->val & PCI_COMMAND_INVALIDATE) &&
 102                   !(value & PCI_COMMAND_INVALIDATE)) {
 103                dev_dbg(&dev->dev, "disable memory-write-invalidate\n");
 104                pci_clear_mwi(dev);
 105        }
 106
 107        if (dev_data && dev_data->allow_interrupt_control) {
 108                if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
 109                        if (value & PCI_COMMAND_INTX_DISABLE) {
 110                                pci_intx(dev, 0);
 111                        } else {
 112                                /* Do not allow enabling INTx together with MSI or MSI-X. */
 113                                switch (xen_pcibk_get_interrupt_type(dev)) {
 114                                case INTERRUPT_TYPE_NONE:
 115                                        pci_intx(dev, 1);
 116                                        break;
 117                                case INTERRUPT_TYPE_INTX:
 118                                        break;
 119                                default:
 120                                        return PCIBIOS_SET_FAILED;
 121                                }
 122                        }
 123                }
 124        }
 125
 126        cmd->val = value;
 127
 128        if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))
 129                return 0;
 130
 131        /* Only allow the guest to control certain bits. */
 132        err = pci_read_config_word(dev, offset, &val);
 133        if (err || val == value)
 134                return err;
 135
 136        value &= PCI_COMMAND_GUEST;
 137        value |= val & ~PCI_COMMAND_GUEST;
 138
 139        return pci_write_config_word(dev, offset, value);
 140}
 141
 142static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)
 143{
 144        struct pci_bar_info *bar = data;
 145
 146        if (unlikely(!bar)) {
 147                dev_warn(&dev->dev, "driver data not found\n");
 148                return XEN_PCI_ERR_op_failed;
 149        }
 150
 151        /* A write to obtain the length must happen as a 32-bit write.
 152         * This does not (yet) support writing individual bytes
 153         */
 154        if ((value | ~PCI_ROM_ADDRESS_MASK) == ~0U)
 155                bar->which = 1;
 156        else {
 157                u32 tmpval;
 158                pci_read_config_dword(dev, offset, &tmpval);
 159                if (tmpval != bar->val && value == bar->val) {
 160                        /* Allow restoration of bar value. */
 161                        pci_write_config_dword(dev, offset, bar->val);
 162                }
 163                bar->which = 0;
 164        }
 165
 166        /* Do we need to support enabling/disabling the rom address here? */
 167
 168        return 0;
 169}
 170
 171/* For the BARs, only allow writes which write ~0 or
 172 * the correct resource information
 173 * (Needed for when the driver probes the resource usage)
 174 */
 175static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)
 176{
 177        struct pci_bar_info *bar = data;
 178        unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4;
 179        const struct resource *res = dev->resource;
 180        u32 mask;
 181
 182        if (unlikely(!bar)) {
 183                dev_warn(&dev->dev, "driver data not found\n");
 184                return XEN_PCI_ERR_op_failed;
 185        }
 186
 187        /* A write to obtain the length must happen as a 32-bit write.
 188         * This does not (yet) support writing individual bytes
 189         */
 190        if (res[pos].flags & IORESOURCE_IO)
 191                mask = ~PCI_BASE_ADDRESS_IO_MASK;
 192        else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64))
 193                mask = 0;
 194        else
 195                mask = ~PCI_BASE_ADDRESS_MEM_MASK;
 196        if ((value | mask) == ~0U)
 197                bar->which = 1;
 198        else {
 199                u32 tmpval;
 200                pci_read_config_dword(dev, offset, &tmpval);
 201                if (tmpval != bar->val && value == bar->val) {
 202                        /* Allow restoration of bar value. */
 203                        pci_write_config_dword(dev, offset, bar->val);
 204                }
 205                bar->which = 0;
 206        }
 207
 208        return 0;
 209}
 210
 211static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
 212{
 213        struct pci_bar_info *bar = data;
 214
 215        if (unlikely(!bar)) {
 216                dev_warn(&dev->dev, "driver data not found\n");
 217                return XEN_PCI_ERR_op_failed;
 218        }
 219
 220        *value = bar->which ? bar->len_val : bar->val;
 221
 222        return 0;
 223}
 224
 225static void *bar_init(struct pci_dev *dev, int offset)
 226{
 227        unsigned int pos;
 228        const struct resource *res = dev->resource;
 229        struct pci_bar_info *bar = kzalloc(sizeof(*bar), GFP_KERNEL);
 230
 231        if (!bar)
 232                return ERR_PTR(-ENOMEM);
 233
 234        if (offset == PCI_ROM_ADDRESS || offset == PCI_ROM_ADDRESS1)
 235                pos = PCI_ROM_RESOURCE;
 236        else {
 237                pos = (offset - PCI_BASE_ADDRESS_0) / 4;
 238                if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) {
 239                        bar->val = res[pos - 1].start >> 32;
 240                        bar->len_val = -resource_size(&res[pos - 1]) >> 32;
 241                        return bar;
 242                }
 243        }
 244
 245        if (!res[pos].flags ||
 246            (res[pos].flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET |
 247                               IORESOURCE_BUSY)))
 248                return bar;
 249
 250        bar->val = res[pos].start |
 251                   (res[pos].flags & PCI_REGION_FLAG_MASK);
 252        bar->len_val = -resource_size(&res[pos]) |
 253                       (res[pos].flags & PCI_REGION_FLAG_MASK);
 254
 255        return bar;
 256}
 257
 258static void bar_reset(struct pci_dev *dev, int offset, void *data)
 259{
 260        struct pci_bar_info *bar = data;
 261
 262        bar->which = 0;
 263}
 264
 265static void bar_release(struct pci_dev *dev, int offset, void *data)
 266{
 267        kfree(data);
 268}
 269
 270static int xen_pcibk_read_vendor(struct pci_dev *dev, int offset,
 271                               u16 *value, void *data)
 272{
 273        *value = dev->vendor;
 274
 275        return 0;
 276}
 277
 278static int xen_pcibk_read_device(struct pci_dev *dev, int offset,
 279                               u16 *value, void *data)
 280{
 281        *value = dev->device;
 282
 283        return 0;
 284}
 285
 286static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,
 287                          void *data)
 288{
 289        *value = (u8) dev->irq;
 290
 291        return 0;
 292}
 293
 294static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
 295{
 296        u8 cur_value;
 297        int err;
 298
 299        err = pci_read_config_byte(dev, offset, &cur_value);
 300        if (err)
 301                goto out;
 302
 303        if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
 304            || value == PCI_BIST_START)
 305                err = pci_write_config_byte(dev, offset, value);
 306
 307out:
 308        return err;
 309}
 310
 311static const struct config_field header_common[] = {
 312        {
 313         .offset    = PCI_VENDOR_ID,
 314         .size      = 2,
 315         .u.w.read  = xen_pcibk_read_vendor,
 316        },
 317        {
 318         .offset    = PCI_DEVICE_ID,
 319         .size      = 2,
 320         .u.w.read  = xen_pcibk_read_device,
 321        },
 322        {
 323         .offset    = PCI_COMMAND,
 324         .size      = 2,
 325         .init      = command_init,
 326         .release   = bar_release,
 327         .u.w.read  = command_read,
 328         .u.w.write = command_write,
 329        },
 330        {
 331         .offset    = PCI_INTERRUPT_LINE,
 332         .size      = 1,
 333         .u.b.read  = interrupt_read,
 334        },
 335        {
 336         .offset    = PCI_INTERRUPT_PIN,
 337         .size      = 1,
 338         .u.b.read  = xen_pcibk_read_config_byte,
 339        },
 340        {
 341         /* Any side effects of letting driver domain control cache line? */
 342         .offset    = PCI_CACHE_LINE_SIZE,
 343         .size      = 1,
 344         .u.b.read  = xen_pcibk_read_config_byte,
 345         .u.b.write = xen_pcibk_write_config_byte,
 346        },
 347        {
 348         .offset    = PCI_LATENCY_TIMER,
 349         .size      = 1,
 350         .u.b.read  = xen_pcibk_read_config_byte,
 351        },
 352        {
 353         .offset    = PCI_BIST,
 354         .size      = 1,
 355         .u.b.read  = xen_pcibk_read_config_byte,
 356         .u.b.write = bist_write,
 357        },
 358        {}
 359};
 360
 361#define CFG_FIELD_BAR(reg_offset)                       \
 362        {                                               \
 363        .offset     = reg_offset,                       \
 364        .size       = 4,                                \
 365        .init       = bar_init,                         \
 366        .reset      = bar_reset,                        \
 367        .release    = bar_release,                      \
 368        .u.dw.read  = bar_read,                         \
 369        .u.dw.write = bar_write,                        \
 370        }
 371
 372#define CFG_FIELD_ROM(reg_offset)                       \
 373        {                                               \
 374        .offset     = reg_offset,                       \
 375        .size       = 4,                                \
 376        .init       = bar_init,                         \
 377        .reset      = bar_reset,                        \
 378        .release    = bar_release,                      \
 379        .u.dw.read  = bar_read,                         \
 380        .u.dw.write = rom_write,                        \
 381        }
 382
 383static const struct config_field header_0[] = {
 384        CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
 385        CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
 386        CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
 387        CFG_FIELD_BAR(PCI_BASE_ADDRESS_3),
 388        CFG_FIELD_BAR(PCI_BASE_ADDRESS_4),
 389        CFG_FIELD_BAR(PCI_BASE_ADDRESS_5),
 390        CFG_FIELD_ROM(PCI_ROM_ADDRESS),
 391        {}
 392};
 393
 394static const struct config_field header_1[] = {
 395        CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
 396        CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
 397        CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
 398        {}
 399};
 400
 401int xen_pcibk_config_header_add_fields(struct pci_dev *dev)
 402{
 403        int err;
 404
 405        err = xen_pcibk_config_add_fields(dev, header_common);
 406        if (err)
 407                goto out;
 408
 409        switch (dev->hdr_type) {
 410        case PCI_HEADER_TYPE_NORMAL:
 411                err = xen_pcibk_config_add_fields(dev, header_0);
 412                break;
 413
 414        case PCI_HEADER_TYPE_BRIDGE:
 415                err = xen_pcibk_config_add_fields(dev, header_1);
 416                break;
 417
 418        default:
 419                err = -EINVAL;
 420                dev_err(&dev->dev, "Unsupported header type %d!\n",
 421                        dev->hdr_type);
 422                break;
 423        }
 424
 425out:
 426        return err;
 427}
 428