@@ -1531,6 +1531,39 @@ static int kvm_s390_set_processor_subfunc(struct kvm *kvm,
15311531 return 0 ;
15321532}
15331533
1534+ #define KVM_S390_VM_CPU_UV_FEAT_GUEST_MASK \
1535+ ( \
1536+ ((struct kvm_s390_vm_cpu_uv_feat){ \
1537+ .ap = 1, \
1538+ .ap_intr = 1, \
1539+ }) \
1540+ .feat \
1541+ )
1542+
1543+ static int kvm_s390_set_uv_feat (struct kvm * kvm , struct kvm_device_attr * attr )
1544+ {
1545+ struct kvm_s390_vm_cpu_uv_feat __user * ptr = (void __user * )attr -> addr ;
1546+ unsigned long data , filter ;
1547+
1548+ filter = uv_info .uv_feature_indications & KVM_S390_VM_CPU_UV_FEAT_GUEST_MASK ;
1549+ if (get_user (data , & ptr -> feat ))
1550+ return - EFAULT ;
1551+ if (!bitmap_subset (& data , & filter , KVM_S390_VM_CPU_UV_FEAT_NR_BITS ))
1552+ return - EINVAL ;
1553+
1554+ mutex_lock (& kvm -> lock );
1555+ if (kvm -> created_vcpus ) {
1556+ mutex_unlock (& kvm -> lock );
1557+ return - EBUSY ;
1558+ }
1559+ kvm -> arch .model .uv_feat_guest .feat = data ;
1560+ mutex_unlock (& kvm -> lock );
1561+
1562+ VM_EVENT (kvm , 3 , "SET: guest UV-feat: 0x%16.16lx" , data );
1563+
1564+ return 0 ;
1565+ }
1566+
15341567static int kvm_s390_set_cpu_model (struct kvm * kvm , struct kvm_device_attr * attr )
15351568{
15361569 int ret = - ENXIO ;
@@ -1545,6 +1578,9 @@ static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
15451578 case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC :
15461579 ret = kvm_s390_set_processor_subfunc (kvm , attr );
15471580 break ;
1581+ case KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST :
1582+ ret = kvm_s390_set_uv_feat (kvm , attr );
1583+ break ;
15481584 }
15491585 return ret ;
15501586}
@@ -1777,6 +1813,33 @@ static int kvm_s390_get_machine_subfunc(struct kvm *kvm,
17771813 return 0 ;
17781814}
17791815
1816+ static int kvm_s390_get_processor_uv_feat (struct kvm * kvm , struct kvm_device_attr * attr )
1817+ {
1818+ struct kvm_s390_vm_cpu_uv_feat __user * dst = (void __user * )attr -> addr ;
1819+ unsigned long feat = kvm -> arch .model .uv_feat_guest .feat ;
1820+
1821+ if (put_user (feat , & dst -> feat ))
1822+ return - EFAULT ;
1823+ VM_EVENT (kvm , 3 , "GET: guest UV-feat: 0x%16.16lx" , feat );
1824+
1825+ return 0 ;
1826+ }
1827+
1828+ static int kvm_s390_get_machine_uv_feat (struct kvm * kvm , struct kvm_device_attr * attr )
1829+ {
1830+ struct kvm_s390_vm_cpu_uv_feat __user * dst = (void __user * )attr -> addr ;
1831+ unsigned long feat ;
1832+
1833+ BUILD_BUG_ON (sizeof (* dst ) != sizeof (uv_info .uv_feature_indications ));
1834+
1835+ feat = uv_info .uv_feature_indications & KVM_S390_VM_CPU_UV_FEAT_GUEST_MASK ;
1836+ if (put_user (feat , & dst -> feat ))
1837+ return - EFAULT ;
1838+ VM_EVENT (kvm , 3 , "GET: guest UV-feat: 0x%16.16lx" , feat );
1839+
1840+ return 0 ;
1841+ }
1842+
17801843static int kvm_s390_get_cpu_model (struct kvm * kvm , struct kvm_device_attr * attr )
17811844{
17821845 int ret = - ENXIO ;
@@ -1800,6 +1863,12 @@ static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
18001863 case KVM_S390_VM_CPU_MACHINE_SUBFUNC :
18011864 ret = kvm_s390_get_machine_subfunc (kvm , attr );
18021865 break ;
1866+ case KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST :
1867+ ret = kvm_s390_get_processor_uv_feat (kvm , attr );
1868+ break ;
1869+ case KVM_S390_VM_CPU_MACHINE_UV_FEAT_GUEST :
1870+ ret = kvm_s390_get_machine_uv_feat (kvm , attr );
1871+ break ;
18031872 }
18041873 return ret ;
18051874}
@@ -1952,6 +2021,8 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
19522021 case KVM_S390_VM_CPU_MACHINE_FEAT :
19532022 case KVM_S390_VM_CPU_MACHINE_SUBFUNC :
19542023 case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC :
2024+ case KVM_S390_VM_CPU_MACHINE_UV_FEAT_GUEST :
2025+ case KVM_S390_VM_CPU_PROCESSOR_UV_FEAT_GUEST :
19552026 ret = 0 ;
19562027 break ;
19572028 default :
@@ -3296,6 +3367,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
32963367 kvm -> arch .model .cpuid = kvm_s390_get_initial_cpuid ();
32973368 kvm -> arch .model .ibc = sclp .ibc & 0x0fff ;
32983369
3370+ kvm -> arch .model .uv_feat_guest .feat = 0 ;
3371+
32993372 kvm_s390_crypto_init (kvm );
33003373
33013374 if (IS_ENABLED (CONFIG_VFIO_PCI_ZDEV_KVM )) {
0 commit comments