aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/priv.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-03-05 07:14:42 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2013-03-07 14:21:20 -0500
commit59a1fa2d80c0d351755cb29273b2b256dc4b3a11 (patch)
tree45c45e881ca3806a5d4c859519e471348c0d4a2d /arch/s390/kvm/priv.c
parent9e0fdb4145205bea95c2888a195c3ead2652f120 (diff)
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: 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>
Diffstat (limited to 'arch/s390/kvm/priv.c')
-rw-r--r--arch/s390/kvm/priv.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 0ef9894606e5..75ad91e38e8a 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -575,20 +575,13 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
575 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT) 575 if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_DAT)
576 return -EOPNOTSUPP; 576 return -EOPNOTSUPP;
577 577
578
579 /* we must resolve the address without holding the mmap semaphore.
580 * This is ok since the userspace hypervisor is not supposed to change
581 * the mapping while the guest queries the memory. Otherwise the guest
582 * might crash or get wrong info anyway. */
583 user_address = (unsigned long) __guestaddr_to_user(vcpu, address1);
584
585 down_read(&current->mm->mmap_sem); 578 down_read(&current->mm->mmap_sem);
579 user_address = __gmap_translate(address1, vcpu->arch.gmap);
580 if (IS_ERR_VALUE(user_address))
581 goto out_inject;
586 vma = find_vma(current->mm, user_address); 582 vma = find_vma(current->mm, user_address);
587 if (!vma) { 583 if (!vma)
588 up_read(&current->mm->mmap_sem); 584 goto out_inject;
589 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
590 }
591
592 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 585 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44);
593 if (!(vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_READ)) 586 if (!(vma->vm_flags & VM_WRITE) && (vma->vm_flags & VM_READ))
594 vcpu->arch.sie_block->gpsw.mask |= (1ul << 44); 587 vcpu->arch.sie_block->gpsw.mask |= (1ul << 44);
@@ -597,6 +590,10 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
597 590
598 up_read(&current->mm->mmap_sem); 591 up_read(&current->mm->mmap_sem);
599 return 0; 592 return 0;
593
594out_inject:
595 up_read(&current->mm->mmap_sem);
596 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
600} 597}
601 598
602int kvm_s390_handle_e5(struct kvm_vcpu *vcpu) 599int kvm_s390_handle_e5(struct kvm_vcpu *vcpu)