aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorTony Krowiak <akrowiak@linux.vnet.ibm.com>2014-09-03 04:13:53 -0400
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-01-23 07:25:40 -0500
commita374e892c3421f81a71e85d5a8c526959221f279 (patch)
tree4c57b494fc2d530fd1457472f4b850989ec68d57 /arch/s390/kvm
parent72f250206f0f291190ab7f54e4d92ab211779929 (diff)
KVM: s390/cpacf: Enable/disable protected key functions for kvm guest
Created new KVM device attributes for indicating whether the AES and DES/TDES protected key functions are available for programs running on the KVM guest. The attributes are used to set up the controls in the guest SIE block that specify whether programs running on the guest will be given access to the protected key functions available on the s390 hardware. 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/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 9cf899e9a5d4..b2371c0fd1f8 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -22,6 +22,7 @@
22#include <linux/kvm.h> 22#include <linux/kvm.h>
23#include <linux/kvm_host.h> 23#include <linux/kvm_host.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/random.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/timer.h> 27#include <linux/timer.h>
27#include <asm/asm-offsets.h> 28#include <asm/asm-offsets.h>
@@ -342,6 +343,53 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att
342 return ret; 343 return ret;
343} 344}
344 345
346static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu);
347
348static int kvm_s390_vm_set_crypto(struct kvm *kvm, struct kvm_device_attr *attr)
349{
350 struct kvm_vcpu *vcpu;
351 int i;
352
353 if (!test_vfacility(76))
354 return -EINVAL;
355
356 mutex_lock(&kvm->lock);
357 switch (attr->attr) {
358 case KVM_S390_VM_CRYPTO_ENABLE_AES_KW:
359 get_random_bytes(
360 kvm->arch.crypto.crycb->aes_wrapping_key_mask,
361 sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
362 kvm->arch.crypto.aes_kw = 1;
363 break;
364 case KVM_S390_VM_CRYPTO_ENABLE_DEA_KW:
365 get_random_bytes(
366 kvm->arch.crypto.crycb->dea_wrapping_key_mask,
367 sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
368 kvm->arch.crypto.dea_kw = 1;
369 break;
370 case KVM_S390_VM_CRYPTO_DISABLE_AES_KW:
371 kvm->arch.crypto.aes_kw = 0;
372 memset(kvm->arch.crypto.crycb->aes_wrapping_key_mask, 0,
373 sizeof(kvm->arch.crypto.crycb->aes_wrapping_key_mask));
374 break;
375 case KVM_S390_VM_CRYPTO_DISABLE_DEA_KW:
376 kvm->arch.crypto.dea_kw = 0;
377 memset(kvm->arch.crypto.crycb->dea_wrapping_key_mask, 0,
378 sizeof(kvm->arch.crypto.crycb->dea_wrapping_key_mask));
379 break;
380 default:
381 mutex_unlock(&kvm->lock);
382 return -ENXIO;
383 }
384
385 kvm_for_each_vcpu(i, vcpu, kvm) {
386 kvm_s390_vcpu_crypto_setup(vcpu);
387 exit_sie(vcpu);
388 }
389 mutex_unlock(&kvm->lock);
390 return 0;
391}
392
345static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr) 393static int kvm_s390_set_tod_high(struct kvm *kvm, struct kvm_device_attr *attr)
346{ 394{
347 u8 gtod_high; 395 u8 gtod_high;
@@ -460,6 +508,9 @@ static int kvm_s390_vm_set_attr(struct kvm *kvm, struct kvm_device_attr *attr)
460 case KVM_S390_VM_TOD: 508 case KVM_S390_VM_TOD:
461 ret = kvm_s390_set_tod(kvm, attr); 509 ret = kvm_s390_set_tod(kvm, attr);
462 break; 510 break;
511 case KVM_S390_VM_CRYPTO:
512 ret = kvm_s390_vm_set_crypto(kvm, attr);
513 break;
463 default: 514 default:
464 ret = -ENXIO; 515 ret = -ENXIO;
465 break; 516 break;
@@ -515,6 +566,19 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
515 break; 566 break;
516 } 567 }
517 break; 568 break;
569 case KVM_S390_VM_CRYPTO:
570 switch (attr->attr) {
571 case KVM_S390_VM_CRYPTO_ENABLE_AES_KW:
572 case KVM_S390_VM_CRYPTO_ENABLE_DEA_KW:
573 case KVM_S390_VM_CRYPTO_DISABLE_AES_KW:
574 case KVM_S390_VM_CRYPTO_DISABLE_DEA_KW:
575 ret = 0;
576 break;
577 default:
578 ret = -ENXIO;
579 break;
580 }
581 break;
518 default: 582 default:
519 ret = -ENXIO; 583 ret = -ENXIO;
520 break; 584 break;
@@ -602,6 +666,10 @@ static int kvm_s390_crypto_init(struct kvm *kvm)
602 kvm->arch.crypto.crycbd = (__u32) (unsigned long) kvm->arch.crypto.crycb | 666 kvm->arch.crypto.crycbd = (__u32) (unsigned long) kvm->arch.crypto.crycb |
603 CRYCB_FORMAT1; 667 CRYCB_FORMAT1;
604 668
669 /* Disable AES/DEA protected key functions by default */
670 kvm->arch.crypto.aes_kw = 0;
671 kvm->arch.crypto.dea_kw = 0;
672
605 return 0; 673 return 0;
606} 674}
607 675
@@ -823,6 +891,13 @@ static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
823 if (!test_vfacility(76)) 891 if (!test_vfacility(76))
824 return; 892 return;
825 893
894 vcpu->arch.sie_block->ecb3 &= ~(ECB3_AES | ECB3_DEA);
895
896 if (vcpu->kvm->arch.crypto.aes_kw)
897 vcpu->arch.sie_block->ecb3 |= ECB3_AES;
898 if (vcpu->kvm->arch.crypto.dea_kw)
899 vcpu->arch.sie_block->ecb3 |= ECB3_DEA;
900
826 vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd; 901 vcpu->arch.sie_block->crycbd = vcpu->kvm->arch.crypto.crycbd;
827} 902}
828 903