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

Commit 59a1fa2d authored by Heiko Carstens's avatar Heiko Carstens Committed by Marcelo Tosatti
Browse files

s390/kvm,tprot: use new gmap_translate() function



When out-of-memory the tprot code incorrectly injected a program check
for the guest which reported an addressing exception even if the guest
address was valid.
Let's use the new gmap_translate() which translates a guest address to
a user space address whithout the chance of running into an out-of-memory
situation.
Also make it more explicit that for -EFAULT we won't find a vma.

Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
parent 9e0fdb41
Loading
Loading
Loading
Loading
+9 −12
Original line number Diff line number Diff line
@@ -575,20 +575,13 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT)
		return -EOPNOTSUPP;


	/* we must resolve the address without holding the mmap semaphore.
	 * This is ok since the userspace hypervisor is not supposed to change
	 * the mapping while the guest queries the memory. Otherwise the guest
	 * might crash or get wrong info anyway. */
	user_address = (unsigned long) __guestaddr_to_user(vcpu, address1);

	down_read(&current->mm->mmap_sem);
	user_address = __gmap_translate(address1, vcpu->arch.gmap);
	if (IS_ERR_VALUE(user_address))
		goto out_inject;
	vma = find_vma(current->mm, user_address);
	if (!vma) {
		up_read(&current->mm->mmap_sem);
		return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
	}

	if (!vma)
		goto out_inject;
	vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
	if (!(vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_READ))
		vcpu->arch.sie_block->gpsw.mask |= (1ul << 44);
@@ -597,6 +590,10 @@ static int handle_tprot(struct kvm_vcpu *vcpu)

	up_read(&current->mm->mmap_sem);
	return 0;

out_inject:
	up_read(&current->mm->mmap_sem);
	return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
}

int kvm_s390_handle_e5(struct kvm_vcpu *vcpu)