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 /arch/s390/kvm | |
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>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 19 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 11 |
2 files changed, 22 insertions, 8 deletions
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 | { |