diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-11 08:06:32 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-05-11 08:06:32 -0400 |
commit | cba3d2765e9fcbce45fa3930c4d5f4da7652e752 (patch) | |
tree | 194fbda3ddde55ec0ebbbf5ed85f82fd9a8bf967 /arch/s390/kvm | |
parent | 31fd9880a1c52de8880ea49dca7848caacb4b3a3 (diff) | |
parent | 06b36753a6466239fc945b6756e12d635621ae5f (diff) |
Merge tag 'kvm-s390-next-20150508' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
KVM: s390: Fixes and features for 4.2 (kvm/next)
Mostly a bunch of fixes, reworks and optimizations for s390.
There is one new feature (EDAT-2 inside the guest), which boils
down to 2GB pages.
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/intercept.c | 16 | ||||
-rw-r--r-- | arch/s390/kvm/interrupt.c | 87 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 51 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 25 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 8 |
5 files changed, 112 insertions, 75 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 9e3779e3e496..7365e8a46032 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -241,21 +241,6 @@ static int handle_prog(struct kvm_vcpu *vcpu) | |||
241 | return kvm_s390_inject_prog_irq(vcpu, &pgm_info); | 241 | return kvm_s390_inject_prog_irq(vcpu, &pgm_info); |
242 | } | 242 | } |
243 | 243 | ||
244 | static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) | ||
245 | { | ||
246 | int rc, rc2; | ||
247 | |||
248 | vcpu->stat.exit_instr_and_program++; | ||
249 | rc = handle_instruction(vcpu); | ||
250 | rc2 = handle_prog(vcpu); | ||
251 | |||
252 | if (rc == -EOPNOTSUPP) | ||
253 | vcpu->arch.sie_block->icptcode = 0x04; | ||
254 | if (rc) | ||
255 | return rc; | ||
256 | return rc2; | ||
257 | } | ||
258 | |||
259 | /** | 244 | /** |
260 | * handle_external_interrupt - used for external interruption interceptions | 245 | * handle_external_interrupt - used for external interruption interceptions |
261 | * | 246 | * |
@@ -355,7 +340,6 @@ static const intercept_handler_t intercept_funcs[] = { | |||
355 | [0x00 >> 2] = handle_noop, | 340 | [0x00 >> 2] = handle_noop, |
356 | [0x04 >> 2] = handle_instruction, | 341 | [0x04 >> 2] = handle_instruction, |
357 | [0x08 >> 2] = handle_prog, | 342 | [0x08 >> 2] = handle_prog, |
358 | [0x0C >> 2] = handle_instruction_and_prog, | ||
359 | [0x10 >> 2] = handle_noop, | 343 | [0x10 >> 2] = handle_noop, |
360 | [0x14 >> 2] = handle_external_interrupt, | 344 | [0x14 >> 2] = handle_external_interrupt, |
361 | [0x18 >> 2] = handle_noop, | 345 | [0x18 >> 2] = handle_noop, |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 9de47265ef73..322ef9cfdc80 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -134,6 +134,8 @@ static unsigned long deliverable_irqs(struct kvm_vcpu *vcpu) | |||
134 | 134 | ||
135 | active_mask = pending_local_irqs(vcpu); | 135 | active_mask = pending_local_irqs(vcpu); |
136 | active_mask |= pending_floating_irqs(vcpu); | 136 | active_mask |= pending_floating_irqs(vcpu); |
137 | if (!active_mask) | ||
138 | return 0; | ||
137 | 139 | ||
138 | if (psw_extint_disabled(vcpu)) | 140 | if (psw_extint_disabled(vcpu)) |
139 | active_mask &= ~IRQ_PEND_EXT_MASK; | 141 | active_mask &= ~IRQ_PEND_EXT_MASK; |
@@ -941,12 +943,9 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | |||
941 | if (cpu_timer_irq_pending(vcpu)) | 943 | if (cpu_timer_irq_pending(vcpu)) |
942 | set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); | 944 | set_bit(IRQ_PEND_EXT_CPU_TIMER, &li->pending_irqs); |
943 | 945 | ||
944 | do { | 946 | while ((irqs = deliverable_irqs(vcpu)) && !rc) { |
945 | irqs = deliverable_irqs(vcpu); | ||
946 | /* bits are in the order of interrupt priority */ | 947 | /* bits are in the order of interrupt priority */ |
947 | irq_type = find_first_bit(&irqs, IRQ_PEND_COUNT); | 948 | irq_type = find_first_bit(&irqs, IRQ_PEND_COUNT); |
948 | if (irq_type == IRQ_PEND_COUNT) | ||
949 | break; | ||
950 | if (is_ioirq(irq_type)) { | 949 | if (is_ioirq(irq_type)) { |
951 | rc = __deliver_io(vcpu, irq_type); | 950 | rc = __deliver_io(vcpu, irq_type); |
952 | } else { | 951 | } else { |
@@ -958,9 +957,7 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu) | |||
958 | } | 957 | } |
959 | rc = func(vcpu); | 958 | rc = func(vcpu); |
960 | } | 959 | } |
961 | if (rc) | 960 | } |
962 | break; | ||
963 | } while (!rc); | ||
964 | 961 | ||
965 | set_intercept_indicators(vcpu); | 962 | set_intercept_indicators(vcpu); |
966 | 963 | ||
@@ -1061,7 +1058,7 @@ static int __inject_extcall(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq) | |||
1061 | if (sclp_has_sigpif()) | 1058 | if (sclp_has_sigpif()) |
1062 | return __inject_extcall_sigpif(vcpu, src_id); | 1059 | return __inject_extcall_sigpif(vcpu, src_id); |
1063 | 1060 | ||
1064 | if (!test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs)) | 1061 | if (test_and_set_bit(IRQ_PEND_EXT_EXTERNAL, &li->pending_irqs)) |
1065 | return -EBUSY; | 1062 | return -EBUSY; |
1066 | *extcall = irq->u.extcall; | 1063 | *extcall = irq->u.extcall; |
1067 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | 1064 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); |
@@ -1340,12 +1337,54 @@ static int __inject_io(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
1340 | return 0; | 1337 | return 0; |
1341 | } | 1338 | } |
1342 | 1339 | ||
1343 | static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | 1340 | /* |
1341 | * Find a destination VCPU for a floating irq and kick it. | ||
1342 | */ | ||
1343 | static void __floating_irq_kick(struct kvm *kvm, u64 type) | ||
1344 | { | 1344 | { |
1345 | struct kvm_s390_float_interrupt *fi = &kvm->arch.float_int; | ||
1345 | struct kvm_s390_local_interrupt *li; | 1346 | struct kvm_s390_local_interrupt *li; |
1347 | struct kvm_vcpu *dst_vcpu; | ||
1348 | int sigcpu, online_vcpus, nr_tries = 0; | ||
1349 | |||
1350 | online_vcpus = atomic_read(&kvm->online_vcpus); | ||
1351 | if (!online_vcpus) | ||
1352 | return; | ||
1353 | |||
1354 | /* find idle VCPUs first, then round robin */ | ||
1355 | sigcpu = find_first_bit(fi->idle_mask, online_vcpus); | ||
1356 | if (sigcpu == online_vcpus) { | ||
1357 | do { | ||
1358 | sigcpu = fi->next_rr_cpu; | ||
1359 | fi->next_rr_cpu = (fi->next_rr_cpu + 1) % online_vcpus; | ||
1360 | /* avoid endless loops if all vcpus are stopped */ | ||
1361 | if (nr_tries++ >= online_vcpus) | ||
1362 | return; | ||
1363 | } while (is_vcpu_stopped(kvm_get_vcpu(kvm, sigcpu))); | ||
1364 | } | ||
1365 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); | ||
1366 | |||
1367 | /* make the VCPU drop out of the SIE, or wake it up if sleeping */ | ||
1368 | li = &dst_vcpu->arch.local_int; | ||
1369 | spin_lock(&li->lock); | ||
1370 | switch (type) { | ||
1371 | case KVM_S390_MCHK: | ||
1372 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | ||
1373 | break; | ||
1374 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
1375 | atomic_set_mask(CPUSTAT_IO_INT, li->cpuflags); | ||
1376 | break; | ||
1377 | default: | ||
1378 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1379 | break; | ||
1380 | } | ||
1381 | spin_unlock(&li->lock); | ||
1382 | kvm_s390_vcpu_wakeup(dst_vcpu); | ||
1383 | } | ||
1384 | |||
1385 | static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | ||
1386 | { | ||
1346 | struct kvm_s390_float_interrupt *fi; | 1387 | struct kvm_s390_float_interrupt *fi; |
1347 | struct kvm_vcpu *dst_vcpu = NULL; | ||
1348 | int sigcpu; | ||
1349 | u64 type = READ_ONCE(inti->type); | 1388 | u64 type = READ_ONCE(inti->type); |
1350 | int rc; | 1389 | int rc; |
1351 | 1390 | ||
@@ -1373,32 +1412,8 @@ static int __inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti) | |||
1373 | if (rc) | 1412 | if (rc) |
1374 | return rc; | 1413 | return rc; |
1375 | 1414 | ||
1376 | sigcpu = find_first_bit(fi->idle_mask, KVM_MAX_VCPUS); | 1415 | __floating_irq_kick(kvm, type); |
1377 | if (sigcpu == KVM_MAX_VCPUS) { | ||
1378 | do { | ||
1379 | sigcpu = fi->next_rr_cpu++; | ||
1380 | if (sigcpu == KVM_MAX_VCPUS) | ||
1381 | sigcpu = fi->next_rr_cpu = 0; | ||
1382 | } while (kvm_get_vcpu(kvm, sigcpu) == NULL); | ||
1383 | } | ||
1384 | dst_vcpu = kvm_get_vcpu(kvm, sigcpu); | ||
1385 | li = &dst_vcpu->arch.local_int; | ||
1386 | spin_lock(&li->lock); | ||
1387 | switch (type) { | ||
1388 | case KVM_S390_MCHK: | ||
1389 | atomic_set_mask(CPUSTAT_STOP_INT, li->cpuflags); | ||
1390 | break; | ||
1391 | case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: | ||
1392 | atomic_set_mask(CPUSTAT_IO_INT, li->cpuflags); | ||
1393 | break; | ||
1394 | default: | ||
1395 | atomic_set_mask(CPUSTAT_EXT_INT, li->cpuflags); | ||
1396 | break; | ||
1397 | } | ||
1398 | spin_unlock(&li->lock); | ||
1399 | kvm_s390_vcpu_wakeup(kvm_get_vcpu(kvm, sigcpu)); | ||
1400 | return 0; | 1416 | return 0; |
1401 | |||
1402 | } | 1417 | } |
1403 | 1418 | ||
1404 | int kvm_s390_inject_vm(struct kvm *kvm, | 1419 | int kvm_s390_inject_vm(struct kvm *kvm, |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 2be391bb8557..d461f8a15c07 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -110,7 +110,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
110 | /* upper facilities limit for kvm */ | 110 | /* upper facilities limit for kvm */ |
111 | unsigned long kvm_s390_fac_list_mask[] = { | 111 | unsigned long kvm_s390_fac_list_mask[] = { |
112 | 0xffe6fffbfcfdfc40UL, | 112 | 0xffe6fffbfcfdfc40UL, |
113 | 0x005c800000000000UL, | 113 | 0x005e800000000000UL, |
114 | }; | 114 | }; |
115 | 115 | ||
116 | unsigned long kvm_s390_fac_list_mask_size(void) | 116 | unsigned long kvm_s390_fac_list_mask_size(void) |
@@ -454,10 +454,10 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr) | |||
454 | 454 | ||
455 | mutex_lock(&kvm->lock); | 455 | mutex_lock(&kvm->lock); |
456 | kvm->arch.epoch = gtod - host_tod; | 456 | kvm->arch.epoch = gtod - host_tod; |
457 | kvm_for_each_vcpu(vcpu_idx, cur_vcpu, kvm) { | 457 | kvm_s390_vcpu_block_all(kvm); |
458 | kvm_for_each_vcpu(vcpu_idx, cur_vcpu, kvm) | ||
458 | cur_vcpu->arch.sie_block->epoch = kvm->arch.epoch; | 459 | cur_vcpu->arch.sie_block->epoch = kvm->arch.epoch; |
459 | exit_sie(cur_vcpu); | 460 | kvm_s390_vcpu_unblock_all(kvm); |
460 | } | ||
461 | mutex_unlock(&kvm->lock); | 461 | mutex_unlock(&kvm->lock); |
462 | return 0; | 462 | return 0; |
463 | } | 463 | } |
@@ -1311,8 +1311,13 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1311 | 1311 | ||
1312 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | | 1312 | atomic_set(&vcpu->arch.sie_block->cpuflags, CPUSTAT_ZARCH | |
1313 | CPUSTAT_SM | | 1313 | CPUSTAT_SM | |
1314 | CPUSTAT_STOPPED | | 1314 | CPUSTAT_STOPPED); |
1315 | CPUSTAT_GED); | 1315 | |
1316 | if (test_kvm_facility(vcpu->kvm, 78)) | ||
1317 | atomic_set_mask(CPUSTAT_GED2, &vcpu->arch.sie_block->cpuflags); | ||
1318 | else if (test_kvm_facility(vcpu->kvm, 8)) | ||
1319 | atomic_set_mask(CPUSTAT_GED, &vcpu->arch.sie_block->cpuflags); | ||
1320 | |||
1316 | kvm_s390_vcpu_setup_model(vcpu); | 1321 | kvm_s390_vcpu_setup_model(vcpu); |
1317 | 1322 | ||
1318 | vcpu->arch.sie_block->ecb = 6; | 1323 | vcpu->arch.sie_block->ecb = 6; |
@@ -1409,16 +1414,26 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) | |||
1409 | return kvm_s390_vcpu_has_irq(vcpu, 0); | 1414 | return kvm_s390_vcpu_has_irq(vcpu, 0); |
1410 | } | 1415 | } |
1411 | 1416 | ||
1412 | void s390_vcpu_block(struct kvm_vcpu *vcpu) | 1417 | void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu) |
1413 | { | 1418 | { |
1414 | atomic_set_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); | 1419 | atomic_set_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); |
1415 | } | 1420 | } |
1416 | 1421 | ||
1417 | void s390_vcpu_unblock(struct kvm_vcpu *vcpu) | 1422 | void kvm_s390_vcpu_unblock(struct kvm_vcpu *vcpu) |
1418 | { | 1423 | { |
1419 | atomic_clear_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); | 1424 | atomic_clear_mask(PROG_BLOCK_SIE, &vcpu->arch.sie_block->prog20); |
1420 | } | 1425 | } |
1421 | 1426 | ||
1427 | static void kvm_s390_vcpu_request(struct kvm_vcpu *vcpu) | ||
1428 | { | ||
1429 | atomic_set_mask(PROG_REQUEST, &vcpu->arch.sie_block->prog20); | ||
1430 | } | ||
1431 | |||
1432 | static void kvm_s390_vcpu_request_handled(struct kvm_vcpu *vcpu) | ||
1433 | { | ||
1434 | atomic_clear_mask(PROG_REQUEST, &vcpu->arch.sie_block->prog20); | ||
1435 | } | ||
1436 | |||
1422 | /* | 1437 | /* |
1423 | * Kick a guest cpu out of SIE and wait until SIE is not running. | 1438 | * Kick a guest cpu out of SIE and wait until SIE is not running. |
1424 | * If the CPU is not running (e.g. waiting as idle) the function will | 1439 | * If the CPU is not running (e.g. waiting as idle) the function will |
@@ -1430,10 +1445,11 @@ void exit_sie(struct kvm_vcpu *vcpu) | |||
1430 | cpu_relax(); | 1445 | cpu_relax(); |
1431 | } | 1446 | } |
1432 | 1447 | ||
1433 | /* Kick a guest cpu out of SIE and prevent SIE-reentry */ | 1448 | /* Kick a guest cpu out of SIE to process a request synchronously */ |
1434 | void exit_sie_sync(struct kvm_vcpu *vcpu) | 1449 | void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu) |
1435 | { | 1450 | { |
1436 | s390_vcpu_block(vcpu); | 1451 | kvm_make_request(req, vcpu); |
1452 | kvm_s390_vcpu_request(vcpu); | ||
1437 | exit_sie(vcpu); | 1453 | exit_sie(vcpu); |
1438 | } | 1454 | } |
1439 | 1455 | ||
@@ -1447,8 +1463,7 @@ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long address) | |||
1447 | /* match against both prefix pages */ | 1463 | /* match against both prefix pages */ |
1448 | if (kvm_s390_get_prefix(vcpu) == (address & ~0x1000UL)) { | 1464 | if (kvm_s390_get_prefix(vcpu) == (address & ~0x1000UL)) { |
1449 | VCPU_EVENT(vcpu, 2, "gmap notifier for %lx", address); | 1465 | VCPU_EVENT(vcpu, 2, "gmap notifier for %lx", address); |
1450 | kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); | 1466 | kvm_s390_sync_request(KVM_REQ_MMU_RELOAD, vcpu); |
1451 | exit_sie_sync(vcpu); | ||
1452 | } | 1467 | } |
1453 | } | 1468 | } |
1454 | } | 1469 | } |
@@ -1720,8 +1735,10 @@ static bool ibs_enabled(struct kvm_vcpu *vcpu) | |||
1720 | 1735 | ||
1721 | static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) | 1736 | static int kvm_s390_handle_requests(struct kvm_vcpu *vcpu) |
1722 | { | 1737 | { |
1738 | if (!vcpu->requests) | ||
1739 | return 0; | ||
1723 | retry: | 1740 | retry: |
1724 | s390_vcpu_unblock(vcpu); | 1741 | kvm_s390_vcpu_request_handled(vcpu); |
1725 | /* | 1742 | /* |
1726 | * We use MMU_RELOAD just to re-arm the ipte notifier for the | 1743 | * We use MMU_RELOAD just to re-arm the ipte notifier for the |
1727 | * guest prefix page. gmap_ipte_notify will wait on the ptl lock. | 1744 | * guest prefix page. gmap_ipte_notify will wait on the ptl lock. |
@@ -2208,8 +2225,7 @@ int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
2208 | static void __disable_ibs_on_vcpu(struct kvm_vcpu *vcpu) | 2225 | static void __disable_ibs_on_vcpu(struct kvm_vcpu *vcpu) |
2209 | { | 2226 | { |
2210 | kvm_check_request(KVM_REQ_ENABLE_IBS, vcpu); | 2227 | kvm_check_request(KVM_REQ_ENABLE_IBS, vcpu); |
2211 | kvm_make_request(KVM_REQ_DISABLE_IBS, vcpu); | 2228 | kvm_s390_sync_request(KVM_REQ_DISABLE_IBS, vcpu); |
2212 | exit_sie_sync(vcpu); | ||
2213 | } | 2229 | } |
2214 | 2230 | ||
2215 | static void __disable_ibs_on_all_vcpus(struct kvm *kvm) | 2231 | static void __disable_ibs_on_all_vcpus(struct kvm *kvm) |
@@ -2225,8 +2241,7 @@ static void __disable_ibs_on_all_vcpus(struct kvm *kvm) | |||
2225 | static void __enable_ibs_on_vcpu(struct kvm_vcpu *vcpu) | 2241 | static void __enable_ibs_on_vcpu(struct kvm_vcpu *vcpu) |
2226 | { | 2242 | { |
2227 | kvm_check_request(KVM_REQ_DISABLE_IBS, vcpu); | 2243 | kvm_check_request(KVM_REQ_DISABLE_IBS, vcpu); |
2228 | kvm_make_request(KVM_REQ_ENABLE_IBS, vcpu); | 2244 | kvm_s390_sync_request(KVM_REQ_ENABLE_IBS, vcpu); |
2229 | exit_sie_sync(vcpu); | ||
2230 | } | 2245 | } |
2231 | 2246 | ||
2232 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu) | 2247 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index ca108b90ae56..c5704786e473 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -211,10 +211,10 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); | |||
211 | int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr); | 211 | int kvm_s390_vcpu_store_adtl_status(struct kvm_vcpu *vcpu, unsigned long addr); |
212 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); | 212 | void kvm_s390_vcpu_start(struct kvm_vcpu *vcpu); |
213 | void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); | 213 | void kvm_s390_vcpu_stop(struct kvm_vcpu *vcpu); |
214 | void s390_vcpu_block(struct kvm_vcpu *vcpu); | 214 | void kvm_s390_vcpu_block(struct kvm_vcpu *vcpu); |
215 | void s390_vcpu_unblock(struct kvm_vcpu *vcpu); | 215 | void kvm_s390_vcpu_unblock(struct kvm_vcpu *vcpu); |
216 | void exit_sie(struct kvm_vcpu *vcpu); | 216 | void exit_sie(struct kvm_vcpu *vcpu); |
217 | void exit_sie_sync(struct kvm_vcpu *vcpu); | 217 | void kvm_s390_sync_request(int req, struct kvm_vcpu *vcpu); |
218 | int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu); | 218 | int kvm_s390_vcpu_setup_cmma(struct kvm_vcpu *vcpu); |
219 | void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); | 219 | void kvm_s390_vcpu_unsetup_cmma(struct kvm_vcpu *vcpu); |
220 | /* is cmma enabled */ | 220 | /* is cmma enabled */ |
@@ -228,6 +228,25 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu); | |||
228 | int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu, | 228 | int kvm_s390_inject_prog_irq(struct kvm_vcpu *vcpu, |
229 | struct kvm_s390_pgm_info *pgm_info); | 229 | struct kvm_s390_pgm_info *pgm_info); |
230 | 230 | ||
231 | static inline void kvm_s390_vcpu_block_all(struct kvm *kvm) | ||
232 | { | ||
233 | int i; | ||
234 | struct kvm_vcpu *vcpu; | ||
235 | |||
236 | WARN_ON(!mutex_is_locked(&kvm->lock)); | ||
237 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
238 | kvm_s390_vcpu_block(vcpu); | ||
239 | } | ||
240 | |||
241 | static inline void kvm_s390_vcpu_unblock_all(struct kvm *kvm) | ||
242 | { | ||
243 | int i; | ||
244 | struct kvm_vcpu *vcpu; | ||
245 | |||
246 | kvm_for_each_vcpu(i, vcpu, kvm) | ||
247 | kvm_s390_vcpu_unblock(vcpu); | ||
248 | } | ||
249 | |||
231 | /** | 250 | /** |
232 | * kvm_s390_inject_prog_cond - conditionally inject a program check | 251 | * kvm_s390_inject_prog_cond - conditionally inject a program check |
233 | * @vcpu: virtual cpu | 252 | * @vcpu: virtual cpu |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d22d8ee1ff9d..ad4242245771 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -698,10 +698,14 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
698 | case 0x00001000: | 698 | case 0x00001000: |
699 | end = (start + (1UL << 20)) & ~((1UL << 20) - 1); | 699 | end = (start + (1UL << 20)) & ~((1UL << 20) - 1); |
700 | break; | 700 | break; |
701 | /* We dont support EDAT2 | ||
702 | case 0x00002000: | 701 | case 0x00002000: |
702 | /* only support 2G frame size if EDAT2 is available and we are | ||
703 | not in 24-bit addressing mode */ | ||
704 | if (!test_kvm_facility(vcpu->kvm, 78) || | ||
705 | psw_bits(vcpu->arch.sie_block->gpsw).eaba == PSW_AMODE_24BIT) | ||
706 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | ||
703 | end = (start + (1UL << 31)) & ~((1UL << 31) - 1); | 707 | end = (start + (1UL << 31)) & ~((1UL << 31) - 1); |
704 | break;*/ | 708 | break; |
705 | default: | 709 | default: |
706 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 710 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
707 | } | 711 | } |