From: Christian Borntraeger <[email protected]>

The general purpose registers are often necessary to handle SIE exits.
Avoid additional ioctls by providing the guest registers in the r/w 
section of the kvm_run structure.

Signed-off-by: Christian Borntraeger <[email protected]>
---
 arch/s390/include/asm/kvm.h      |    1 +
 arch/s390/include/asm/kvm_host.h |    2 +-
 arch/s390/kvm/diag.c             |    6 +++---
 arch/s390/kvm/intercept.c        |    4 ++--
 arch/s390/kvm/kvm-s390.c         |   16 ++++++++--------
 arch/s390/kvm/priv.c             |   24 ++++++++++++------------
 arch/s390/kvm/sigp.c             |   14 +++++++-------
 7 files changed, 34 insertions(+), 33 deletions(-)

==================================================================
Index: b/arch/s390/include/asm/kvm.h
===================================================================
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -47,5 +47,6 @@ struct sync_ro_regs {
 };
 
 struct sync_rw_regs {
+       __u64 gprs[16]; /* general purpose registers */
 };
 #endif
Index: b/arch/s390/include/asm/kvm_host.h
===================================================================
--- a/arch/s390/include/asm/kvm_host.h
+++ b/arch/s390/include/asm/kvm_host.h
@@ -253,5 +253,5 @@ struct kvm_arch{
        struct gmap *gmap;
 };
 
-extern int sie64a(struct kvm_s390_sie_block *, unsigned long *);
+extern int sie64a(struct kvm_s390_sie_block *, u64 *);
 #endif
Index: b/arch/s390/kvm/diag.c
===================================================================
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -20,8 +20,8 @@ static int diag_release_pages(struct kvm
        unsigned long start, end;
        unsigned long prefix  = vcpu->arch.sie_block->prefix;
 
-       start = vcpu->arch.guest_gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
-       end = vcpu->arch.guest_gprs[vcpu->arch.sie_block->ipa & 0xf] + 4096;
+       start = vcpu->run->sync_rw_regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) 
>> 4];
+       end = vcpu->run->sync_rw_regs.gprs[vcpu->arch.sie_block->ipa & 0xf] + 
4096;
 
        if (start & ~PAGE_MASK || end & ~PAGE_MASK || start > end
            || start < 2 * PAGE_SIZE)
