diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
commit | f244d910ea2974d88efcc6d04594f25e22718f90 (patch) | |
tree | 7236a244a09fa76d73105df476d2f20a19066d70 /virt/kvm | |
parent | 4f34d683e52271197e1ee17b7095e8ba27761ba6 (diff) | |
parent | 536336c21697551ceca44bdffb9f53e6cc5f2f20 (diff) |
Merge tag 'kvm-s390-20140130' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
Two new features are added by this patch set:
- The floating interrupt controller (flic) that allows us to inject,
clear and inspect non-vcpu local interrupts. This also gives us an
opportunity to fix deficiencies in our existing interrupt definitions.
- Support for asynchronous page faults via the pfault mechanism. Testing
show significant guest performance improvements under host swap.
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/Kconfig | 4 | ||||
-rw-r--r-- | virt/kvm/async_pf.c | 25 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 5 |
3 files changed, 32 insertions, 2 deletions
diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index fbe1a48bd629..13f2d19793e3 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig | |||
@@ -22,6 +22,10 @@ config KVM_MMIO | |||
22 | config KVM_ASYNC_PF | 22 | config KVM_ASYNC_PF |
23 | bool | 23 | bool |
24 | 24 | ||
25 | # Toggle to switch between direct notification and batch job | ||
26 | config KVM_ASYNC_PF_SYNC | ||
27 | bool | ||
28 | |||
25 | config HAVE_KVM_MSI | 29 | config HAVE_KVM_MSI |
26 | bool | 30 | bool |
27 | 31 | ||
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c index 8631d9c14320..889aad022014 100644 --- a/virt/kvm/async_pf.c +++ b/virt/kvm/async_pf.c | |||
@@ -28,6 +28,21 @@ | |||
28 | #include "async_pf.h" | 28 | #include "async_pf.h" |
29 | #include <trace/events/kvm.h> | 29 | #include <trace/events/kvm.h> |
30 | 30 | ||
31 | static inline void kvm_async_page_present_sync(struct kvm_vcpu *vcpu, | ||
32 | struct kvm_async_pf *work) | ||
33 | { | ||
34 | #ifdef CONFIG_KVM_ASYNC_PF_SYNC | ||
35 | kvm_arch_async_page_present(vcpu, work); | ||
36 | #endif | ||
37 | } | ||
38 | static inline void kvm_async_page_present_async(struct kvm_vcpu *vcpu, | ||
39 | struct kvm_async_pf *work) | ||
40 | { | ||
41 | #ifndef CONFIG_KVM_ASYNC_PF_SYNC | ||
42 | kvm_arch_async_page_present(vcpu, work); | ||
43 | #endif | ||
44 | } | ||
45 | |||
31 | static struct kmem_cache *async_pf_cache; | 46 | static struct kmem_cache *async_pf_cache; |
32 | 47 | ||
33 | int kvm_async_pf_init(void) | 48 | int kvm_async_pf_init(void) |
@@ -69,6 +84,7 @@ static void async_pf_execute(struct work_struct *work) | |||
69 | down_read(&mm->mmap_sem); | 84 | down_read(&mm->mmap_sem); |
70 | get_user_pages(current, mm, addr, 1, 1, 0, NULL, NULL); | 85 | get_user_pages(current, mm, addr, 1, 1, 0, NULL, NULL); |
71 | up_read(&mm->mmap_sem); | 86 | up_read(&mm->mmap_sem); |
87 | kvm_async_page_present_sync(vcpu, apf); | ||
72 | unuse_mm(mm); | 88 | unuse_mm(mm); |
73 | 89 | ||
74 | spin_lock(&vcpu->async_pf.lock); | 90 | spin_lock(&vcpu->async_pf.lock); |
@@ -97,11 +113,16 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) | |||
97 | list_entry(vcpu->async_pf.queue.next, | 113 | list_entry(vcpu->async_pf.queue.next, |
98 | typeof(*work), queue); | 114 | typeof(*work), queue); |
99 | list_del(&work->queue); | 115 | list_del(&work->queue); |
116 | |||
117 | #ifdef CONFIG_KVM_ASYNC_PF_SYNC | ||
118 | flush_work(&work->work); | ||
119 | #else | ||
100 | if (cancel_work_sync(&work->work)) { | 120 | if (cancel_work_sync(&work->work)) { |
101 | mmdrop(work->mm); | 121 | mmdrop(work->mm); |
102 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ | 122 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ |
103 | kmem_cache_free(async_pf_cache, work); | 123 | kmem_cache_free(async_pf_cache, work); |
104 | } | 124 | } |
125 | #endif | ||
105 | } | 126 | } |
106 | 127 | ||
107 | spin_lock(&vcpu->async_pf.lock); | 128 | spin_lock(&vcpu->async_pf.lock); |
@@ -138,7 +159,7 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu) | |||
138 | } | 159 | } |
139 | } | 160 | } |
140 | 161 | ||
141 | int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn, | 162 | int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, |
142 | struct kvm_arch_async_pf *arch) | 163 | struct kvm_arch_async_pf *arch) |
143 | { | 164 | { |
144 | struct kvm_async_pf *work; | 165 | struct kvm_async_pf *work; |
@@ -159,7 +180,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn, | |||
159 | work->wakeup_all = false; | 180 | work->wakeup_all = false; |
160 | work->vcpu = vcpu; | 181 | work->vcpu = vcpu; |
161 | work->gva = gva; | 182 | work->gva = gva; |
162 | work->addr = gfn_to_hva(vcpu->kvm, gfn); | 183 | work->addr = hva; |
163 | work->arch = *arch; | 184 | work->arch = *arch; |
164 | work->mm = current->mm; | 185 | work->mm = current->mm; |
165 | atomic_inc(&work->mm->mm_count); | 186 | atomic_inc(&work->mm->mm_count); |
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 03a0381b1cb7..a9e999a48e43 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -2284,6 +2284,11 @@ static int kvm_ioctl_create_device(struct kvm *kvm, | |||
2284 | ops = &kvm_arm_vgic_v2_ops; | 2284 | ops = &kvm_arm_vgic_v2_ops; |
2285 | break; | 2285 | break; |
2286 | #endif | 2286 | #endif |
2287 | #ifdef CONFIG_S390 | ||
2288 | case KVM_DEV_TYPE_FLIC: | ||
2289 | ops = &kvm_flic_ops; | ||
2290 | break; | ||
2291 | #endif | ||
2287 | default: | 2292 | default: |
2288 | return -ENODEV; | 2293 | return -ENODEV; |
2289 | } | 2294 | } |