aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/assigned-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/assigned-dev.c')
-rw-r--r--virt/kvm/assigned-dev.c93
1 files changed, 84 insertions, 9 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index 3ad0925d23a9..758e3b36d4cf 100644
--- a/virt/kvm/assigned-dev.c
+++ b/virt/kvm/assigned-dev.c
@@ -17,6 +17,8 @@
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/namei.h>
21#include <linux/fs.h>
20#include "irq.h" 22#include "irq.h"
21 23
22static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head, 24static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
@@ -480,12 +482,76 @@ out:
480 return r; 482 return r;
481} 483}
482 484
485/*
486 * We want to test whether the caller has been granted permissions to
487 * use this device. To be able to configure and control the device,
488 * the user needs access to PCI configuration space and BAR resources.
489 * These are accessed through PCI sysfs. PCI config space is often
490 * passed to the process calling this ioctl via file descriptor, so we
491 * can't rely on access to that file. We can check for permissions
492 * on each of the BAR resource files, which is a pretty clear
493 * indicator that the user has been granted access to the device.
494 */
495static int probe_sysfs_permissions(struct pci_dev *dev)
496{
497#ifdef CONFIG_SYSFS
498 int i;
499 bool bar_found = false;
500
501 for (i = PCI_STD_RESOURCES; i <= PCI_STD_RESOURCE_END; i++) {
502 char *kpath, *syspath;
503 struct path path;
504 struct inode *inode;
505 int r;
506
507 if (!pci_resource_len(dev, i))
508 continue;
509
510 kpath = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
511 if (!kpath)
512 return -ENOMEM;
513
514 /* Per sysfs-rules, sysfs is always at /sys */
515 syspath = kasprintf(GFP_KERNEL, "/sys%s/resource%d", kpath, i);
516 kfree(kpath);
517 if (!syspath)
518 return -ENOMEM;
519
520 r = kern_path(syspath, LOOKUP_FOLLOW, &path);
521 kfree(syspath);
522 if (r)
523 return r;
524
525 inode = path.dentry->d_inode;
526
527 r = inode_permission(inode, MAY_READ | MAY_WRITE | MAY_ACCESS);
528 path_put(&path);
529 if (r)
530 return r;
531
532 bar_found = true;
533 }
534
535 /* If no resources, probably something special */
536 if (!bar_found)
537 return -EPERM;
538
539 return 0;
540#else
541 return -EINVAL; /* No way to control the device without sysfs */
542#endif
543}
544
483static int kvm_vm_ioctl_assign_device(struct kvm *kvm, 545static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
484 struct kvm_assigned_pci_dev *assigned_dev) 546 struct kvm_assigned_pci_dev *assigned_dev)
485{ 547{
486 int r = 0, idx; 548 int r = 0, idx;
487 struct kvm_assigned_dev_kernel *match; 549 struct kvm_assigned_dev_kernel *match;
488 struct pci_dev *dev; 550 struct pci_dev *dev;
551 u8 header_type;
552
553 if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU))
554 return -EINVAL;
489 555
490 mutex_lock(&kvm->lock); 556 mutex_lock(&kvm->lock);
491 idx = srcu_read_lock(&kvm->srcu); 557 idx = srcu_read_lock(&kvm->srcu);
@@ -513,6 +579,18 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
513 r = -EINVAL; 579 r = -EINVAL;
514 goto out_free; 580 goto out_free;
515 } 581 }
582
583 /* Don't allow bridges to be assigned */
584 pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
585 if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) {
586 r = -EPERM;
587 goto out_put;
588 }
589
590 r = probe_sysfs_permissions(dev);
591 if (r)
592 goto out_put;
593
516 if (pci_enable_device(dev)) { 594 if (pci_enable_device(dev)) {
517 printk(KERN_INFO "%s: Could not enable PCI device\n", __func__); 595 printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
518 r = -EBUSY; 596 r = -EBUSY;
@@ -544,16 +622,14 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
544 622
545 list_add(&match->list, &kvm->arch.assigned_dev_head); 623 list_add(&match->list, &kvm->arch.assigned_dev_head);
546 624
547 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { 625 if (!kvm->arch.iommu_domain) {
548 if (!kvm->arch.iommu_domain) { 626 r = kvm_iommu_map_guest(kvm);
549 r = kvm_iommu_map_guest(kvm);
550 if (r)
551 goto out_list_del;
552 }
553 r = kvm_assign_device(kvm, match);
554 if (r) 627 if (r)
555 goto out_list_del; 628 goto out_list_del;
556 } 629 }
630 r = kvm_assign_device(kvm, match);
631 if (r)
632 goto out_list_del;
557 633
558out: 634out:
559 srcu_read_unlock(&kvm->srcu, idx); 635 srcu_read_unlock(&kvm->srcu, idx);
@@ -593,8 +669,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
593 goto out; 669 goto out;
594 } 670 }
595 671
596 if (match->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) 672 kvm_deassign_device(kvm, match);
597 kvm_deassign_device(kvm, match);
598 673
599 kvm_free_assigned_device(kvm, match); 674 kvm_free_assigned_device(kvm, match);
600 675