Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ae04b8f authored by Alexander Yarygin's avatar Alexander Yarygin Committed by Christian Borntraeger
Browse files

KVM: s390: Guest's memory access functions get access registers



In access register mode, the write_guest() read_guest() and other
functions will invoke the access register translation, which
requires an ar, designated by one of the instruction fields.

Signed-off-by: default avatarAlexander Yarygin <yarygin@linux.vnet.ibm.com>
Reviewed-by: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
Acked-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent dd9e5b7b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu)

	if (vcpu->run->s.regs.gprs[rx] & 7)
		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
	rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
	rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm));
	if (rc)
		return kvm_s390_inject_prog_cond(vcpu, rc);
	if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)
@@ -230,7 +230,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)

int kvm_s390_handle_diag(struct kvm_vcpu *vcpu)
{
	int code = kvm_s390_get_base_disp_rs(vcpu) & 0xffff;
	int code = kvm_s390_get_base_disp_rs(vcpu, NULL) & 0xffff;

	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+2 −2
Original line number Diff line number Diff line
@@ -578,7 +578,7 @@ static int guest_page_range(struct kvm_vcpu *vcpu, unsigned long ga,
	return 0;
}

int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
		 unsigned long len, int write)
{
	psw_t *psw = &vcpu->arch.sie_block->gpsw;
@@ -652,7 +652,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
 * Note: The IPTE lock is not taken during this function, so the caller
 * has to take care of this.
 */
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva, ar_t ar,
			    unsigned long *gpa, int write)
{
	struct kvm_s390_pgm_info *pgm = &vcpu->arch.pgm;
+8 −6
Original line number Diff line number Diff line
@@ -156,9 +156,9 @@ int read_guest_lc(struct kvm_vcpu *vcpu, unsigned long gra, void *data,
}

int guest_translate_address(struct kvm_vcpu *vcpu, unsigned long gva,
			    unsigned long *gpa, int write);
			    ar_t ar, unsigned long *gpa, int write);

int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
int access_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
		 unsigned long len, int write);

int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
@@ -168,6 +168,7 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
 * write_guest - copy data from kernel space to guest space
 * @vcpu: virtual cpu
 * @ga: guest address
 * @ar: access register
 * @data: source address in kernel space
 * @len: number of bytes to copy
 *
@@ -210,16 +211,17 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra,
 *	 if data has been changed in guest space in case of an exception.
 */
static inline __must_check
int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
		unsigned long len)
{
	return access_guest(vcpu, ga, data, len, 1);
	return access_guest(vcpu, ga, ar, data, len, 1);
}

/**
 * read_guest - copy data from guest space to kernel space
 * @vcpu: virtual cpu
 * @ga: guest address
 * @ar: access register
 * @data: destination address in kernel space
 * @len: number of bytes to copy
 *
@@ -229,10 +231,10 @@ int write_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
 * data will be copied from guest space to kernel space.
 */
static inline __must_check
int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, void *data,
int read_guest(struct kvm_vcpu *vcpu, unsigned long ga, ar_t ar, void *data,
	       unsigned long len)
{
	return access_guest(vcpu, ga, data, len, 0);
	return access_guest(vcpu, ga, ar, data, len, 0);
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)

	/* Make sure that the source is paged-in */
	rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg2],
				     &srcaddr, 0);
				     reg2, &srcaddr, 0);
	if (rc)
		return kvm_s390_inject_prog_cond(vcpu, rc);
	rc = kvm_arch_fault_in_page(vcpu, srcaddr, 0);
@@ -329,7 +329,7 @@ static int handle_mvpg_pei(struct kvm_vcpu *vcpu)

	/* Make sure that the destination is paged-in */
	rc = guest_translate_address(vcpu, vcpu->run->s.regs.gprs[reg1],
				     &dstaddr, 1);
				     reg1, &dstaddr, 1);
	if (rc)
		return kvm_s390_inject_prog_cond(vcpu, rc);
	rc = kvm_arch_fault_in_page(vcpu, dstaddr, 1);
+1 −1
Original line number Diff line number Diff line
@@ -1776,7 +1776,7 @@ static int vcpu_post_run_fault_in_sie(struct kvm_vcpu *vcpu)
	 * to look up the current opcode to get the length of the instruction
	 * to be able to forward the PSW.
	 */
	rc = read_guest(vcpu, psw->addr, &opcode, 1);
	rc = read_guest(vcpu, psw->addr, 0, &opcode, 1);
	if (rc)
		return kvm_s390_inject_prog_cond(vcpu, rc);
	psw->addr = __rewind_psw(*psw, -insn_length(opcode));
Loading