Commit d0bce605 authored by Heiko Carstens's avatar Heiko Carstens Committed by Christian Borntraeger
Browse files

KVM: s390: convert kvm_s390_store_status_unloaded()



Convert kvm_s390_store_status_unloaded() to new guest access functions.

Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 0040e7d2
Loading
Loading
Loading
Loading
+31 −64
Original line number Diff line number Diff line
@@ -1249,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))
			return -EFAULT;
		addr = SAVE_AREA_BASE;
		prefix = 0;
	} else if (addr == KVM_S390_STORE_STATUS_PREFIXED) {
		if (copy_to_guest(vcpu, 163ul, &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))
	if (gpa == KVM_S390_STORE_STATUS_NOADDR) {
		if (write_guest_abs(vcpu, 163, &archmode, 1))
			return -EFAULT;

	if (__guestcopy(vcpu, addr + offsetof(struct save_area, timer),
			&vcpu->arch.sie_block->cputm, 8, prefix))
		gpa = SAVE_AREA_BASE;
	} else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) {
		if (write_guest_real(vcpu, 163, &archmode, 1))
			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)