aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-11-28 09:30:16 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2013-11-28 09:30:16 -0500
commitd6d63b51fe3bfea0cf596993afa480b0b3b02c32 (patch)
treeebe038c7ba4a00b6367c3eade0f218f2b518c4ef
parent0a00a775d2a49d16efba721c786859844184599c (diff)
parent36daca9bb36f0395755817d1b0c45ab6fbf0441b (diff)
Merge tag 'kvm-s390-20131128' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
Several fixes for kvm-next. The diagnose decoding and the missing store status are more major (can cause the host to execute different things than the guest wanted resp. produce unusable dumps when something breaks). The other patches contain more minor fixes and cleanups.
-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