aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
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)