KVM: s390: convert kvm_s390_store_status_unloaded()
[cascardo/linux.git] / arch / s390 / kvm / kvm-s390.c
index e1dfe24..ae7c126 100644 (file)
@@ -1058,8 +1058,9 @@ static int kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu)
        if (!vcpu->arch.gmap->pfault_enabled)
                return 0;
 
-       hva = gmap_fault(current->thread.gmap_addr, vcpu->arch.gmap);
-       if (copy_from_guest(vcpu, &arch.pfault_token, vcpu->arch.pfault_token, 8))
+       hva = gfn_to_hva(vcpu->kvm, gpa_to_gfn(current->thread.gmap_addr));
+       hva += current->thread.gmap_addr & ~PAGE_MASK;
+       if (read_guest_real(vcpu, vcpu->arch.pfault_token, &arch.pfault_token, 8))
                return 0;
 
        rc = kvm_setup_async_pf(vcpu, current->thread.gmap_addr, hva, &arch);
@@ -1248,83 +1249,50 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
        return rc;
 }
 
-static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from,
-                      unsigned long n, int prefix)
-{
-       if (prefix)
-               return copy_to_guest(vcpu, guestdest, from, n);
-       else
-               return copy_to_guest_absolute(vcpu, guestdest, from, n);
-}
-
 /*
  * store status at address
  * we use have two special cases:
  * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit
  * KVM_S390_STORE_STATUS_PREFIXED: -> prefix
  */
-int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr)
+int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
 {
        unsigned char archmode = 1;
-       int prefix;
        u64 clkcomp;
+       int rc;
 
-       if (addr == KVM_S390_STORE_STATUS_NOADDR) {
-               if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1))
+       if (gpa == KVM_S390_STORE_STATUS_NOADDR) {
+               if (write_guest_abs(vcpu, 163, &archmode, 1))
                        return -EFAULT;
-               addr = SAVE_AREA_BASE;
-               prefix = 0;
-       } else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
-               if (copy_to_guest(vcpu, 163ul, &archmode, 1))
+               gpa = SAVE_AREA_BASE;
+       } else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) {
+               if (write_guest_real(vcpu, 163, &archmode, 1))
                        return -EFAULT;
-               addr = SAVE_AREA_BASE;
-               prefix = 1;
-       } else
-               prefix = 0;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs),
-                       vcpu->arch.guest_fpregs.fprs, 128, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, gp_regs),
-                       vcpu->run->s.regs.gprs, 128, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, psw),
-                       &vcpu->arch.sie_block->gpsw, 16, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, pref_reg),
-                       &vcpu->arch.sie_block->prefix, 4, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu,
-                       addr + offsetof(struct save_area, fp_ctrl_reg),
-                       &vcpu->arch.guest_fpregs.fpc, 4, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, tod_reg),
-                       &vcpu->arch.sie_block->todpr, 4, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
-                       &vcpu->arch.sie_block->cputm, 8, prefix))
-               return -EFAULT;
-
+               gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE);
+       }
+       rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs),
+                            vcpu->arch.guest_fpregs.fprs, 128);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs),
+                             vcpu->run->s.regs.gprs, 128);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw),
+                             &vcpu->arch.sie_block->gpsw, 16);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg),
+                             &vcpu->arch.sie_block->prefix, 4);
+       rc |= write_guest_abs(vcpu,
+                             gpa + offsetof(struct save_area, fp_ctrl_reg),
+                             &vcpu->arch.guest_fpregs.fpc, 4);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg),
+                             &vcpu->arch.sie_block->todpr, 4);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer),
+                             &vcpu->arch.sie_block->cputm, 8);
        clkcomp = vcpu->arch.sie_block->ckc >> 8;
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp),
-                       &clkcomp, 8, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs),
-                       &vcpu->run->s.regs.acrs, 64, prefix))
-               return -EFAULT;
-
-       if (__guestcopy(vcpu,
-                       addr + offsetof(struct save_area, ctrl_regs),
-                       &vcpu->arch.sie_block->gcr, 128, prefix))
-               return -EFAULT;
-       return 0;
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp),
+                             &clkcomp, 8);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs),
+                             &vcpu->run->s.regs.acrs, 64);
+       rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs),
+                             &vcpu->arch.sie_block->gcr, 128);
+       return rc ? -EFAULT : 0;
 }
 
 int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr)