aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kvm/diag.c2
-rw-r--r--arch/s390/kvm/kvm-s390.c53
-rw-r--r--arch/s390/kvm/kvm-s390.h10
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/kvm/sigp.c56
-rw-r--r--arch/s390/kvm/trace.h1
6 files changed, 78 insertions, 48 deletions
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 78d967f180f4..5ff29be7d87a 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -137,7 +137,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
137 137
138int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) 138int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
139{ 139{
140 int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16; 140 int code = kvm_s390_get_base_disp_rs(vcpu) & 0xffff;
141 141
142 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) 142 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
143 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); 143 return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 569494e01ec6..1bb1ddaf93c0 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -732,14 +732,12 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason)
732 732
733 if (exit_reason >= 0) { 733 if (exit_reason >= 0) {
734 rc = 0; 734 rc = 0;
735 } else { 735 } else if (kvm_is_ucontrol(vcpu->kvm)) {
736 if (kvm_is_ucontrol(vcpu->kvm)) { 736 vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL;
737 rc = SIE_INTERCEPT_UCONTROL; 737 vcpu->run->s390_ucontrol.trans_exc_code =
738 } else { 738 current->thread.gmap_addr;
739 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); 739 vcpu->run->s390_ucontrol.pgm_code = 0x10;
740 trace_kvm_s390_sie_fault(vcpu); 740 rc = -EREMOTE;
741 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
742 }
743 } 741 }
744 742
745 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); 743 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
@@ -833,16 +831,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
833 rc = -EINTR; 831 rc = -EINTR;
834 } 832 }
835 833
836#ifdef CONFIG_KVM_S390_UCONTROL
837 if (rc == SIE_INTERCEPT_UCONTROL) {
838 kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL;
839 kvm_run->s390_ucontrol.trans_exc_code =
840 current->thread.gmap_addr;
841 kvm_run->s390_ucontrol.pgm_code = 0x10;
842 rc = 0;
843 }
844#endif
845
846 if (rc == -EOPNOTSUPP) { 834 if (rc == -EOPNOTSUPP) {
847 /* intercept cannot be handled in-kernel, prepare kvm-run */ 835 /* intercept cannot be handled in-kernel, prepare kvm-run */
848 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; 836 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
@@ -885,10 +873,11 @@ static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
885 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit 873 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
886 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix 874 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
887 */ 875 */
888int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) 876int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr)
889{ 877{
890 unsigned char archmode = 1; 878 unsigned char archmode = 1;
891 int prefix; 879 int prefix;
880 u64 clkcomp;
892 881
893 if (addr == KVM_S390_STORE_STATUS_NOADDR) { 882 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
894 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1)) 883 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
@@ -903,15 +892,6 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
903 } else 892 } else
904 prefix = 0; 893 prefix = 0;
905 894
906 /*
907 * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy
908 * copying in vcpu load/put. Lets update our copies before we save
909 * it into the save area
910 */
911 save_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
912 save_fp_regs(vcpu->arch.guest_fpregs.fprs);
913 save_access_regs(vcpu->run->s.regs.acrs);
914
915 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), 895 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
916 vcpu->arch.guest_fpregs.fprs, 128, prefix)) 896 vcpu->arch.guest_fpregs.fprs, 128, prefix))
917 return -EFAULT; 897 return -EFAULT;
@@ -941,8 +921,9 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
941 &vcpu->arch.sie_block->cputm, 8, prefix)) 921 &vcpu->arch.sie_block->cputm, 8, prefix))
942 return -EFAULT; 922 return -EFAULT;
943 923
924 clkcomp = vcpu->arch.sie_block->ckc >> 8;
944 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), 925 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
945 &vcpu->arch.sie_block->ckc, 8, prefix)) 926 &clkcomp, 8, prefix))
946 return -EFAULT; 927 return -EFAULT;
947 928
948 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), 929 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
@@ -956,6 +937,20 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
956 return 0; 937 return 0;
957} 938}
958 939
940int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
941{
942 /*
943 * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy
944 * copying in vcpu load/put. Lets update our copies before we save
945 * it into the save area
946 */
947 save_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
948 save_fp_regs(vcpu->arch.guest_fpregs.fprs);
949 save_access_regs(vcpu->run->s.regs.acrs);
950
951 return kvm_s390_store_status_unloaded(vcpu, addr);
952}
953
959static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, 954static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
960 struct kvm_enable_cap *cap) 955 struct kvm_enable_cap *cap)
961{ 956{
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index b44912a32949..095cf51b16ec 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -19,16 +19,11 @@
19#include <linux/kvm.h> 19#include <linux/kvm.h>
20#include <linux/kvm_host.h> 20#include <linux/kvm_host.h>
21 21
22/* The current code can have up to 256 pages for virtio */
23#define VIRTIODESCSPACE (256ul * 4096ul)
24
25typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); 22typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu);
26 23
27/* declare vfacilities extern */ 24/* declare vfacilities extern */
28extern unsigned long *vfacilities; 25extern unsigned long *vfacilities;
29 26
30/* negativ values are error codes, positive values for internal conditions */
31#define SIE_INTERCEPT_UCONTROL (1<<0)
32int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); 27int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu);
33 28
34#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ 29#define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\
@@ -133,7 +128,6 @@ int __must_check kvm_s390_inject_vm(struct kvm *kvm,
133int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, 128int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
134 struct kvm_s390_interrupt *s390int); 129 struct kvm_s390_interrupt *s390int);
135int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); 130int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
136int __must_check kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
137struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, 131struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
138 u64 cr6, u64 schid); 132 u64 cr6, u64 schid);
139 133
@@ -150,8 +144,8 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu);
150int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); 144int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
151 145
152/* implemented in kvm-s390.c */ 146/* implemented in kvm-s390.c */
153int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, 147int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr);
154 unsigned long addr); 148int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr);
155void s390_vcpu_block(struct kvm_vcpu *vcpu); 149void s390_vcpu_block(struct kvm_vcpu *vcpu);
156void s390_vcpu_unblock(struct kvm_vcpu *vcpu); 150void s390_vcpu_unblock(struct kvm_vcpu *vcpu);
157void exit_sie(struct kvm_vcpu *vcpu); 151void exit_sie(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 2440602e6df1..05537ab22382 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -197,7 +197,7 @@ static int handle_tpi(struct kvm_vcpu *vcpu)
197 if (addr & 3) 197 if (addr & 3)
198 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 198 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
199 cc = 0; 199 cc = 0;
200 inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->run->s.regs.crs[6], 0); 200 inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0);
201 if (!inti) 201 if (!inti)
202 goto no_interrupt; 202 goto no_interrupt;
203 cc = 1; 203 cc = 1;
@@ -638,7 +638,6 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
638 638
639static const intercept_handler_t b9_handlers[256] = { 639static const intercept_handler_t b9_handlers[256] = {
640 [0x8d] = handle_epsw, 640 [0x8d] = handle_epsw,
641 [0x9c] = handle_io_inst,
642 [0xaf] = handle_pfmf, 641 [0xaf] = handle_pfmf,
643}; 642};
644 643
@@ -731,7 +730,6 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
731 730
732static const intercept_handler_t eb_handlers[256] = { 731static const intercept_handler_t eb_handlers[256] = {
733 [0x2f] = handle_lctlg, 732 [0x2f] = handle_lctlg,
734 [0x8a] = handle_io_inst,
735}; 733};
736 734
737int kvm_s390_handle_eb(struct kvm_vcpu *vcpu) 735int kvm_s390_handle_eb(struct kvm_vcpu *vcpu)
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index bec398c57acf..c3700585b4bb 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -130,6 +130,7 @@ unlock:
130static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) 130static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
131{ 131{
132 struct kvm_s390_interrupt_info *inti; 132 struct kvm_s390_interrupt_info *inti;
133 int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
133 134
134 inti = kzalloc(sizeof(*inti), GFP_ATOMIC); 135 inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
135 if (!inti) 136 if (!inti)
@@ -139,6 +140,8 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
139 spin_lock_bh(&li->lock); 140 spin_lock_bh(&li->lock);
140 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { 141 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
141 kfree(inti); 142 kfree(inti);
143 if ((action & ACTION_STORE_ON_STOP) != 0)
144 rc = -ESHUTDOWN;
142 goto out; 145 goto out;
143 } 146 }
144 list_add_tail(&inti->list, &li->list); 147 list_add_tail(&inti->list, &li->list);
@@ -150,7 +153,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
150out: 153out:
151 spin_unlock_bh(&li->lock); 154 spin_unlock_bh(&li->lock);
152 155
153 return SIGP_CC_ORDER_CODE_ACCEPTED; 156 return rc;
154} 157}
155 158
156static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) 159static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
@@ -174,13 +177,17 @@ static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
174unlock: 177unlock:
175 spin_unlock(&fi->lock); 178 spin_unlock(&fi->lock);
176 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); 179 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
177 return rc;
178}
179 180
180int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action) 181 if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) {
181{ 182 /* If the CPU has already been stopped, we still have
182 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 183 * to save the status when doing stop-and-store. This
183 return __inject_sigp_stop(li, action); 184 * has to be done after unlocking all spinlocks. */
185 struct kvm_vcpu *dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
186 rc = kvm_s390_store_status_unloaded(dst_vcpu,
187 KVM_S390_STORE_STATUS_NOADDR);
188 }
189
190 return rc;
184} 191}
185 192
186static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) 193static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
@@ -262,6 +269,37 @@ out_fi:
262 return rc; 269 return rc;
263} 270}
264 271
272static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id,
273 u32 addr, u64 *reg)
274{
275 struct kvm_vcpu *dst_vcpu = NULL;
276 int flags;
277 int rc;
278
279 if (cpu_id < KVM_MAX_VCPUS)
280 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id);
281 if (!dst_vcpu)
282 return SIGP_CC_NOT_OPERATIONAL;
283
284 spin_lock_bh(&dst_vcpu->arch.local_int.lock);
285 flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
286 spin_unlock_bh(&dst_vcpu->arch.local_int.lock);
287 if (!(flags & CPUSTAT_STOPPED)) {
288 *reg &= 0xffffffff00000000UL;
289 *reg |= SIGP_STATUS_INCORRECT_STATE;
290 return SIGP_CC_STATUS_STORED;
291 }
292
293 addr &= 0x7ffffe00;
294 rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);
295 if (rc == -EFAULT) {
296 *reg &= 0xffffffff00000000UL;
297 *reg |= SIGP_STATUS_INVALID_PARAMETER;
298 rc = SIGP_CC_STATUS_STORED;
299 }
300 return rc;
301}
302
265static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, 303static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
266 u64 *reg) 304 u64 *reg)
267{ 305{
@@ -366,6 +404,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
366 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | 404 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP |
367 ACTION_STOP_ON_STOP); 405 ACTION_STOP_ON_STOP);
368 break; 406 break;
407 case SIGP_STORE_STATUS_AT_ADDRESS:
408 rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
409 &vcpu->run->s.regs.gprs[r1]);
410 break;
369 case SIGP_SET_ARCHITECTURE: 411 case SIGP_SET_ARCHITECTURE:
370 vcpu->stat.instruction_sigp_arch++; 412 vcpu->stat.instruction_sigp_arch++;
371 rc = __sigp_set_arch(vcpu, parameter); 413 rc = __sigp_set_arch(vcpu, parameter);
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h
index 0c991c6748ab..3db76b2daed7 100644
--- a/arch/s390/kvm/trace.h
+++ b/arch/s390/kvm/trace.h
@@ -175,6 +175,7 @@ TRACE_EVENT(kvm_s390_intercept_validity,
175 {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \ 175 {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \
176 {SIGP_SET_ARCHITECTURE, "set architecture"}, \ 176 {SIGP_SET_ARCHITECTURE, "set architecture"}, \
177 {SIGP_SET_PREFIX, "set prefix"}, \ 177 {SIGP_SET_PREFIX, "set prefix"}, \
178 {SIGP_STORE_STATUS_AT_ADDRESS, "store status at addr"}, \
178 {SIGP_SENSE_RUNNING, "sense running"}, \ 179 {SIGP_SENSE_RUNNING, "sense running"}, \
179 {SIGP_RESTART, "restart"} 180 {SIGP_RESTART, "restart"}
180 181