16 #include <linux/errno.h>
17 #include <asm/current.h>
18 #include <asm/debug.h>
20 #include <asm/sysinfo.h>
25 static int handle_set_prefix(
struct kvm_vcpu *vcpu)
27 int base2 = vcpu->
arch.sie_block->ipb >> 28;
28 int disp2 = ((vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16);
33 vcpu->
stat.instruction_spx++;
37 operand2 += vcpu->
run->s.regs.gprs[
base2];
46 if (get_guest_u32(vcpu, operand2, &address)) {
51 address = address & 0x7fffe000
u;
54 if (copy_from_guest_absolute(vcpu, &tmp, address, 1) ||
55 (copy_from_guest_absolute(vcpu, &tmp, address +
PAGE_SIZE, 1))) {
60 kvm_s390_set_prefix(vcpu, address);
62 VCPU_EVENT(vcpu, 5,
"setting prefix to %x", address);
63 trace_kvm_s390_handle_prefix(vcpu, 1, address);
68 static int handle_store_prefix(
struct kvm_vcpu *vcpu)
70 int base2 = vcpu->
arch.sie_block->ipb >> 28;
71 int disp2 = ((vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16);
75 vcpu->
stat.instruction_stpx++;
78 operand2 += vcpu->
run->s.regs.gprs[
base2];
86 address = vcpu->
arch.sie_block->prefix;
87 address = address & 0x7fffe000
u;
90 if (put_guest_u32(vcpu, operand2, address)) {
95 VCPU_EVENT(vcpu, 5,
"storing prefix to %x", address);
96 trace_kvm_s390_handle_prefix(vcpu, 0, address);
101 static int handle_store_cpu_address(
struct kvm_vcpu *vcpu)
103 int base2 = vcpu->
arch.sie_block->ipb >> 28;
104 int disp2 = ((vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16);
108 vcpu->
stat.instruction_stap++;
111 useraddr += vcpu->
run->s.regs.gprs[
base2];
118 rc = put_guest_u16(vcpu, useraddr, vcpu->
vcpu_id);
124 VCPU_EVENT(vcpu, 5,
"storing cpu address to %llx", useraddr);
125 trace_kvm_s390_handle_stap(vcpu, useraddr);
130 static int handle_skey(
struct kvm_vcpu *vcpu)
132 vcpu->
stat.instruction_storage_key++;
133 vcpu->
arch.sie_block->gpsw.addr -= 4;
134 VCPU_EVENT(vcpu, 4,
"%s",
"retrying storage key operation");
138 static int handle_stsch(
struct kvm_vcpu *vcpu)
140 vcpu->
stat.instruction_stsch++;
141 VCPU_EVENT(vcpu, 4,
"%s",
"store subchannel - CC3");
143 vcpu->
arch.sie_block->gpsw.mask &= ~(3ul << 44);
144 vcpu->
arch.sie_block->gpsw.mask |= (3 & 3ul) << 44;
148 static int handle_chsc(
struct kvm_vcpu *vcpu)
150 vcpu->
stat.instruction_chsc++;
151 VCPU_EVENT(vcpu, 4,
"%s",
"channel subsystem call - CC3");
153 vcpu->
arch.sie_block->gpsw.mask &= ~(3ul << 44);
154 vcpu->
arch.sie_block->gpsw.mask |= (3 & 3ul) << 44;
158 static int handle_stfl(
struct kvm_vcpu *vcpu)
160 unsigned int facility_list;
163 vcpu->
stat.instruction_stfl++;
165 facility_list =
S390_lowcore.stfl_fac_list & 0xff00fff3;
168 &facility_list,
sizeof(facility_list));
172 VCPU_EVENT(vcpu, 5,
"store facility list value %x",
174 trace_kvm_s390_handle_stfl(vcpu, facility_list);
179 static int handle_stidp(
struct kvm_vcpu *vcpu)
181 int base2 = vcpu->
arch.sie_block->ipb >> 28;
182 int disp2 = ((vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16);
186 vcpu->
stat.instruction_stidp++;
189 operand2 += vcpu->
run->s.regs.gprs[
base2];
196 rc = put_guest_u64(vcpu, operand2, vcpu->
arch.stidp_data);
213 spin_lock(&fi->
lock);
217 spin_unlock(&fi->
lock);
220 if (
stsi(mem, 3, 2, 2))
224 for (n = mem->
count - 1; n > 0 ; n--)
225 memcpy(&mem->
vm[n], &mem->
vm[n - 1],
sizeof(mem->
vm[0]));
227 mem->
vm[0].cpus_total =
cpus;
228 mem->
vm[0].cpus_configured =
cpus;
229 mem->
vm[0].cpus_standby = 0;
230 mem->
vm[0].cpus_reserved = 0;
231 mem->
vm[0].caf = 1000;
232 memcpy(mem->
vm[0].name,
"KVMguest", 8);
234 memcpy(mem->
vm[0].cpi,
"KVM/Linux ", 16);
238 static int handle_stsi(
struct kvm_vcpu *vcpu)
240 int fc = (vcpu->
run->s.regs.gprs[0] & 0xf0000000) >> 28;
241 int sel1 = vcpu->
run->s.regs.gprs[0] & 0xff;
242 int sel2 = vcpu->
run->s.regs.gprs[1] & 0xffff;
243 int base2 = vcpu->
arch.sie_block->ipb >> 28;
244 int disp2 = ((vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16);
248 vcpu->
stat.instruction_stsi++;
249 VCPU_EVENT(vcpu, 4,
"stsi: fc: %x sel1: %x sel2: %x", fc, sel1, sel2);
253 operand2 += vcpu->
run->s.regs.gprs[
base2];
255 if (operand2 & 0xfff && fc > 0)
260 vcpu->
run->s.regs.gprs[0] = 3 << 28;
261 vcpu->
arch.sie_block->gpsw.mask &= ~(3ul << 44);
268 if (
stsi((
void *) mem, fc, sel1, sel2))
272 if (sel1 != 2 || sel2 != 2)
277 handle_stsi_3_2_2(vcpu, (
void *) mem);
283 if (copy_to_guest_absolute(vcpu, operand2, (
void *) mem,
PAGE_SIZE)) {
287 trace_kvm_s390_handle_stsi(vcpu, fc, sel1, sel2, operand2);
289 vcpu->
arch.sie_block->gpsw.mask &= ~(3ul << 44);
290 vcpu->
run->s.regs.gprs[0] = 0;
296 vcpu->
arch.sie_block->gpsw.mask |= 3ul << 44;
301 [0x02] = handle_stidp,
302 [0x10] = handle_set_prefix,
303 [0x11] = handle_store_prefix,
304 [0x12] = handle_store_cpu_address,
305 [0x29] = handle_skey,
306 [0x2a] = handle_skey,
307 [0x2b] = handle_skey,
308 [0x34] = handle_stsch,
309 [0x5f] = handle_chsc,
310 [0x7d] = handle_stsi,
311 [0xb1] = handle_stfl,
325 handler = priv_handlers[vcpu->
arch.sie_block->ipa & 0x00ff];
331 return handler(vcpu);
336 static int handle_tprot(
struct kvm_vcpu *vcpu)
338 int base1 = (vcpu->
arch.sie_block->ipb & 0xf0000000) >> 28;
339 int disp1 = (vcpu->
arch.sie_block->ipb & 0x0fff0000) >> 16;
340 int base2 = (vcpu->
arch.sie_block->ipb & 0xf000) >> 12;
341 int disp2 = vcpu->
arch.sie_block->ipb & 0x0fff;
342 u64 address1 = disp1 + base1 ? vcpu->
run->s.regs.gprs[
base1] : 0;
343 u64 address2 = disp2 + base2 ? vcpu->
run->s.regs.gprs[
base2] : 0;
345 unsigned long user_address;
347 vcpu->
stat.instruction_tprot++;
363 user_address = (
unsigned long) __guestaddr_to_user(vcpu, address1);
372 vcpu->
arch.sie_block->gpsw.mask &= ~(3ul << 44);
374 vcpu->
arch.sie_block->gpsw.mask |= (1ul << 44);
376 vcpu->
arch.sie_block->gpsw.mask |= (2ul << 44);
385 if ((vcpu->
arch.sie_block->ipa & 0x00ff) == 0x01)
386 return handle_tprot(vcpu);
390 static int handle_sckpf(
struct kvm_vcpu *vcpu)
398 if (vcpu->
run->s.regs.gprs[0] & 0x00000000ffff0000)
402 value = vcpu->
run->s.regs.gprs[0] & 0x000000000000ffff;
409 [0x07] = handle_sckpf,
416 handler = x01_handlers[vcpu->
arch.sie_block->ipa & 0x00ff];
418 return handler(vcpu);