aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/virtual/kvm/api.txt4
-rw-r--r--arch/s390/include/asm/kvm_host.h8
-rw-r--r--arch/s390/kvm/intercept.c2
-rw-r--r--arch/s390/kvm/interrupt.c112
-rw-r--r--arch/s390/kvm/kvm-s390.h3
-rw-r--r--arch/s390/kvm/priv.c135
-rw-r--r--arch/s390/kvm/trace-s390.h6
-rw-r--r--include/uapi/linux/kvm.h1
8 files changed, 268 insertions, 3 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 83bd92b52936..8a0de309932f 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2073,6 +2073,10 @@ KVM_S390_INT_IO(ai,cssid,ssid,schid) (vm) - compound value to indicate an
2073 I/O interrupt (ai - adapter interrupt; cssid,ssid,schid - subchannel); 2073 I/O interrupt (ai - adapter interrupt; cssid,ssid,schid - subchannel);
2074 I/O interruption parameters in parm (subchannel) and parm64 (intparm, 2074 I/O interruption parameters in parm (subchannel) and parm64 (intparm,
2075 interruption subclass) 2075 interruption subclass)
2076KVM_S390_MCHK (vm, vcpu) - machine check interrupt; cr 14 bits in parm,
2077 machine check interrupt code in parm64 (note that
2078 machine checks needing further payload are not
2079 supported by this ioctl)
2076 2080
2077Note that the vcpu ioctl is asynchronous to vcpu execution. 2081Note that the vcpu ioctl is asynchronous to vcpu execution.
2078 2082
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index a8e35c43df78..29363d155cd5 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -75,8 +75,10 @@ struct kvm_s390_sie_block {
75 __u8 reserved40[4]; /* 0x0040 */ 75 __u8 reserved40[4]; /* 0x0040 */
76#define LCTL_CR0 0x8000 76#define LCTL_CR0 0x8000
77#define LCTL_CR6 0x0200 77#define LCTL_CR6 0x0200
78#define LCTL_CR14 0x0002
78 __u16 lctl; /* 0x0044 */ 79 __u16 lctl; /* 0x0044 */
79 __s16 icpua; /* 0x0046 */ 80 __s16 icpua; /* 0x0046 */
81#define ICTL_LPSW 0x00400000
80 __u32 ictl; /* 0x0048 */ 82 __u32 ictl; /* 0x0048 */
81 __u32 eca; /* 0x004c */ 83 __u32 eca; /* 0x004c */
82 __u8 icptcode; /* 0x0050 */ 84 __u8 icptcode; /* 0x0050 */
@@ -187,6 +189,11 @@ struct kvm_s390_emerg_info {
187 __u16 code; 189 __u16 code;
188}; 190};
189 191
192struct kvm_s390_mchk_info {
193 __u64 cr14;
194 __u64 mcic;
195};
196
190struct kvm_s390_interrupt_info { 197struct kvm_s390_interrupt_info {
191 struct list_head list; 198 struct list_head list;
192 u64 type; 199 u64 type;
@@ -197,6 +204,7 @@ struct kvm_s390_interrupt_info {
197 struct kvm_s390_emerg_info emerg; 204 struct kvm_s390_emerg_info emerg;
198 struct kvm_s390_extcall_info extcall; 205 struct kvm_s390_extcall_info extcall;
199 struct kvm_s390_prefix_info prefix; 206 struct kvm_s390_prefix_info prefix;
207 struct kvm_s390_mchk_info mchk;
200 }; 208 };
201}; 209};
202 210
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index df6c0ad085aa..950c13ecaf60 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -97,10 +97,12 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
97 97
98static const intercept_handler_t instruction_handlers[256] = { 98static const intercept_handler_t instruction_handlers[256] = {
99 [0x01] = kvm_s390_handle_01, 99 [0x01] = kvm_s390_handle_01,
100 [0x82] = kvm_s390_handle_lpsw,
100 [0x83] = kvm_s390_handle_diag, 101 [0x83] = kvm_s390_handle_diag,
101 [0xae] = kvm_s390_handle_sigp, 102 [0xae] = kvm_s390_handle_sigp,
102 [0xb2] = kvm_s390_handle_b2, 103 [0xb2] = kvm_s390_handle_b2,
103 [0xb7] = handle_lctl, 104 [0xb7] = handle_lctl,
105 [0xb9] = kvm_s390_handle_b9,
104 [0xe5] = kvm_s390_handle_e5, 106 [0xe5] = kvm_s390_handle_e5,
105 [0xeb] = handle_lctlg, 107 [0xeb] = handle_lctlg,
106}; 108};
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 52cdf20906ab..b3b4748485ee 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -41,6 +41,11 @@ static int psw_ioint_disabled(struct kvm_vcpu *vcpu)
41 return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO); 41 return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_IO);
42} 42}
43 43
44static int psw_mchk_disabled(struct kvm_vcpu *vcpu)
45{
46 return !(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_MCHECK);
47}
48
44static int psw_interrupts_disabled(struct kvm_vcpu *vcpu) 49static int psw_interrupts_disabled(struct kvm_vcpu *vcpu)
45{ 50{
46 if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) || 51 if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER) ||
@@ -82,6 +87,12 @@ static int __interrupt_is_deliverable(struct kvm_vcpu *vcpu,
82 case KVM_S390_SIGP_SET_PREFIX: 87 case KVM_S390_SIGP_SET_PREFIX:
83 case KVM_S390_RESTART: 88 case KVM_S390_RESTART:
84 return 1; 89 return 1;
90 case KVM_S390_MCHK:
91 if (psw_mchk_disabled(vcpu))
92 return 0;
93 if (vcpu->arch.sie_block->gcr[14] & inti->mchk.cr14)
94 return 1;
95 return 0;
85 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 96 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
86 if (psw_ioint_disabled(vcpu)) 97 if (psw_ioint_disabled(vcpu))
87 return 0; 98 return 0;
@@ -116,6 +127,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
116 CPUSTAT_IO_INT | CPUSTAT_EXT_INT | CPUSTAT_STOP_INT, 127 CPUSTAT_IO_INT | CPUSTAT_EXT_INT | CPUSTAT_STOP_INT,
117 &vcpu->arch.sie_block->cpuflags); 128 &vcpu->arch.sie_block->cpuflags);
118 vcpu->arch.sie_block->lctl = 0x0000; 129 vcpu->arch.sie_block->lctl = 0x0000;
130 vcpu->arch.sie_block->ictl &= ~ICTL_LPSW;
119} 131}
120 132
121static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag) 133static void __set_cpuflag(struct kvm_vcpu *vcpu, u32 flag)
@@ -139,6 +151,12 @@ static void __set_intercept_indicator(struct kvm_vcpu *vcpu,
139 case KVM_S390_SIGP_STOP: 151 case KVM_S390_SIGP_STOP:
140 __set_cpuflag(vcpu, CPUSTAT_STOP_INT); 152 __set_cpuflag(vcpu, CPUSTAT_STOP_INT);
141 break; 153 break;
154 case KVM_S390_MCHK:
155 if (psw_mchk_disabled(vcpu))
156 vcpu->arch.sie_block->ictl |= ICTL_LPSW;
157 else
158 vcpu->arch.sie_block->lctl |= LCTL_CR14;
159 break;
142 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 160 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
143 if (psw_ioint_disabled(vcpu)) 161 if (psw_ioint_disabled(vcpu))
144 __set_cpuflag(vcpu, CPUSTAT_IO_INT); 162 __set_cpuflag(vcpu, CPUSTAT_IO_INT);
@@ -326,6 +344,32 @@ static void __do_deliver_interrupt(struct kvm_vcpu *vcpu,
326 exception = 1; 344 exception = 1;
327 break; 345 break;
328 346
347 case KVM_S390_MCHK:
348 VCPU_EVENT(vcpu, 4, "interrupt: machine check mcic=%llx",
349 inti->mchk.mcic);
350 trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, inti->type,
351 inti->mchk.cr14,
352 inti->mchk.mcic);
353 rc = kvm_s390_vcpu_store_status(vcpu,
354 KVM_S390_STORE_STATUS_PREFIXED);
355 if (rc == -EFAULT)
356 exception = 1;
357
358 rc = put_guest_u64(vcpu, __LC_MCCK_CODE, inti->mchk.mcic);
359 if (rc == -EFAULT)
360 exception = 1;
361
362 rc = copy_to_guest(vcpu, __LC_MCK_OLD_PSW,
363 &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
364 if (rc == -EFAULT)
365 exception = 1;
366
367 rc = copy_from_guest(vcpu, &vcpu->arch.sie_block->gpsw,
368 __LC_MCK_NEW_PSW, sizeof(psw_t));
369 if (rc == -EFAULT)
370 exception = 1;
371 break;
372
329 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 373 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
330 { 374 {
331 __u32 param0 = ((__u32)inti->io.subchannel_id << 16) | 375 __u32 param0 = ((__u32)inti->io.subchannel_id << 16) |
@@ -588,6 +632,61 @@ void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
588 } 632 }
589} 633}
590 634
635void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu)
636{
637 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
638 struct kvm_s390_float_interrupt *fi = vcpu->arch.local_int.float_int;
639 struct kvm_s390_interrupt_info *n, *inti = NULL;
640 int deliver;
641
642 __reset_intercept_indicators(vcpu);
643 if (atomic_read(&li->active)) {
644 do {
645 deliver = 0;
646 spin_lock_bh(&li->lock);
647 list_for_each_entry_safe(inti, n, &li->list, list) {
648 if ((inti->type == KVM_S390_MCHK) &&
649 __interrupt_is_deliverable(vcpu, inti)) {
650 list_del(&inti->list);
651 deliver = 1;
652 break;
653 }
654 __set_intercept_indicator(vcpu, inti);
655 }
656 if (list_empty(&li->list))
657 atomic_set(&li->active, 0);
658 spin_unlock_bh(&li->lock);
659 if (deliver) {
660 __do_deliver_interrupt(vcpu, inti);
661 kfree(inti);
662 }
663 } while (deliver);
664 }
665
666 if (atomic_read(&fi->active)) {
667 do {
668 deliver = 0;
669 spin_lock(&fi->lock);
670 list_for_each_entry_safe(inti, n, &fi->list, list) {
671 if ((inti->type == KVM_S390_MCHK) &&
672 __interrupt_is_deliverable(vcpu, inti)) {
673 list_del(&inti->list);
674 deliver = 1;
675 break;
676 }
677 __set_intercept_indicator(vcpu, inti);
678 }
679 if (list_empty(&fi->list))
680 atomic_set(&fi->active, 0);
681 spin_unlock(&fi->lock);
682 if (deliver) {
683 __do_deliver_interrupt(vcpu, inti);
684 kfree(inti);
685 }
686 } while (deliver);
687 }
688}
689
591int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code) 690int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code)
592{ 691{
593 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; 692 struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
@@ -641,6 +740,13 @@ int kvm_s390_inject_vm(struct kvm *kvm,
641 case KVM_S390_INT_EMERGENCY: 740 case KVM_S390_INT_EMERGENCY:
642 kfree(inti); 741 kfree(inti);
643 return -EINVAL; 742 return -EINVAL;
743 case KVM_S390_MCHK:
744 VM_EVENT(kvm, 5, "inject: machine check parm64:%llx",
745 s390int->parm64);
746 inti->type = s390int->type;
747 inti->mchk.cr14 = s390int->parm; /* upper bits are not used */
748 inti->mchk.mcic = s390int->parm64;
749 break;
644 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 750 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
645 if (s390int->type & IOINT_AI_MASK) 751 if (s390int->type & IOINT_AI_MASK)
646 VM_EVENT(kvm, 5, "%s", "inject: I/O (AI)"); 752 VM_EVENT(kvm, 5, "%s", "inject: I/O (AI)");
@@ -749,6 +855,12 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
749 inti->type = s390int->type; 855 inti->type = s390int->type;
750 inti->emerg.code = s390int->parm; 856 inti->emerg.code = s390int->parm;
751 break; 857 break;
858 case KVM_S390_MCHK:
859 VCPU_EVENT(vcpu, 5, "inject: machine check parm64:%llx",
860 s390int->parm64);
861 inti->type = s390int->type;
862 inti->mchk.mcic = s390int->parm64;
863 break;
752 case KVM_S390_INT_VIRTIO: 864 case KVM_S390_INT_VIRTIO:
753 case KVM_S390_INT_SERVICE: 865 case KVM_S390_INT_SERVICE:
754 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX: 866 case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index dccc0242b7ca..1f7cc6ccf102 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -106,6 +106,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu);
106enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer); 106enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer);
107void kvm_s390_tasklet(unsigned long parm); 107void kvm_s390_tasklet(unsigned long parm);
108void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); 108void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu);
109void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu);
109int kvm_s390_inject_vm(struct kvm *kvm, 110int kvm_s390_inject_vm(struct kvm *kvm,
110 struct kvm_s390_interrupt *s390int); 111 struct kvm_s390_interrupt *s390int);
111int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, 112int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
@@ -117,6 +118,8 @@ int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
117int kvm_s390_handle_b2(struct kvm_vcpu *vcpu); 118int kvm_s390_handle_b2(struct kvm_vcpu *vcpu);
118int kvm_s390_handle_e5(struct kvm_vcpu *vcpu); 119int kvm_s390_handle_e5(struct kvm_vcpu *vcpu);
119int kvm_s390_handle_01(struct kvm_vcpu *vcpu); 120int kvm_s390_handle_01(struct kvm_vcpu *vcpu);
121int kvm_s390_handle_b9(struct kvm_vcpu *vcpu);
122int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu);
120 123
121/* implemented in sigp.c */ 124/* implemented in sigp.c */
122int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); 125int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu);
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index d715842f56ca..d3cbcd3c9ada 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -18,6 +18,8 @@
18#include <asm/debug.h> 18#include <asm/debug.h>
19#include <asm/ebcdic.h> 19#include <asm/ebcdic.h>
20#include <asm/sysinfo.h> 20#include <asm/sysinfo.h>
21#include <asm/ptrace.h>
22#include <asm/compat.h>
21#include "gaccess.h" 23#include "gaccess.h"
22#include "kvm-s390.h" 24#include "kvm-s390.h"
23#include "trace.h" 25#include "trace.h"
@@ -166,6 +168,99 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
166 return 0; 168 return 0;
167} 169}
168 170
171static void handle_new_psw(struct kvm_vcpu *vcpu)
172{
173 /* Check whether the new psw is enabled for machine checks. */
174 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_MCHECK)
175 kvm_s390_deliver_pending_machine_checks(vcpu);
176}
177
178#define PSW_MASK_ADDR_MODE (PSW_MASK_EA | PSW_MASK_BA)
179#define PSW_MASK_UNASSIGNED 0xb80800fe7fffffffUL
180#define PSW_ADDR_24 0x00000000000fffffUL
181#define PSW_ADDR_31 0x000000007fffffffUL
182
183int kvm_s390_handle_lpsw(struct kvm_vcpu *vcpu)
184{
185 u64 addr;
186 psw_compat_t new_psw;
187
188 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
189 return kvm_s390_inject_program_int(vcpu,
190 PGM_PRIVILEGED_OPERATION);
191
192 addr = kvm_s390_get_base_disp_s(vcpu);
193
194 if (addr & 7) {
195 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
196 goto out;
197 }
198
199 if (copy_from_guest(vcpu, &new_psw, addr, sizeof(new_psw))) {
200 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
201 goto out;
202 }
203
204 if (!(new_psw.mask & PSW32_MASK_BASE)) {
205 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
206 goto out;
207 }
208
209 vcpu->arch.sie_block->gpsw.mask =
210 (new_psw.mask & ~PSW32_MASK_BASE) << 32;
211 vcpu->arch.sie_block->gpsw.addr = new_psw.addr;
212
213 if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_UNASSIGNED) ||
214 (!(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_ADDR_MODE) &&
215 (vcpu->arch.sie_block->gpsw.addr & ~PSW_ADDR_24)) ||
216 ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_ADDR_MODE) ==
217 PSW_MASK_EA)) {
218 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
219 goto out;
220 }
221
222 handle_new_psw(vcpu);
223out:
224 return 0;
225}
226
227static int handle_lpswe(struct kvm_vcpu *vcpu)
228{
229 u64 addr;
230 psw_t new_psw;
231
232 addr = kvm_s390_get_base_disp_s(vcpu);
233
234 if (addr & 7) {
235 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
236 goto out;
237 }
238
239 if (copy_from_guest(vcpu, &new_psw, addr, sizeof(new_psw))) {
240 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
241 goto out;
242 }
243
244 vcpu->arch.sie_block->gpsw.mask = new_psw.mask;
245 vcpu->arch.sie_block->gpsw.addr = new_psw.addr;
246
247 if ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_UNASSIGNED) ||
248 (((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_ADDR_MODE) ==
249 PSW_MASK_BA) &&
250 (vcpu->arch.sie_block->gpsw.addr & ~PSW_ADDR_31)) ||
251 (!(vcpu->arch.sie_block->gpsw.mask & PSW_MASK_ADDR_MODE) &&
252 (vcpu->arch.sie_block->gpsw.addr & ~PSW_ADDR_24)) ||
253 ((vcpu->arch.sie_block->gpsw.mask & PSW_MASK_ADDR_MODE) ==
254 PSW_MASK_EA)) {
255 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
256 goto out;
257 }
258
259 handle_new_psw(vcpu);
260out:
261 return 0;
262}
263
169static int handle_stidp(struct kvm_vcpu *vcpu) 264static int handle_stidp(struct kvm_vcpu *vcpu)
170{ 265{
171 u64 operand2; 266 u64 operand2;
@@ -292,6 +387,7 @@ static const intercept_handler_t priv_handlers[256] = {
292 [0x5f] = handle_chsc, 387 [0x5f] = handle_chsc,
293 [0x7d] = handle_stsi, 388 [0x7d] = handle_stsi,
294 [0xb1] = handle_stfl, 389 [0xb1] = handle_stfl,
390 [0xb2] = handle_lpswe,
295}; 391};
296 392
297int kvm_s390_handle_b2(struct kvm_vcpu *vcpu) 393int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
@@ -316,6 +412,45 @@ int kvm_s390_handle_b2(struct kvm_vcpu *vcpu)
316 return -EOPNOTSUPP; 412 return -EOPNOTSUPP;
317} 413}
318 414
415static int handle_epsw(struct kvm_vcpu *vcpu)
416{
417 int reg1, reg2;
418
419 reg1 = (vcpu->arch.sie_block->ipb & 0x00f00000) >> 24;
420 reg2 = (vcpu->arch.sie_block->ipb & 0x000f0000) >> 16;
421
422 /* This basically extracts the mask half of the psw. */
423 vcpu->run->s.regs.gprs[reg1] &= 0xffffffff00000000;
424 vcpu->run->s.regs.gprs[reg1] |= vcpu->arch.sie_block->gpsw.mask >> 32;
425 if (reg2) {
426 vcpu->run->s.regs.gprs[reg2] &= 0xffffffff00000000;
427 vcpu->run->s.regs.gprs[reg2] |=
428 vcpu->arch.sie_block->gpsw.mask & 0x00000000ffffffff;
429 }
430 return 0;
431}
432
433static const intercept_handler_t b9_handlers[256] = {
434 [0x8d] = handle_epsw,
435};
436
437int kvm_s390_handle_b9(struct kvm_vcpu *vcpu)
438{
439 intercept_handler_t handler;
440
441 /* This is handled just as for the B2 instructions. */
442 handler = b9_handlers[vcpu->arch.sie_block->ipa & 0x00ff];
443 if (handler) {
444 if ((handler != handle_epsw) &&
445 (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE))
446 return kvm_s390_inject_program_int(vcpu,
447 PGM_PRIVILEGED_OPERATION);
448 else
449 return handler(vcpu);
450 }
451 return -EOPNOTSUPP;
452}
453
319static int handle_tprot(struct kvm_vcpu *vcpu) 454static int handle_tprot(struct kvm_vcpu *vcpu)
320{ 455{
321 u64 address1, address2; 456 u64 address1, address2;
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h
index 90fdf85b5ff7..95fbc1ab88dc 100644
--- a/arch/s390/kvm/trace-s390.h
+++ b/arch/s390/kvm/trace-s390.h
@@ -141,13 +141,13 @@ TRACE_EVENT(kvm_s390_inject_vcpu,
141 * Trace point for the actual delivery of interrupts. 141 * Trace point for the actual delivery of interrupts.
142 */ 142 */
143TRACE_EVENT(kvm_s390_deliver_interrupt, 143TRACE_EVENT(kvm_s390_deliver_interrupt,
144 TP_PROTO(unsigned int id, __u64 type, __u32 data0, __u64 data1), 144 TP_PROTO(unsigned int id, __u64 type, __u64 data0, __u64 data1),
145 TP_ARGS(id, type, data0, data1), 145 TP_ARGS(id, type, data0, data1),
146 146
147 TP_STRUCT__entry( 147 TP_STRUCT__entry(
148 __field(int, id) 148 __field(int, id)
149 __field(__u32, inttype) 149 __field(__u32, inttype)
150 __field(__u32, data0) 150 __field(__u64, data0)
151 __field(__u64, data1) 151 __field(__u64, data1)
152 ), 152 ),
153 153
@@ -159,7 +159,7 @@ TRACE_EVENT(kvm_s390_deliver_interrupt,
159 ), 159 ),
160 160
161 TP_printk("deliver interrupt (vcpu %d): type:%x (%s) " \ 161 TP_printk("deliver interrupt (vcpu %d): type:%x (%s) " \
162 "data:%08x %016llx", 162 "data:%08llx %016llx",
163 __entry->id, __entry->inttype, 163 __entry->id, __entry->inttype,
164 __print_symbolic(__entry->inttype, kvm_s390_int_type), 164 __print_symbolic(__entry->inttype, kvm_s390_int_type),
165 __entry->data0, __entry->data1) 165 __entry->data0, __entry->data1)
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 54540bdd3340..80bb3b801116 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -397,6 +397,7 @@ struct kvm_s390_psw {
397#define KVM_S390_PROGRAM_INT 0xfffe0001u 397#define KVM_S390_PROGRAM_INT 0xfffe0001u
398#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u 398#define KVM_S390_SIGP_SET_PREFIX 0xfffe0002u
399#define KVM_S390_RESTART 0xfffe0003u 399#define KVM_S390_RESTART 0xfffe0003u
400#define KVM_S390_MCHK 0xfffe1000u
400#define KVM_S390_INT_VIRTIO 0xffff2603u 401#define KVM_S390_INT_VIRTIO 0xffff2603u
401#define KVM_S390_INT_SERVICE 0xffff2401u 402#define KVM_S390_INT_SERVICE 0xffff2401u
402#define KVM_S390_INT_EMERGENCY 0xffff1201u 403#define KVM_S390_INT_EMERGENCY 0xffff1201u