aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2012-01-11 05:20:32 -0500
committerAvi Kivity <avi@redhat.com>2012-03-05 07:52:22 -0500
commit5a32c1af56b3c74212b1de2a1d1658c303dd3516 (patch)
tree4eb6f52e1bdc4b2427fdea83c88a0c188ad54b4f
parent60b413c9248495ea400e80e08e4d1e28ed7ee05e (diff)
KVM: s390: provide general purpose guest registers via kvm_run
This patch adds the general purpose registers to the kvm_run structure. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r--arch/s390/include/asm/kvm.h2
-rw-r--r--arch/s390/include/asm/kvm_host.h3
-rw-r--r--arch/s390/kvm/diag.c6
-rw-r--r--arch/s390/kvm/intercept.c4
-rw-r--r--arch/s390/kvm/kvm-s390.c14
-rw-r--r--arch/s390/kvm/priv.c24
-rw-r--r--arch/s390/kvm/sigp.c20
7 files changed, 37 insertions, 36 deletions
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 9fc328c26159..420dbb7db8dd 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -42,8 +42,10 @@ struct kvm_guest_debug_arch {
42}; 42};
43 43
44#define KVM_SYNC_PREFIX (1UL << 0) 44#define KVM_SYNC_PREFIX (1UL << 0)
45#define KVM_SYNC_GPRS (1UL << 1)
45/* definition of registers in kvm_run */ 46/* definition of registers in kvm_run */
46struct kvm_sync_regs { 47struct kvm_sync_regs {
47 __u64 prefix; /* prefix register */ 48 __u64 prefix; /* prefix register */
49 __u64 gprs[16]; /* general purpose registers */
48}; 50};
49#endif 51#endif
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h
index e34fb2ba76c1..ed843cad4194 100644
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -228,7 +228,6 @@ struct kvm_s390_float_interrupt {
228 228
229struct kvm_vcpu_arch { 229struct kvm_vcpu_arch {
230 struct kvm_s390_sie_block *sie_block; 230 struct kvm_s390_sie_block *sie_block;
231 unsigned long guest_gprs[16];
232 s390_fp_regs host_fpregs; 231 s390_fp_regs host_fpregs;
233 unsigned int host_acrs[NUM_ACRS]; 232 unsigned int host_acrs[NUM_ACRS];
234 s390_fp_regs guest_fpregs; 233 s390_fp_regs guest_fpregs;
@@ -254,5 +253,5 @@ struct kvm_arch{
254 struct gmap *gmap; 253 struct gmap *gmap;
255}; 254};
256 255
257extern int sie64a(struct kvm_s390_sie_block *, unsigned long *); 256extern int sie64a(struct kvm_s390_sie_block *, u64 *);
258#endif 257#endif
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 8943e82cd4d9..a353f0ea45c2 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -20,8 +20,8 @@ static int diag_release_pages(struct kvm_vcpu *vcpu)
20 unsigned long start, end; 20 unsigned long start, end;
21 unsigned long prefix = vcpu->arch.sie_block->prefix; 21 unsigned long prefix = vcpu->arch.sie_block->prefix;
22 22
23 start = vcpu->arch.guest_gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; 23 start = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
24 end = vcpu->arch.guest_gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096; 24 end = vcpu->run->s.regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
25 25
26 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end 26 if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end
27 || start < 2 * PAGE_SIZE) 27 || start < 2 * PAGE_SIZE)
@@ -56,7 +56,7 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu)
56static int __diag_ipl_functions(struct kvm_vcpu *vcpu) 56static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
57{ 57{
58 unsigned int reg = vcpu->arch.sie_block->ipa & 0xf; 58 unsigned int reg = vcpu->arch.sie_block->ipa & 0xf;
59 unsigned long subcode = vcpu->arch.guest_gprs[reg] & 0xffff; 59 unsigned long subcode = vcpu->run->s.regs.gprs[reg] & 0xffff;
60 60
61 VCPU_EVENT(vcpu, 5, "diag ipl functions, subcode %lx", subcode); 61 VCPU_EVENT(vcpu, 5, "diag ipl functions, subcode %lx", subcode);
62 switch (subcode) { 62 switch (subcode) {
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
index 02434543eabb..776ef83c2771 100644
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -36,7 +36,7 @@ static int handle_lctlg(struct kvm_vcpu *vcpu)
36 36
37 useraddr = disp2; 37 useraddr = disp2;
38 if (base2) 38 if (base2)
39 useraddr += vcpu->arch.guest_gprs[base2]; 39 useraddr += vcpu->run->s.regs.gprs[base2];
40 40
41 if (useraddr & 7) 41 if (useraddr & 7)
42 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 42 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -75,7 +75,7 @@ static int handle_lctl(struct kvm_vcpu *vcpu)
75 75
76 useraddr = disp2; 76 useraddr = disp2;
77 if (base2) 77 if (base2)
78 useraddr += vcpu->arch.guest_gprs[base2]; 78 useraddr += vcpu->run->s.regs.gprs[base2];
79 79
80 if (useraddr & 3) 80 if (useraddr & 3)
81 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 81 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 6962c1b9eec6..80b12bac6a5b 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -289,7 +289,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
289 } 289 }
290 290
291 vcpu->arch.gmap = vcpu->kvm->arch.gmap; 291 vcpu->arch.gmap = vcpu->kvm->arch.gmap;
292 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX; 292 vcpu->run->kvm_valid_regs = KVM_SYNC_PREFIX | KVM_SYNC_GPRS;
293 return 0; 293 return 0;
294} 294}
295 295
@@ -428,13 +428,13 @@ static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
428 428
429int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 429int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
430{ 430{
431 memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs)); 431 memcpy(&vcpu->run->s.regs.gprs, &regs->gprs, sizeof(regs->gprs));
432 return 0; 432 return 0;
433} 433}
434 434
435int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) 435int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
436{ 436{
437 memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs)); 437 memcpy(&regs->gprs, &vcpu->run->s.regs.gprs, sizeof(regs->gprs));
438 return 0; 438 return 0;
439} 439}
440 440
@@ -511,7 +511,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
511{ 511{
512 int rc; 512 int rc;
513 513
514 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16); 514 memcpy(&vcpu->arch.sie_block->gg14, &vcpu->run->s.regs.gprs[14], 16);
515 515
516 if (need_resched()) 516 if (need_resched())
517 schedule(); 517 schedule();
@@ -528,7 +528,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
528 local_irq_enable(); 528 local_irq_enable();
529 VCPU_EVENT(vcpu, 6, "entering sie flags %x", 529 VCPU_EVENT(vcpu, 6, "entering sie flags %x",
530 atomic_read(&vcpu->arch.sie_block->cpuflags)); 530 atomic_read(&vcpu->arch.sie_block->cpuflags));
531 rc = sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs); 531 rc = sie64a(vcpu->arch.sie_block, vcpu->run->s.regs.gprs);
532 if (rc) { 532 if (rc) {
533 if (kvm_is_ucontrol(vcpu->kvm)) { 533 if (kvm_is_ucontrol(vcpu->kvm)) {
534 rc = SIE_INTERCEPT_UCONTROL; 534 rc = SIE_INTERCEPT_UCONTROL;
@@ -544,7 +544,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu)
544 kvm_guest_exit(); 544 kvm_guest_exit();
545 local_irq_enable(); 545 local_irq_enable();
546 546
547 memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16); 547 memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16);
548 return rc; 548 return rc;
549} 549}
550 550
@@ -673,7 +673,7 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)
673 return -EFAULT; 673 return -EFAULT;
674 674
675 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs), 675 if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
676 vcpu->arch.guest_gprs, 128, prefix)) 676 vcpu->run->s.regs.gprs, 128, prefix))
677 return -EFAULT; 677 return -EFAULT;
678 678
679 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw), 679 if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 9c83b8a53843..e5a45dbd26ac 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -33,7 +33,7 @@ static int handle_set_prefix(struct kvm_vcpu *vcpu)
33 33
34 operand2 = disp2; 34 operand2 = disp2;
35 if (base2) 35 if (base2)
36 operand2 += vcpu->arch.guest_gprs[base2]; 36 operand2 += vcpu->run->s.regs.gprs[base2];
37 37
38 /* must be word boundary */ 38 /* must be word boundary */
39 if (operand2 & 3) { 39 if (operand2 & 3) {
@@ -73,7 +73,7 @@ static int handle_store_prefix(struct kvm_vcpu *vcpu)
73 vcpu->stat.instruction_stpx++; 73 vcpu->stat.instruction_stpx++;
74 operand2 = disp2; 74 operand2 = disp2;
75 if (base2) 75 if (base2)
76 operand2 += vcpu->arch.guest_gprs[base2]; 76 operand2 += vcpu->run->s.regs.gprs[base2];
77 77
78 /* must be word boundary */ 78 /* must be word boundary */
79 if (operand2 & 3) { 79 if (operand2 & 3) {
@@ -105,7 +105,7 @@ static int handle_store_cpu_address(struct kvm_vcpu *vcpu)
105 vcpu->stat.instruction_stap++; 105 vcpu->stat.instruction_stap++;
106 useraddr = disp2; 106 useraddr = disp2;
107 if (base2) 107 if (base2)
108 useraddr += vcpu->arch.guest_gprs[base2]; 108 useraddr += vcpu->run->s.regs.gprs[base2];
109 109
110 if (useraddr & 1) { 110 if (useraddr & 1) {
111 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 111 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -180,7 +180,7 @@ static int handle_stidp(struct kvm_vcpu *vcpu)
180 vcpu->stat.instruction_stidp++; 180 vcpu->stat.instruction_stidp++;
181 operand2 = disp2; 181 operand2 = disp2;
182 if (base2) 182 if (base2)
183 operand2 += vcpu->arch.guest_gprs[base2]; 183 operand2 += vcpu->run->s.regs.gprs[base2];
184 184
185 if (operand2 & 7) { 185 if (operand2 & 7) {
186 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 186 kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -231,9 +231,9 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
231 231
232static int handle_stsi(struct kvm_vcpu *vcpu) 232static int handle_stsi(struct kvm_vcpu *vcpu)
233{ 233{
234 int fc = (vcpu->arch.guest_gprs[0] & 0xf0000000) >> 28; 234 int fc = (vcpu->run->s.regs.gprs[0] & 0xf0000000) >> 28;
235 int sel1 = vcpu->arch.guest_gprs[0] & 0xff; 235 int sel1 = vcpu->run->s.regs.gprs[0] & 0xff;
236 int sel2 = vcpu->arch.guest_gprs[1] & 0xffff; 236 int sel2 = vcpu->run->s.regs.gprs[1] & 0xffff;
237 int base2 = vcpu->arch.sie_block->ipb >> 28; 237 int base2 = vcpu->arch.sie_block->ipb >> 28;
238 int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); 238 int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
239 u64 operand2; 239 u64 operand2;
@@ -244,14 +244,14 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
244 244
245 operand2 = disp2; 245 operand2 = disp2;
246 if (base2) 246 if (base2)
247 operand2 += vcpu->arch.guest_gprs[base2]; 247 operand2 += vcpu->run->s.regs.gprs[base2];
248 248
249 if (operand2 & 0xfff && fc > 0) 249 if (operand2 & 0xfff && fc > 0)
250 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); 250 return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
251 251
252 switch (fc) { 252 switch (fc) {
253 case 0: 253 case 0:
254 vcpu->arch.guest_gprs[0] = 3 << 28; 254 vcpu->run->s.regs.gprs[0] = 3 << 28;
255 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 255 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
256 return 0; 256 return 0;
257 case 1: /* same handling for 1 and 2 */ 257 case 1: /* same handling for 1 and 2 */
@@ -280,7 +280,7 @@ static int handle_stsi(struct kvm_vcpu *vcpu)
280 } 280 }
281 free_page(mem); 281 free_page(mem);
282 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 282 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
283 vcpu->arch.guest_gprs[0] = 0; 283 vcpu->run->s.regs.gprs[0] = 0;
284 return 0; 284 return 0;
285out_mem: 285out_mem:
286 free_page(mem); 286 free_page(mem);
@@ -332,8 +332,8 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
332 int disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16; 332 int disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16;
333 int base2 = (vcpu->arch.sie_block->ipb & 0xf000) >> 12; 333 int base2 = (vcpu->arch.sie_block->ipb & 0xf000) >> 12;
334 int disp2 = vcpu->arch.sie_block->ipb & 0x0fff; 334 int disp2 = vcpu->arch.sie_block->ipb & 0x0fff;
335 u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0; 335 u64 address1 = disp1 + base1 ? vcpu->run->s.regs.gprs[base1] : 0;
336 u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0; 336 u64 address2 = disp2 + base2 ? vcpu->run->s.regs.gprs[base2] : 0;
337 struct vm_area_struct *vma; 337 struct vm_area_struct *vma;
338 unsigned long user_address; 338 unsigned long user_address;
339 339
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 0a7941d74bc6..30eb0f73f9d5 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -48,7 +48,7 @@
48 48
49 49
50static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr, 50static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
51 unsigned long *reg) 51 u64 *reg)
52{ 52{
53 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 53 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
54 int rc; 54 int rc;
@@ -220,7 +220,7 @@ static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter)
220} 220}
221 221
222static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address, 222static int __sigp_set_prefix(struct kvm_vcpu *vcpu, u16 cpu_addr, u32 address,
223 unsigned long *reg) 223 u64 *reg)
224{ 224{
225 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 225 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
226 struct kvm_s390_local_interrupt *li = NULL; 226 struct kvm_s390_local_interrupt *li = NULL;
@@ -278,7 +278,7 @@ out_fi:
278} 278}
279 279
280static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, 280static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
281 unsigned long *reg) 281 u64 *reg)
282{ 282{
283 int rc; 283 int rc;
284 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 284 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
@@ -316,7 +316,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
316 int base2 = vcpu->arch.sie_block->ipb >> 28; 316 int base2 = vcpu->arch.sie_block->ipb >> 28;
317 int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16); 317 int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
318 u32 parameter; 318 u32 parameter;
319 u16 cpu_addr = vcpu->arch.guest_gprs[r3]; 319 u16 cpu_addr = vcpu->run->s.regs.gprs[r3];
320 u8 order_code; 320 u8 order_code;
321 int rc; 321 int rc;
322 322
@@ -327,18 +327,18 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
327 327
328 order_code = disp2; 328 order_code = disp2;
329 if (base2) 329 if (base2)
330 order_code += vcpu->arch.guest_gprs[base2]; 330 order_code += vcpu->run->s.regs.gprs[base2];
331 331
332 if (r1 % 2) 332 if (r1 % 2)
333 parameter = vcpu->arch.guest_gprs[r1]; 333 parameter = vcpu->run->s.regs.gprs[r1];
334 else 334 else
335 parameter = vcpu->arch.guest_gprs[r1 + 1]; 335 parameter = vcpu->run->s.regs.gprs[r1 + 1];
336 336
337 switch (order_code) { 337 switch (order_code) {
338 case SIGP_SENSE: 338 case SIGP_SENSE:
339 vcpu->stat.instruction_sigp_sense++; 339 vcpu->stat.instruction_sigp_sense++;
340 rc = __sigp_sense(vcpu, cpu_addr, 340 rc = __sigp_sense(vcpu, cpu_addr,
341 &vcpu->arch.guest_gprs[r1]); 341 &vcpu->run->s.regs.gprs[r1]);
342 break; 342 break;
343 case SIGP_EXTERNAL_CALL: 343 case SIGP_EXTERNAL_CALL:
344 vcpu->stat.instruction_sigp_external_call++; 344 vcpu->stat.instruction_sigp_external_call++;
@@ -363,12 +363,12 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
363 case SIGP_SET_PREFIX: 363 case SIGP_SET_PREFIX:
364 vcpu->stat.instruction_sigp_prefix++; 364 vcpu->stat.instruction_sigp_prefix++;
365 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, 365 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
366 &vcpu->arch.guest_gprs[r1]); 366 &vcpu->run->s.regs.gprs[r1]);
367 break; 367 break;
368 case SIGP_SENSE_RUNNING: 368 case SIGP_SENSE_RUNNING:
369 vcpu->stat.instruction_sigp_sense_running++; 369 vcpu->stat.instruction_sigp_sense_running++;
370 rc = __sigp_sense_running(vcpu, cpu_addr, 370 rc = __sigp_sense_running(vcpu, cpu_addr,
371 &vcpu->arch.guest_gprs[r1]); 371 &vcpu->run->s.regs.gprs[r1]);
372 break; 372 break;
373 case SIGP_RESTART: 373 case SIGP_RESTART:
374 vcpu->stat.instruction_sigp_restart++; 374 vcpu->stat.instruction_sigp_restart++;