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