@@ -56,7 +56,7 @@ static int __diag_time_slice_end(struct 
 static int __diag_ipl_functions(struct kvm_vcpu *vcpu)
 {
        unsigned int reg = vcpu->arch.sie_block->ipa & 0xf;
-       unsigned long subcode = vcpu->arch.guest_gprs[reg] & 0xffff;
+       unsigned long subcode = vcpu->run->sync_rw_regs.gprs[reg] & 0xffff;
 
        VCPU_EVENT(vcpu, 5, "diag ipl functions, subcode %lx", subcode);
        switch (subcode) {
Index: b/arch/s390/kvm/intercept.c
===================================================================
--- a/arch/s390/kvm/intercept.c
+++ b/arch/s390/kvm/intercept.c
@@ -36,7 +36,7 @@ static int handle_lctlg(struct kvm_vcpu 
 
        useraddr = disp2;
        if (base2)
-               useraddr += vcpu->arch.guest_gprs[base2];
+               useraddr += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (useraddr & 7)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -75,7 +75,7 @@ static int handle_lctl(struct kvm_vcpu *
 
        useraddr = disp2;
        if (base2)
-               useraddr += vcpu->arch.guest_gprs[base2];
+               useraddr += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (useraddr & 3)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
Index: b/arch/s390/kvm/kvm-s390.c
===================================================================
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -389,13 +389,13 @@ static int kvm_arch_vcpu_ioctl_initial_r
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       memcpy(&vcpu->arch.guest_gprs, &regs->gprs, sizeof(regs->gprs));
+       memcpy(&vcpu->run->sync_rw_regs.gprs, &regs->gprs, sizeof(regs->gprs));
        return 0;
 }
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
-       memcpy(&regs->gprs, &vcpu->arch.guest_gprs, sizeof(regs->gprs));
+       memcpy(&regs->gprs, &vcpu->run->sync_rw_regs.gprs, sizeof(regs->gprs));
        return 0;
 }
 
@@ -468,9 +468,9 @@ int kvm_arch_vcpu_ioctl_set_mpstate(stru
        return -EINVAL; /* not implemented yet */
 }
 
-static void __vcpu_run(struct kvm_vcpu *vcpu)
+static void __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-       memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16);
+       memcpy(&vcpu->arch.sie_block->gg14, &kvm_run->sync_rw_regs.gprs[14], 
16);
 
        if (need_resched())
                schedule();
@@ -486,7 +486,7 @@ static void __vcpu_run(struct kvm_vcpu *
        local_irq_enable();
        VCPU_EVENT(vcpu, 6, "entering sie flags %x",
                   atomic_read(&vcpu->arch.sie_block->cpuflags));
-       if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) {
+       if (sie64a(vcpu->arch.sie_block, kvm_run->sync_rw_regs.gprs)) {
                VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction");
                kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
        }
@@ -496,7 +496,7 @@ static void __vcpu_run(struct kvm_vcpu *
        kvm_guest_exit();
        local_irq_enable();
 
-       memcpy(&vcpu->arch.guest_gprs[14], &vcpu->arch.sie_block->gg14, 16);
+       memcpy(&kvm_run->sync_rw_regs.gprs[14], &vcpu->arch.sie_block->gg14, 
16);
 }
 
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -528,7 +528,7 @@ rerun_vcpu:
        might_fault();
 
        do {
-               __vcpu_run(vcpu);
+               __vcpu_run(vcpu, kvm_run);
                rc = kvm_handle_sie_intercept(vcpu);
        } while (!signal_pending(current) && !rc);
 
@@ -604,7 +604,7 @@ int kvm_s390_vcpu_store_status(struct kv
                return -EFAULT;
 
        if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
-                       vcpu->arch.guest_gprs, 128, prefix))
+                       vcpu->run->sync_rw_regs.gprs, 128, prefix))
                return -EFAULT;
 
        if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
