diff options
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 49 |
2 files changed, 49 insertions, 2 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index f79058e3fd98..77ae01444e98 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -163,6 +163,7 @@ struct kvm_s390_sie_block { | |||
| 163 | __u64 tecmc; /* 0x00e8 */ | 163 | __u64 tecmc; /* 0x00e8 */ |
| 164 | __u8 reservedf0[12]; /* 0x00f0 */ | 164 | __u8 reservedf0[12]; /* 0x00f0 */ |
| 165 | #define CRYCB_FORMAT1 0x00000001 | 165 | #define CRYCB_FORMAT1 0x00000001 |
| 166 | #define CRYCB_FORMAT2 0x00000003 | ||
| 166 | __u32 crycbd; /* 0x00fc */ | 167 | __u32 crycbd; /* 0x00fc */ |
| 167 | __u64 gcr[16]; /* 0x0100 */ | 168 | __u64 gcr[16]; /* 0x0100 */ |
| 168 | __u64 gbea; /* 0x0180 */ | 169 | __u64 gbea; /* 0x0180 */ |
| @@ -516,6 +517,7 @@ struct kvm_s390_crypto_cb { | |||
| 516 | __u8 reserved00[72]; /* 0x0000 */ | 517 | __u8 reserved00[72]; /* 0x0000 */ |
| 517 | __u8 dea_wrapping_key_mask[24]; /* 0x0048 */ | 518 | __u8 dea_wrapping_key_mask[24]; /* 0x0048 */ |
| 518 | __u8 aes_wrapping_key_mask[32]; /* 0x0060 */ | 519 | __u8 aes_wrapping_key_mask[32]; /* 0x0060 */ |
| 520 | __u8 reserved80[128]; /* 0x0080 */ | ||
| 519 | }; | 521 | }; |
| 520 | 522 | ||
| 521 | struct kvm_arch{ | 523 | struct kvm_arch{ |
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; |
