aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorTony Krowiak <akrowiak@linux.vnet.ibm.com>2014-06-27 14:46:01 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-09-10 06:19:05 -0400
commit5102ee879539ebd2e0de1eb93290e3d691973e79 (patch)
tree1672adbecd97fa7e06c8c5514bbf4e520bee6a26 /arch/s390
parentfd2752352bbc98850d83b5448a288d8991590317 (diff)
KVM: CPACF: Enable MSA4 instructions for kvm guest
We have to provide a per guest crypto block for the CPUs to enable MSA4 instructions. According to icainfo on z196 or later this enables CCM-AES-128, CMAC-AES-128, CMAC-AES-192 and CMAC-AES-256. Signed-off-by: Tony Krowiak <akrowiak@linux.vnet.ibm.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Michael Mueller <mimu@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> [split MSA4/protected key into two patches]
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/kvm_host.h14
-rw-r--r--arch/s390/kvm/kvm-s390.c33
2 files changed, 46 insertions, 1 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/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 628e992eeded..2037738d01a0 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);
@@ -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