diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/s390/include/asm/kvm_host.h | 12 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 30 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 3 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 2 |
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 | ||
518 | struct s390_model_fac { | 518 | struct 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 | ||
525 | struct kvm_s390_cpu_model { | 525 | struct 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 */ |
129 | static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) | 129 | static 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) |