aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichael Mueller <mimu@linux.vnet.ibm.com>2015-02-24 07:51:04 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2015-03-04 04:33:25 -0500
commit981467c930bdfa4be59acbbc9f3a80eb9e3167a8 (patch)
tree053681bb659da7ff0923bad2a338609f8e58f5fa /arch
parent94422ee880afc4af050bac172ea39af8e2130034 (diff)
KVM: s390: include guest facilities in kvm facility test
Most facility related decisions in KVM have to take into account: - the facilities offered by the underlying run container (LPAR/VM) - the facilities supported by the KVM code itself - the facilities requested by a guest VM This patch adds the KVM driver requested facilities to the test routine. It additionally renames struct s390_model_fac to kvm_s390_fac and its field names to be more meaningful. The semantics of the facilities stored in the KVM architecture structure is changed. The address arch.model.fac->list now points to the guest facility list and arch.model.fac->mask points to the KVM facility mask. This patch fixes the behaviour of KVM for some facilities for guests that ignore the guest visible facility bits, e.g. guests could use transactional memory intructions on hosts supporting them even if the chosen cpu model would not offer them. The userspace interface is not affected by this change. Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/include/asm/kvm_host.h12
-rw-r--r--arch/s390/kvm/kvm-s390.c30
-rw-r--r--arch/s390/kvm/kvm-s390.h3
-rw-r--r--arch/s390/kvm/priv.c2
4 files changed, 25 insertions, 22 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index d84559e31f32..f407bbf5ee94 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -515,15 +515,15 @@ struct s390_io_adapter {
515#define S390_ARCH_FAC_MASK_SIZE_U64 \ 515#define S390_ARCH_FAC_MASK_SIZE_U64 \
516 (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64)) 516 (S390_ARCH_FAC_MASK_SIZE_BYTE / sizeof(u64))
517 517
518struct s390_model_fac { 518struct kvm_s390_fac {
519 /* facilities used in SIE context */ 519 /* facility list requested by guest */
520 __u64 sie[S390_ARCH_FAC_LIST_SIZE_U64]; 520 __u64 list[S390_ARCH_FAC_LIST_SIZE_U64];
521 /* subset enabled by kvm */ 521 /* facility mask supported by kvm & hosting machine */
522 __u64 kvm[S390_ARCH_FAC_LIST_SIZE_U64]; 522 __u64 mask[S390_ARCH_FAC_LIST_SIZE_U64];
523}; 523};
524 524
525struct kvm_s390_cpu_model { 525struct kvm_s390_cpu_model {
526 struct s390_model_fac *fac; 526 struct kvm_s390_fac *fac;
527 struct cpuid cpu_id; 527 struct cpuid cpu_id;
528 unsigned short ibc; 528 unsigned short ibc;
529}; 529};
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 76894c8db4d7..5a02be4628f1 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -522,7 +522,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr)
522 memcpy(&kvm->arch.model.cpu_id, &proc->cpuid, 522 memcpy(&kvm->arch.model.cpu_id, &proc->cpuid,
523 sizeof(struct cpuid)); 523 sizeof(struct cpuid));
524 kvm->arch.model.ibc = proc->ibc; 524 kvm->arch.model.ibc = proc->ibc;
525 memcpy(kvm->arch.model.fac->kvm, proc->fac_list, 525 memcpy(kvm->arch.model.fac->list, proc->fac_list,
526 S390_ARCH_FAC_LIST_SIZE_BYTE); 526 S390_ARCH_FAC_LIST_SIZE_BYTE);
527 } else 527 } else
528 ret = -EFAULT; 528 ret = -EFAULT;
@@ -556,7 +556,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr)
556 } 556 }
557 memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid)); 557 memcpy(&proc->cpuid, &kvm->arch.model.cpu_id, sizeof(struct cpuid));
558 proc->ibc = kvm->arch.model.ibc; 558 proc->ibc = kvm->arch.model.ibc;
559 memcpy(&proc->fac_list, kvm->arch.model.fac->kvm, S390_ARCH_FAC_LIST_SIZE_BYTE); 559 memcpy(&proc->fac_list, kvm->arch.model.fac->list, S390_ARCH_FAC_LIST_SIZE_BYTE);
560 if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc))) 560 if (copy_to_user((void __user *)attr->addr, proc, sizeof(*proc)))
561 ret = -EFAULT; 561 ret = -EFAULT;
562 kfree(proc); 562 kfree(proc);
@@ -576,8 +576,8 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr)
576 } 576 }
577 get_cpu_id((struct cpuid *) &mach->cpuid); 577 get_cpu_id((struct cpuid *) &mach->cpuid);
578 mach->ibc = sclp_get_ibc(); 578 mach->ibc = sclp_get_ibc();
579 memcpy(&mach->fac_mask, kvm_s390_fac_list_mask, 579 memcpy(&mach->fac_mask, kvm->arch.model.fac->mask,
580 kvm_s390_fac_list_mask_size() * sizeof(u64)); 580 S390_ARCH_FAC_LIST_SIZE_BYTE);
581 memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, 581 memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list,
582 S390_ARCH_FAC_LIST_SIZE_BYTE); 582 S390_ARCH_FAC_LIST_SIZE_BYTE);
583 if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach))) 583 if (copy_to_user((void __user *)attr->addr, mach, sizeof(*mach)))
@@ -893,16 +893,16 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
893 /* 893 /*
894 * The architectural maximum amount of facilities is 16 kbit. To store 894 * The architectural maximum amount of facilities is 16 kbit. To store
895 * this amount, 2 kbyte of memory is required. Thus we need a full 895 * this amount, 2 kbyte of memory is required. Thus we need a full
896 * page to hold the active copy (arch.model.fac->sie) and the current 896 * page to hold the guest facility list (arch.model.fac->list) and the
897 * facilities set (arch.model.fac->kvm). Its address size has to be 897 * facility mask (arch.model.fac->mask). Its address size has to be
898 * 31 bits and word aligned. 898 * 31 bits and word aligned.
899 */ 899 */
900 kvm->arch.model.fac = 900 kvm->arch.model.fac =
901 (struct s390_model_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 901 (struct kvm_s390_fac *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
902 if (!kvm->arch.model.fac) 902 if (!kvm->arch.model.fac)
903 goto out_nofac; 903 goto out_nofac;
904 904
905 memcpy(kvm->arch.model.fac->kvm, S390_lowcore.stfle_fac_list, 905 memcpy(kvm->arch.model.fac->mask, S390_lowcore.stfle_fac_list,
906 S390_ARCH_FAC_LIST_SIZE_BYTE); 906 S390_ARCH_FAC_LIST_SIZE_BYTE);
907 907
908 /* 908 /*
@@ -914,7 +914,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
914 */ 914 */
915 if (!MACHINE_IS_LPAR) 915 if (!MACHINE_IS_LPAR)
916 for (i = 0; i < kvm_s390_fac_list_mask_size(); i++) 916 for (i = 0; i < kvm_s390_fac_list_mask_size(); i++)
917 kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->kvm[i]; 917 kvm_s390_fac_list_mask[i] &= kvm->arch.model.fac->mask[i];
918 918
919 /* 919 /*
920 * Apply the kvm facility mask to limit the kvm supported/tolerated 920 * Apply the kvm facility mask to limit the kvm supported/tolerated
@@ -922,11 +922,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
922 */ 922 */
923 for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) { 923 for (i = 0; i < S390_ARCH_FAC_LIST_SIZE_U64; i++) {
924 if (i < kvm_s390_fac_list_mask_size()) 924 if (i < kvm_s390_fac_list_mask_size())
925 kvm->arch.model.fac->kvm[i] &= kvm_s390_fac_list_mask[i]; 925 kvm->arch.model.fac->mask[i] &= kvm_s390_fac_list_mask[i];
926 else 926 else
927 kvm->arch.model.fac->kvm[i] = 0UL; 927 kvm->arch.model.fac->mask[i] = 0UL;
928 } 928 }
929 929
930 /* Populate the facility list initially. */
931 memcpy(kvm->arch.model.fac->list, kvm->arch.model.fac->mask,
932 S390_ARCH_FAC_LIST_SIZE_BYTE);
933
930 kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id); 934 kvm_s390_get_cpu_id(&kvm->arch.model.cpu_id);
931 kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff; 935 kvm->arch.model.ibc = sclp_get_ibc() & 0x0fff;
932 936
@@ -1172,8 +1176,6 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
1172 1176
1173 mutex_lock(&vcpu->kvm->lock); 1177 mutex_lock(&vcpu->kvm->lock);
1174 vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id; 1178 vcpu->arch.cpu_id = vcpu->kvm->arch.model.cpu_id;
1175 memcpy(vcpu->kvm->arch.model.fac->sie, vcpu->kvm->arch.model.fac->kvm,
1176 S390_ARCH_FAC_LIST_SIZE_BYTE);
1177 vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc; 1179 vcpu->arch.sie_block->ibc = vcpu->kvm->arch.model.ibc;
1178 mutex_unlock(&vcpu->kvm->lock); 1180 mutex_unlock(&vcpu->kvm->lock);
1179 1181
@@ -1219,7 +1221,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
1219 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca; 1221 vcpu->arch.sie_block->scaol = (__u32)(__u64)kvm->arch.sca;
1220 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn); 1222 set_bit(63 - id, (unsigned long *) &kvm->arch.sca->mcn);
1221 } 1223 }
1222 vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->sie; 1224 vcpu->arch.sie_block->fac = (int) (long) kvm->arch.model.fac->list;
1223 1225
1224 spin_lock_init(&vcpu->arch.local_int.lock); 1226 spin_lock_init(&vcpu->arch.local_int.lock);
1225 vcpu->arch.local_int.float_int = &kvm->arch.float_int; 1227 vcpu->arch.local_int.float_int = &kvm->arch.float_int;
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 985c2114d7ef..c34109aa552d 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -128,7 +128,8 @@ static inline void kvm_s390_set_psw_cc(struct kvm_vcpu *vcpu, unsigned long cc)
128/* test availability of facility in a kvm intance */ 128/* test availability of facility in a kvm intance */
129static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) 129static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr)
130{ 130{
131 return __test_facility(nr, kvm->arch.model.fac->kvm); 131 return __test_facility(nr, kvm->arch.model.fac->mask) &&
132 __test_facility(nr, kvm->arch.model.fac->list);
132} 133}
133 134
134/* are cpu states controlled by user space */ 135/* are cpu states controlled by user space */
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index bdd9b5b17e03..351116939ea2 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -348,7 +348,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
348 * We need to shift the lower 32 facility bits (bit 0-31) from a u64 348 * We need to shift the lower 32 facility bits (bit 0-31) from a u64
349 * into a u32 memory representation. They will remain bits 0-31. 349 * into a u32 memory representation. They will remain bits 0-31.
350 */ 350 */
351 fac = *vcpu->kvm->arch.model.fac->sie >> 32; 351 fac = *vcpu->kvm->arch.model.fac->list >> 32;
352 rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), 352 rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list),
353 &fac, sizeof(fac)); 353 &fac, sizeof(fac));
354 if (rc) 354 if (rc)