s390/kvm,tprot: use new gmap_translate() function
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 5 Mar 2013 12:14:42 +0000 (13:14 +0100)
committerMarcelo Tosatti <mtosatti@redhat.com>
Thu, 7 Mar 2013 19:21:20 +0000 (16:21 -0300)
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: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
arch/s390/kvm/priv.c

index 0ef9894606e519874fb531bb890b4d36badb75aa..75ad91e38e8adeda02213ea2edd11b9ad3cc08ff 100644 (file)
@@ -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)