diff options
| author | Michael Mueller <mimu@linux.vnet.ibm.com> | 2015-03-16 11:05:41 -0400 |
|---|---|---|
| committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2015-03-17 11:33:14 -0400 |
| commit | 18280d8b4bcd4a2b174ee3cd748166c6190acacb (patch) | |
| tree | ff82ed01c51560e596d7321ca27d3353e3bc7c93 | |
| parent | 400ac6cd73633f61e42a035b910c3db2b590b9d5 (diff) | |
KVM: s390: represent SIMD cap in kvm facility
The patch represents capability KVM_CAP_S390_VECTOR_REGISTERS by means
of the SIMD facility bit. This allows to a) disable the use of SIMD when
used in conjunction with a not-SIMD-aware QEMU, b) to enable SIMD when
used with a SIMD-aware version of QEMU and c) finally by means of a QEMU
version using the future cpu model ioctls.
Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com>
Reviewed-by: Eric Farman <farman@linux.vnet.ibm.com>
Tested-by: Eric Farman <farman@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
| -rw-r--r-- | arch/s390/include/asm/kvm_host.h | 1 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.c | 19 | ||||
| -rw-r--r-- | arch/s390/kvm/kvm-s390.h | 11 |
3 files changed, 22 insertions, 9 deletions
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 2356a8c660b3..b8d1e97fb201 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -562,7 +562,6 @@ struct kvm_arch{ | |||
| 562 | int css_support; | 562 | int css_support; |
| 563 | int use_irqchip; | 563 | int use_irqchip; |
| 564 | int use_cmma; | 564 | int use_cmma; |
| 565 | int use_vectors; | ||
| 566 | int user_cpu_state_ctrl; | 565 | int user_cpu_state_ctrl; |
| 567 | int user_sigp; | 566 | int user_sigp; |
| 568 | int user_stsi; | 567 | int user_stsi; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 42b8a2595237..9072127bd51b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
| @@ -278,8 +278,12 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) | |||
| 278 | r = 0; | 278 | r = 0; |
| 279 | break; | 279 | break; |
| 280 | case KVM_CAP_S390_VECTOR_REGISTERS: | 280 | case KVM_CAP_S390_VECTOR_REGISTERS: |
| 281 | kvm->arch.use_vectors = MACHINE_HAS_VX; | 281 | if (MACHINE_HAS_VX) { |
| 282 | r = MACHINE_HAS_VX ? 0 : -EINVAL; | 282 | set_kvm_facility(kvm->arch.model.fac->mask, 129); |
| 283 | set_kvm_facility(kvm->arch.model.fac->list, 129); | ||
| 284 | r = 0; | ||
| 285 | } else | ||
| 286 | r = -EINVAL; | ||
| 283 | break; | 287 | break; |
| 284 | case KVM_CAP_S390_USER_STSI: | 288 | case KVM_CAP_S390_USER_STSI: |
| 285 | kvm->arch.user_stsi = 1; | 289 | kvm->arch.user_stsi = 1; |
| @@ -1084,7 +1088,6 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 1084 | 1088 | ||
| 1085 | kvm->arch.css_support = 0; | 1089 | kvm->arch.css_support = 0; |
| 1086 | kvm->arch.use_irqchip = 0; | 1090 | kvm->arch.use_irqchip = 0; |
| 1087 | kvm->arch.use_vectors = 0; | ||
| 1088 | kvm->arch.epoch = 0; | 1091 | kvm->arch.epoch = 0; |
| 1089 | 1092 | ||
| 1090 | spin_lock_init(&kvm->arch.start_stop_lock); | 1093 | spin_lock_init(&kvm->arch.start_stop_lock); |
| @@ -1186,12 +1189,12 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | |||
| 1186 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 1189 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
| 1187 | { | 1190 | { |
| 1188 | save_fp_ctl(&vcpu->arch.host_fpregs.fpc); | 1191 | save_fp_ctl(&vcpu->arch.host_fpregs.fpc); |
| 1189 | if (vcpu->kvm->arch.use_vectors) | 1192 | if (test_kvm_facility(vcpu->kvm, 129)) |
| 1190 | save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); | 1193 | save_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); |
| 1191 | else | 1194 | else |
| 1192 | save_fp_regs(vcpu->arch.host_fpregs.fprs); | 1195 | save_fp_regs(vcpu->arch.host_fpregs.fprs); |
| 1193 | save_access_regs(vcpu->arch.host_acrs); | 1196 | save_access_regs(vcpu->arch.host_acrs); |
| 1194 | if (vcpu->kvm->arch.use_vectors) { | 1197 | if (test_kvm_facility(vcpu->kvm, 129)) { |
| 1195 | restore_fp_ctl(&vcpu->run->s.regs.fpc); | 1198 | restore_fp_ctl(&vcpu->run->s.regs.fpc); |
| 1196 | restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); | 1199 | restore_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); |
| 1197 | } else { | 1200 | } else { |
| @@ -1207,7 +1210,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
| 1207 | { | 1210 | { |
| 1208 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 1211 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
| 1209 | gmap_disable(vcpu->arch.gmap); | 1212 | gmap_disable(vcpu->arch.gmap); |
| 1210 | if (vcpu->kvm->arch.use_vectors) { | 1213 | if (test_kvm_facility(vcpu->kvm, 129)) { |
| 1211 | save_fp_ctl(&vcpu->run->s.regs.fpc); | 1214 | save_fp_ctl(&vcpu->run->s.regs.fpc); |
| 1212 | save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); | 1215 | save_vx_regs((__vector128 *)&vcpu->run->s.regs.vrs); |
| 1213 | } else { | 1216 | } else { |
| @@ -1216,7 +1219,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | |||
| 1216 | } | 1219 | } |
| 1217 | save_access_regs(vcpu->run->s.regs.acrs); | 1220 | save_access_regs(vcpu->run->s.regs.acrs); |
| 1218 | restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); | 1221 | restore_fp_ctl(&vcpu->arch.host_fpregs.fpc); |
| 1219 | if (vcpu->kvm->arch.use_vectors) | 1222 | if (test_kvm_facility(vcpu->kvm, 129)) |
| 1220 | restore_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); | 1223 | restore_vx_regs((__vector128 *)&vcpu->arch.host_vregs->vrs); |
| 1221 | else | 1224 | else |
| 1222 | restore_fp_regs(vcpu->arch.host_fpregs.fprs); | 1225 | restore_fp_regs(vcpu->arch.host_fpregs.fprs); |
| @@ -1316,7 +1319,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
| 1316 | vcpu->arch.sie_block->eca |= 1; | 1319 | vcpu->arch.sie_block->eca |= 1; |
| 1317 | if (sclp_has_sigpif()) | 1320 | if (sclp_has_sigpif()) |
| 1318 | vcpu->arch.sie_block->eca |= 0x10000000U; | 1321 | vcpu->arch.sie_block->eca |= 0x10000000U; |
| 1319 | if (vcpu->kvm->arch.use_vectors) { | 1322 | if (test_kvm_facility(vcpu->kvm, 129)) { |
| 1320 | vcpu->arch.sie_block->eca |= 0x00020000; | 1323 | vcpu->arch.sie_block->eca |= 0x00020000; |
| 1321 | vcpu->arch.sie_block->ecd |= 0x20000000; | 1324 | vcpu->arch.sie_block->ecd |= 0x20000000; |
| 1322 | } | 1325 | } |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 5d54191e573e..c5aefef158e5 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
| @@ -149,6 +149,17 @@ static inline int test_kvm_facility(struct kvm *kvm, unsigned long nr) | |||
| 149 | __test_facility(nr, kvm->arch.model.fac->list); | 149 | __test_facility(nr, kvm->arch.model.fac->list); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static inline int set_kvm_facility(u64 *fac_list, unsigned long nr) | ||
| 153 | { | ||
| 154 | unsigned char *ptr; | ||
| 155 | |||
| 156 | if (nr >= MAX_FACILITY_BIT) | ||
| 157 | return -EINVAL; | ||
| 158 | ptr = (unsigned char *) fac_list + (nr >> 3); | ||
| 159 | *ptr |= (0x80UL >> (nr & 7)); | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 152 | /* are cpu states controlled by user space */ | 163 | /* are cpu states controlled by user space */ |
| 153 | static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) | 164 | static inline int kvm_s390_user_cpu_state_ctrl(struct kvm *kvm) |
| 154 | { | 165 | { |
