diff options
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/assigned-dev.c | 2 | ||||
-rw-r--r-- | virt/kvm/iommu.c | 18 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 110 |
3 files changed, 119 insertions, 11 deletions
diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 6cc4b97ec458..4e9eaeb518c7 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c | |||
@@ -617,7 +617,7 @@ static int kvm_vm_ioctl_set_msix_nr(struct kvm *kvm, | |||
617 | if (adev->entries_nr == 0) { | 617 | if (adev->entries_nr == 0) { |
618 | adev->entries_nr = entry_nr->entry_nr; | 618 | adev->entries_nr = entry_nr->entry_nr; |
619 | if (adev->entries_nr == 0 || | 619 | if (adev->entries_nr == 0 || |
620 | adev->entries_nr >= KVM_MAX_MSIX_PER_DEV) { | 620 | adev->entries_nr > KVM_MAX_MSIX_PER_DEV) { |
621 | r = -EINVAL; | 621 | r = -EINVAL; |
622 | goto msix_nr_out; | 622 | goto msix_nr_out; |
623 | } | 623 | } |
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c index 62a9caf0563c..78c80f67f535 100644 --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c | |||
@@ -30,6 +30,12 @@ | |||
30 | #include <linux/iommu.h> | 30 | #include <linux/iommu.h> |
31 | #include <linux/intel-iommu.h> | 31 | #include <linux/intel-iommu.h> |
32 | 32 | ||
33 | static int allow_unsafe_assigned_interrupts; | ||
34 | module_param_named(allow_unsafe_assigned_interrupts, | ||
35 | allow_unsafe_assigned_interrupts, bool, S_IRUGO | S_IWUSR); | ||
36 | MODULE_PARM_DESC(allow_unsafe_assigned_interrupts, | ||
37 | "Enable device assignment on platforms without interrupt remapping support."); | ||
38 | |||
33 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); | 39 | static int kvm_iommu_unmap_memslots(struct kvm *kvm); |
34 | static void kvm_iommu_put_pages(struct kvm *kvm, | 40 | static void kvm_iommu_put_pages(struct kvm *kvm, |
35 | gfn_t base_gfn, unsigned long npages); | 41 | gfn_t base_gfn, unsigned long npages); |
@@ -231,6 +237,18 @@ int kvm_iommu_map_guest(struct kvm *kvm) | |||
231 | if (!kvm->arch.iommu_domain) | 237 | if (!kvm->arch.iommu_domain) |
232 | return -ENOMEM; | 238 | return -ENOMEM; |
233 | 239 | ||
240 | if (!allow_unsafe_assigned_interrupts && | ||
241 | !iommu_domain_has_cap(kvm->arch.iommu_domain, | ||
242 | IOMMU_CAP_INTR_REMAP)) { | ||
243 | printk(KERN_WARNING "%s: No interrupt remapping support," | ||
244 | " disallowing device assignment." | ||
245 | " Re-enble with \"allow_unsafe_assigned_interrupts=1\"" | ||
246 | " module option.\n", __func__); | ||
247 | iommu_domain_free(kvm->arch.iommu_domain); | ||
248 | kvm->arch.iommu_domain = NULL; | ||
249 | return -EPERM; | ||
250 | } | ||
251 | |||
234 | r = kvm_iommu_map_memslots(kvm); | 252 | r = kvm_iommu_map_memslots(kvm); |
235 | if (r) | 253 | if (r) |
236 | goto out_unmap; | 254 | goto out_unmap; |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 96ebc0679415..aefdda390f5e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -84,6 +84,10 @@ struct dentry *kvm_debugfs_dir; | |||
84 | 84 | ||
85 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, | 85 | static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, |
86 | unsigned long arg); | 86 | unsigned long arg); |
87 | #ifdef CONFIG_COMPAT | ||
88 | static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl, | ||
89 | unsigned long arg); | ||
90 | #endif | ||
87 | static int hardware_enable_all(void); | 91 | static int hardware_enable_all(void); |
88 | static void hardware_disable_all(void); | 92 | static void hardware_disable_all(void); |
89 | 93 | ||
@@ -97,8 +101,8 @@ static bool largepages_enabled = true; | |||
97 | static struct page *hwpoison_page; | 101 | static struct page *hwpoison_page; |
98 | static pfn_t hwpoison_pfn; | 102 | static pfn_t hwpoison_pfn; |
99 | 103 | ||
100 | static struct page *fault_page; | 104 | struct page *fault_page; |
101 | static pfn_t fault_pfn; | 105 | pfn_t fault_pfn; |
102 | 106 | ||
103 | inline int kvm_is_mmio_pfn(pfn_t pfn) | 107 | inline int kvm_is_mmio_pfn(pfn_t pfn) |
104 | { | 108 | { |
@@ -827,6 +831,13 @@ skip_lpage: | |||
827 | 831 | ||
828 | kvm_arch_commit_memory_region(kvm, mem, old, user_alloc); | 832 | kvm_arch_commit_memory_region(kvm, mem, old, user_alloc); |
829 | 833 | ||
834 | /* | ||
835 | * If the new memory slot is created, we need to clear all | ||
836 | * mmio sptes. | ||
837 | */ | ||
838 | if (npages && old.base_gfn != mem->guest_phys_addr >> PAGE_SHIFT) | ||
839 | kvm_arch_flush_shadow(kvm); | ||
840 | |||
830 | kvm_free_physmem_slot(&old, &new); | 841 | kvm_free_physmem_slot(&old, &new); |
831 | kfree(old_memslots); | 842 | kfree(old_memslots); |
832 | 843 | ||
@@ -927,6 +938,18 @@ int is_fault_pfn(pfn_t pfn) | |||
927 | } | 938 | } |
928 | EXPORT_SYMBOL_GPL(is_fault_pfn); | 939 | EXPORT_SYMBOL_GPL(is_fault_pfn); |
929 | 940 | ||
941 | int is_noslot_pfn(pfn_t pfn) | ||
942 | { | ||
943 | return pfn == bad_pfn; | ||
944 | } | ||
945 | EXPORT_SYMBOL_GPL(is_noslot_pfn); | ||
946 | |||
947 | int is_invalid_pfn(pfn_t pfn) | ||
948 | { | ||
949 | return pfn == hwpoison_pfn || pfn == fault_pfn; | ||
950 | } | ||
951 | EXPORT_SYMBOL_GPL(is_invalid_pfn); | ||
952 | |||
930 | static inline unsigned long bad_hva(void) | 953 | static inline unsigned long bad_hva(void) |
931 | { | 954 | { |
932 | return PAGE_OFFSET; | 955 | return PAGE_OFFSET; |
@@ -1345,7 +1368,7 @@ int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data, | |||
1345 | addr = gfn_to_hva(kvm, gfn); | 1368 | addr = gfn_to_hva(kvm, gfn); |
1346 | if (kvm_is_error_hva(addr)) | 1369 | if (kvm_is_error_hva(addr)) |
1347 | return -EFAULT; | 1370 | return -EFAULT; |
1348 | r = copy_to_user((void __user *)addr + offset, data, len); | 1371 | r = __copy_to_user((void __user *)addr + offset, data, len); |
1349 | if (r) | 1372 | if (r) |
1350 | return -EFAULT; | 1373 | return -EFAULT; |
1351 | mark_page_dirty(kvm, gfn); | 1374 | mark_page_dirty(kvm, gfn); |
@@ -1405,7 +1428,7 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, | |||
1405 | if (kvm_is_error_hva(ghc->hva)) | 1428 | if (kvm_is_error_hva(ghc->hva)) |
1406 | return -EFAULT; | 1429 | return -EFAULT; |
1407 | 1430 | ||
1408 | r = copy_to_user((void __user *)ghc->hva, data, len); | 1431 | r = __copy_to_user((void __user *)ghc->hva, data, len); |
1409 | if (r) | 1432 | if (r) |
1410 | return -EFAULT; | 1433 | return -EFAULT; |
1411 | mark_page_dirty_in_slot(kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT); | 1434 | mark_page_dirty_in_slot(kvm, ghc->memslot, ghc->gpa >> PAGE_SHIFT); |
@@ -1414,6 +1437,26 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, | |||
1414 | } | 1437 | } |
1415 | EXPORT_SYMBOL_GPL(kvm_write_guest_cached); | 1438 | EXPORT_SYMBOL_GPL(kvm_write_guest_cached); |
1416 | 1439 | ||
1440 | int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, | ||
1441 | void *data, unsigned long len) | ||
1442 | { | ||
1443 | struct kvm_memslots *slots = kvm_memslots(kvm); | ||
1444 | int r; | ||
1445 | |||
1446 | if (slots->generation != ghc->generation) | ||
1447 | kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); | ||
1448 | |||
1449 | if (kvm_is_error_hva(ghc->hva)) | ||
1450 | return -EFAULT; | ||
1451 | |||
1452 | r = __copy_from_user(data, (void __user *)ghc->hva, len); | ||
1453 | if (r) | ||
1454 | return -EFAULT; | ||
1455 | |||
1456 | return 0; | ||
1457 | } | ||
1458 | EXPORT_SYMBOL_GPL(kvm_read_guest_cached); | ||
1459 | |||
1417 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) | 1460 | int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len) |
1418 | { | 1461 | { |
1419 | return kvm_write_guest_page(kvm, gfn, (const void *) empty_zero_page, | 1462 | return kvm_write_guest_page(kvm, gfn, (const void *) empty_zero_page, |
@@ -1586,7 +1629,9 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) | |||
1586 | static struct file_operations kvm_vcpu_fops = { | 1629 | static struct file_operations kvm_vcpu_fops = { |
1587 | .release = kvm_vcpu_release, | 1630 | .release = kvm_vcpu_release, |
1588 | .unlocked_ioctl = kvm_vcpu_ioctl, | 1631 | .unlocked_ioctl = kvm_vcpu_ioctl, |
1589 | .compat_ioctl = kvm_vcpu_ioctl, | 1632 | #ifdef CONFIG_COMPAT |
1633 | .compat_ioctl = kvm_vcpu_compat_ioctl, | ||
1634 | #endif | ||
1590 | .mmap = kvm_vcpu_mmap, | 1635 | .mmap = kvm_vcpu_mmap, |
1591 | .llseek = noop_llseek, | 1636 | .llseek = noop_llseek, |
1592 | }; | 1637 | }; |
@@ -1615,18 +1660,18 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) | |||
1615 | 1660 | ||
1616 | r = kvm_arch_vcpu_setup(vcpu); | 1661 | r = kvm_arch_vcpu_setup(vcpu); |
1617 | if (r) | 1662 | if (r) |
1618 | return r; | 1663 | goto vcpu_destroy; |
1619 | 1664 | ||
1620 | mutex_lock(&kvm->lock); | 1665 | mutex_lock(&kvm->lock); |
1621 | if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) { | 1666 | if (atomic_read(&kvm->online_vcpus) == KVM_MAX_VCPUS) { |
1622 | r = -EINVAL; | 1667 | r = -EINVAL; |
1623 | goto vcpu_destroy; | 1668 | goto unlock_vcpu_destroy; |
1624 | } | 1669 | } |
1625 | 1670 | ||
1626 | kvm_for_each_vcpu(r, v, kvm) | 1671 | kvm_for_each_vcpu(r, v, kvm) |
1627 | if (v->vcpu_id == id) { | 1672 | if (v->vcpu_id == id) { |
1628 | r = -EEXIST; | 1673 | r = -EEXIST; |
1629 | goto vcpu_destroy; | 1674 | goto unlock_vcpu_destroy; |
1630 | } | 1675 | } |
1631 | 1676 | ||
1632 | BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]); | 1677 | BUG_ON(kvm->vcpus[atomic_read(&kvm->online_vcpus)]); |
@@ -1636,7 +1681,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) | |||
1636 | r = create_vcpu_fd(vcpu); | 1681 | r = create_vcpu_fd(vcpu); |
1637 | if (r < 0) { | 1682 | if (r < 0) { |
1638 | kvm_put_kvm(kvm); | 1683 | kvm_put_kvm(kvm); |
1639 | goto vcpu_destroy; | 1684 | goto unlock_vcpu_destroy; |
1640 | } | 1685 | } |
1641 | 1686 | ||
1642 | kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu; | 1687 | kvm->vcpus[atomic_read(&kvm->online_vcpus)] = vcpu; |
@@ -1650,8 +1695,9 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id) | |||
1650 | mutex_unlock(&kvm->lock); | 1695 | mutex_unlock(&kvm->lock); |
1651 | return r; | 1696 | return r; |
1652 | 1697 | ||
1653 | vcpu_destroy: | 1698 | unlock_vcpu_destroy: |
1654 | mutex_unlock(&kvm->lock); | 1699 | mutex_unlock(&kvm->lock); |
1700 | vcpu_destroy: | ||
1655 | kvm_arch_vcpu_destroy(vcpu); | 1701 | kvm_arch_vcpu_destroy(vcpu); |
1656 | return r; | 1702 | return r; |
1657 | } | 1703 | } |
@@ -1874,6 +1920,50 @@ out: | |||
1874 | return r; | 1920 | return r; |
1875 | } | 1921 | } |
1876 | 1922 | ||
1923 | #ifdef CONFIG_COMPAT | ||
1924 | static long kvm_vcpu_compat_ioctl(struct file *filp, | ||
1925 | unsigned int ioctl, unsigned long arg) | ||
1926 | { | ||
1927 | struct kvm_vcpu *vcpu = filp->private_data; | ||
1928 | void __user *argp = compat_ptr(arg); | ||
1929 | int r; | ||
1930 | |||
1931 | if (vcpu->kvm->mm != current->mm) | ||
1932 | return -EIO; | ||
1933 | |||
1934 | switch (ioctl) { | ||
1935 | case KVM_SET_SIGNAL_MASK: { | ||
1936 | struct kvm_signal_mask __user *sigmask_arg = argp; | ||
1937 | struct kvm_signal_mask kvm_sigmask; | ||
1938 | compat_sigset_t csigset; | ||
1939 | sigset_t sigset; | ||
1940 | |||
1941 | if (argp) { | ||
1942 | r = -EFAULT; | ||
1943 | if (copy_from_user(&kvm_sigmask, argp, | ||
1944 | sizeof kvm_sigmask)) | ||
1945 | goto out; | ||
1946 | r = -EINVAL; | ||
1947 | if (kvm_sigmask.len != sizeof csigset) | ||
1948 | goto out; | ||
1949 | r = -EFAULT; | ||
1950 | if (copy_from_user(&csigset, sigmask_arg->sigset, | ||
1951 | sizeof csigset)) | ||
1952 | goto out; | ||
1953 | } | ||
1954 | sigset_from_compat(&sigset, &csigset); | ||
1955 | r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset); | ||
1956 | break; | ||
1957 | } | ||
1958 | default: | ||
1959 | r = kvm_vcpu_ioctl(filp, ioctl, arg); | ||
1960 | } | ||
1961 | |||
1962 | out: | ||
1963 | return r; | ||
1964 | } | ||
1965 | #endif | ||
1966 | |||
1877 | static long kvm_vm_ioctl(struct file *filp, | 1967 | static long kvm_vm_ioctl(struct file *filp, |
1878 | unsigned int ioctl, unsigned long arg) | 1968 | unsigned int ioctl, unsigned long arg) |
1879 | { | 1969 | { |