aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2014-09-11 05:09:33 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-09-11 05:09:33 -0400
commit2c69c1a32140262d5d6104ab96df2e52c08c1e93 (patch)
tree6cf99e80917ea03591031c6801704a5668fc9310
parent209cf19fcd927e6db9f2ef38e3ca6afdcc0d4d5a (diff)
parentbfac1f59a1afb13a3cf225bffd04be99a49c51a6 (diff)
Merge tag 'kvm-s390-next-20140910' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
KVM: s390: Fixes and features for next (3.18) 1. Crypto/CPACF support: To enable the MSA4 instructions we have to provide a common control structure for each SIE control block 2. Two cleanups found by a static code checker: one redundant assignment and one useless if 3. Fix the page handling of the diag10 ballooning interface. If the guest freed the pages at absolute 0 some checks and frees were incorrect 4. Limit guests to 16TB 5. Add __must_check to interrupt injection code
-rw-r--r--arch/s390/include/asm/kvm_host.h14
-rw-r--r--arch/s390/kvm/diag.c26
-rw-r--r--arch/s390/kvm/gaccess.c3
-rw-r--r--arch/s390/kvm/interrupt.c14
-rw-r--r--arch/s390/kvm/kvm-s390.c35
-rw-r--r--arch/s390/kvm/kvm-s390.h2
6 files changed, 74 insertions, 20 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index a76a124dff48..1a6f6fd8bd34 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -157,7 +157,9 @@ struct kvm_s390_sie_block {
157 __u8 armid; /* 0x00e3 */ 157 __u8 armid; /* 0x00e3 */
158 __u8 reservede4[4]; /* 0x00e4 */ 158 __u8 reservede4[4]; /* 0x00e4 */
159 __u64 tecmc; /* 0x00e8 */ 159 __u64 tecmc; /* 0x00e8 */
160 __u8 reservedf0[16]; /* 0x00f0 */ 160 __u8 reservedf0[12]; /* 0x00f0 */
161#define CRYCB_FORMAT1 0x00000001
162 __u32 crycbd; /* 0x00fc */
161 __u64 gcr[16]; /* 0x0100 */ 163 __u64 gcr[16]; /* 0x0100 */
162 __u64 gbea; /* 0x0180 */ 164 __u64 gbea; /* 0x0180 */
163 __u8 reserved188[24]; /* 0x0188 */ 165 __u8 reserved188[24]; /* 0x0188 */
@@ -410,6 +412,15 @@ struct s390_io_adapter {
410#define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8) 412#define MAX_S390_IO_ADAPTERS ((MAX_ISC + 1) * 8)
411#define MAX_S390_ADAPTER_MAPS 256 413#define MAX_S390_ADAPTER_MAPS 256
412 414
415struct kvm_s390_crypto {
416 struct kvm_s390_crypto_cb *crycb;
417 __u32 crycbd;
418};
419
420struct kvm_s390_crypto_cb {
421 __u8 reserved00[128]; /* 0x0000 */
422};
423
413struct kvm_arch{ 424struct kvm_arch{
414 struct sca_block *sca; 425 struct sca_block *sca;
415 debug_info_t *dbf; 426 debug_info_t *dbf;
@@ -423,6 +434,7 @@ struct kvm_arch{
423 struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS]; 434 struct s390_io_adapter *adapters[MAX_S390_IO_ADAPTERS];
424 wait_queue_head_t ipte_wq; 435 wait_queue_head_t ipte_wq;
425 spinlock_t start_stop_lock; 436 spinlock_t start_stop_lock;
437 struct kvm_s390_crypto crypto;
426}; 438};
427 439
428#define KVM_HVA_ERR_BAD (-1UL) 440#define KVM_HVA_ERR_BAD (-1UL)
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index b374b6cb7785..9254afff250c 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -28,22 +28,32 @@ static int diag_release_pages(struct kvm_vcpu *vcpu)
28 start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; 28 start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
29 end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096; 29 end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
30 30
31 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end 31 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start >= end
32 || start < 2 * PAGE_SIZE) 32 || start < 2 * PAGE_SIZE)
33 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 33 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
34 34
35 VCPU_EVENT(vcpu, 5, "diag release pages %lX %lX", start, end); 35 VCPU_EVENT(vcpu, 5, "diag release pages %lX %lX", start, end);
36 vcpu->stat.diagnose_10++; 36 vcpu->stat.diagnose_10++;
37 37
38 /* we checked for start > end above */ 38 /*
39 if (end < prefix || start >= prefix + 2 * PAGE_SIZE) { 39 * We checked for start >= end above, so lets check for the
40 * fast path (no prefix swap page involved)
41 */
42 if (end <= prefix || start >= prefix + 2 * PAGE_SIZE) {
40 gmap_discard(vcpu->arch.gmap, start, end); 43 gmap_discard(vcpu->arch.gmap, start, end);
41 } else { 44 } else {
42 if (start < prefix) 45 /*
43 gmap_discard(vcpu->arch.gmap, start, prefix); 46 * This is slow path. gmap_discard will check for start
44 if (end >= prefix) 47 * so lets split this into before prefix, prefix, after
45 gmap_discard(vcpu->arch.gmap, 48 * prefix and let gmap_discard make some of these calls
46 prefix + 2 * PAGE_SIZE, end); 49 * NOPs.
50 */
51 gmap_discard(vcpu->arch.gmap, start, prefix);
52 if (start <= prefix)
53 gmap_discard(vcpu->arch.gmap, 0, 4096);
54 if (end > prefix + 4096)
55 gmap_discard(vcpu->arch.gmap, 4096, 8192);
56 gmap_discard(vcpu->arch.gmap, prefix + 2 * PAGE_SIZE, end);
47 } 57 }
48 return 0; 58 return 0;
49} 59}
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 4653ac6e182b..0f961a1c64b3 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -254,8 +254,7 @@ static void ipte_unlock_simple(struct kvm_vcpu *vcpu)
254 new = old = ACCESS_ONCE(*ic); 254 new = old = ACCESS_ONCE(*ic);
255 new.k = 0; 255 new.k = 0;
256 } while (cmpxchg(&ic->val, old.val, new.val) != old.val); 256 } while (cmpxchg(&ic->val, old.val, new.val) != old.val);
257 if (!ipte_lock_count) 257 wake_up(&vcpu->kvm->arch.ipte_wq);
258 wake_up(&vcpu->kvm->arch.ipte_wq);
259out: 258out:
260 mutex_unlock(&ipte_mutex); 259 mutex_unlock(&ipte_mutex);
261} 260}
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 60a5cf40d49a..4cad00adef93 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -28,7 +28,7 @@
28#define IOINT_AI_MASK 0x04000000 28#define IOINT_AI_MASK 0x04000000
29#define PFAULT_INIT 0x0600 29#define PFAULT_INIT 0x0600
30 30
31static int deliver_ckc_interrupt(struct kvm_vcpu *vcpu); 31static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu);
32 32
33static int is_ioint(u64 type) 33static int is_ioint(u64 type)
34{ 34{
@@ -77,7 +77,7 @@ static u64 int_word_to_isc_bits(u32 int_word)
77 return (0x80 >> isc) << 24; 77 return (0x80 >> isc) << 24;
78} 78}
79 79
80static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu, 80static int __must_check __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
81 struct kvm_s390_interrupt_info *inti) 81 struct kvm_s390_interrupt_info *inti)
82{ 82{
83 switch (inti->type) { 83 switch (inti->type) {
@@ -86,6 +86,7 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
86 return 0; 86 return 0;
87 if (vcpu->arch.sie_block->gcr[0] & 0x2000ul) 87 if (vcpu->arch.sie_block->gcr[0] & 0x2000ul)
88 return 1; 88 return 1;
89 return 0;
89 case KVM_S390_INT_EMERGENCY: 90 case KVM_S390_INT_EMERGENCY:
90 if (psw_extint_disabled(vcpu)) 91 if (psw_extint_disabled(vcpu))
91 return 0; 92 return 0;
@@ -225,7 +226,7 @@ static u16 get_ilc(struct kvm_vcpu *vcpu)
225 } 226 }
226} 227}
227 228
228static int __deliver_prog_irq(struct kvm_vcpu *vcpu, 229static int __must_check __deliver_prog_irq(struct kvm_vcpu *vcpu,
229 struct kvm_s390_pgm_info *pgm_info) 230 struct kvm_s390_pgm_info *pgm_info)
230{ 231{
231 int rc = 0; 232 int rc = 0;
@@ -307,7 +308,7 @@ static int __deliver_prog_irq(struct kvm_vcpu *vcpu,
307 return rc; 308 return rc;
308} 309}
309 310
310static int __do_deliver_interrupt(struct kvm_vcpu *vcpu, 311static int __must_check __do_deliver_interrupt(struct kvm_vcpu *vcpu,
311 struct kvm_s390_interrupt_info *inti) 312 struct kvm_s390_interrupt_info *inti)
312{ 313{
313 const unsigned short table[] = { 2, 4, 4, 6 }; 314 const unsigned short table[] = { 2, 4, 4, 6 };
@@ -508,7 +509,7 @@ static int __do_deliver_interrupt(struct kvm_vcpu *vcpu,
508 return rc; 509 return rc;
509} 510}
510 511
511static int deliver_ckc_interrupt(struct kvm_vcpu *vcpu) 512static int __must_check deliver_ckc_interrupt(struct kvm_vcpu *vcpu)
512{ 513{
513 int rc; 514 int rc;
514 515
@@ -657,7 +658,7 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
657 &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl); 658 &vcpu->kvm->arch.sca->cpu[vcpu->vcpu_id].ctrl);
658} 659}
659 660
660int kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) 661int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
661{ 662{
662 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 663 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
663 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int; 664 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
@@ -1351,7 +1352,6 @@ static int flic_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
1351 r = enqueue_floating_irq(dev, attr); 1352 r = enqueue_floating_irq(dev, attr);
1352 break; 1353 break;
1353 case KVM_DEV_FLIC_CLEAR_IRQS: 1354 case KVM_DEV_FLIC_CLEAR_IRQS:
1354 r = 0;
1355 kvm_s390_clear_float_irqs(dev->kvm); 1355 kvm_s390_clear_float_irqs(dev->kvm);
1356 break; 1356 break;
1357 case KVM_DEV_FLIC_APF_ENABLE: 1357 case KVM_DEV_FLIC_APF_ENABLE:
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 628e992eeded..b95d4a481b0c 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -392,6 +392,22 @@ long kvm_arch_vm_ioctl(struct file *filp,
392 return r; 392 return r;
393} 393}
394 394
395static int kvm_s390_crypto_init(struct kvm *kvm)
396{
397 if (!test_vfacility(76))
398 return 0;
399
400 kvm->arch.crypto.crycb = kzalloc(sizeof(*kvm->arch.crypto.crycb),
401 GFP_KERNEL | GFP_DMA);
402 if (!kvm->arch.crypto.crycb)
403 return -ENOMEM;
404
405 kvm->arch.crypto.crycbd = (__u32) (unsigned long) kvm->arch.crypto.crycb |
406 CRYCB_FORMAT1;
407
408 return 0;
409}
410
395int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) 411int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
396{ 412{
397 int rc; 413 int rc;
@@ -429,6 +445,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
429 if (!kvm->arch.dbf) 445 if (!kvm->arch.dbf)
430 goto out_nodbf; 446 goto out_nodbf;
431 447
448 if (kvm_s390_crypto_init(kvm) < 0)
449 goto out_crypto;
450
432 spin_lock_init(&kvm->arch.float_int.lock); 451 spin_lock_init(&kvm->arch.float_int.lock);
433 INIT_LIST_HEAD(&kvm->arch.float_int.list); 452 INIT_LIST_HEAD(&kvm->arch.float_int.list);
434 init_waitqueue_head(&kvm->arch.ipte_wq); 453 init_waitqueue_head(&kvm->arch.ipte_wq);
@@ -439,7 +458,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
439 if (type & KVM_VM_S390_UCONTROL) { 458 if (type & KVM_VM_S390_UCONTROL) {
440 kvm->arch.gmap = NULL; 459 kvm->arch.gmap = NULL;
441 } else { 460 } else {
442 kvm->arch.gmap = gmap_alloc(current->mm, -1UL); 461 kvm->arch.gmap = gmap_alloc(current->mm, (1UL << 44) - 1);
443 if (!kvm->arch.gmap) 462 if (!kvm->arch.gmap)
444 goto out_nogmap; 463 goto out_nogmap;
445 kvm->arch.gmap->private = kvm; 464 kvm->arch.gmap->private = kvm;
@@ -453,6 +472,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
453 472
454 return 0; 473 return 0;
455out_nogmap: 474out_nogmap:
475 kfree(kvm->arch.crypto.crycb);
476out_crypto:
456 debug_unregister(kvm->arch.dbf); 477 debug_unregister(kvm->arch.dbf);
457out_nodbf: 478out_nodbf:
458 free_page((unsigned long)(kvm->arch.sca)); 479 free_page((unsigned long)(kvm->arch.sca));
@@ -507,6 +528,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm)
507 kvm_free_vcpus(kvm); 528 kvm_free_vcpus(kvm);
508 free_page((unsigned long)(kvm->arch.sca)); 529 free_page((unsigned long)(kvm->arch.sca));
509 debug_unregister(kvm->arch.dbf); 530 debug_unregister(kvm->arch.dbf);
531 kfree(kvm->arch.crypto.crycb);
510 if (!kvm_is_ucontrol(kvm)) 532 if (!kvm_is_ucontrol(kvm))
511 gmap_free(kvm->arch.gmap); 533 gmap_free(kvm->arch.gmap);
512 kvm_s390_destroy_adapters(kvm); 534 kvm_s390_destroy_adapters(kvm);
@@ -588,6 +610,14 @@ int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
588 return 0; 610 return 0;
589} 611}
590 612
613static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
614{
615 if (!test_vfacility(76))
616 return;
617
618 vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd;
619}
620
591void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu) 621void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu)
592{ 622{
593 free_page(vcpu->arch.sie_block->cbrlo); 623 free_page(vcpu->arch.sie_block->cbrlo);
@@ -634,6 +664,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
634 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup; 664 vcpu->arch.ckc_timer.function = kvm_s390_idle_wakeup;
635 get_cpu_id(&vcpu->arch.cpu_id); 665 get_cpu_id(&vcpu->arch.cpu_id);
636 vcpu->arch.cpu_id.version = 0xff; 666 vcpu->arch.cpu_id.version = 0xff;
667
668 kvm_s390_vcpu_crypto_setup(vcpu);
669
637 return rc; 670 return rc;
638} 671}
639 672
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 99abcb56e478..b1a77669137b 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -138,7 +138,7 @@ static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm)
138int kvm_s390_handle_wait(struct kvm_vcpu *vcpu); 138int kvm_s390_handle_wait(struct kvm_vcpu *vcpu);
139void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu); 139void kvm_s390_vcpu_wakeup(struct kvm_vcpu *vcpu);
140enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); 140enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer);
141int kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); 141int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu);
142void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu); 142void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu);
143void kvm_s390_clear_float_irqs(struct kvm *kvm); 143void kvm_s390_clear_float_irqs(struct kvm *kvm);
144int __must_check kvm_s390_inject_vm(struct kvm *kvm, 144int __must_check kvm_s390_inject_vm(struct kvm *kvm,