diff options
-rw-r--r-- | virt/kvm/coalesced_mmio.c | 25 | ||||
-rw-r--r-- | virt/kvm/coalesced_mmio.h | 10 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 7 |
3 files changed, 34 insertions, 8 deletions
diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 04d69cd7049b..d68e6c68e0ff 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c | |||
@@ -92,11 +92,19 @@ static const struct kvm_io_device_ops coalesced_mmio_ops = { | |||
92 | int kvm_coalesced_mmio_init(struct kvm *kvm) | 92 | int kvm_coalesced_mmio_init(struct kvm *kvm) |
93 | { | 93 | { |
94 | struct kvm_coalesced_mmio_dev *dev; | 94 | struct kvm_coalesced_mmio_dev *dev; |
95 | struct page *page; | ||
95 | int ret; | 96 | int ret; |
96 | 97 | ||
98 | ret = -ENOMEM; | ||
99 | page = alloc_page(GFP_KERNEL | __GFP_ZERO); | ||
100 | if (!page) | ||
101 | goto out_err; | ||
102 | kvm->coalesced_mmio_ring = page_address(page); | ||
103 | |||
104 | ret = -ENOMEM; | ||
97 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); | 105 | dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), GFP_KERNEL); |
98 | if (!dev) | 106 | if (!dev) |
99 | return -ENOMEM; | 107 | goto out_free_page; |
100 | spin_lock_init(&dev->lock); | 108 | spin_lock_init(&dev->lock); |
101 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); | 109 | kvm_iodevice_init(&dev->dev, &coalesced_mmio_ops); |
102 | dev->kvm = kvm; | 110 | dev->kvm = kvm; |
@@ -104,11 +112,24 @@ int kvm_coalesced_mmio_init(struct kvm *kvm) | |||
104 | 112 | ||
105 | ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev); | 113 | ret = kvm_io_bus_register_dev(kvm, &kvm->mmio_bus, &dev->dev); |
106 | if (ret < 0) | 114 | if (ret < 0) |
107 | kfree(dev); | 115 | goto out_free_dev; |
116 | |||
117 | return ret; | ||
108 | 118 | ||
119 | out_free_dev: | ||
120 | kfree(dev); | ||
121 | out_free_page: | ||
122 | __free_page(page); | ||
123 | out_err: | ||
109 | return ret; | 124 | return ret; |
110 | } | 125 | } |
111 | 126 | ||
127 | void kvm_coalesced_mmio_free(struct kvm *kvm) | ||
128 | { | ||
129 | if (kvm->coalesced_mmio_ring) | ||
130 | free_page((unsigned long)kvm->coalesced_mmio_ring); | ||
131 | } | ||
132 | |||
112 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, | 133 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, |
113 | struct kvm_coalesced_mmio_zone *zone) | 134 | struct kvm_coalesced_mmio_zone *zone) |
114 | { | 135 | { |
diff --git a/virt/kvm/coalesced_mmio.h b/virt/kvm/coalesced_mmio.h index e7033469733d..8a5959e3535f 100644 --- a/virt/kvm/coalesced_mmio.h +++ b/virt/kvm/coalesced_mmio.h | |||
@@ -10,6 +10,8 @@ | |||
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifdef CONFIG_KVM_MMIO | ||
14 | |||
13 | #define KVM_COALESCED_MMIO_ZONE_MAX 100 | 15 | #define KVM_COALESCED_MMIO_ZONE_MAX 100 |
14 | 16 | ||
15 | struct kvm_coalesced_mmio_dev { | 17 | struct kvm_coalesced_mmio_dev { |
@@ -21,9 +23,17 @@ struct kvm_coalesced_mmio_dev { | |||
21 | }; | 23 | }; |
22 | 24 | ||
23 | int kvm_coalesced_mmio_init(struct kvm *kvm); | 25 | int kvm_coalesced_mmio_init(struct kvm *kvm); |
26 | void kvm_coalesced_mmio_free(struct kvm *kvm); | ||
24 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, | 27 | int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, |
25 | struct kvm_coalesced_mmio_zone *zone); | 28 | struct kvm_coalesced_mmio_zone *zone); |
26 | int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, | 29 | int kvm_vm_ioctl_unregister_coalesced_mmio(struct kvm *kvm, |
27 | struct kvm_coalesced_mmio_zone *zone); | 30 | struct kvm_coalesced_mmio_zone *zone); |
28 | 31 | ||
32 | #else | ||
33 | |||
34 | static inline int kvm_coalesced_mmio_init(struct kvm *kvm) { return 0; } | ||
35 | static inline void kvm_coalesced_mmio_free(struct kvm *kvm) { } | ||
36 | |||
37 | #endif | ||
38 | |||
29 | #endif | 39 | #endif |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index c10d117c4317..bc23b8e0609b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -51,9 +51,7 @@ | |||
51 | #include <asm/pgtable.h> | 51 | #include <asm/pgtable.h> |
52 | #include <asm-generic/bitops/le.h> | 52 | #include <asm-generic/bitops/le.h> |
53 | 53 | ||
54 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | ||
55 | #include "coalesced_mmio.h" | 54 | #include "coalesced_mmio.h" |
56 | #endif | ||
57 | 55 | ||
58 | #define CREATE_TRACE_POINTS | 56 | #define CREATE_TRACE_POINTS |
59 | #include <trace/events/kvm.h> | 57 | #include <trace/events/kvm.h> |
@@ -468,10 +466,7 @@ static void kvm_destroy_vm(struct kvm *kvm) | |||
468 | kvm_free_irq_routing(kvm); | 466 | kvm_free_irq_routing(kvm); |
469 | kvm_io_bus_destroy(&kvm->pio_bus); | 467 | kvm_io_bus_destroy(&kvm->pio_bus); |
470 | kvm_io_bus_destroy(&kvm->mmio_bus); | 468 | kvm_io_bus_destroy(&kvm->mmio_bus); |
471 | #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET | 469 | kvm_coalesced_mmio_free(kvm); |
472 | if (kvm->coalesced_mmio_ring != NULL) | ||
473 | free_page((unsigned long)kvm->coalesced_mmio_ring); | ||
474 | #endif | ||
475 | #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) | 470 | #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER) |
476 | mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); | 471 | mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); |
477 | #else | 472 | #else |