diff options
author | Tony Krowiak <akrowiak@linux.vnet.ibm.com> | 2015-01-13 11:33:26 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2015-02-09 06:44:12 -0500 |
commit | 45c9b47c5883d02abab6c7c7788e3d97a2f158e1 (patch) | |
tree | da38a436bce71e8c93126a1c1b00d7e1d85659a9 /arch/s390/kvm | |
parent | f3d0bd6c7f07d2be4b429230386d49f1b1b14f1c (diff) |
KVM: s390/CPACF: Choose crypto control block format
We need to specify a different format for the crypto control block
depending on whether the APXA facility is installed or not. Let's
test for it by executing the PQAP(QCI) function and use either a
format-1 or a format-2 crypto control block accordingly. This is a
host only change for z13 and does not affect the guest view.
Signed-off-by: Tony Krowiak <akrowiak@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 3acf08ba88e4..deac47378f77 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -654,6 +654,52 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
654 | return r; | 654 | return r; |
655 | } | 655 | } |
656 | 656 | ||
657 | static int kvm_s390_query_ap_config(u8 *config) | ||
658 | { | ||
659 | u32 fcn_code = 0x04000000UL; | ||
660 | u32 cc; | ||
661 | |||
662 | asm volatile( | ||
663 | "lgr 0,%1\n" | ||
664 | "lgr 2,%2\n" | ||
665 | ".long 0xb2af0000\n" /* PQAP(QCI) */ | ||
666 | "ipm %0\n" | ||
667 | "srl %0,28\n" | ||
668 | : "=r" (cc) | ||
669 | : "r" (fcn_code), "r" (config) | ||
670 | : "cc", "0", "2", "memory" | ||
671 | ); | ||
672 | |||
673 | return cc; | ||
674 | } | ||
675 | |||
676 | static int kvm_s390_apxa_installed(void) | ||
677 | { | ||
678 | u8 config[128]; | ||
679 | int cc; | ||
680 | |||
681 | if (test_facility(2) && test_facility(12)) { | ||
682 | cc = kvm_s390_query_ap_config(config); | ||
683 | |||
684 | if (cc) | ||
685 | pr_err("PQAP(QCI) failed with cc=%d", cc); | ||
686 | else | ||
687 | return config[0] & 0x40; | ||
688 | } | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | static void kvm_s390_set_crycb_format(struct kvm *kvm) | ||
694 | { | ||
695 | kvm->arch.crypto.crycbd = (__u32)(unsigned long) kvm->arch.crypto.crycb; | ||
696 | |||
697 | if (kvm_s390_apxa_installed()) | ||
698 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT2; | ||
699 | else | ||
700 | kvm->arch.crypto.crycbd |= CRYCB_FORMAT1; | ||
701 | } | ||
702 | |||
657 | static int kvm_s390_crypto_init(struct kvm *kvm) | 703 | static int kvm_s390_crypto_init(struct kvm *kvm) |
658 | { | 704 | { |
659 | if (!test_vfacility(76)) | 705 | if (!test_vfacility(76)) |
@@ -664,8 +710,7 @@ static int kvm_s390_crypto_init(struct kvm *kvm) | |||
664 | if (!kvm->arch.crypto.crycb) | 710 | if (!kvm->arch.crypto.crycb) |
665 | return -ENOMEM; | 711 | return -ENOMEM; |
666 | 712 | ||
667 | kvm->arch.crypto.crycbd = (__u32) (unsigned long) kvm->arch.crypto.crycb | | 713 | kvm_s390_set_crycb_format(kvm); |
668 | CRYCB_FORMAT1; | ||
669 | 714 | ||
670 | /* Disable AES/DEA protected key functions by default */ | 715 | /* Disable AES/DEA protected key functions by default */ |
671 | kvm->arch.crypto.aes_kw = 0; | 716 | kvm->arch.crypto.aes_kw = 0; |