aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 00:40:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 00:40:43 -0500
commit7ebd3faa9b5b42caf2d5aa1352a93dcfa0098011 (patch)
treec45acf88b7976dcec117b6a3dbe31a7fe710ef33 /arch/s390
parentbb1281f2aae08e5ef23eb0692c8833e95579cdf2 (diff)
parent7650b6870930055426abb32cc47d164ccdea49db (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Paolo Bonzini: "First round of KVM updates for 3.14; PPC parts will come next week. Nothing major here, just bugfixes all over the place. The most interesting part is the ARM guys' virtualized interrupt controller overhaul, which lets userspace get/set the state and thus enables migration of ARM VMs" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (67 commits) kvm: make KVM_MMU_AUDIT help text more readable KVM: s390: Fix memory access error detection KVM: nVMX: Update guest activity state field on L2 exits KVM: nVMX: Fix nested_run_pending on activity state HLT KVM: nVMX: Clean up handling of VMX-related MSRs KVM: nVMX: Add tracepoints for nested_vmexit and nested_vmexit_inject KVM: nVMX: Pass vmexit parameters to nested_vmx_vmexit KVM: nVMX: Leave VMX mode on clearing of feature control MSR KVM: VMX: Fix DR6 update on #DB exception KVM: SVM: Fix reading of DR6 KVM: x86: Sync DR7 on KVM_SET_DEBUGREGS add support for Hyper-V reference time counter KVM: remove useless write to vcpu->hv_clock.tsc_timestamp KVM: x86: fix tsc catchup issue with tsc scaling KVM: x86: limit PIT timer frequency KVM: x86: handle invalid root_hpa everywhere kvm: Provide kvm_vcpu_eligible_for_directed_yield() stub kvm: vfio: silence GCC warning KVM: ARM: Remove duplicate include arm/arm64: KVM: relax the requirements of VMA alignment for THP ...
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/sigp.h2
-rw-r--r--arch/s390/kvm/diag.c4
-rw-r--r--arch/s390/kvm/kvm-s390.c55
-rw-r--r--arch/s390/kvm/kvm-s390.h10
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/kvm/sigp.c120
-rw-r--r--arch/s390/kvm/trace.h1
7 files changed, 137 insertions, 59 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index 5a87d16d3e7c..d091aa1aaf11 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -5,6 +5,7 @@
5#define SIGP_SENSE 1 5#define SIGP_SENSE 1
6#define SIGP_EXTERNAL_CALL 2 6#define SIGP_EXTERNAL_CALL 2
7#define SIGP_EMERGENCY_SIGNAL 3 7#define SIGP_EMERGENCY_SIGNAL 3
8#define SIGP_START 4
8#define SIGP_STOP 5 9#define SIGP_STOP 5
9#define SIGP_RESTART 6 10#define SIGP_RESTART 6
10#define SIGP_STOP_AND_STORE_STATUS 9 11#define SIGP_STOP_AND_STORE_STATUS 9
@@ -12,6 +13,7 @@
12#define SIGP_SET_PREFIX 13 13#define SIGP_SET_PREFIX 13
13#define SIGP_STORE_STATUS_AT_ADDRESS 14 14#define SIGP_STORE_STATUS_AT_ADDRESS 14
14#define SIGP_SET_ARCHITECTURE 18 15#define SIGP_SET_ARCHITECTURE 18
16#define SIGP_COND_EMERGENCY_SIGNAL 19
15#define SIGP_SENSE_RUNNING 21 17#define SIGP_SENSE_RUNNING 21
16 18
17/* SIGP condition codes */ 19/* SIGP condition codes */
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 78d967f180f4..8216c0e0b2e2 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -121,7 +121,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
121 * - gpr 4 contains the index on the bus (optionally) 121 * - gpr 4 contains the index on the bus (optionally)
122 */ 122 */
123 ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, 123 ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS,
124 vcpu->run->s.regs.gprs[2], 124 vcpu->run->s.regs.gprs[2] & 0xffffffff,
125 8, &vcpu->run->s.regs.gprs[3], 125 8, &vcpu->run->s.regs.gprs[3],
126 vcpu->run->s.regs.gprs[4]); 126 vcpu->run->s.regs.gprs[4]);
127 127
@@ -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..7635c00a1479 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -732,14 +732,16 @@ 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 if (kvm_is_ucontrol(vcpu->kvm)) {
736 vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL;
737 vcpu->run->s390_ucontrol.trans_exc_code =
738 current->thread.gmap_addr;
739 vcpu->run->s390_ucontrol.pgm_code = 0x10;
740 rc = -EREMOTE;
735 } else { 741 } else {
736 if (kvm_is_ucontrol(vcpu->kvm)) { 742 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
737 rc = SIE_INTERCEPT_UCONTROL; 743 trace_kvm_s390_sie_fault(vcpu);
738 } else { 744 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
739 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
740 trace_kvm_s390_sie_fault(vcpu);
741 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
742 }
743 } 745 }
744 746
745 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); 747 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
@@ -833,16 +835,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
833 rc = -EINTR; 835 rc = -EINTR;
834 } 836 }
835 837
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) { 838 if (rc == -EOPNOTSUPP) {
847 /* intercept cannot be handled in-kernel, prepare kvm-run */ 839 /* intercept cannot be handled in-kernel, prepare kvm-run */
848 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; 840 kvm_run->exit_reason = KVM_EXIT_S390_SIEIC;
@@ -885,10 +877,11 @@ static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
885 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit 877 * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
886 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix 878 * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
887 */ 879 */
888int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) 880int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr)
889{ 881{
890 unsigned char archmode = 1; 882 unsigned char archmode = 1;
891 int prefix; 883 int prefix;
884 u64 clkcomp;
892 885
893 if (addr == KVM_S390_STORE_STATUS_NOADDR) { 886 if (addr == KVM_S390_STORE_STATUS_NOADDR) {
894 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1)) 887 if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
@@ -903,15 +896,6 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
903 } else 896 } else
904 prefix = 0; 897 prefix = 0;
905 898
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), 899 if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
916 vcpu->arch.guest_fpregs.fprs, 128, prefix)) 900 vcpu->arch.guest_fpregs.fprs, 128, prefix))
917 return -EFAULT; 901 return -EFAULT;
@@ -941,8 +925,9 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
941 &vcpu->arch.sie_block->cputm, 8, prefix)) 925 &vcpu->arch.sie_block->cputm, 8, prefix))
942 return -EFAULT; 926 return -EFAULT;
943 927
928 clkcomp = vcpu->arch.sie_block->ckc >> 8;
944 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), 929 if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
945 &vcpu->arch.sie_block->ckc, 8, prefix)) 930 &clkcomp, 8, prefix))
946 return -EFAULT; 931 return -EFAULT;
947 932
948 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), 933 if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
@@ -956,6 +941,20 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
956 return 0; 941 return 0;
957} 942}
958 943
944int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
945{
946 /*
947 * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy
948 * copying in vcpu load/put. Lets update our copies before we save
949 * it into the save area
950 */
951 save_fp_ctl(&vcpu->arch.guest_fpregs.fpc);
952 save_fp_regs(vcpu->arch.guest_fpregs.fprs);
953 save_access_regs(vcpu->run->s.regs.acrs);
954
955 return kvm_s390_store_status_unloaded(vcpu, addr);
956}
957
959static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, 958static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
960 struct kvm_enable_cap *cap) 959 struct kvm_enable_cap *cap)
961{ 960{
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 d101dae62771..75beea632a10 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..87c2b3a3bd3e 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * handling interprocessor communication 2 * handling interprocessor communication
3 * 3 *
4 * Copyright IBM Corp. 2008, 2009 4 * Copyright IBM Corp. 2008, 2013
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -89,6 +89,37 @@ unlock:
89 return rc; 89 return rc;
90} 90}
91 91
92static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr,
93 u16 asn, u64 *reg)
94{
95 struct kvm_vcpu *dst_vcpu = NULL;
96 const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
97 u16 p_asn, s_asn;
98 psw_t *psw;
99 u32 flags;
100
101 if (cpu_addr < KVM_MAX_VCPUS)
102 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
103 if (!dst_vcpu)
104 return SIGP_CC_NOT_OPERATIONAL;
105 flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags);
106 psw = &dst_vcpu->arch.sie_block->gpsw;
107 p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */
108 s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */
109
110 /* Deliver the emergency signal? */
111 if (!(flags & CPUSTAT_STOPPED)
112 || (psw->mask & psw_int_mask) != psw_int_mask
113 || ((flags & CPUSTAT_WAIT) && psw->addr != 0)
114 || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) {
115 return __sigp_emergency(vcpu, cpu_addr);
116 } else {
117 *reg &= 0xffffffff00000000UL;
118 *reg |= SIGP_STATUS_INCORRECT_STATE;
119 return SIGP_CC_STATUS_STORED;
120 }
121}
122
92static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) 123static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)
93{ 124{
94 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 125 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
@@ -130,6 +161,7 @@ unlock:
130static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) 161static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
131{ 162{
132 struct kvm_s390_interrupt_info *inti; 163 struct kvm_s390_interrupt_info *inti;
164 int rc = SIGP_CC_ORDER_CODE_ACCEPTED;
133 165
134 inti = kzalloc(sizeof(*inti), GFP_ATOMIC); 166 inti = kzalloc(sizeof(*inti), GFP_ATOMIC);
135 if (!inti) 167 if (!inti)
@@ -139,6 +171,8 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
139 spin_lock_bh(&li->lock); 171 spin_lock_bh(&li->lock);
140 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { 172 if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) {
141 kfree(inti); 173 kfree(inti);
174 if ((action & ACTION_STORE_ON_STOP) != 0)
175 rc = -ESHUTDOWN;
142 goto out; 176 goto out;
143 } 177 }
144 list_add_tail(&inti->list, &li->list); 178 list_add_tail(&inti->list, &li->list);
@@ -150,7 +184,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action)
150out: 184out:
151 spin_unlock_bh(&li->lock); 185 spin_unlock_bh(&li->lock);
152 186
153 return SIGP_CC_ORDER_CODE_ACCEPTED; 187 return rc;
154} 188}
155 189
156static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) 190static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
@@ -174,13 +208,17 @@ static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action)
174unlock: 208unlock:
175 spin_unlock(&fi->lock); 209 spin_unlock(&fi->lock);
176 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); 210 VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr);
177 return rc;
178}
179 211
180int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action) 212 if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) {
181{ 213 /* If the CPU has already been stopped, we still have
182 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 214 * to save the status when doing stop-and-store. This
183 return __inject_sigp_stop(li, action); 215 * has to be done after unlocking all spinlocks. */
216 struct kvm_vcpu *dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
217 rc = kvm_s390_store_status_unloaded(dst_vcpu,
218 KVM_S390_STORE_STATUS_NOADDR);
219 }
220
221 return rc;
184} 222}
185 223
186static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) 224static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
@@ -262,6 +300,37 @@ out_fi:
262 return rc; 300 return rc;
263} 301}
264 302
303static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id,
304 u32 addr, u64 *reg)
305{
306 struct kvm_vcpu *dst_vcpu = NULL;
307 int flags;
308 int rc;
309
310 if (cpu_id < KVM_MAX_VCPUS)
311 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id);
312 if (!dst_vcpu)
313 return SIGP_CC_NOT_OPERATIONAL;
314
315 spin_lock_bh(&dst_vcpu->arch.local_int.lock);
316 flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
317 spin_unlock_bh(&dst_vcpu->arch.local_int.lock);
318 if (!(flags & CPUSTAT_STOPPED)) {
319 *reg &= 0xffffffff00000000UL;
320 *reg |= SIGP_STATUS_INCORRECT_STATE;
321 return SIGP_CC_STATUS_STORED;
322 }
323
324 addr &= 0x7ffffe00;
325 rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);
326 if (rc == -EFAULT) {
327 *reg &= 0xffffffff00000000UL;
328 *reg |= SIGP_STATUS_INVALID_PARAMETER;
329 rc = SIGP_CC_STATUS_STORED;
330 }
331 return rc;
332}
333
265static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, 334static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
266 u64 *reg) 335 u64 *reg)
267{ 336{
@@ -294,7 +363,8 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
294 return rc; 363 return rc;
295} 364}
296 365
297static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) 366/* Test whether the destination CPU is available and not busy */
367static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
298{ 368{
299 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 369 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
300 struct kvm_s390_local_interrupt *li; 370 struct kvm_s390_local_interrupt *li;
@@ -313,9 +383,6 @@ static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr)
313 spin_lock_bh(&li->lock); 383 spin_lock_bh(&li->lock);
314 if (li->action_bits & ACTION_STOP_ON_STOP) 384 if (li->action_bits & ACTION_STOP_ON_STOP)
315 rc = SIGP_CC_BUSY; 385 rc = SIGP_CC_BUSY;
316 else
317 VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace",
318 cpu_addr);
319 spin_unlock_bh(&li->lock); 386 spin_unlock_bh(&li->lock);
320out: 387out:
321 spin_unlock(&fi->lock); 388 spin_unlock(&fi->lock);
@@ -366,6 +433,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
366 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | 433 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP |
367 ACTION_STOP_ON_STOP); 434 ACTION_STOP_ON_STOP);
368 break; 435 break;
436 case SIGP_STORE_STATUS_AT_ADDRESS:
437 rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
438 &vcpu->run->s.regs.gprs[r1]);
439 break;
369 case SIGP_SET_ARCHITECTURE: 440 case SIGP_SET_ARCHITECTURE:
370 vcpu->stat.instruction_sigp_arch++; 441 vcpu->stat.instruction_sigp_arch++;
371 rc = __sigp_set_arch(vcpu, parameter); 442 rc = __sigp_set_arch(vcpu, parameter);
@@ -375,17 +446,31 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
375 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, 446 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
376 &vcpu->run->s.regs.gprs[r1]); 447 &vcpu->run->s.regs.gprs[r1]);
377 break; 448 break;
449 case SIGP_COND_EMERGENCY_SIGNAL:
450 rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
451 &vcpu->run->s.regs.gprs[r1]);
452 break;
378 case SIGP_SENSE_RUNNING: 453 case SIGP_SENSE_RUNNING:
379 vcpu->stat.instruction_sigp_sense_running++; 454 vcpu->stat.instruction_sigp_sense_running++;
380 rc = __sigp_sense_running(vcpu, cpu_addr, 455 rc = __sigp_sense_running(vcpu, cpu_addr,
381 &vcpu->run->s.regs.gprs[r1]); 456 &vcpu->run->s.regs.gprs[r1]);
382 break; 457 break;
458 case SIGP_START:
459 rc = sigp_check_callable(vcpu, cpu_addr);
460 if (rc == SIGP_CC_ORDER_CODE_ACCEPTED)
461 rc = -EOPNOTSUPP; /* Handle START in user space */
462 break;
383 case SIGP_RESTART: 463 case SIGP_RESTART:
384 vcpu->stat.instruction_sigp_restart++; 464 vcpu->stat.instruction_sigp_restart++;
385 rc = __sigp_restart(vcpu, cpu_addr); 465 rc = sigp_check_callable(vcpu, cpu_addr);
386 if (rc == SIGP_CC_BUSY) 466 if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) {
387 break; 467 VCPU_EVENT(vcpu, 4,
388 /* user space must know about restart */ 468 "sigp restart %x to handle userspace",
469 cpu_addr);
470 /* user space must know about restart */
471 rc = -EOPNOTSUPP;
472 }
473 break;
389 default: 474 default:
390 return -EOPNOTSUPP; 475 return -EOPNOTSUPP;
391 } 476 }
@@ -393,7 +478,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
393 if (rc < 0) 478 if (rc < 0)
394 return rc; 479 return rc;
395 480
396 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 481 kvm_s390_set_psw_cc(vcpu, rc);
397 vcpu->arch.sie_block->gpsw.mask |= (rc & 3ul) << 44;
398 return 0; 482 return 0;
399} 483}
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