Index: b/arch/s390/kvm/priv.c
===================================================================
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -33,7 +33,7 @@ static int handle_set_prefix(struct kvm_
 
        operand2 = disp2;
        if (base2)
-               operand2 += vcpu->arch.guest_gprs[base2];
+               operand2 += vcpu->run->sync_rw_regs.gprs[base2];
 
        /* must be word boundary */
        if (operand2 & 3) {
@@ -74,7 +74,7 @@ static int handle_store_prefix(struct kv
        vcpu->stat.instruction_stpx++;
        operand2 = disp2;
        if (base2)
-               operand2 += vcpu->arch.guest_gprs[base2];
+               operand2 += vcpu->run->sync_rw_regs.gprs[base2];
 
        /* must be word boundary */
        if (operand2 & 3) {
@@ -106,7 +106,7 @@ static int handle_store_cpu_address(stru
        vcpu->stat.instruction_stap++;
        useraddr = disp2;
        if (base2)
-               useraddr += vcpu->arch.guest_gprs[base2];
+               useraddr += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (useraddr & 1) {
                kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -181,7 +181,7 @@ static int handle_stidp(struct kvm_vcpu 
        vcpu->stat.instruction_stidp++;
        operand2 = disp2;
        if (base2)
-               operand2 += vcpu->arch.guest_gprs[base2];
+               operand2 += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (operand2 & 7) {
                kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
@@ -232,9 +232,9 @@ static void handle_stsi_3_2_2(struct kvm
 
 static int handle_stsi(struct kvm_vcpu *vcpu)
 {
-       int fc = (vcpu->arch.guest_gprs[0] & 0xf0000000) >> 28;
-       int sel1 = vcpu->arch.guest_gprs[0] & 0xff;
-       int sel2 = vcpu->arch.guest_gprs[1] & 0xffff;
+       int fc = (vcpu->run->sync_rw_regs.gprs[0] & 0xf0000000) >> 28;
+       int sel1 = vcpu->run->sync_rw_regs.gprs[0] & 0xff;
+       int sel2 = vcpu->run->sync_rw_regs.gprs[1] & 0xffff;
        int base2 = vcpu->arch.sie_block->ipb >> 28;
        int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
        u64 operand2;
@@ -245,14 +245,14 @@ static int handle_stsi(struct kvm_vcpu *
 
        operand2 = disp2;
        if (base2)
-               operand2 += vcpu->arch.guest_gprs[base2];
+               operand2 += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (operand2 & 0xfff && fc > 0)
                return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
 
        switch (fc) {
        case 0:
-               vcpu->arch.guest_gprs[0] = 3 << 28;
+               vcpu->run->sync_rw_regs.gprs[0] = 3 << 28;
                vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
                return 0;
        case 1: /* same handling for 1 and 2 */
@@ -281,7 +281,7 @@ static int handle_stsi(struct kvm_vcpu *
        }
        free_page(mem);
        vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
-       vcpu->arch.guest_gprs[0] = 0;
+       vcpu->run->sync_rw_regs.gprs[0] = 0;
        return 0;
 out_mem:
        free_page(mem);
@@ -333,8 +333,8 @@ static int handle_tprot(struct kvm_vcpu 
        int disp1 = (vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16;
        int base2 = (vcpu->arch.sie_block->ipb & 0xf000) >> 12;
        int disp2 = vcpu->arch.sie_block->ipb & 0x0fff;
-       u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0;
-       u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0;
+       u64 address1 = disp1 + base1 ? vcpu->run->sync_rw_regs.gprs[base1] : 0;
+       u64 address2 = disp2 + base2 ? vcpu->run->sync_rw_regs.gprs[base2] : 0;
        struct vm_area_struct *vma;
        unsigned long user_address;
 
Index: b/arch/s390/kvm/sigp.c
===================================================================
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -316,7 +316,7 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
        int base2 = vcpu->arch.sie_block->ipb >> 28;
        int disp2 = ((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16);
        u32 parameter;
-       u16 cpu_addr = vcpu->arch.guest_gprs[r3];
+       u16 cpu_addr = vcpu->run->sync_rw_regs.gprs[r3];
        u8 order_code;
        int rc;
 
@@ -327,18 +327,18 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
 
        order_code = disp2;
        if (base2)
-               order_code += vcpu->arch.guest_gprs[base2];
+               order_code += vcpu->run->sync_rw_regs.gprs[base2];
 
        if (r1 % 2)
-               parameter = vcpu->arch.guest_gprs[r1];
+               parameter = vcpu->run->sync_rw_regs.gprs[r1];
        else
-               parameter = vcpu->arch.guest_gprs[r1 + 1];
+               parameter = vcpu->run->sync_rw_regs.gprs[r1 + 1];
 
        switch (order_code) {
        case SIGP_SENSE:
                vcpu->stat.instruction_sigp_sense++;
                rc = __sigp_sense(vcpu, cpu_addr,
-                                 &vcpu->arch.guest_gprs[r1]);
+                                 &vcpu->run->sync_rw_regs.gprs[r1]);
                break;
        case SIGP_EXTERNAL_CALL:
                vcpu->stat.instruction_sigp_external_call++;
@@ -363,12 +363,12 @@ int kvm_s390_handle_sigp(struct kvm_vcpu
        case SIGP_SET_PREFIX:
                vcpu->stat.instruction_sigp_prefix++;
                rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
-                                      &vcpu->arch.guest_gprs[r1]);
+                                      &vcpu->run->sync_rw_regs.gprs[r1]);
                break;
        case SIGP_SENSE_RUNNING:
                vcpu->stat.instruction_sigp_sense_running++;
                rc = __sigp_sense_running(vcpu, cpu_addr,
-                                         &vcpu->arch.guest_gprs[r1]);
+                                         &vcpu->run->sync_rw_regs.gprs[r1]);
                break;
        case SIGP_RESTART:
                vcpu->stat.instruction_sigp_restart++;

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to