aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorMichael Mueller <mimu@linux.vnet.ibm.com>2013-07-26 09:04:04 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-07-29 03:03:28 -0400
commit78c4b59f721fb0c30e8520f1c8e78fbf47bddfdf (patch)
treeb30db035569c0d4e80cd0262fb850c626991b36d /arch/s390/kvm
parentee6ee55bb505c5bd8e64bc652281a93fb99c07b3 (diff)
KVM: s390: declare virtual HW facilities
The patch renames the array holding the HW facility bitmaps. This allows to interprete the variable as set of virtual machine specific "virtual" facilities. The basic idea is to make virtual facilities externally managable in future. An availability test for virtual facilites has been added as well. Signed-off-by: Michael Mueller <mimu@linux.vnet.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c23
-rw-r--r--arch/s390/kvm/kvm-s390.h3
-rw-r--r--arch/s390/kvm/priv.c11
3 files changed, 22 insertions, 15 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index a3d797b689a3..ac8e6670c551 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -28,6 +28,7 @@
28#include <asm/pgtable.h> 28#include <asm/pgtable.h>
29#include <asm/nmi.h> 29#include <asm/nmi.h>
30#include <asm/switch_to.h> 30#include <asm/switch_to.h>
31#include <asm/facility.h>
31#include <asm/sclp.h> 32#include <asm/sclp.h>
32#include "kvm-s390.h" 33#include "kvm-s390.h"
33#include "gaccess.h" 34#include "gaccess.h"
@@ -84,9 +85,15 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
84 { NULL } 85 { NULL }
85}; 86};
86 87
87static unsigned long long *facilities; 88unsigned long *vfacilities;
88static struct gmap_notifier gmap_notifier; 89static struct gmap_notifier gmap_notifier;
89 90
91/* test availability of vfacility */
92static inline int test_vfacility(unsigned long nr)
93{
94 return __test_facility(nr, (void *) vfacilities);
95}
96
90/* Section: not file related */ 97/* Section: not file related */
91int kvm_arch_hardware_enable(void *garbage) 98int kvm_arch_hardware_enable(void *garbage)
92{ 99{
@@ -387,7 +394,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
387 vcpu->arch.sie_block->ecb = 6; 394 vcpu->arch.sie_block->ecb = 6;
388 vcpu->arch.sie_block->ecb2 = 8; 395 vcpu->arch.sie_block->ecb2 = 8;
389 vcpu->arch.sie_block->eca = 0xC1002001U; 396 vcpu->arch.sie_block->eca = 0xC1002001U;
390 vcpu->arch.sie_block->fac = (int) (long) facilities; 397 vcpu->arch.sie_block->fac = (int) (long) vfacilities;
391 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); 398 hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS);
392 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, 399 tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet,
393 (unsigned long) vcpu); 400 (unsigned long) vcpu);
@@ -1126,20 +1133,20 @@ static int __init kvm_s390_init(void)
1126 * to hold the maximum amount of facilities. On the other hand, we 1133 * to hold the maximum amount of facilities. On the other hand, we
1127 * only set facilities that are known to work in KVM. 1134 * only set facilities that are known to work in KVM.
1128 */ 1135 */
1129 facilities = (unsigned long long *) get_zeroed_page(GFP_KERNEL|GFP_DMA); 1136 vfacilities = (unsigned long *) get_zeroed_page(GFP_KERNEL|GFP_DMA);
1130 if (!facilities) { 1137 if (!vfacilities) {
1131 kvm_exit(); 1138 kvm_exit();
1132 return -ENOMEM; 1139 return -ENOMEM;
1133 } 1140 }
1134 memcpy(facilities, S390_lowcore.stfle_fac_list, 16); 1141 memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16);
1135 facilities[0] &= 0xff82fff3f47c0000ULL; 1142 vfacilities[0] &= 0xff82fff3f47c0000UL;
1136 facilities[1] &= 0x001c000000000000ULL; 1143 vfacilities[1] &= 0x001c000000000000UL;
1137 return 0; 1144 return 0;
1138} 1145}
1139 1146
1140static void __exit kvm_s390_exit(void) 1147static void __exit kvm_s390_exit(void)
1141{ 1148{
1142 free_page((unsigned long) facilities); 1149 free_page((unsigned long) vfacilities);
1143 kvm_exit(); 1150 kvm_exit();
1144} 1151}
1145 1152
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 028ca9fd2158..faa4df633474 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -24,6 +24,9 @@
24 24
25typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); 25typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
26 26
27/* declare vfacilities extern */
28extern unsigned long *vfacilities;
29
27/* negativ values are error codes, positive values for internal conditions */ 30/* negativ values are error codes, positive values for internal conditions */
28#define SIE_INTERCEPT_RERUNVCPU (1<<0) 31#define SIE_INTERCEPT_RERUNVCPU (1<<0)
29#define SIE_INTERCEPT_UCONTROL (1<<1) 32#define SIE_INTERCEPT_UCONTROL (1<<1)
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 0da3e6eb6be6..a14c4b68aed7 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -227,7 +227,6 @@ static int handle_io_inst(struct kvm_vcpu *vcpu)
227 227
228static int handle_stfl(struct kvm_vcpu *vcpu) 228static int handle_stfl(struct kvm_vcpu *vcpu)
229{ 229{
230 unsigned int facility_list;
231 int rc; 230 int rc;
232 231
233 vcpu->stat.instruction_stfl++; 232 vcpu->stat.instruction_stfl++;
@@ -235,15 +234,13 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
235 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 234 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
236 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 235 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
237 236
238 /* only pass the facility bits, which we can handle */
239 facility_list = S390_lowcore.stfl_fac_list & 0xff82fff3;
240
241 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), 237 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
242 &facility_list, sizeof(facility_list)); 238 vfacilities, 4);
243 if (rc) 239 if (rc)
244 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 240 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
245 VCPU_EVENT(vcpu, 5, "store facility list value %x", facility_list); 241 VCPU_EVENT(vcpu, 5, "store facility list value %x",
246 trace_kvm_s390_handle_stfl(vcpu, facility_list); 242 *(unsigned int *) vfacilities);
243 trace_kvm_s390_handle_stfl(vcpu, *(unsigned int *) vfacilities);
247 return 0; 244 return 0;
248} 245}
249 246