diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-03-25 10:44:06 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-03-25 10:44:06 -0400 |
commit | f7b9ddb8a5e8a25954217fa25d114bd8cf4491a4 (patch) | |
tree | 06837e268d145e59ad46d9cd5f6c36c16f2424c9 /arch | |
parent | ea2108c9308071ae41ae6f537724cb2734045943 (diff) | |
parent | 2ed10cc15e7edf2daf22ce807a877a1266e97711 (diff) |
Merge tag 'kvm-s390-20140325' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
3 fixes
- memory leak on certain SIGP conditions
- wrong size for idle bitmap (always too big)
- clear local interrupts on initial CPU reset
1 performance improvement
- improve performance with many guests on certain workloads
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 3 | ||||
-rw-r--r-- | arch/s390/kvm/interrupt.c | 14 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 6 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 1 | ||||
-rw-r--r-- | arch/s390/kvm/sigp.c | 14 |
5 files changed, 28 insertions, 10 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index dd3933754d23..68897fc65950 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -222,8 +222,7 @@ struct kvm_s390_float_interrupt { | |||
222 | struct list_head list; | 222 | struct list_head list; |
223 | atomic_t active; | 223 | atomic_t active; |
224 | int next_rr_cpu; | 224 | int next_rr_cpu; |
225 | unsigned long idle_mask[(KVM_MAX_VCPUS + sizeof(long) - 1) | 225 | unsigned long idle_mask[BITS_TO_LONGS(KVM_MAX_VCPUS)]; |
226 | / sizeof(long)]; | ||
227 | unsigned int irq_count; | 226 | unsigned int irq_count; |
228 | }; | 227 | }; |
229 | 228 | ||
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 2e2814eceb85..200a8f9390b6 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -510,6 +510,20 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer) | |||
510 | return HRTIMER_NORESTART; | 510 | return HRTIMER_NORESTART; |
511 | } | 511 | } |
512 | 512 | ||
513 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu) | ||
514 | { | ||
515 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | ||
516 | struct kvm_s390_interrupt_info *n, *inti = NULL; | ||
517 | |||
518 | spin_lock_bh(&li->lock); | ||
519 | list_for_each_entry_safe(inti, n, &li->list, list) { | ||
520 | list_del(&inti->list); | ||
521 | kfree(inti); | ||
522 | } | ||
523 | atomic_set(&li->active, 0); | ||
524 | spin_unlock_bh(&li->lock); | ||
525 | } | ||
526 | |||
513 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | 527 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) |
514 | { | 528 | { |
515 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 529 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ce5b659ec531..6e1b990e427f 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -255,6 +255,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
255 | { | 255 | { |
256 | int rc; | 256 | int rc; |
257 | char debug_name[16]; | 257 | char debug_name[16]; |
258 | static unsigned long sca_offset; | ||
258 | 259 | ||
259 | rc = -EINVAL; | 260 | rc = -EINVAL; |
260 | #ifdef CONFIG_KVM_S390_UCONTROL | 261 | #ifdef CONFIG_KVM_S390_UCONTROL |
@@ -276,6 +277,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
276 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); | 277 | kvm->arch.sca = (struct sca_block *) get_zeroed_page(GFP_KERNEL); |
277 | if (!kvm->arch.sca) | 278 | if (!kvm->arch.sca) |
278 | goto out_err; | 279 | goto out_err; |
280 | spin_lock(&kvm_lock); | ||
281 | sca_offset = (sca_offset + 16) & 0x7f0; | ||
282 | kvm->arch.sca = (struct sca_block *) ((char *) kvm->arch.sca + sca_offset); | ||
283 | spin_unlock(&kvm_lock); | ||
279 | 284 | ||
280 | sprintf(debug_name, "kvm-%u", current->pid); | 285 | sprintf(debug_name, "kvm-%u", current->pid); |
281 | 286 | ||
@@ -432,6 +437,7 @@ static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu) | |||
432 | vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; | 437 | vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID; |
433 | kvm_clear_async_pf_completion_queue(vcpu); | 438 | kvm_clear_async_pf_completion_queue(vcpu); |
434 | atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); | 439 | atomic_set_mask(CPUSTAT_STOPPED, &vcpu->arch.sie_block->cpuflags); |
440 | kvm_s390_clear_local_irqs(vcpu); | ||
435 | } | 441 | } |
436 | 442 | ||
437 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) | 443 | int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 5502cc951868..660e79f8f8e8 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -129,6 +129,7 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); | |||
129 | void kvm_s390_tasklet(unsigned long parm); | 129 | void kvm_s390_tasklet(unsigned long parm); |
130 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); | 130 | void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); |
131 | void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu); | 131 | void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu); |
132 | void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu); | ||
132 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, | 133 | int __must_check kvm_s390_inject_vm(struct kvm *kvm, |
133 | struct kvm_s390_interrupt *s390int); | 134 | struct kvm_s390_interrupt *s390int); |
134 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 135 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 3fe44c441609..26caeb530a78 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -58,7 +58,9 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
58 | struct kvm_s390_interrupt_info *inti; | 58 | struct kvm_s390_interrupt_info *inti; |
59 | struct kvm_vcpu *dst_vcpu = NULL; | 59 | struct kvm_vcpu *dst_vcpu = NULL; |
60 | 60 | ||
61 | if (cpu_addr >= KVM_MAX_VCPUS) | 61 | if (cpu_addr < KVM_MAX_VCPUS) |
62 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
63 | if (!dst_vcpu) | ||
62 | return SIGP_CC_NOT_OPERATIONAL; | 64 | return SIGP_CC_NOT_OPERATIONAL; |
63 | 65 | ||
64 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 66 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
@@ -68,9 +70,6 @@ static int __sigp_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
68 | inti->type = KVM_S390_INT_EMERGENCY; | 70 | inti->type = KVM_S390_INT_EMERGENCY; |
69 | inti->emerg.code = vcpu->vcpu_id; | 71 | inti->emerg.code = vcpu->vcpu_id; |
70 | 72 | ||
71 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
72 | if (!dst_vcpu) | ||
73 | return SIGP_CC_NOT_OPERATIONAL; | ||
74 | li = &dst_vcpu->arch.local_int; | 73 | li = &dst_vcpu->arch.local_int; |
75 | spin_lock_bh(&li->lock); | 74 | spin_lock_bh(&li->lock); |
76 | list_add_tail(&inti->list, &li->list); | 75 | list_add_tail(&inti->list, &li->list); |
@@ -121,7 +120,9 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
121 | struct kvm_s390_interrupt_info *inti; | 120 | struct kvm_s390_interrupt_info *inti; |
122 | struct kvm_vcpu *dst_vcpu = NULL; | 121 | struct kvm_vcpu *dst_vcpu = NULL; |
123 | 122 | ||
124 | if (cpu_addr >= KVM_MAX_VCPUS) | 123 | if (cpu_addr < KVM_MAX_VCPUS) |
124 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
125 | if (!dst_vcpu) | ||
125 | return SIGP_CC_NOT_OPERATIONAL; | 126 | return SIGP_CC_NOT_OPERATIONAL; |
126 | 127 | ||
127 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); | 128 | inti = kzalloc(sizeof(*inti), GFP_KERNEL); |
@@ -131,9 +132,6 @@ static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
131 | inti->type = KVM_S390_INT_EXTERNAL_CALL; | 132 | inti->type = KVM_S390_INT_EXTERNAL_CALL; |
132 | inti->extcall.code = vcpu->vcpu_id; | 133 | inti->extcall.code = vcpu->vcpu_id; |
133 | 134 | ||
134 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
135 | if (!dst_vcpu) | ||
136 | return SIGP_CC_NOT_OPERATIONAL; | ||
137 | li = &dst_vcpu->arch.local_int; | 135 | li = &dst_vcpu->arch.local_int; |
138 | spin_lock_bh(&li->lock); | 136 | spin_lock_bh(&li->lock); |
139 | list_add_tail(&inti->list, &li->list); | 137 | list_add_tail(&inti->list, &li->list); |