Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * PCI Backend - Handles the virtual fields in the configuration space headers.
0004  *
0005  * Author: Ryan Wilson <hap9@epoch.ncsc.mil>
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 #define dev_fmt pr_fmt
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/pci.h>
0013 #include "pciback.h"
0014 #include "conf_space.h"
0015 
0016 struct pci_cmd_info {
0017     u16 val;
0018 };
0019 
0020 struct pci_bar_info {
0021     u32 val;
0022     u32 len_val;
0023     int which;
0024 };
0025 
0026 #define is_enable_cmd(value) ((value)&(PCI_COMMAND_MEMORY|PCI_COMMAND_IO))
0027 #define is_master_cmd(value) ((value)&PCI_COMMAND_MASTER)
0028 
0029 /* Bits guests are allowed to control in permissive mode. */
0030 #define PCI_COMMAND_GUEST (PCI_COMMAND_MASTER|PCI_COMMAND_SPECIAL| \
0031                PCI_COMMAND_INVALIDATE|PCI_COMMAND_VGA_PALETTE| \
0032                PCI_COMMAND_WAIT|PCI_COMMAND_FAST_BACK)
0033 
0034 static void *command_init(struct pci_dev *dev, int offset)
0035 {
0036     struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL);
0037     int err;
0038 
0039     if (!cmd)
0040         return ERR_PTR(-ENOMEM);
0041 
0042     err = pci_read_config_word(dev, PCI_COMMAND, &cmd->val);
0043     if (err) {
0044         kfree(cmd);
0045         return ERR_PTR(err);
0046     }
0047 
0048     return cmd;
0049 }
0050 
0051 static int command_read(struct pci_dev *dev, int offset, u16 *value, void *data)
0052 {
0053     int ret = pci_read_config_word(dev, offset, value);
0054     const struct pci_cmd_info *cmd = data;
0055 
0056     *value &= PCI_COMMAND_GUEST;
0057     *value |= cmd->val & ~PCI_COMMAND_GUEST;
0058 
0059     return ret;
0060 }
0061 
0062 static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
0063 {
0064     struct xen_pcibk_dev_data *dev_data;
0065     int err;
0066     u16 val;
0067     struct pci_cmd_info *cmd = data;
0068 
0069     dev_data = pci_get_drvdata(dev);
0070     if (!pci_is_enabled(dev) && is_enable_cmd(value)) {
0071         dev_dbg(&dev->dev, "enable\n");
0072         err = pci_enable_device(dev);
0073         if (err)
0074             return err;
0075         if (dev_data)
0076             dev_data->enable_intx = 1;
0077     } else if (pci_is_enabled(dev) && !is_enable_cmd(value)) {
0078         dev_dbg(&dev->dev, "disable\n");
0079         pci_disable_device(dev);
0080         if (dev_data)
0081             dev_data->enable_intx = 0;
0082     }
0083 
0084     if (!dev->is_busmaster && is_master_cmd(value)) {
0085         dev_dbg(&dev->dev, "set bus master\n");
0086         pci_set_master(dev);
0087     } else if (dev->is_busmaster && !is_master_cmd(value)) {
0088         dev_dbg(&dev->dev, "clear bus master\n");
0089         pci_clear_master(dev);
0090     }
0091 
0092     if (!(cmd->val & PCI_COMMAND_INVALIDATE) &&
0093         (value & PCI_COMMAND_INVALIDATE)) {
0094         dev_dbg(&dev->dev, "enable memory-write-invalidate\n");
0095         err = pci_set_mwi(dev);
0096         if (err) {
0097             dev_warn(&dev->dev, "cannot enable memory-write-invalidate (%d)\n",
0098                 err);
0099             value &= ~PCI_COMMAND_INVALIDATE;
0100         }
0101     } else if ((cmd->val & PCI_COMMAND_INVALIDATE) &&
0102            !(value & PCI_COMMAND_INVALIDATE)) {
0103         dev_dbg(&dev->dev, "disable memory-write-invalidate\n");
0104         pci_clear_mwi(dev);
0105     }
0106 
0107     if (dev_data && dev_data->allow_interrupt_control) {
0108         if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
0109             if (value & PCI_COMMAND_INTX_DISABLE) {
0110                 pci_intx(dev, 0);
0111             } else {
0112                 /* Do not allow enabling INTx together with MSI or MSI-X. */
0113                 switch (xen_pcibk_get_interrupt_type(dev)) {
0114                 case INTERRUPT_TYPE_NONE:
0115                     pci_intx(dev, 1);
0116                     break;
0117                 case INTERRUPT_TYPE_INTX:
0118                     break;
0119                 default:
0120                     return PCIBIOS_SET_FAILED;
0121                 }
0122             }
0123         }
0124     }
0125 
0126     cmd->val = value;
0127 
0128     if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))
0129         return 0;
0130 
0131     /* Only allow the guest to control certain bits. */
0132     err = pci_read_config_word(dev, offset, &val);
0133     if (err || val == value)
0134         return err;
0135 
0136     value &= PCI_COMMAND_GUEST;
0137     value |= val & ~PCI_COMMAND_GUEST;
0138 
0139     return pci_write_config_word(dev, offset, value);
0140 }
0141 
0142 static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)
0143 {
0144     struct pci_bar_info *bar = data;
0145 
0146     if (unlikely(!bar)) {
0147         dev_warn(&dev->dev, "driver data not found\n");
0148         return XEN_PCI_ERR_op_failed;
0149     }
0150 
0151     /* A write to obtain the length must happen as a 32-bit write.
0152      * This does not (yet) support writing individual bytes
0153      */
0154     if ((value | ~PCI_ROM_ADDRESS_MASK) == ~0U)
0155         bar->which = 1;
0156     else {
0157         u32 tmpval;
0158         pci_read_config_dword(dev, offset, &tmpval);
0159         if (tmpval != bar->val && value == bar->val) {
0160             /* Allow restoration of bar value. */
0161             pci_write_config_dword(dev, offset, bar->val);
0162         }
0163         bar->which = 0;
0164     }
0165 
0166     /* Do we need to support enabling/disabling the rom address here? */
0167 
0168     return 0;
0169 }
0170 
0171 /* For the BARs, only allow writes which write ~0 or
0172  * the correct resource information
0173  * (Needed for when the driver probes the resource usage)
0174  */
0175 static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)
0176 {
0177     struct pci_bar_info *bar = data;
0178     unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4;
0179     const struct resource *res = dev->resource;
0180     u32 mask;
0181 
0182     if (unlikely(!bar)) {
0183         dev_warn(&dev->dev, "driver data not found\n");
0184         return XEN_PCI_ERR_op_failed;
0185     }
0186 
0187     /* A write to obtain the length must happen as a 32-bit write.
0188      * This does not (yet) support writing individual bytes
0189      */
0190     if (res[pos].flags & IORESOURCE_IO)
0191         mask = ~PCI_BASE_ADDRESS_IO_MASK;
0192     else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64))
0193         mask = 0;
0194     else
0195         mask = ~PCI_BASE_ADDRESS_MEM_MASK;
0196     if ((value | mask) == ~0U)
0197         bar->which = 1;
0198     else {
0199         u32 tmpval;
0200         pci_read_config_dword(dev, offset, &tmpval);
0201         if (tmpval != bar->val && value == bar->val) {
0202             /* Allow restoration of bar value. */
0203             pci_write_config_dword(dev, offset, bar->val);
0204         }
0205         bar->which = 0;
0206     }
0207 
0208     return 0;
0209 }
0210 
0211 static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)
0212 {
0213     struct pci_bar_info *bar = data;
0214 
0215     if (unlikely(!bar)) {
0216         dev_warn(&dev->dev, "driver data not found\n");
0217         return XEN_PCI_ERR_op_failed;
0218     }
0219 
0220     *value = bar->which ? bar->len_val : bar->val;
0221 
0222     return 0;
0223 }
0224 
0225 static void *bar_init(struct pci_dev *dev, int offset)
0226 {
0227     unsigned int pos;
0228     const struct resource *res = dev->resource;
0229     struct pci_bar_info *bar = kzalloc(sizeof(*bar), GFP_KERNEL);
0230 
0231     if (!bar)
0232         return ERR_PTR(-ENOMEM);
0233 
0234     if (offset == PCI_ROM_ADDRESS || offset == PCI_ROM_ADDRESS1)
0235         pos = PCI_ROM_RESOURCE;
0236     else {
0237         pos = (offset - PCI_BASE_ADDRESS_0) / 4;
0238         if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) {
0239             /*
0240              * Use ">> 16 >> 16" instead of direct ">> 32" shift
0241              * to avoid warnings on 32-bit architectures.
0242              */
0243             bar->val = res[pos - 1].start >> 16 >> 16;
0244             bar->len_val = -resource_size(&res[pos - 1]) >> 16 >> 16;
0245             return bar;
0246         }
0247     }
0248 
0249     if (!res[pos].flags ||
0250         (res[pos].flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET |
0251                    IORESOURCE_BUSY)))
0252         return bar;
0253 
0254     bar->val = res[pos].start |
0255            (res[pos].flags & PCI_REGION_FLAG_MASK);
0256     bar->len_val = -resource_size(&res[pos]) |
0257                (res[pos].flags & PCI_REGION_FLAG_MASK);
0258 
0259     return bar;
0260 }
0261 
0262 static void bar_reset(struct pci_dev *dev, int offset, void *data)
0263 {
0264     struct pci_bar_info *bar = data;
0265 
0266     bar->which = 0;
0267 }
0268 
0269 static void bar_release(struct pci_dev *dev, int offset, void *data)
0270 {
0271     kfree(data);
0272 }
0273 
0274 static int xen_pcibk_read_vendor(struct pci_dev *dev, int offset,
0275                    u16 *value, void *data)
0276 {
0277     *value = dev->vendor;
0278 
0279     return 0;
0280 }
0281 
0282 static int xen_pcibk_read_device(struct pci_dev *dev, int offset,
0283                    u16 *value, void *data)
0284 {
0285     *value = dev->device;
0286 
0287     return 0;
0288 }
0289 
0290 static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,
0291               void *data)
0292 {
0293     *value = (u8) dev->irq;
0294 
0295     return 0;
0296 }
0297 
0298 static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)
0299 {
0300     u8 cur_value;
0301     int err;
0302 
0303     err = pci_read_config_byte(dev, offset, &cur_value);
0304     if (err)
0305         goto out;
0306 
0307     if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)
0308         || value == PCI_BIST_START)
0309         err = pci_write_config_byte(dev, offset, value);
0310 
0311 out:
0312     return err;
0313 }
0314 
0315 static const struct config_field header_common[] = {
0316     {
0317      .offset    = PCI_VENDOR_ID,
0318      .size      = 2,
0319      .u.w.read  = xen_pcibk_read_vendor,
0320     },
0321     {
0322      .offset    = PCI_DEVICE_ID,
0323      .size      = 2,
0324      .u.w.read  = xen_pcibk_read_device,
0325     },
0326     {
0327      .offset    = PCI_COMMAND,
0328      .size      = 2,
0329      .init      = command_init,
0330      .release   = bar_release,
0331      .u.w.read  = command_read,
0332      .u.w.write = command_write,
0333     },
0334     {
0335      .offset    = PCI_INTERRUPT_LINE,
0336      .size      = 1,
0337      .u.b.read  = interrupt_read,
0338     },
0339     {
0340      .offset    = PCI_INTERRUPT_PIN,
0341      .size      = 1,
0342      .u.b.read  = xen_pcibk_read_config_byte,
0343     },
0344     {
0345      /* Any side effects of letting driver domain control cache line? */
0346      .offset    = PCI_CACHE_LINE_SIZE,
0347      .size      = 1,
0348      .u.b.read  = xen_pcibk_read_config_byte,
0349      .u.b.write = xen_pcibk_write_config_byte,
0350     },
0351     {
0352      .offset    = PCI_LATENCY_TIMER,
0353      .size      = 1,
0354      .u.b.read  = xen_pcibk_read_config_byte,
0355     },
0356     {
0357      .offset    = PCI_BIST,
0358      .size      = 1,
0359      .u.b.read  = xen_pcibk_read_config_byte,
0360      .u.b.write = bist_write,
0361     },
0362     {}
0363 };
0364 
0365 #define CFG_FIELD_BAR(reg_offset)           \
0366     {                       \
0367     .offset     = reg_offset,           \
0368     .size       = 4,                \
0369     .init       = bar_init,             \
0370     .reset      = bar_reset,            \
0371     .release    = bar_release,          \
0372     .u.dw.read  = bar_read,             \
0373     .u.dw.write = bar_write,            \
0374     }
0375 
0376 #define CFG_FIELD_ROM(reg_offset)           \
0377     {                       \
0378     .offset     = reg_offset,           \
0379     .size       = 4,                \
0380     .init       = bar_init,             \
0381     .reset      = bar_reset,            \
0382     .release    = bar_release,          \
0383     .u.dw.read  = bar_read,             \
0384     .u.dw.write = rom_write,            \
0385     }
0386 
0387 static const struct config_field header_0[] = {
0388     CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
0389     CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
0390     CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),
0391     CFG_FIELD_BAR(PCI_BASE_ADDRESS_3),
0392     CFG_FIELD_BAR(PCI_BASE_ADDRESS_4),
0393     CFG_FIELD_BAR(PCI_BASE_ADDRESS_5),
0394     CFG_FIELD_ROM(PCI_ROM_ADDRESS),
0395     {}
0396 };
0397 
0398 static const struct config_field header_1[] = {
0399     CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),
0400     CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),
0401     CFG_FIELD_ROM(PCI_ROM_ADDRESS1),
0402     {}
0403 };
0404 
0405 int xen_pcibk_config_header_add_fields(struct pci_dev *dev)
0406 {
0407     int err;
0408 
0409     err = xen_pcibk_config_add_fields(dev, header_common);
0410     if (err)
0411         goto out;
0412 
0413     switch (dev->hdr_type) {
0414     case PCI_HEADER_TYPE_NORMAL:
0415         err = xen_pcibk_config_add_fields(dev, header_0);
0416         break;
0417 
0418     case PCI_HEADER_TYPE_BRIDGE:
0419         err = xen_pcibk_config_add_fields(dev, header_1);
0420         break;
0421 
0422     default:
0423         err = -EINVAL;
0424         dev_err(&dev->dev, "Unsupported header type %d!\n",
0425             dev->hdr_type);
0426         break;
0427     }
0428 
0429 out:
0430     return err;
0431 }