@@ -348,6 +348,16 @@ static inline int plo_test_bit(unsigned char nr)
348348 return cc == 0 ;
349349}
350350
351+ static __always_inline void pfcr_query (u8 (* query )[16 ])
352+ {
353+ asm volatile (
354+ " lghi 0,0\n"
355+ " .insn rsy,0xeb0000000016,0,0,%[query]\n"
356+ : [query ] "=QS" (* query )
357+ :
358+ : "cc" , "0" );
359+ }
360+
351361static __always_inline void __sortl_query (u8 (* query )[32 ])
352362{
353363 asm volatile (
@@ -429,6 +439,9 @@ static void __init kvm_s390_cpu_feat_init(void)
429439 if (test_facility (151 )) /* DFLTCC */
430440 __dfltcc_query (& kvm_s390_available_subfunc .dfltcc );
431441
442+ if (test_facility (201 )) /* PFCR */
443+ pfcr_query (& kvm_s390_available_subfunc .pfcr );
444+
432445 if (MACHINE_HAS_ESOP )
433446 allow_cpu_feat (KVM_S390_VM_CPU_FEAT_ESOP );
434447 /*
@@ -797,6 +810,14 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
797810 set_kvm_facility (kvm -> arch .model .fac_mask , 192 );
798811 set_kvm_facility (kvm -> arch .model .fac_list , 192 );
799812 }
813+ if (test_facility (198 )) {
814+ set_kvm_facility (kvm -> arch .model .fac_mask , 198 );
815+ set_kvm_facility (kvm -> arch .model .fac_list , 198 );
816+ }
817+ if (test_facility (199 )) {
818+ set_kvm_facility (kvm -> arch .model .fac_mask , 199 );
819+ set_kvm_facility (kvm -> arch .model .fac_list , 199 );
820+ }
800821 r = 0 ;
801822 } else
802823 r = - EINVAL ;
@@ -1541,6 +1562,9 @@ static int kvm_s390_set_processor_subfunc(struct kvm *kvm,
15411562 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[1 ],
15421563 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[2 ],
15431564 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[3 ]);
1565+ VM_EVENT (kvm , 3 , "GET: guest PFCR subfunc 0x%16.16lx.%16.16lx" ,
1566+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1567+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
15441568
15451569 return 0 ;
15461570}
@@ -1755,6 +1779,9 @@ static int kvm_s390_get_processor_subfunc(struct kvm *kvm,
17551779 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[1 ],
17561780 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[2 ],
17571781 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[3 ]);
1782+ VM_EVENT (kvm , 3 , "GET: guest PFCR subfunc 0x%16.16lx.%16.16lx" ,
1783+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1784+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
17581785
17591786 return 0 ;
17601787}
@@ -1823,6 +1850,9 @@ static int kvm_s390_get_machine_subfunc(struct kvm *kvm,
18231850 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[1 ],
18241851 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[2 ],
18251852 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[3 ]);
1853+ VM_EVENT (kvm , 3 , "GET: host PFCR subfunc 0x%16.16lx.%16.16lx" ,
1854+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1855+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
18261856
18271857 return 0 ;
18281858}
@@ -3777,6 +3807,13 @@ static bool kvm_has_pckmo_ecc(struct kvm *kvm)
37773807
37783808}
37793809
3810+ static bool kvm_has_pckmo_hmac (struct kvm * kvm )
3811+ {
3812+ /* At least one HMAC subfunction must be present */
3813+ return kvm_has_pckmo_subfunc (kvm , 118 ) ||
3814+ kvm_has_pckmo_subfunc (kvm , 122 );
3815+ }
3816+
37803817static void kvm_s390_vcpu_crypto_setup (struct kvm_vcpu * vcpu )
37813818{
37823819 /*
@@ -3789,17 +3826,19 @@ static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
37893826 vcpu -> arch .sie_block -> crycbd = vcpu -> kvm -> arch .crypto .crycbd ;
37903827 vcpu -> arch .sie_block -> ecb3 &= ~(ECB3_AES | ECB3_DEA );
37913828 vcpu -> arch .sie_block -> eca &= ~ECA_APIE ;
3792- vcpu -> arch .sie_block -> ecd &= ~ECD_ECC ;
3829+ vcpu -> arch .sie_block -> ecd &= ~( ECD_ECC | ECD_HMAC ) ;
37933830
37943831 if (vcpu -> kvm -> arch .crypto .apie )
37953832 vcpu -> arch .sie_block -> eca |= ECA_APIE ;
37963833
37973834 /* Set up protected key support */
37983835 if (vcpu -> kvm -> arch .crypto .aes_kw ) {
37993836 vcpu -> arch .sie_block -> ecb3 |= ECB3_AES ;
3800- /* ecc is also wrapped with AES key */
3837+ /* ecc/hmac is also wrapped with AES key */
38013838 if (kvm_has_pckmo_ecc (vcpu -> kvm ))
38023839 vcpu -> arch .sie_block -> ecd |= ECD_ECC ;
3840+ if (kvm_has_pckmo_hmac (vcpu -> kvm ))
3841+ vcpu -> arch .sie_block -> ecd |= ECD_HMAC ;
38033842 }
38043843
38053844 if (vcpu -> kvm -> arch .crypto .dea_kw )
0 commit comments