aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/intercept.c12
-rw-r--r--arch/s390/kvm/kvm-s390.c3
-rw-r--r--arch/s390/kvm/kvm-s390.h12
-rw-r--r--arch/s390/kvm/priv.c83
4 files changed, 37 insertions, 73 deletions
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index c6ba4dfd7f1e..b7d1b2edeeb3 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -45,10 +45,8 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
45 do { 45 do {
46 rc = get_guest(vcpu, vcpu->arch.sie_block->gcr[reg], 46 rc = get_guest(vcpu, vcpu->arch.sie_block->gcr[reg],
47 (u64 __user *) useraddr); 47 (u64 __user *) useraddr);
48 if (rc) { 48 if (rc)
49 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 49 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
50 break;
51 }
52 useraddr += 8; 50 useraddr += 8;
53 if (reg == reg3) 51 if (reg == reg3)
54 break; 52 break;
@@ -79,10 +77,8 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
79 reg = reg1; 77 reg = reg1;
80 do { 78 do {
81 rc = get_guest(vcpu, val, (u32 __user *) useraddr); 79 rc = get_guest(vcpu, val, (u32 __user *) useraddr);
82 if (rc) { 80 if (rc)
83 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 81 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
84 break;
85 }
86 vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul; 82 vcpu->arch.sie_block->gcr[reg] &= 0xffffffff00000000ul;
87 vcpu->arch.sie_block->gcr[reg] |= val; 83 vcpu->arch.sie_block->gcr[reg] |= val;
88 useraddr += 4; 84 useraddr += 4;
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index f241e3315ebb..d05a59c1eea7 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -633,8 +633,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
633 } else { 633 } else {
634 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); 634 VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
635 trace_kvm_s390_sie_fault(vcpu); 635 trace_kvm_s390_sie_fault(vcpu);
636 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 636 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
637 rc = 0;
638 } 637 }
639 } 638 }
640 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", 639 VCPU_EVENT(vcpu, 6, "exit sie icptcode %d",
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index 4d89d64a8161..efc14f687265 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -110,12 +110,12 @@ enum hrtimer_restart kvm_s390_idle_wakeup(struct hrtimer *timer);
110void kvm_s390_tasklet(unsigned long parm); 110void kvm_s390_tasklet(unsigned long parm);
111void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu); 111void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu);
112void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu); 112void kvm_s390_deliver_pending_machine_checks(struct kvm_vcpu *vcpu);
113int kvm_s390_inject_vm(struct kvm *kvm, 113int __must_check kvm_s390_inject_vm(struct kvm *kvm,
114 struct kvm_s390_interrupt *s390int); 114 struct kvm_s390_interrupt *s390int);
115int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, 115int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
116 struct kvm_s390_interrupt *s390int); 116 struct kvm_s390_interrupt *s390int);
117int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); 117int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
118int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action); 118int __must_check kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
119struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, 119struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm,
120 u64 cr6, u64 schid); 120 u64 cr6, u64 schid);
121 121
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 05d186c21eca..23a8370b1045 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -36,31 +36,24 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
36 operand2 = kvm_s390_get_base_disp_s(vcpu); 36 operand2 = kvm_s390_get_base_disp_s(vcpu);
37 37
38 /* must be word boundary */ 38 /* must be word boundary */
39 if (operand2 & 3) { 39 if (operand2 & 3)
40 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 40 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
41 goto out;
42 }
43 41
44 /* get the value */ 42 /* get the value */
45 if (get_guest(vcpu, address, (u32 __user *) operand2)) { 43 if (get_guest(vcpu, address, (u32 __user *) operand2))
46 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 44 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
47 goto out;
48 }
49 45
50 address = address & 0x7fffe000u; 46 address = address & 0x7fffe000u;
51 47
52 /* make sure that the new value is valid memory */ 48 /* make sure that the new value is valid memory */
53 if (copy_from_guest_absolute(vcpu, &tmp, address, 1) || 49 if (copy_from_guest_absolute(vcpu, &tmp, address, 1) ||
54 (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1))) { 50 (copy_from_guest_absolute(vcpu, &tmp, address + PAGE_SIZE, 1)))
55 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 51 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
56 goto out;
57 }
58 52
59 kvm_s390_set_prefix(vcpu, address); 53 kvm_s390_set_prefix(vcpu, address);
60 54
61 VCPU_EVENT(vcpu, 5, "setting prefix to %x", address); 55 VCPU_EVENT(vcpu, 5, "setting prefix to %x", address);
62 trace_kvm_s390_handle_prefix(vcpu, 1, address); 56 trace_kvm_s390_handle_prefix(vcpu, 1, address);
63out:
64 return 0; 57 return 0;
65} 58}
66 59
@@ -74,49 +67,37 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu)
74 operand2 = kvm_s390_get_base_disp_s(vcpu); 67 operand2 = kvm_s390_get_base_disp_s(vcpu);
75 68
76 /* must be word boundary */ 69 /* must be word boundary */
77 if (operand2 & 3) { 70 if (operand2 & 3)
78 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 71 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
79 goto out;
80 }
81 72
82 address = vcpu->arch.sie_block->prefix; 73 address = vcpu->arch.sie_block->prefix;
83 address = address & 0x7fffe000u; 74 address = address & 0x7fffe000u;
84 75
85 /* get the value */ 76 /* get the value */
86 if (put_guest(vcpu, address, (u32 __user *)operand2)) { 77 if (put_guest(vcpu, address, (u32 __user *)operand2))
87 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 78 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
88 goto out;
89 }
90 79
91 VCPU_EVENT(vcpu, 5, "storing prefix to %x", address); 80 VCPU_EVENT(vcpu, 5, "storing prefix to %x", address);
92 trace_kvm_s390_handle_prefix(vcpu, 0, address); 81 trace_kvm_s390_handle_prefix(vcpu, 0, address);
93out:
94 return 0; 82 return 0;
95} 83}
96 84
97static int handle_store_cpu_address(struct kvm_vcpu *vcpu) 85static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
98{ 86{
99 u64 useraddr; 87 u64 useraddr;
100 int rc;
101 88
102 vcpu->stat.instruction_stap++; 89 vcpu->stat.instruction_stap++;
103 90
104 useraddr = kvm_s390_get_base_disp_s(vcpu); 91 useraddr = kvm_s390_get_base_disp_s(vcpu);
105 92
106 if (useraddr & 1) { 93 if (useraddr & 1)
107 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 94 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
108 goto out;
109 }
110 95
111 rc = put_guest(vcpu, vcpu->vcpu_id, (u16 __user *)useraddr); 96 if (put_guest(vcpu, vcpu->vcpu_id, (u16 __user *)useraddr))
112 if (rc) { 97 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
113 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
114 goto out;
115 }
116 98
117 VCPU_EVENT(vcpu, 5, "storing cpu address to %llx", useraddr); 99 VCPU_EVENT(vcpu, 5, "storing cpu address to %llx", useraddr);
118 trace_kvm_s390_handle_stap(vcpu, useraddr); 100 trace_kvm_s390_handle_stap(vcpu, useraddr);
119out:
120 return 0; 101 return 0;
121} 102}
122 103
@@ -135,10 +116,8 @@ static int handle_tpi(struct kvm_vcpu *vcpu)
135 int cc; 116 int cc;
136 117
137 addr = kvm_s390_get_base_disp_s(vcpu); 118 addr = kvm_s390_get_base_disp_s(vcpu);
138 if (addr & 3) { 119 if (addr & 3)
139 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 120 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
140 goto out;
141 }
142 cc = 0; 121 cc = 0;
143 inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->run->s.regs.crs[6], 0); 122 inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->run->s.regs.crs[6], 0);
144 if (!inti) 123 if (!inti)
@@ -167,7 +146,6 @@ no_interrupt:
167 /* Set condition code and we're done. */ 146 /* Set condition code and we're done. */
168 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 147 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
169 vcpu->arch.sie_block->gpsw.mask |= (cc & 3ul) << 44; 148 vcpu->arch.sie_block->gpsw.mask |= (cc & 3ul) << 44;
170out:
171 return 0; 149 return 0;
172} 150}
173 151
@@ -237,12 +215,9 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
237 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), 215 rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
238 &facility_list, sizeof(facility_list)); 216 &facility_list, sizeof(facility_list));
239 if (rc) 217 if (rc)
240 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 218 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
241 else { 219 VCPU_EVENT(vcpu, 5, "store facility list value %x", facility_list);
242 VCPU_EVENT(vcpu, 5, "store facility list value %x", 220 trace_kvm_s390_handle_stfl(vcpu, facility_list);
243 facility_list);
244 trace_kvm_s390_handle_stfl(vcpu, facility_list);
245 }
246 return 0; 221 return 0;
247} 222}
248 223
@@ -317,25 +292,18 @@ static int handle_lpswe(struct kvm_vcpu *vcpu)
317static int handle_stidp(struct kvm_vcpu *vcpu) 292static int handle_stidp(struct kvm_vcpu *vcpu)
318{ 293{
319 u64 operand2; 294 u64 operand2;
320 int rc;
321 295
322 vcpu->stat.instruction_stidp++; 296 vcpu->stat.instruction_stidp++;
323 297
324 operand2 = kvm_s390_get_base_disp_s(vcpu); 298 operand2 = kvm_s390_get_base_disp_s(vcpu);
325 299
326 if (operand2 & 7) { 300 if (operand2 & 7)
327 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 301 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
328 goto out;
329 }
330 302
331 rc = put_guest(vcpu, vcpu->arch.stidp_data, (u64 __user *)operand2); 303 if (put_guest(vcpu, vcpu->arch.stidp_data, (u64 __user *)operand2))
332 if (rc) { 304 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
333 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
334 goto out;
335 }
336 305
337 VCPU_EVENT(vcpu, 5, "%s", "store cpu id"); 306 VCPU_EVENT(vcpu, 5, "%s", "store cpu id");
338out:
339 return 0; 307 return 0;
340} 308}
341 309
@@ -377,6 +345,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
377 int sel2 = vcpu->run->s.regs.gprs[1] & 0xffff; 345 int sel2 = vcpu->run->s.regs.gprs[1] & 0xffff;
378 u64 operand2; 346 u64 operand2;
379 unsigned long mem; 347 unsigned long mem;
348 int rc = 0;
380 349
381 vcpu->stat.instruction_stsi++; 350 vcpu->stat.instruction_stsi++;
382 VCPU_EVENT(vcpu, 4, "stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2); 351 VCPU_EVENT(vcpu, 4, "stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2);
@@ -412,7 +381,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
412 } 381 }
413 382
414 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) { 383 if (copy_to_guest_absolute(vcpu, operand2, (void *) mem, PAGE_SIZE)) {
415 kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 384 rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
416 goto out_mem; 385 goto out_mem;
417 } 386 }
418 trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2); 387 trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2);
@@ -425,7 +394,7 @@ out_mem:
425out_fail: 394out_fail:
426 /* condition code 3 */ 395 /* condition code 3 */
427 vcpu->arch.sie_block->gpsw.mask |= 3ul << 44; 396 vcpu->arch.sie_block->gpsw.mask |= 3ul << 44;
428 return 0; 397 return rc;
429} 398}
430 399
431static const intercept_handler_t b2_handlers[256] = { 400static const intercept_handler_t b2_handlers[256] = {