diff options
author | Tony Krowiak <akrowiak@linux.vnet.ibm.com> | 2014-06-27 14:46:01 -0400 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2014-09-10 06:19:05 -0400 |
commit | 5102ee879539ebd2e0de1eb93290e3d691973e79 (patch) | |
tree | 1672adbecd97fa7e06c8c5514bbf4e520bee6a26 /arch/s390 | |
parent | fd2752352bbc98850d83b5448a288d8991590317 (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.h | 14 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 33 |
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 | ||
415 | struct kvm_s390_crypto { | ||
416 | struct kvm_s390_crypto_cb *crycb; | ||
417 | __u32 crycbd; | ||
418 | }; | ||
419 | |||
420 | struct kvm_s390_crypto_cb { | ||
421 | __u8 reserved00[128]; /* 0x0000 */ | ||
422 | }; | ||
423 | |||
413 | struct kvm_arch{ | 424 | struct 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 | ||
395 | static 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 | |||
395 | int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | 411 | int 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; |
455 | out_nogmap: | 474 | out_nogmap: |
475 | kfree(kvm->arch.crypto.crycb); | ||
476 | out_crypto: | ||
456 | debug_unregister(kvm->arch.dbf); | 477 | debug_unregister(kvm->arch.dbf); |
457 | out_nodbf: | 478 | out_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 | ||
613 | static 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 | |||
591 | void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu) | 621 | void 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 | ||