summaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm/priv.c
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2012-01-13 13:57:45 +0200
committerKalle Valo <kvalo@qca.qualcomm.com>2012-01-13 13:57:45 +0200
commita0afd4f7c1ff8cb7a9747150500f8ce081fbcfc9 (patch)
tree12d6c61b17e3b3b9874b9a0d1063e711af483b02 /arch/s390/kvm/priv.c
parente80ec84d9352419a7c0482edfbf1b96eaa4c8b95 (diff)
parenta8c1f65c79cbbb2f7da782d4c9d15639a9b94b27 (diff)
Merge remote branch 'wireless-next/master' into ath6kl-next
Conflicts: drivers/net/wireless/ath/ath6kl/usb.c
Diffstat (limited to 'arch/s390/kvm/priv.c')
-rw-r--r--arch/s390/kvm/priv.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 39162636108..d0263895992 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -336,6 +336,7 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
u64 address1 = disp1 + base1 ? vcpu->arch.guest_gprs[base1] : 0;
u64 address2 = disp2 + base2 ? vcpu->arch.guest_gprs[base2] : 0;
struct vm_area_struct *vma;
+ unsigned long user_address;
vcpu->stat.instruction_tprot++;
@@ -349,9 +350,14 @@ static int handle_tprot(struct kvm_vcpu *vcpu)
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);
- vma = find_vma(current->mm,
- (unsigned long) __guestaddr_to_user(vcpu, address1));
+ vma = find_vma(current->mm, user_address);
if (!vma) {
up_read(&current->mm->mmap_sem);
return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);