aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
authorLaurent Vivier <Laurent.Vivier@bull.net>2008-05-30 10:05:54 -0400
committerAvi Kivity <avi@qumranet.com>2008-07-20 05:42:31 -0400
commit5f94c1741bdc7a336553122036e8a779e616ccbf (patch)
treefb0dc4edf0c346dc266eb2ee2d433cb2678a0bc4 /virt/kvm/kvm_main.c
parent92760499d01ef91518119908eb9b8798b6c9bd3f (diff)
KVM: Add coalesced MMIO support (common part)
This patch adds all needed structures to coalesce MMIOs. Until an architecture uses it, it is not compiled. Coalesced MMIO introduces two ioctl() to define where are the MMIO zones that can be coalesced: - KVM_REGISTER_COALESCED_MMIO registers a coalesced MMIO zone. It requests one parameter (struct kvm_coalesced_mmio_zone) which defines a memory area where MMIOs can be coalesced until the next switch to user space. The maximum number of MMIO zones is KVM_COALESCED_MMIO_ZONE_MAX. - KVM_UNREGISTER_COALESCED_MMIO cancels all registered zones inside the given bounds (bounds are also given by struct kvm_coalesced_mmio_zone). The userspace client can check kernel coalesced MMIO availability by asking ioctl(KVM_CHECK_EXTENSION) for the KVM_CAP_COALESCED_MMIO capability. The ioctl() call to KVM_CAP_COALESCED_MMIO will return 0 if not supported, or the page offset where will be stored the ring buffer. The page offset depends on the architecture. After an ioctl(KVM_RUN), the first page of the KVM memory mapped points to a kvm_run structure. The offset given by KVM_CAP_COALESCED_MMIO is an offset to the coalesced MMIO ring expressed in PAGE_SIZE relatively to the address of the start of th kvm_run structure. The MMIO ring buffer is defined by the structure kvm_coalesced_mmio_ring. [akio: fix oops during guest shutdown] Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net> Signed-off-by: Akio Takebe <takebe_akio@jp.fujitsu.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9330fad2b918..7d10dfa0d388 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -47,6 +47,10 @@
47#include <asm/uaccess.h> 47#include <asm/uaccess.h>
48#include <asm/pgtable.h> 48#include <asm/pgtable.h>
49 49
50#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
51#include "coalesced_mmio.h"
52#endif
53
50MODULE_AUTHOR("Qumranet"); 54MODULE_AUTHOR("Qumranet");
51MODULE_LICENSE("GPL"); 55MODULE_LICENSE("GPL");
52 56
@@ -185,10 +189,23 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_uninit);
185static struct kvm *kvm_create_vm(void) 189static struct kvm *kvm_create_vm(void)
186{ 190{
187 struct kvm *kvm = kvm_arch_create_vm(); 191 struct kvm *kvm = kvm_arch_create_vm();
192#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
193 struct page *page;
194#endif
188 195
189 if (IS_ERR(kvm)) 196 if (IS_ERR(kvm))
190 goto out; 197 goto out;
191 198
199#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
200 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
201 if (!page) {
202 kfree(kvm);
203 return ERR_PTR(-ENOMEM);
204 }
205 kvm->coalesced_mmio_ring =
206 (struct kvm_coalesced_mmio_ring *)page_address(page);
207#endif
208
192 kvm->mm = current->mm; 209 kvm->mm = current->mm;
193 atomic_inc(&kvm->mm->mm_count); 210 atomic_inc(&kvm->mm->mm_count);
194 spin_lock_init(&kvm->mmu_lock); 211 spin_lock_init(&kvm->mmu_lock);
@@ -200,6 +217,9 @@ static struct kvm *kvm_create_vm(void)
200 spin_lock(&kvm_lock); 217 spin_lock(&kvm_lock);
201 list_add(&kvm->vm_list, &vm_list); 218 list_add(&kvm->vm_list, &vm_list);
202 spin_unlock(&kvm_lock); 219 spin_unlock(&kvm_lock);
220#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
221 kvm_coalesced_mmio_init(kvm);
222#endif
203out: 223out:
204 return kvm; 224 return kvm;
205} 225}
@@ -242,6 +262,10 @@ static void kvm_destroy_vm(struct kvm *kvm)
242 spin_unlock(&kvm_lock); 262 spin_unlock(&kvm_lock);
243 kvm_io_bus_destroy(&kvm->pio_bus); 263 kvm_io_bus_destroy(&kvm->pio_bus);
244 kvm_io_bus_destroy(&kvm->mmio_bus); 264 kvm_io_bus_destroy(&kvm->mmio_bus);
265#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
266 if (kvm->coalesced_mmio_ring != NULL)
267 free_page((unsigned long)kvm->coalesced_mmio_ring);
268#endif
245 kvm_arch_destroy_vm(kvm); 269 kvm_arch_destroy_vm(kvm);
246 mmdrop(mm); 270 mmdrop(mm);
247} 271}
@@ -826,6 +850,10 @@ static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
826 else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET) 850 else if (vmf->pgoff == KVM_PIO_PAGE_OFFSET)
827 page = virt_to_page(vcpu->arch.pio_data); 851 page = virt_to_page(vcpu->arch.pio_data);
828#endif 852#endif
853#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
854 else if (vmf->pgoff == KVM_COALESCED_MMIO_PAGE_OFFSET)
855 page = virt_to_page(vcpu->kvm->coalesced_mmio_ring);
856#endif
829 else 857 else
830 return VM_FAULT_SIGBUS; 858 return VM_FAULT_SIGBUS;
831 get_page(page); 859 get_page(page);
@@ -1148,6 +1176,32 @@ static long kvm_vm_ioctl(struct file *filp,
1148 goto out; 1176 goto out;
1149 break; 1177 break;
1150 } 1178 }
1179#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
1180 case KVM_REGISTER_COALESCED_MMIO: {
1181 struct kvm_coalesced_mmio_zone zone;
1182 r = -EFAULT;
1183 if (copy_from_user(&zone, argp, sizeof zone))
1184 goto out;
1185 r = -ENXIO;
1186 r = kvm_vm_ioctl_register_coalesced_mmio(kvm, &zone);
1187 if (r)
1188 goto out;
1189 r = 0;
1190 break;
1191 }
1192 case KVM_UNREGISTER_COALESCED_MMIO: {
1193 struct kvm_coalesced_mmio_zone zone;
1194 r = -EFAULT;
1195 if (copy_from_user(&zone, argp, sizeof zone))
1196 goto out;
1197 r = -ENXIO;
1198 r = kvm_vm_ioctl_unregister_coalesced_mmio(kvm, &zone);
1199 if (r)
1200 goto out;
1201 r = 0;
1202 break;
1203 }
1204#endif
1151 default: 1205 default:
1152 r = kvm_arch_vm_ioctl(filp, ioctl, arg); 1206 r = kvm_arch_vm_ioctl(filp, ioctl, arg);
1153 } 1207 }
@@ -1232,6 +1286,9 @@ static long kvm_dev_ioctl(struct file *filp,
1232#ifdef CONFIG_X86 1286#ifdef CONFIG_X86
1233 r += PAGE_SIZE; /* pio data page */ 1287 r += PAGE_SIZE; /* pio data page */
1234#endif 1288#endif
1289#ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
1290 r += PAGE_SIZE; /* coalesced mmio ring page */
1291#endif
1235 break; 1292 break;
1236 case KVM_TRACE_ENABLE: 1293 case KVM_TRACE_ENABLE:
1237 case KVM_TRACE_PAUSE: 1294 case KVM_TRACE_PAUSE: