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.c95
1 files changed, 85 insertions, 10 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c
index 6cc4b97ec45..af7910228fb 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,
@@ -474,12 +476,76 @@ out:
474 return r; 476 return r;
475} 477}
476 478
479/*
480 * We want to test whether the caller has been granted permissions to
481 * use this device. To be able to configure and control the device,
482 * the user needs access to PCI configuration space and BAR resources.
483 * These are accessed through PCI sysfs. PCI config space is often
484 * passed to the process calling this ioctl via file descriptor, so we
485 * can't rely on access to that file. We can check for permissions
486 * on each of the BAR resource files, which is a pretty clear
487 * indicator that the user has been granted access to the device.
488 */
489static int probe_sysfs_permissions(struct pci_dev *dev)
490{
491#ifdef CONFIG_SYSFS
492 int i;
493 bool bar_found = false;
494
495 for (i = PCI_STD_RESOURCES; i <= PCI_STD_RESOURCE_END; i++) {
496 char *kpath, *syspath;
497 struct path path;
498 struct inode *inode;
499 int r;
500
501 if (!pci_resource_len(dev, i))
502 continue;
503
504 kpath = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
505 if (!kpath)
506 return -ENOMEM;
507
508 /* Per sysfs-rules, sysfs is always at /sys */
509 syspath = kasprintf(GFP_KERNEL, "/sys%s/resource%d", kpath, i);
510 kfree(kpath);
511 if (!syspath)
512 return -ENOMEM;
513
514 r = kern_path(syspath, LOOKUP_FOLLOW, &path);
515 kfree(syspath);
516 if (r)
517 return r;
518
519 inode = path.dentry->d_inode;
520
521 r = inode_permission(inode, MAY_READ | MAY_WRITE | MAY_ACCESS);
522 path_put(&path);
523 if (r)
524 return r;
525
526 bar_found = true;
527 }
528
529 /* If no resources, probably something special */
530 if (!bar_found)
531 return -EPERM;
532
533 return 0;
534#else
535 return -EINVAL; /* No way to control the device without sysfs */
536#endif
537}
538
477static int kvm_vm_ioctl_assign_device(struct kvm *kvm, 539static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
478 struct kvm_assigned_pci_dev *assigned_dev) 540 struct kvm_assigned_pci_dev *assigned_dev)
479{ 541{
480 int r = 0, idx; 542 int r = 0, idx;
481 struct kvm_assigned_dev_kernel *match; 543 struct kvm_assigned_dev_kernel *match;
482 struct pci_dev *dev; 544 struct pci_dev *dev;
545 u8 header_type;
546
547 if (!(assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU))
548 return -EINVAL;
483 549
484 mutex_lock(&kvm->lock); 550 mutex_lock(&kvm->lock);
485 idx = srcu_read_lock(&kvm->srcu); 551 idx = srcu_read_lock(&kvm->srcu);
@@ -507,6 +573,18 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
507 r = -EINVAL; 573 r = -EINVAL;
508 goto out_free; 574 goto out_free;
509 } 575 }
576
577 /* Don't allow bridges to be assigned */
578 pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type);
579 if ((header_type & PCI_HEADER_TYPE) != PCI_HEADER_TYPE_NORMAL) {
580 r = -EPERM;
581 goto out_put;
582 }
583
584 r = probe_sysfs_permissions(dev);
585 if (r)
586 goto out_put;
587
510 if (pci_enable_device(dev)) { 588 if (pci_enable_device(dev)) {
511 printk(KERN_INFO "%s: Could not enable PCI device\n", __func__); 589 printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
512 r = -EBUSY; 590 r = -EBUSY;
@@ -538,16 +616,14 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
538 616
539 list_add(&match->list, &kvm->arch.assigned_dev_head); 617 list_add(&match->list, &kvm->arch.assigned_dev_head);
540 618
541 if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) { 619 if (!kvm->arch.iommu_domain) {
542 if (!kvm->arch.iommu_domain) { 620 r = kvm_iommu_map_guest(kvm);
543 r = kvm_iommu_map_guest(kvm);
544 if (r)
545 goto out_list_del;
546 }
547 r = kvm_assign_device(kvm, match);
548 if (r) 621 if (r)
549 goto out_list_del; 622 goto out_list_del;
550 } 623 }
624 r = kvm_assign_device(kvm, match);
625 if (r)
626 goto out_list_del;
551 627
552out: 628out:
553 srcu_read_unlock(&kvm->srcu, idx); 629 srcu_read_unlock(&kvm->srcu, idx);
@@ -587,8 +663,7 @@ static int kvm_vm_ioctl_deassign_device(struct kvm *kvm,
587 goto out; 663 goto out;
588 } 664 }
589 665
590 if (match->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) 666 kvm_deassign_device(kvm, match);
591 kvm_deassign_device(kvm, match);
592 667
593 kvm_free_assigned_device(kvm, match); 668 kvm_free_assigned_device(kvm, match);
594 669
@@ -617,7 +692,7 @@ static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm,
617 if (adev->entries_nr == 0) { 692 if (adev->entries_nr == 0) {
618 adev->entries_nr = entry_nr->entry_nr; 693 adev->entries_nr = entry_nr->entry_nr;
619 if (adev->entries_nr == 0 || 694 if (adev->entries_nr == 0 ||
620 adev->entries_nr >= KVM_MAX_MSIX_PER_DEV) { 695 adev->entries_nr > KVM_MAX_MSIX_PER_DEV) {
621 r = -EINVAL; 696 r = -EINVAL;
622 goto msix_nr_out; 697 goto msix_nr_out;
623 } 698 }