aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorTony Krowiak <akrowiak@linux.vnet.ibm.com>2015-01-13 11:33:26 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-02-09 06:44:12 -0500
commit45c9b47c5883d02abab6c7c7788e3d97a2f158e1 (patch)
treeda38a436bce71e8c93126a1c1b00d7e1d85659a9 /arch/s390/kvm
parentf3d0bd6c7f07d2be4b429230386d49f1b1b14f1c (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.c49
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
657static 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
676static 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
693static 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
657static int kvm_s390_crypto_init(struct kvm *kvm) 703static 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;