diff options
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r-- | arch/s390/kvm/Kconfig | 2 | ||||
-rw-r--r-- | arch/s390/kvm/diag.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/intercept.c | 22 | ||||
-rw-r--r-- | arch/s390/kvm/interrupt.c | 13 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.c | 79 | ||||
-rw-r--r-- | arch/s390/kvm/kvm-s390.h | 10 | ||||
-rw-r--r-- | arch/s390/kvm/priv.c | 3 | ||||
-rw-r--r-- | arch/s390/kvm/sigp.c | 11 |
8 files changed, 85 insertions, 59 deletions
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index bf164fc21864..a7251580891c 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
@@ -20,7 +20,6 @@ config KVM | |||
20 | depends on HAVE_KVM && EXPERIMENTAL | 20 | depends on HAVE_KVM && EXPERIMENTAL |
21 | select PREEMPT_NOTIFIERS | 21 | select PREEMPT_NOTIFIERS |
22 | select ANON_INODES | 22 | select ANON_INODES |
23 | select S390_SWITCH_AMODE | ||
24 | ---help--- | 23 | ---help--- |
25 | Support hosting paravirtualized guest machines using the SIE | 24 | Support hosting paravirtualized guest machines using the SIE |
26 | virtualization capability on the mainframe. This should work | 25 | virtualization capability on the mainframe. This should work |
@@ -36,6 +35,7 @@ config KVM | |||
36 | 35 | ||
37 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under | 36 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under |
38 | # the virtualization menu. | 37 | # the virtualization menu. |
38 | source drivers/vhost/Kconfig | ||
39 | source drivers/virtio/Kconfig | 39 | source drivers/virtio/Kconfig |
40 | 40 | ||
41 | endif # VIRTUALIZATION | 41 | endif # VIRTUALIZATION |
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 8300309698fa..9e4c84187cf5 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -39,7 +39,7 @@ static int __diag_ipl_functions(struct kvm_vcpu *vcpu) | |||
39 | vcpu->run->s390_reset_flags = 0; | 39 | vcpu->run->s390_reset_flags = 0; |
40 | break; | 40 | break; |
41 | default: | 41 | default: |
42 | return -ENOTSUPP; | 42 | return -EOPNOTSUPP; |
43 | } | 43 | } |
44 | 44 | ||
45 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); | 45 | atomic_clear_mask(CPUSTAT_RUNNING, &vcpu->arch.sie_block->cpuflags); |
@@ -62,6 +62,6 @@ int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) | |||
62 | case 0x308: | 62 | case 0x308: |
63 | return __diag_ipl_functions(vcpu); | 63 | return __diag_ipl_functions(vcpu); |
64 | default: | 64 | default: |
65 | return -ENOTSUPP; | 65 | return -EOPNOTSUPP; |
66 | } | 66 | } |
67 | } | 67 | } |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index ba9d8a7bc1ac..3ddc30895e31 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -32,7 +32,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) | |||
32 | 32 | ||
33 | vcpu->stat.instruction_lctlg++; | 33 | vcpu->stat.instruction_lctlg++; |
34 | if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) | 34 | if ((vcpu->arch.sie_block->ipb & 0xff) != 0x2f) |
35 | return -ENOTSUPP; | 35 | return -EOPNOTSUPP; |
36 | 36 | ||
37 | useraddr = disp2; | 37 | useraddr = disp2; |
38 | if (base2) | 38 | if (base2) |
@@ -138,7 +138,7 @@ static int handle_stop(struct kvm_vcpu *vcpu) | |||
138 | rc = __kvm_s390_vcpu_store_status(vcpu, | 138 | rc = __kvm_s390_vcpu_store_status(vcpu, |
139 | KVM_S390_STORE_STATUS_NOADDR); | 139 | KVM_S390_STORE_STATUS_NOADDR); |
140 | if (rc >= 0) | 140 | if (rc >= 0) |
141 | rc = -ENOTSUPP; | 141 | rc = -EOPNOTSUPP; |
142 | } | 142 | } |
143 | 143 | ||
144 | if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { | 144 | if (vcpu->arch.local_int.action_bits & ACTION_RELOADVCPU_ON_STOP) { |
@@ -150,7 +150,7 @@ static int handle_stop(struct kvm_vcpu *vcpu) | |||
150 | if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { | 150 | if (vcpu->arch.local_int.action_bits & ACTION_STOP_ON_STOP) { |
151 | vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; | 151 | vcpu->arch.local_int.action_bits &= ~ACTION_STOP_ON_STOP; |
152 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); | 152 | VCPU_EVENT(vcpu, 3, "%s", "cpu stopped"); |
153 | rc = -ENOTSUPP; | 153 | rc = -EOPNOTSUPP; |
154 | } | 154 | } |
155 | 155 | ||
156 | spin_unlock_bh(&vcpu->arch.local_int.lock); | 156 | spin_unlock_bh(&vcpu->arch.local_int.lock); |
@@ -171,9 +171,9 @@ static int handle_validity(struct kvm_vcpu *vcpu) | |||
171 | 2*PAGE_SIZE); | 171 | 2*PAGE_SIZE); |
172 | if (rc) | 172 | if (rc) |
173 | /* user will receive sigsegv, exit to user */ | 173 | /* user will receive sigsegv, exit to user */ |
174 | rc = -ENOTSUPP; | 174 | rc = -EOPNOTSUPP; |
175 | } else | 175 | } else |
176 | rc = -ENOTSUPP; | 176 | rc = -EOPNOTSUPP; |
177 | 177 | ||
178 | if (rc) | 178 | if (rc) |
179 | VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d", | 179 | VCPU_EVENT(vcpu, 2, "unhandled validity intercept code %d", |
@@ -189,7 +189,7 @@ static int handle_instruction(struct kvm_vcpu *vcpu) | |||
189 | handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; | 189 | handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8]; |
190 | if (handler) | 190 | if (handler) |
191 | return handler(vcpu); | 191 | return handler(vcpu); |
192 | return -ENOTSUPP; | 192 | return -EOPNOTSUPP; |
193 | } | 193 | } |
194 | 194 | ||
195 | static int handle_prog(struct kvm_vcpu *vcpu) | 195 | static int handle_prog(struct kvm_vcpu *vcpu) |
@@ -206,14 +206,14 @@ static int handle_instruction_and_prog(struct kvm_vcpu *vcpu) | |||
206 | rc = handle_instruction(vcpu); | 206 | rc = handle_instruction(vcpu); |
207 | rc2 = handle_prog(vcpu); | 207 | rc2 = handle_prog(vcpu); |
208 | 208 | ||
209 | if (rc == -ENOTSUPP) | 209 | if (rc == -EOPNOTSUPP) |
210 | vcpu->arch.sie_block->icptcode = 0x04; | 210 | vcpu->arch.sie_block->icptcode = 0x04; |
211 | if (rc) | 211 | if (rc) |
212 | return rc; | 212 | return rc; |
213 | return rc2; | 213 | return rc2; |
214 | } | 214 | } |
215 | 215 | ||
216 | static const intercept_handler_t intercept_funcs[0x48 >> 2] = { | 216 | static const intercept_handler_t intercept_funcs[] = { |
217 | [0x00 >> 2] = handle_noop, | 217 | [0x00 >> 2] = handle_noop, |
218 | [0x04 >> 2] = handle_instruction, | 218 | [0x04 >> 2] = handle_instruction, |
219 | [0x08 >> 2] = handle_prog, | 219 | [0x08 >> 2] = handle_prog, |
@@ -230,10 +230,10 @@ int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu) | |||
230 | intercept_handler_t func; | 230 | intercept_handler_t func; |
231 | u8 code = vcpu->arch.sie_block->icptcode; | 231 | u8 code = vcpu->arch.sie_block->icptcode; |
232 | 232 | ||
233 | if (code & 3 || code > 0x48) | 233 | if (code & 3 || (code >> 2) >= ARRAY_SIZE(intercept_funcs)) |
234 | return -ENOTSUPP; | 234 | return -EOPNOTSUPP; |
235 | func = intercept_funcs[code >> 2]; | 235 | func = intercept_funcs[code >> 2]; |
236 | if (func) | 236 | if (func) |
237 | return func(vcpu); | 237 | return func(vcpu); |
238 | return -ENOTSUPP; | 238 | return -EOPNOTSUPP; |
239 | } | 239 | } |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 43486c2408e1..35c21bf910c5 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -10,12 +10,13 @@ | |||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | 10 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <asm/lowcore.h> | ||
14 | #include <asm/uaccess.h> | ||
15 | #include <linux/hrtimer.h> | ||
16 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
17 | #include <linux/kvm_host.h> | 14 | #include <linux/kvm_host.h> |
15 | #include <linux/hrtimer.h> | ||
18 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
17 | #include <linux/slab.h> | ||
18 | #include <asm/asm-offsets.h> | ||
19 | #include <asm/uaccess.h> | ||
19 | #include "kvm-s390.h" | 20 | #include "kvm-s390.h" |
20 | #include "gaccess.h" | 21 | #include "gaccess.h" |
21 | 22 | ||
@@ -187,8 +188,8 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu, | |||
187 | if (rc == -EFAULT) | 188 | if (rc == -EFAULT) |
188 | exception = 1; | 189 | exception = 1; |
189 | 190 | ||
190 | rc = put_guest_u64(vcpu, __LC_PFAULT_INTPARM, | 191 | rc = put_guest_u64(vcpu, __LC_EXT_PARAMS2, |
191 | inti->ext.ext_params2); | 192 | inti->ext.ext_params2); |
192 | if (rc == -EFAULT) | 193 | if (rc == -EFAULT) |
193 | exception = 1; | 194 | exception = 1; |
194 | break; | 195 | break; |
@@ -342,7 +343,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) | |||
342 | if (psw_interrupts_disabled(vcpu)) { | 343 | if (psw_interrupts_disabled(vcpu)) { |
343 | VCPU_EVENT(vcpu, 3, "%s", "disabled wait"); | 344 | VCPU_EVENT(vcpu, 3, "%s", "disabled wait"); |
344 | __unset_cpu_idle(vcpu); | 345 | __unset_cpu_idle(vcpu); |
345 | return -ENOTSUPP; /* disabled wait */ | 346 | return -EOPNOTSUPP; /* disabled wait */ |
346 | } | 347 | } |
347 | 348 | ||
348 | if (psw_extint_disabled(vcpu) || | 349 | if (psw_extint_disabled(vcpu) || |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 07ced89740d7..49292869a5cd 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/timer.h> | 25 | #include <linux/timer.h> |
26 | #include <asm/asm-offsets.h> | ||
26 | #include <asm/lowcore.h> | 27 | #include <asm/lowcore.h> |
27 | #include <asm/pgtable.h> | 28 | #include <asm/pgtable.h> |
28 | #include <asm/nmi.h> | 29 | #include <asm/nmi.h> |
@@ -74,9 +75,10 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
74 | static unsigned long long *facilities; | 75 | static unsigned long long *facilities; |
75 | 76 | ||
76 | /* Section: not file related */ | 77 | /* Section: not file related */ |
77 | void kvm_arch_hardware_enable(void *garbage) | 78 | int kvm_arch_hardware_enable(void *garbage) |
78 | { | 79 | { |
79 | /* every s390 is virtualization enabled ;-) */ | 80 | /* every s390 is virtualization enabled ;-) */ |
81 | return 0; | ||
80 | } | 82 | } |
81 | 83 | ||
82 | void kvm_arch_hardware_disable(void *garbage) | 84 | void kvm_arch_hardware_disable(void *garbage) |
@@ -116,10 +118,16 @@ long kvm_arch_dev_ioctl(struct file *filp, | |||
116 | 118 | ||
117 | int kvm_dev_ioctl_check_extension(long ext) | 119 | int kvm_dev_ioctl_check_extension(long ext) |
118 | { | 120 | { |
121 | int r; | ||
122 | |||
119 | switch (ext) { | 123 | switch (ext) { |
124 | case KVM_CAP_S390_PSW: | ||
125 | r = 1; | ||
126 | break; | ||
120 | default: | 127 | default: |
121 | return 0; | 128 | r = 0; |
122 | } | 129 | } |
130 | return r; | ||
123 | } | 131 | } |
124 | 132 | ||
125 | /* Section: vm related */ | 133 | /* Section: vm related */ |
@@ -150,7 +158,7 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
150 | break; | 158 | break; |
151 | } | 159 | } |
152 | default: | 160 | default: |
153 | r = -EINVAL; | 161 | r = -ENOTTY; |
154 | } | 162 | } |
155 | 163 | ||
156 | return r; | 164 | return r; |
@@ -234,6 +242,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) | |||
234 | kvm_free_physmem(kvm); | 242 | kvm_free_physmem(kvm); |
235 | free_page((unsigned long)(kvm->arch.sca)); | 243 | free_page((unsigned long)(kvm->arch.sca)); |
236 | debug_unregister(kvm->arch.dbf); | 244 | debug_unregister(kvm->arch.dbf); |
245 | cleanup_srcu_struct(&kvm->srcu); | ||
237 | kfree(kvm); | 246 | kfree(kvm); |
238 | } | 247 | } |
239 | 248 | ||
@@ -419,8 +428,10 @@ static int kvm_arch_vcpu_ioctl_set_initial_psw(struct kvm_vcpu *vcpu, psw_t psw) | |||
419 | vcpu_load(vcpu); | 428 | vcpu_load(vcpu); |
420 | if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) | 429 | if (atomic_read(&vcpu->arch.sie_block->cpuflags) & CPUSTAT_RUNNING) |
421 | rc = -EBUSY; | 430 | rc = -EBUSY; |
422 | else | 431 | else { |
423 | vcpu->arch.sie_block->gpsw = psw; | 432 | vcpu->run->psw_mask = psw.mask; |
433 | vcpu->run->psw_addr = psw.addr; | ||
434 | } | ||
424 | vcpu_put(vcpu); | 435 | vcpu_put(vcpu); |
425 | return rc; | 436 | return rc; |
426 | } | 437 | } |
@@ -508,9 +519,6 @@ rerun_vcpu: | |||
508 | 519 | ||
509 | switch (kvm_run->exit_reason) { | 520 | switch (kvm_run->exit_reason) { |
510 | case KVM_EXIT_S390_SIEIC: | 521 | case KVM_EXIT_S390_SIEIC: |
511 | vcpu->arch.sie_block->gpsw.mask = kvm_run->s390_sieic.mask; | ||
512 | vcpu->arch.sie_block->gpsw.addr = kvm_run->s390_sieic.addr; | ||
513 | break; | ||
514 | case KVM_EXIT_UNKNOWN: | 522 | case KVM_EXIT_UNKNOWN: |
515 | case KVM_EXIT_INTR: | 523 | case KVM_EXIT_INTR: |
516 | case KVM_EXIT_S390_RESET: | 524 | case KVM_EXIT_S390_RESET: |
@@ -519,6 +527,9 @@ rerun_vcpu: | |||
519 | BUG(); | 527 | BUG(); |
520 | } | 528 | } |
521 | 529 | ||
530 | vcpu->arch.sie_block->gpsw.mask = kvm_run->psw_mask; | ||
531 | vcpu->arch.sie_block->gpsw.addr = kvm_run->psw_addr; | ||
532 | |||
522 | might_fault(); | 533 | might_fault(); |
523 | 534 | ||
524 | do { | 535 | do { |
@@ -534,12 +545,10 @@ rerun_vcpu: | |||
534 | rc = -EINTR; | 545 | rc = -EINTR; |
535 | } | 546 | } |
536 | 547 | ||
537 | if (rc == -ENOTSUPP) { | 548 | if (rc == -EOPNOTSUPP) { |
538 | /* intercept cannot be handled in-kernel, prepare kvm-run */ | 549 | /* intercept cannot be handled in-kernel, prepare kvm-run */ |
539 | kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; | 550 | kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; |
540 | kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; | 551 | kvm_run->s390_sieic.icptcode = vcpu->arch.sie_block->icptcode; |
541 | kvm_run->s390_sieic.mask = vcpu->arch.sie_block->gpsw.mask; | ||
542 | kvm_run->s390_sieic.addr = vcpu->arch.sie_block->gpsw.addr; | ||
543 | kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; | 552 | kvm_run->s390_sieic.ipa = vcpu->arch.sie_block->ipa; |
544 | kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; | 553 | kvm_run->s390_sieic.ipb = vcpu->arch.sie_block->ipb; |
545 | rc = 0; | 554 | rc = 0; |
@@ -551,6 +560,9 @@ rerun_vcpu: | |||
551 | rc = 0; | 560 | rc = 0; |
552 | } | 561 | } |
553 | 562 | ||
563 | kvm_run->psw_mask = vcpu->arch.sie_block->gpsw.mask; | ||
564 | kvm_run->psw_addr = vcpu->arch.sie_block->gpsw.addr; | ||
565 | |||
554 | if (vcpu->sigset_active) | 566 | if (vcpu->sigset_active) |
555 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 567 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); |
556 | 568 | ||
@@ -593,45 +605,45 @@ int __kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
593 | } else | 605 | } else |
594 | prefix = 0; | 606 | prefix = 0; |
595 | 607 | ||
596 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, fp_regs), | 608 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), |
597 | vcpu->arch.guest_fpregs.fprs, 128, prefix)) | 609 | vcpu->arch.guest_fpregs.fprs, 128, prefix)) |
598 | return -EFAULT; | 610 | return -EFAULT; |
599 | 611 | ||
600 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, gp_regs), | 612 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs), |
601 | vcpu->arch.guest_gprs, 128, prefix)) | 613 | vcpu->arch.guest_gprs, 128, prefix)) |
602 | return -EFAULT; | 614 | return -EFAULT; |
603 | 615 | ||
604 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, psw), | 616 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw), |
605 | &vcpu->arch.sie_block->gpsw, 16, prefix)) | 617 | &vcpu->arch.sie_block->gpsw, 16, prefix)) |
606 | return -EFAULT; | 618 | return -EFAULT; |
607 | 619 | ||
608 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, pref_reg), | 620 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg), |
609 | &vcpu->arch.sie_block->prefix, 4, prefix)) | 621 | &vcpu->arch.sie_block->prefix, 4, prefix)) |
610 | return -EFAULT; | 622 | return -EFAULT; |
611 | 623 | ||
612 | if (__guestcopy(vcpu, | 624 | if (__guestcopy(vcpu, |
613 | addr + offsetof(struct save_area_s390x, fp_ctrl_reg), | 625 | addr + offsetof(struct save_area, fp_ctrl_reg), |
614 | &vcpu->arch.guest_fpregs.fpc, 4, prefix)) | 626 | &vcpu->arch.guest_fpregs.fpc, 4, prefix)) |
615 | return -EFAULT; | 627 | return -EFAULT; |
616 | 628 | ||
617 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, tod_reg), | 629 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg), |
618 | &vcpu->arch.sie_block->todpr, 4, prefix)) | 630 | &vcpu->arch.sie_block->todpr, 4, prefix)) |
619 | return -EFAULT; | 631 | return -EFAULT; |
620 | 632 | ||
621 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, timer), | 633 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer), |
622 | &vcpu->arch.sie_block->cputm, 8, prefix)) | 634 | &vcpu->arch.sie_block->cputm, 8, prefix)) |
623 | return -EFAULT; | 635 | return -EFAULT; |
624 | 636 | ||
625 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, clk_cmp), | 637 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), |
626 | &vcpu->arch.sie_block->ckc, 8, prefix)) | 638 | &vcpu->arch.sie_block->ckc, 8, prefix)) |
627 | return -EFAULT; | 639 | return -EFAULT; |
628 | 640 | ||
629 | if (__guestcopy(vcpu, addr + offsetof(struct save_area_s390x, acc_regs), | 641 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), |
630 | &vcpu->arch.guest_acrs, 64, prefix)) | 642 | &vcpu->arch.guest_acrs, 64, prefix)) |
631 | return -EFAULT; | 643 | return -EFAULT; |
632 | 644 | ||
633 | if (__guestcopy(vcpu, | 645 | if (__guestcopy(vcpu, |
634 | addr + offsetof(struct save_area_s390x, ctrl_regs), | 646 | addr + offsetof(struct save_area, ctrl_regs), |
635 | &vcpu->arch.sie_block->gcr, 128, prefix)) | 647 | &vcpu->arch.sie_block->gcr, 128, prefix)) |
636 | return -EFAULT; | 648 | return -EFAULT; |
637 | return 0; | 649 | return 0; |
@@ -679,14 +691,12 @@ long kvm_arch_vcpu_ioctl(struct file *filp, | |||
679 | } | 691 | } |
680 | 692 | ||
681 | /* Section: memory related */ | 693 | /* Section: memory related */ |
682 | int kvm_arch_set_memory_region(struct kvm *kvm, | 694 | int kvm_arch_prepare_memory_region(struct kvm *kvm, |
683 | struct kvm_userspace_memory_region *mem, | 695 | struct kvm_memory_slot *memslot, |
684 | struct kvm_memory_slot old, | 696 | struct kvm_memory_slot old, |
685 | int user_alloc) | 697 | struct kvm_userspace_memory_region *mem, |
698 | int user_alloc) | ||
686 | { | 699 | { |
687 | int i; | ||
688 | struct kvm_vcpu *vcpu; | ||
689 | |||
690 | /* A few sanity checks. We can have exactly one memory slot which has | 700 | /* A few sanity checks. We can have exactly one memory slot which has |
691 | to start at guest virtual zero and which has to be located at a | 701 | to start at guest virtual zero and which has to be located at a |
692 | page boundary in userland and which has to end at a page boundary. | 702 | page boundary in userland and which has to end at a page boundary. |
@@ -709,14 +719,23 @@ int kvm_arch_set_memory_region(struct kvm *kvm, | |||
709 | if (!user_alloc) | 719 | if (!user_alloc) |
710 | return -EINVAL; | 720 | return -EINVAL; |
711 | 721 | ||
722 | return 0; | ||
723 | } | ||
724 | |||
725 | void kvm_arch_commit_memory_region(struct kvm *kvm, | ||
726 | struct kvm_userspace_memory_region *mem, | ||
727 | struct kvm_memory_slot old, | ||
728 | int user_alloc) | ||
729 | { | ||
730 | int i; | ||
731 | struct kvm_vcpu *vcpu; | ||
732 | |||
712 | /* request update of sie control block for all available vcpus */ | 733 | /* request update of sie control block for all available vcpus */ |
713 | kvm_for_each_vcpu(i, vcpu, kvm) { | 734 | kvm_for_each_vcpu(i, vcpu, kvm) { |
714 | if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) | 735 | if (test_and_set_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) |
715 | continue; | 736 | continue; |
716 | kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP); | 737 | kvm_s390_inject_sigp_stop(vcpu, ACTION_RELOADVCPU_ON_STOP); |
717 | } | 738 | } |
718 | |||
719 | return 0; | ||
720 | } | 739 | } |
721 | 740 | ||
722 | void kvm_arch_flush_shadow(struct kvm *kvm) | 741 | void kvm_arch_flush_shadow(struct kvm *kvm) |
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index 06cce8285ba0..60f09ab3672c 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -67,10 +67,14 @@ static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu) | |||
67 | 67 | ||
68 | static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) | 68 | static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) |
69 | { | 69 | { |
70 | int idx; | ||
70 | struct kvm_memory_slot *mem; | 71 | struct kvm_memory_slot *mem; |
72 | struct kvm_memslots *memslots; | ||
71 | 73 | ||
72 | down_read(&vcpu->kvm->slots_lock); | 74 | idx = srcu_read_lock(&vcpu->kvm->srcu); |
73 | mem = &vcpu->kvm->memslots[0]; | 75 | memslots = rcu_dereference(vcpu->kvm->memslots); |
76 | |||
77 | mem = &memslots->memslots[0]; | ||
74 | 78 | ||
75 | vcpu->arch.sie_block->gmsor = mem->userspace_addr; | 79 | vcpu->arch.sie_block->gmsor = mem->userspace_addr; |
76 | vcpu->arch.sie_block->gmslm = | 80 | vcpu->arch.sie_block->gmslm = |
@@ -78,7 +82,7 @@ static inline void kvm_s390_vcpu_set_mem(struct kvm_vcpu *vcpu) | |||
78 | (mem->npages << PAGE_SHIFT) + | 82 | (mem->npages << PAGE_SHIFT) + |
79 | VIRTIODESCSPACE - 1ul; | 83 | VIRTIODESCSPACE - 1ul; |
80 | 84 | ||
81 | up_read(&vcpu->kvm->slots_lock); | 85 | srcu_read_unlock(&vcpu->kvm->srcu, idx); |
82 | } | 86 | } |
83 | 87 | ||
84 | /* implemented in priv.c */ | 88 | /* implemented in priv.c */ |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d426aac8095d..44205507717c 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/kvm.h> | 14 | #include <linux/kvm.h> |
15 | #include <linux/gfp.h> | ||
15 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
16 | #include <asm/current.h> | 17 | #include <asm/current.h> |
17 | #include <asm/debug.h> | 18 | #include <asm/debug.h> |
@@ -323,5 +324,5 @@ int kvm_s390_handle_b2(struct kvm_vcpu *vcpu) | |||
323 | else | 324 | else |
324 | return handler(vcpu); | 325 | return handler(vcpu); |
325 | } | 326 | } |
326 | return -ENOTSUPP; | 327 | return -EOPNOTSUPP; |
327 | } | 328 | } |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index 40c8c6748cfe..eff3c5989b46 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/kvm.h> | 15 | #include <linux/kvm.h> |
16 | #include <linux/kvm_host.h> | 16 | #include <linux/kvm_host.h> |
17 | #include <linux/slab.h> | ||
17 | #include "gaccess.h" | 18 | #include "gaccess.h" |
18 | #include "kvm-s390.h" | 19 | #include "kvm-s390.h" |
19 | 20 | ||
@@ -172,7 +173,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | |||
172 | rc = 0; /* order accepted */ | 173 | rc = 0; /* order accepted */ |
173 | break; | 174 | break; |
174 | default: | 175 | default: |
175 | rc = -ENOTSUPP; | 176 | rc = -EOPNOTSUPP; |
176 | } | 177 | } |
177 | return rc; | 178 | return rc; |
178 | } | 179 | } |
@@ -188,9 +189,9 @@ static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, | |||
188 | 189 | ||
189 | /* make sure that the new value is valid memory */ | 190 | /* make sure that the new value is valid memory */ |
190 | address = address & 0x7fffe000u; | 191 | address = address & 0x7fffe000u; |
191 | if ((copy_from_guest(vcpu, &tmp, | 192 | if ((copy_from_user(&tmp, (void __user *) |
192 | (u64) (address + vcpu->arch.sie_block->gmsor) , 1)) || | 193 | (address + vcpu->arch.sie_block->gmsor) , 1)) || |
193 | (copy_from_guest(vcpu, &tmp, (u64) (address + | 194 | (copy_from_user(&tmp, (void __user *)(address + |
194 | vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) { | 195 | vcpu->arch.sie_block->gmsor + PAGE_SIZE), 1))) { |
195 | *reg |= SIGP_STAT_INVALID_PARAMETER; | 196 | *reg |= SIGP_STAT_INVALID_PARAMETER; |
196 | return 1; /* invalid parameter */ | 197 | return 1; /* invalid parameter */ |
@@ -293,7 +294,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
293 | vcpu->stat.instruction_sigp_restart++; | 294 | vcpu->stat.instruction_sigp_restart++; |
294 | /* user space must know about restart */ | 295 | /* user space must know about restart */ |
295 | default: | 296 | default: |
296 | return -ENOTSUPP; | 297 | return -EOPNOTSUPP; |
297 | } | 298 | } |
298 | 299 | ||
299 | if (rc < 0) | 300 | if (rc < 0) |