aboutsummaryrefslogtreecommitdiffstats
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
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]
-rw-r--r--arch/s390/include/asm/kvm_host.h10
-rw-r--r--arch/s390/include/uapi/asm/kvm.h7
-rw-r--r--arch/s390/kvm/kvm-s390.c75
3 files changed, 90 insertions, 2 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index 8e22aa0f97fd..d1ecc7fd0579 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -134,7 +134,9 @@ struct kvm_s390_sie_block {
134 __u8 reserved60; /* 0x0060 */ 134 __u8 reserved60; /* 0x0060 */
135 __u8 ecb; /* 0x0061 */ 135 __u8 ecb; /* 0x0061 */
136 __u8 ecb2; /* 0x0062 */ 136 __u8 ecb2; /* 0x0062 */
137 __u8 reserved63[1]; /* 0x0063 */ 137#define ECB3_AES 0x04
138#define ECB3_DEA 0x08
139 __u8 ecb3; /* 0x0063 */
138 __u32 scaol; /* 0x0064 */ 140 __u32 scaol; /* 0x0064 */
139 __u8 reserved68[4]; /* 0x0068 */ 141 __u8 reserved68[4]; /* 0x0068 */
140 __u32 todpr; /* 0x006c */ 142 __u32 todpr; /* 0x006c */
@@ -505,10 +507,14 @@ struct s390_io_adapter {
505struct kvm_s390_crypto { 507struct kvm_s390_crypto {
506 struct kvm_s390_crypto_cb *crycb; 508 struct kvm_s390_crypto_cb *crycb;
507 __u32 crycbd; 509 __u32 crycbd;
510 __u8 aes_kw;
511 __u8 dea_kw;
508}; 512};
509 513
510struct kvm_s390_crypto_cb { 514struct kvm_s390_crypto_cb {
511 __u8 reserved00[128]; /* 0x0000 */ 515 __u8 reserved00[72]; /* 0x0000 */
516 __u8 dea_wrapping_key_mask[24]; /* 0x0048 */
517 __u8 aes_wrapping_key_mask[32]; /* 0x0060 */
512}; 518};
513 519
514struct kvm_arch{ 520struct kvm_arch{
diff --git a/arch/s390/include/uapi/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
index cb64319d3e51..546fc3a302e5 100644
--- a/arch/s390/include/uapi/asm/kvm.h
+++ b/arch/s390/include/uapi/asm/kvm.h
@@ -58,6 +58,7 @@ struct kvm_s390_io_adapter_req {
58/* kvm attr_group on vm fd */ 58/* kvm attr_group on vm fd */
59#define KVM_S390_VM_MEM_CTRL 0 59#define KVM_S390_VM_MEM_CTRL 0
60#define KVM_S390_VM_TOD 1 60#define KVM_S390_VM_TOD 1
61#define KVM_S390_VM_CRYPTO 2
61 62
62/* kvm attributes for mem_ctrl */ 63/* kvm attributes for mem_ctrl */
63#define KVM_S390_VM_MEM_ENABLE_CMMA 0 64#define KVM_S390_VM_MEM_ENABLE_CMMA 0
@@ -68,6 +69,12 @@ struct kvm_s390_io_adapter_req {
68#define KVM_S390_VM_TOD_LOW 0 69#define KVM_S390_VM_TOD_LOW 0
69#define KVM_S390_VM_TOD_HIGH 1 70#define KVM_S390_VM_TOD_HIGH 1
70 71
72/* kvm attributes for crypto */
73#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
74#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1
75#define KVM_S390_VM_CRYPTO_DISABLE_AES_KW 2
76#define KVM_S390_VM_CRYPTO_DISABLE_DEA_KW 3
77
71/* for KVM_GET_REGS and KVM_SET_REGS */ 78/* for KVM_GET_REGS and KVM_SET_REGS */
72struct kvm_regs { 79struct kvm_regs {
73 /* general purpose regs for s390 */ 80 /* general purpose regs for s390 */
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