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 ((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 bytes 138 */ 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 or 157 * the correct resource information 158 * (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 bytes 174 */ 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 else 180 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 bar->val = res[pos - 1].start >> 32; 225 bar->len_val = -resource_size(&res[pos - 1]) >> 32; 226 return bar; 227 } 228 } 229 230 if (!res[pos].flags || 231 (res[pos].flags & (IORESOURCE_DISABLED | IORESOURCE_UNSET | 232 IORESOURCE_BUSY))) 233 return bar; 234 235 bar->val = res[pos].start | 236 (res[pos].flags & PCI_REGION_FLAG_MASK); 237 bar->len_val = -resource_size(&res[pos]) | 238 (res[pos].flags & PCI_REGION_FLAG_MASK); 239 240 return bar; 241} 242 243static void bar_reset(struct pci_dev *dev, int offset, void *data) 244{ 245 struct pci_bar_info *bar = data; 246 247 bar->which = 0; 248} 249 250static void bar_release(struct pci_dev *dev, int offset, void *data) 251{ 252 kfree(data); 253} 254 255static int xen_pcibk_read_vendor(struct pci_dev *dev, int offset, 256 u16 *value, void *data) 257{ 258 *value = dev->vendor; 259 260 return 0; 261} 262 263static int xen_pcibk_read_device(struct pci_dev *dev, int offset, 264 u16 *value, void *data) 265{ 266 *value = dev->device; 267 268 return 0; 269} 270 271static int interrupt_read(struct pci_dev *dev, int offset, u8 * value, 272 void *data) 273{ 274 *value = (u8) dev->irq; 275 276 return 0; 277} 278 279static int bist_write(struct pci_dev *dev, int offset, u8 value, void *data) 280{ 281 u8 cur_value; 282 int err; 283 284 err = pci_read_config_byte(dev, offset, &cur_value); 285 if (err) 286 goto out; 287 288 if ((cur_value & ~PCI_BIST_START) == (value & ~PCI_BIST_START) 289 || value == PCI_BIST_START) 290 err = pci_write_config_byte(dev, offset, value); 291 292out: 293 return err; 294} 295 296static const struct config_field header_common[] = { 297 { 298 .offset = PCI_VENDOR_ID, 299 .size = 2, 300 .u.w.read = xen_pcibk_read_vendor, 301 }, 302 { 303 .offset = PCI_DEVICE_ID, 304 .size = 2, 305 .u.w.read = xen_pcibk_read_device, 306 }, 307 { 308 .offset = PCI_COMMAND, 309 .size = 2, 310 .init = command_init, 311 .release = bar_release, 312 .u.w.read = command_read, 313 .u.w.write = command_write, 314 }, 315 { 316 .offset = PCI_INTERRUPT_LINE, 317 .size = 1, 318 .u.b.read = interrupt_read, 319 }, 320 { 321 .offset = PCI_INTERRUPT_PIN, 322 .size = 1, 323 .u.b.read = xen_pcibk_read_config_byte, 324 }, 325 { 326 /* Any side effects of letting driver domain control cache line? */ 327 .offset = PCI_CACHE_LINE_SIZE, 328 .size = 1, 329 .u.b.read = xen_pcibk_read_config_byte, 330 .u.b.write = xen_pcibk_write_config_byte, 331 }, 332 { 333 .offset = PCI_LATENCY_TIMER, 334 .size = 1, 335 .u.b.read = xen_pcibk_read_config_byte, 336 }, 337 { 338 .offset = PCI_BIST, 339 .size = 1, 340 .u.b.read = xen_pcibk_read_config_byte, 341 .u.b.write = bist_write, 342 }, 343 {} 344}; 345 346#define CFG_FIELD_BAR(reg_offset) \ 347 { \ 348 .offset = reg_offset, \ 349 .size = 4, \ 350 .init = bar_init, \ 351 .reset = bar_reset, \ 352 .release = bar_release, \ 353 .u.dw.read = bar_read, \ 354 .u.dw.write = bar_write, \ 355 } 356 357#define CFG_FIELD_ROM(reg_offset) \ 358 { \ 359 .offset = reg_offset, \ 360 .size = 4, \ 361 .init = bar_init, \ 362 .reset = bar_reset, \ 363 .release = bar_release, \ 364 .u.dw.read = bar_read, \ 365 .u.dw.write = rom_write, \ 366 } 367 368static const struct config_field header_0[] = { 369 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0), 370 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1), 371 CFG_FIELD_BAR(PCI_BASE_ADDRESS_2), 372 CFG_FIELD_BAR(PCI_BASE_ADDRESS_3), 373 CFG_FIELD_BAR(PCI_BASE_ADDRESS_4), 374 CFG_FIELD_BAR(PCI_BASE_ADDRESS_5), 375 CFG_FIELD_ROM(PCI_ROM_ADDRESS), 376 {} 377}; 378 379static const struct config_field header_1[] = { 380 CFG_FIELD_BAR(PCI_BASE_ADDRESS_0), 381 CFG_FIELD_BAR(PCI_BASE_ADDRESS_1), 382 CFG_FIELD_ROM(PCI_ROM_ADDRESS1), 383 {} 384}; 385 386int xen_pcibk_config_header_add_fields(struct pci_dev *dev) 387{ 388 int err; 389 390 err = xen_pcibk_config_add_fields(dev, header_common); 391 if (err) 392 goto out; 393 394 switch (dev->hdr_type) { 395 case PCI_HEADER_TYPE_NORMAL: 396 err = xen_pcibk_config_add_fields(dev, header_0); 397 break; 398 399 case PCI_HEADER_TYPE_BRIDGE: 400 err = xen_pcibk_config_add_fields(dev, header_1); 401 break; 402 403 default: 404 err = -EINVAL; 405 dev_err(&dev->dev, "Unsupported header type %d!\n", 406 dev->hdr_type); 407 break; 408 } 409 410out: 411 return err; 412} 413