aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 17:48:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 17:48:30 -0500
commit515d01f7726b9ba4838787d247115e1b259e1cc7 (patch)
treed791be958b963215eefe96b33498269879932191
parent1cef9350cbee6e3bcf2ff646b8978fbec33f8b85 (diff)
parentd65530fbc799e4036d4d3da4ab6e9fa6d8c4a447 (diff)
Merge tag 'vfio-v3.9-rc1' of git://github.com/awilliam/linux-vfio
Pull VFIO updates from Alex Williamson: - Fixes PCIe v1 extended capability support - Cleans up read/write access functions - Fix Removal test to properly wait until devices are unused - Enable pcieport driver usage for non-accessible devices w/in groups - Extensions for PCI VGA support * tag 'vfio-v3.9-rc1' of git://github.com/awilliam/linux-vfio: drivers/vfio: remove depends on CONFIG_EXPERIMENTAL vfio-pci: Add support for VGA region access vfio-pci: Manage user power state transitions vfio: whitelist pcieport vfio: Protect vfio_dev_present against device_del vfio-pci: Cleanup BAR access vfio-pci: Cleanup read/write functions vfio-pci: Enable PCIe extended capabilities on v1
-rw-r--r--drivers/vfio/pci/Kconfig10
-rw-r--r--drivers/vfio/pci/vfio_pci.c75
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c52
-rw-r--r--drivers/vfio/pci/vfio_pci_private.h19
-rw-r--r--drivers/vfio/pci/vfio_pci_rdwr.c281
-rw-r--r--drivers/vfio/vfio.c35
-rw-r--r--include/uapi/linux/vfio.h9
7 files changed, 254 insertions, 227 deletions
diff --git a/drivers/vfio/pci/Kconfig b/drivers/vfio/pci/Kconfig
index 5980758563eb..c41b01e2b693 100644
--- a/drivers/vfio/pci/Kconfig
+++ b/drivers/vfio/pci/Kconfig
@@ -6,3 +6,13 @@ config VFIO_PCI
6 use of PCI drivers using the VFIO framework. 6 use of PCI drivers using the VFIO framework.
7 7
8 If you don't know what to do here, say N. 8 If you don't know what to do here, say N.
9
10config VFIO_PCI_VGA
11 bool "VFIO PCI support for VGA devices"
12 depends on VFIO_PCI && X86 && VGA_ARB
13 help
14 Support for VGA extension to VFIO PCI. This exposes an additional
15 region on VGA devices for accessing legacy VGA addresses used by
16 BIOS and generic video drivers.
17
18 If you don't know what to do here, say N.
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index b28e66c4376a..8189cb6a86af 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -84,6 +84,11 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
84 } else 84 } else
85 vdev->msix_bar = 0xFF; 85 vdev->msix_bar = 0xFF;
86 86
87#ifdef CONFIG_VFIO_PCI_VGA
88 if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
89 vdev->has_vga = true;
90#endif
91
87 return 0; 92 return 0;
88} 93}
89 94
@@ -285,6 +290,16 @@ static long vfio_pci_ioctl(void *device_data,
285 info.flags = VFIO_REGION_INFO_FLAG_READ; 290 info.flags = VFIO_REGION_INFO_FLAG_READ;
286 break; 291 break;
287 } 292 }
293 case VFIO_PCI_VGA_REGION_INDEX:
294 if (!vdev->has_vga)
295 return -EINVAL;
296
297 info.offset = VFIO_PCI_INDEX_TO_OFFSET(info.index);
298 info.size = 0xc0000;
299 info.flags = VFIO_REGION_INFO_FLAG_READ |
300 VFIO_REGION_INFO_FLAG_WRITE;
301
302 break;
288 default: 303 default:
289 return -EINVAL; 304 return -EINVAL;
290 } 305 }
@@ -366,52 +381,50 @@ static long vfio_pci_ioctl(void *device_data,
366 return -ENOTTY; 381 return -ENOTTY;
367} 382}
368 383
369static ssize_t vfio_pci_read(void *device_data, char __user *buf, 384static ssize_t vfio_pci_rw(void *device_data, char __user *buf,
370 size_t count, loff_t *ppos) 385 size_t count, loff_t *ppos, bool iswrite)
371{ 386{
372 unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos); 387 unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
373 struct vfio_pci_device *vdev = device_data; 388 struct vfio_pci_device *vdev = device_data;
374 struct pci_dev *pdev = vdev->pdev;
375 389
376 if (index >= VFIO_PCI_NUM_REGIONS) 390 if (index >= VFIO_PCI_NUM_REGIONS)
377 return -EINVAL; 391 return -EINVAL;
378 392
379 if (index == VFIO_PCI_CONFIG_REGION_INDEX) 393 switch (index) {
380 return vfio_pci_config_readwrite(vdev, buf, count, ppos, false); 394 case VFIO_PCI_CONFIG_REGION_INDEX:
381 else if (index == VFIO_PCI_ROM_REGION_INDEX) 395 return vfio_pci_config_rw(vdev, buf, count, ppos, iswrite);
382 return vfio_pci_mem_readwrite(vdev, buf, count, ppos, false); 396
383 else if (pci_resource_flags(pdev, index) & IORESOURCE_IO) 397 case VFIO_PCI_ROM_REGION_INDEX:
384 return vfio_pci_io_readwrite(vdev, buf, count, ppos, false); 398 if (iswrite)
385 else if (pci_resource_flags(pdev, index) & IORESOURCE_MEM) 399 return -EINVAL;
386 return vfio_pci_mem_readwrite(vdev, buf, count, ppos, false); 400 return vfio_pci_bar_rw(vdev, buf, count, ppos, false);
401
402 case VFIO_PCI_BAR0_REGION_INDEX ... VFIO_PCI_BAR5_REGION_INDEX:
403 return vfio_pci_bar_rw(vdev, buf, count, ppos, iswrite);
404
405 case VFIO_PCI_VGA_REGION_INDEX:
406 return vfio_pci_vga_rw(vdev, buf, count, ppos, iswrite);
407 }
387 408
388 return -EINVAL; 409 return -EINVAL;
389} 410}
390 411
391static ssize_t vfio_pci_write(void *device_data, const char __user *buf, 412static ssize_t vfio_pci_read(void *device_data, char __user *buf,
392 size_t count, loff_t *ppos) 413 size_t count, loff_t *ppos)
393{ 414{
394 unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos); 415 if (!count)
395 struct vfio_pci_device *vdev = device_data; 416 return 0;
396 struct pci_dev *pdev = vdev->pdev;
397 417
398 if (index >= VFIO_PCI_NUM_REGIONS) 418 return vfio_pci_rw(device_data, buf, count, ppos, false);
399 return -EINVAL; 419}
400 420
401 if (index == VFIO_PCI_CONFIG_REGION_INDEX) 421static ssize_t vfio_pci_write(void *device_data, const char __user *buf,
402 return vfio_pci_config_readwrite(vdev, (char __user *)buf, 422 size_t count, loff_t *ppos)
403 count, ppos, true); 423{
404 else if (index == VFIO_PCI_ROM_REGION_INDEX) 424 if (!count)
405 return -EINVAL; 425 return 0;
406 else if (pci_resource_flags(pdev, index) & IORESOURCE_IO)
407 return vfio_pci_io_readwrite(vdev, (char __user *)buf,
408 count, ppos, true);
409 else if (pci_resource_flags(pdev, index) & IORESOURCE_MEM) {
410 return vfio_pci_mem_readwrite(vdev, (char __user *)buf,
411 count, ppos, true);
412 }
413 426
414 return -EINVAL; 427 return vfio_pci_rw(device_data, (char __user *)buf, count, ppos, true);
415} 428}
416 429
417static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma) 430static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 8b8f7d11e102..964ff22bf281 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -587,12 +587,46 @@ static int __init init_pci_cap_basic_perm(struct perm_bits *perm)
587 return 0; 587 return 0;
588} 588}
589 589
590static int vfio_pm_config_write(struct vfio_pci_device *vdev, int pos,
591 int count, struct perm_bits *perm,
592 int offset, __le32 val)
593{
594 count = vfio_default_config_write(vdev, pos, count, perm, offset, val);
595 if (count < 0)
596 return count;
597
598 if (offset == PCI_PM_CTRL) {
599 pci_power_t state;
600
601 switch (le32_to_cpu(val) & PCI_PM_CTRL_STATE_MASK) {
602 case 0:
603 state = PCI_D0;
604 break;
605 case 1:
606 state = PCI_D1;
607 break;
608 case 2:
609 state = PCI_D2;
610 break;
611 case 3:
612 state = PCI_D3hot;
613 break;
614 }
615
616 pci_set_power_state(vdev->pdev, state);
617 }
618
619 return count;
620}
621
590/* Permissions for the Power Management capability */ 622/* Permissions for the Power Management capability */
591static int __init init_pci_cap_pm_perm(struct perm_bits *perm) 623static int __init init_pci_cap_pm_perm(struct perm_bits *perm)