]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
KVM: s390: implement subfunction processor calls
authorChristian Borntraeger <borntraeger@de.ibm.com>
Mon, 18 Feb 2019 12:48:25 +0000 (07:48 -0500)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 22 Feb 2019 10:04:35 +0000 (11:04 +0100)
While we will not implement interception for query functions yet, we can
and should disable functions that have a control bit based on the given
CPU model.

Let us start with enabling the subfunction interface.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Janosch Frank <frankja@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
arch/s390/include/asm/kvm_host.h
arch/s390/kvm/kvm-s390.c

index c5f51566ecd6693a95b2c4fe9ef028c0d4ae46c8..3369677a7df710379341c6eaec200ac5d3130db7 100644 (file)
@@ -711,6 +711,7 @@ struct s390_io_adapter {
 struct kvm_s390_cpu_model {
        /* facility mask supported by kvm & hosting machine */
        __u64 fac_mask[S390_ARCH_FAC_LIST_SIZE_U64];
+       struct kvm_s390_vm_cpu_subfunc subfuncs;
        /* facility list requested by guest (in dma page) */
        __u64 *fac_list;
        u64 cpuid;
index 2e47c724679e32a2950a4c1e4422e63f58370703..82a95afa6629c21d63a009a3357aa2487b543b0e 100644 (file)
@@ -1266,11 +1266,20 @@ static int kvm_s390_set_processor_feat(struct kvm *kvm,
 static int kvm_s390_set_processor_subfunc(struct kvm *kvm,
                                          struct kvm_device_attr *attr)
 {
-       /*
-        * Once supported by kernel + hw, we have to store the subfunctions
-        * in kvm->arch and remember that user space configured them.
-        */
-       return -ENXIO;
+       mutex_lock(&kvm->lock);
+       if (kvm->created_vcpus) {
+               mutex_unlock(&kvm->lock);
+               return -EBUSY;
+       }
+
+       if (copy_from_user(&kvm->arch.model.subfuncs, (void __user *)attr->addr,
+                          sizeof(struct kvm_s390_vm_cpu_subfunc))) {
+               mutex_unlock(&kvm->lock);
+               return -EFAULT;
+       }
+       mutex_unlock(&kvm->lock);
+
+       return 0;
 }
 
 static int kvm_s390_set_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
@@ -1389,12 +1398,11 @@ static int kvm_s390_get_machine_feat(struct kvm *kvm,
 static int kvm_s390_get_processor_subfunc(struct kvm *kvm,
                                          struct kvm_device_attr *attr)
 {
-       /*
-        * Once we can actually configure subfunctions (kernel + hw support),
-        * we have to check if they were already set by user space, if so copy
-        * them from kvm->arch.
-        */
-       return -ENXIO;
+       if (copy_to_user((void __user *)attr->addr, &kvm->arch.model.subfuncs,
+           sizeof(struct kvm_s390_vm_cpu_subfunc)))
+               return -EFAULT;
+
+       return 0;
 }
 
 static int kvm_s390_get_machine_subfunc(struct kvm *kvm,
@@ -1405,6 +1413,7 @@ static int kvm_s390_get_machine_subfunc(struct kvm *kvm,
                return -EFAULT;
        return 0;
 }
+
 static int kvm_s390_get_cpu_model(struct kvm *kvm, struct kvm_device_attr *attr)
 {
        int ret = -ENXIO;
@@ -1522,10 +1531,9 @@ static int kvm_s390_vm_has_attr(struct kvm *kvm, struct kvm_device_attr *attr)
                case KVM_S390_VM_CPU_PROCESSOR_FEAT:
                case KVM_S390_VM_CPU_MACHINE_FEAT:
                case KVM_S390_VM_CPU_MACHINE_SUBFUNC:
+               case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC:
                        ret = 0;
                        break;
-               /* configuring subfunctions is not supported yet */
-               case KVM_S390_VM_CPU_PROCESSOR_SUBFUNC:
                default:
                        ret = -ENXIO;
                        break;
@@ -2227,6 +2235,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
                kvm->arch.model.fac_list[i] = S390_lowcore.stfle_fac_list[i] &
                                              kvm_s390_fac_base[i];
        }
+       kvm->arch.model.subfuncs = kvm_s390_available_subfunc;
 
        /* we are always in czam mode - even on pre z14 machines */
        set_kvm_facility(kvm->arch.model.fac_mask, 138);