diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2008-11-26 08:50:27 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:03 -0500 |
commit | d329c035e754156ffabcb64ff75d05bb8e2ddbf5 (patch) | |
tree | 4417fc296c719f23e952076873cdb91a4c3c757d /arch/s390 | |
parent | 6b7ad61ffb9ca110add6f7fb36cc8a4dd89696a4 (diff) |
KVM: s390: Fix refcounting and allow module unload
Currently it is impossible to unload the kvm module on s390.
This patch fixes kvm_arch_destroy_vm to release all cpus.
This make it possible to unload the module.
In addition we stop messing with the module refcount in arch code.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Carsten Otte <cotte@de.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8b00eb2ddf57..3db9e5d45a67 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -185,8 +185,6 @@ struct kvm *kvm_arch_create_vm(void) | |||
185 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); | 185 | debug_register_view(kvm->arch.dbf, &debug_sprintf_view); |
186 | VM_EVENT(kvm, 3, "%s", "vm created"); | 186 | VM_EVENT(kvm, 3, "%s", "vm created"); |
187 | 187 | ||
188 | try_module_get(THIS_MODULE); | ||
189 | |||
190 | return kvm; | 188 | return kvm; |
191 | out_nodbf: | 189 | out_nodbf: |
192 | free_page((unsigned long)(kvm->arch.sca)); | 190 | free_page((unsigned long)(kvm->arch.sca)); |
@@ -196,13 +194,32 @@ out_nokvm: | |||
196 | return ERR_PTR(rc); | 194 | return ERR_PTR(rc); |
197 | } | 195 | } |
198 | 196 | ||
197 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | ||
198 | { | ||
199 | VCPU_EVENT(vcpu, 3, "%s", "free cpu"); | ||
200 | free_page((unsigned long)(vcpu->arch.sie_block)); | ||
201 | kfree(vcpu); | ||
202 | } | ||
203 | |||
204 | static void kvm_free_vcpus(struct kvm *kvm) | ||
205 | { | ||
206 | unsigned int i; | ||
207 | |||
208 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | ||
209 | if (kvm->vcpus[i]) { | ||
210 | kvm_arch_vcpu_destroy(kvm->vcpus[i]); | ||
211 | kvm->vcpus[i] = NULL; | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
199 | void kvm_arch_destroy_vm(struct kvm *kvm) | 216 | void kvm_arch_destroy_vm(struct kvm *kvm) |
200 | { | 217 | { |
201 | debug_unregister(kvm->arch.dbf); | 218 | kvm_free_vcpus(kvm); |
202 | kvm_free_physmem(kvm); | 219 | kvm_free_physmem(kvm); |
203 | free_page((unsigned long)(kvm->arch.sca)); | 220 | free_page((unsigned long)(kvm->arch.sca)); |
221 | debug_unregister(kvm->arch.dbf); | ||
204 | kfree(kvm); | 222 | kfree(kvm); |
205 | module_put(THIS_MODULE); | ||
206 | } | 223 | } |
207 | 224 | ||
208 | /* Section: vcpu related */ | 225 | /* Section: vcpu related */ |
@@ -308,8 +325,6 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
308 | VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, | 325 | VM_EVENT(kvm, 3, "create cpu %d at %p, sie block at %p", id, vcpu, |
309 | vcpu->arch.sie_block); | 326 | vcpu->arch.sie_block); |
310 | 327 | ||
311 | try_module_get(THIS_MODULE); | ||
312 | |||
313 | return vcpu; | 328 | return vcpu; |
314 | out_free_cpu: | 329 | out_free_cpu: |
315 | kfree(vcpu); | 330 | kfree(vcpu); |
@@ -317,14 +332,6 @@ out_nomem: | |||
317 | return ERR_PTR(rc); | 332 | return ERR_PTR(rc); |
318 | } | 333 | } |
319 | 334 | ||
320 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | ||
321 | { | ||
322 | VCPU_EVENT(vcpu, 3, "%s", "destroy cpu"); | ||
323 | free_page((unsigned long)(vcpu->arch.sie_block)); | ||
324 | kfree(vcpu); | ||
325 | module_put(THIS_MODULE); | ||
326 | } | ||
327 | |||
328 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | 335 | int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) |
329 | { | 336 | { |
330 | /* kvm common code refers to this, but never calls it */ | 337 | /* kvm common code refers to this, but never calls it */ |