417 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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 ": " fmt9#define dev_fmt pr_fmt10 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 ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE))109 pci_intx(dev, !(value & PCI_COMMAND_INTX_DISABLE));110 111 cmd->val = value;112 113 if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))114 return 0;115 116 /* Only allow the guest to control certain bits. */117 err = pci_read_config_word(dev, offset, &val);118 if (err || val == value)119 return err;120 121 value &= PCI_COMMAND_GUEST;122 value |= val & ~PCI_COMMAND_GUEST;123 124 return pci_write_config_word(dev, offset, value);125}126 127static int rom_write(struct pci_dev *dev, int offset, u32 value, void *data)128{129 struct pci_bar_info *bar = data;130 131 if (unlikely(!bar)) {132 dev_warn(&dev->dev, "driver data not found\n");133 return XEN_PCI_ERR_op_failed;134 }135 136 /* A write to obtain the length must happen as a 32-bit write.137 * This does not (yet) support writing individual bytes138 */139 if ((value | ~PCI_ROM_ADDRESS_MASK) == ~0U)140 bar->which = 1;141 else {142 u32 tmpval;143 pci_read_config_dword(dev, offset, &tmpval);144 if (tmpval != bar->val && value == bar->val) {145 /* Allow restoration of bar value. */146 pci_write_config_dword(dev, offset, bar->val);147 }148 bar->which = 0;149 }150 151 /* Do we need to support enabling/disabling the rom address here? */152 153 return 0;154}155 156/* For the BARs, only allow writes which write ~0 or157 * the correct resource information158 * (Needed for when the driver probes the resource usage)159 */160static int bar_write(struct pci_dev *dev, int offset, u32 value, void *data)161{162 struct pci_bar_info *bar = data;163 unsigned int pos = (offset - PCI_BASE_ADDRESS_0) / 4;164 const struct resource *res = dev->resource;165 u32 mask;166 167 if (unlikely(!bar)) {168 dev_warn(&dev->dev, "driver data not found\n");169 return XEN_PCI_ERR_op_failed;170 }171 172 /* A write to obtain the length must happen as a 32-bit write.173 * This does not (yet) support writing individual bytes174 */175 if (res[pos].flags & IORESOURCE_IO)176 mask = ~PCI_BASE_ADDRESS_IO_MASK;177 else if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64))178 mask = 0;179 else180 mask = ~PCI_BASE_ADDRESS_MEM_MASK;181 if ((value | mask) == ~0U)182 bar->which = 1;183 else {184 u32 tmpval;185 pci_read_config_dword(dev, offset, &tmpval);186 if (tmpval != bar->val && value == bar->val) {187 /* Allow restoration of bar value. */188 pci_write_config_dword(dev, offset, bar->val);189 }190 bar->which = 0;191 }192 193 return 0;194}195 196static int bar_read(struct pci_dev *dev, int offset, u32 * value, void *data)197{198 struct pci_bar_info *bar = data;199 200 if (unlikely(!bar)) {201 dev_warn(&dev->dev, "driver data not found\n");202 return XEN_PCI_ERR_op_failed;203 }204 205 *value = bar->which ? bar->len_val : bar->val;206 207 return 0;208}209 210static void *bar_init(struct pci_dev *dev, int offset)211{212 unsigned int pos;213 const struct resource *res = dev->resource;214 struct pci_bar_info *bar = kzalloc(sizeof(*bar), GFP_KERNEL);215 216 if (!bar)217 return ERR_PTR(-ENOMEM);218 219 if (offset == PCI_ROM_ADDRESS || offset == PCI_ROM_ADDRESS1)220 pos = PCI_ROM_RESOURCE;221 else {222 pos = (offset - PCI_BASE_ADDRESS_0) / 4;223 if (pos && (res[pos - 1].flags & IORESOURCE_MEM_64)) {224 /*225 * Use ">> 16 >> 16" instead of direct ">> 32" shift226 * to avoid warnings on 32-bit architectures.227 */228 bar->val = res[pos - 1].start >> 16 >> 16;229 bar->len_val = -resource_size(&res[pos - 1]) >> 16 >> 16;230 return bar;231 }232 }233 234 if (!res[pos].flags ||235 (res[pos].flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET |236 IORESOURCE_BUSY)))237 return bar;238 239 bar->val = res[pos].start |240 (res[pos].flags & PCI_REGION_FLAG_MASK);241 bar->len_val = -resource_size(&res[pos]) |242 (res[pos].flags & PCI_REGION_FLAG_MASK);243 244 return bar;245}246 247static void bar_reset(struct pci_dev *dev, int offset, void *data)248{249 struct pci_bar_info *bar = data;250 251 bar->which = 0;252}253 254static void bar_release(struct pci_dev *dev, int offset, void *data)255{256 kfree(data);257}258 259static int xen_pcibk_read_vendor(struct pci_dev *dev, int offset,260 u16 *value, void *data)261{262 *value = dev->vendor;263 264 return 0;265}266 267static int xen_pcibk_read_device(struct pci_dev *dev, int offset,268 u16 *value, void *data)269{270 *value = dev->device;271 272 return 0;273}274 275static int interrupt_read(struct pci_dev *dev, int offset, u8 * value,276 void *data)277{278 *value = (u8) dev->irq;279 280 return 0;281}282 283static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data)284{285 u8 cur_value;286 int err;287 288 err = pci_read_config_byte(dev, offset, &cur_value);289 if (err)290 goto out;291 292 if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START)293 || value == PCI_BIST_START)294 err = pci_write_config_byte(dev, offset, value);295 296out:297 return err;298}299 300static const struct config_field header_common[] = {301 {302 .offset = PCI_VENDOR_ID,303 .size = 2,304 .u.w.read = xen_pcibk_read_vendor,305 },306 {307 .offset = PCI_DEVICE_ID,308 .size = 2,309 .u.w.read = xen_pcibk_read_device,310 },311 {312 .offset = PCI_COMMAND,313 .size = 2,314 .init = command_init,315 .release = bar_release,316 .u.w.read = command_read,317 .u.w.write = command_write,318 },319 {320 .offset = PCI_INTERRUPT_LINE,321 .size = 1,322 .u.b.read = interrupt_read,323 },324 {325 .offset = PCI_INTERRUPT_PIN,326 .size = 1,327 .u.b.read = xen_pcibk_read_config_byte,328 },329 {330 /* Any side effects of letting driver domain control cache line? */331 .offset = PCI_CACHE_LINE_SIZE,332 .size = 1,333 .u.b.read = xen_pcibk_read_config_byte,334 .u.b.write = xen_pcibk_write_config_byte,335 },336 {337 .offset = PCI_LATENCY_TIMER,338 .size = 1,339 .u.b.read = xen_pcibk_read_config_byte,340 },341 {342 .offset = PCI_BIST,343 .size = 1,344 .u.b.read = xen_pcibk_read_config_byte,345 .u.b.write = bist_write,346 },347 {}348};349 350#define CFG_FIELD_BAR(reg_offset) \351 { \352 .offset = reg_offset, \353 .size = 4, \354 .init = bar_init, \355 .reset = bar_reset, \356 .release = bar_release, \357 .u.dw.read = bar_read, \358 .u.dw.write = bar_write, \359 }360 361#define CFG_FIELD_ROM(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 = rom_write, \370 }371 372static const struct config_field header_0[] = {373 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),374 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),375 CFG_FIELD_BAR(PCI_BASE_ADDRESS_2),376 CFG_FIELD_BAR(PCI_BASE_ADDRESS_3),377 CFG_FIELD_BAR(PCI_BASE_ADDRESS_4),378 CFG_FIELD_BAR(PCI_BASE_ADDRESS_5),379 CFG_FIELD_ROM(PCI_ROM_ADDRESS),380 {}381};382 383static const struct config_field header_1[] = {384 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0),385 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1),386 CFG_FIELD_ROM(PCI_ROM_ADDRESS1),387 {}388};389 390int xen_pcibk_config_header_add_fields(struct pci_dev *dev)391{392 int err;393 394 err = xen_pcibk_config_add_fields(dev, header_common);395 if (err)396 goto out;397 398 switch (dev->hdr_type) {399 case PCI_HEADER_TYPE_NORMAL:400 err = xen_pcibk_config_add_fields(dev, header_0);401 break;402 403 case PCI_HEADER_TYPE_BRIDGE:404 err = xen_pcibk_config_add_fields(dev, header_1);405 break;406 407 default:408 err = -EINVAL;409 dev_err(&dev->dev, "Unsupported header type %d!\n",410 dev->hdr_type);411 break;412 }413 414out:415 return err;416}417