@@ -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 /*
@@ -799,6 +812,14 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
799812 set_kvm_facility (kvm -> arch .model .fac_mask , 192 );
800813 set_kvm_facility (kvm -> arch .model .fac_list , 192 );
801814 }
815+ if (test_facility (198 )) {
816+ set_kvm_facility (kvm -> arch .model .fac_mask , 198 );
817+ set_kvm_facility (kvm -> arch .model .fac_list , 198 );
818+ }
819+ if (test_facility (199 )) {
820+ set_kvm_facility (kvm -> arch .model .fac_mask , 199 );
821+ set_kvm_facility (kvm -> arch .model .fac_list , 199 );
822+ }
802823 r = 0 ;
803824 } else
804825 r = - EINVAL ;
@@ -1543,6 +1564,9 @@ static int kvm_s390_set_processor_subfunc(struct kvm *kvm,
15431564 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[1 ],
15441565 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[2 ],
15451566 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[3 ]);
1567+ VM_EVENT (kvm , 3 , "GET: guest PFCR subfunc 0x%16.16lx.%16.16lx" ,
1568+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1569+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
15461570
15471571 return 0 ;
15481572}
@@ -1757,6 +1781,9 @@ static int kvm_s390_get_processor_subfunc(struct kvm *kvm,
17571781 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[1 ],
17581782 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[2 ],
17591783 ((unsigned long * ) & kvm -> arch .model .subfuncs .dfltcc )[3 ]);
1784+ VM_EVENT (kvm , 3 , "GET: guest PFCR subfunc 0x%16.16lx.%16.16lx" ,
1785+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1786+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
17601787
17611788 return 0 ;
17621789}
@@ -1825,6 +1852,9 @@ static int kvm_s390_get_machine_subfunc(struct kvm *kvm,
18251852 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[1 ],
18261853 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[2 ],
18271854 ((unsigned long * ) & kvm_s390_available_subfunc .dfltcc )[3 ]);
1855+ VM_EVENT (kvm , 3 , "GET: host PFCR subfunc 0x%16.16lx.%16.16lx" ,
1856+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[0 ],
1857+ ((unsigned long * ) & kvm_s390_available_subfunc .pfcr )[1 ]);
18281858
18291859 return 0 ;
18301860}
@@ -3774,6 +3804,13 @@ static bool kvm_has_pckmo_ecc(struct kvm *kvm)
37743804
37753805}
37763806
3807+ static bool kvm_has_pckmo_hmac (struct kvm * kvm )
3808+ {
3809+ /* At least one HMAC subfunction must be present */
3810+ return kvm_has_pckmo_subfunc (kvm , 118 ) ||
3811+ kvm_has_pckmo_subfunc (kvm , 122 );
3812+ }
3813+
37773814static void kvm_s390_vcpu_crypto_setup (struct kvm_vcpu * vcpu )
37783815{
37793816 /*
@@ -3786,17 +3823,19 @@ static void kvm_s390_vcpu_crypto_setup(struct kvm_vcpu *vcpu)
37863823 vcpu -> arch .sie_block -> crycbd = vcpu -> kvm -> arch .crypto .crycbd ;
37873824 vcpu -> arch .sie_block -> ecb3 &= ~(ECB3_AES | ECB3_DEA );
37883825 vcpu -> arch .sie_block -> eca &= ~ECA_APIE ;
3789- vcpu -> arch .sie_block -> ecd &= ~ECD_ECC ;
3826+ vcpu -> arch .sie_block -> ecd &= ~( ECD_ECC | ECD_HMAC ) ;
37903827
37913828 if (vcpu -> kvm -> arch .crypto .apie )
37923829 vcpu -> arch .sie_block -> eca |= ECA_APIE ;
37933830
37943831 /* Set up protected key support */
37953832 if (vcpu -> kvm -> arch .crypto .aes_kw ) {
37963833 vcpu -> arch .sie_block -> ecb3 |= ECB3_AES ;
3797- /* ecc is also wrapped with AES key */
3834+ /* ecc/hmac is also wrapped with AES key */
37983835 if (kvm_has_pckmo_ecc (vcpu -> kvm ))
37993836 vcpu -> arch .sie_block -> ecd |= ECD_ECC ;
3837+ if (kvm_has_pckmo_hmac (vcpu -> kvm ))
3838+ vcpu -> arch .sie_block -> ecd |= ECD_HMAC ;
38003839 }
38013840
38023841 if (vcpu -> kvm -> arch .crypto .dea_kw )
0 commit comments