diff options
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 23 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 3 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 11 |
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 | ||
87 | static unsigned long long *facilities; | 88 | unsigned long *vfacilities; |
88 | static struct gmap_notifier gmap_notifier; | 89 | static struct gmap_notifier gmap_notifier; |
89 | 90 | ||
91 | /* test availability of vfacility */ | ||
92 | static 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 */ |
91 | int kvm_arch_hardware_enable(void *garbage) | 98 | int 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 | ||
1140 | static void __exit kvm_s390_exit(void) | 1147 | static 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 | ||
25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | 25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); |
26 | 26 | ||
27 | /* declare vfacilities extern */ | ||
28 | extern 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 | ||
228 | static int handle_stfl(struct kvm_vcpu *vcpu) | 228 | static 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 | ||