aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kvm
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2016-03-08 05:53:35 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-06-10 06:07:27 -0400
commitd3ed1ceeace311af9973d17a07a114bfaf0ca1b1 (patch)
tree1e9a353c769d89bf8eee9489f931869dcaf0651a /arch/s390/kvm
parentc427c42cd612719e8fb8b5891cc9761e7770024e (diff)
s390/mm: set and get guest storage key mmap locking
Move the mmap semaphore locking out of set_guest_storage_key and get_guest_storage_key. This makes the two functions more like the other ptep_xxx operations and allows to avoid repeated semaphore operations if multiple keys are read or written. Reviewed-by: David Hildenbrand <dahi@linux.vnet.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>
Diffstat (limited to 'arch/s390/kvm')
-rw-r--r--arch/s390/kvm/kvm-s390.c26
-rw-r--r--arch/s390/kvm/priv.c7
2 files changed, 21 insertions, 12 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 9d0e4d0487f4..d0156d7969e0 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1050,26 +1050,30 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
1050 if (!keys) 1050 if (!keys)
1051 return -ENOMEM; 1051 return -ENOMEM;
1052 1052
1053 down_read(&current->mm->mmap_sem);
1053 for (i = 0; i < args->count; i++) { 1054 for (i = 0; i < args->count; i++) {
1054 hva = gfn_to_hva(kvm, args->start_gfn + i); 1055 hva = gfn_to_hva(kvm, args->start_gfn + i);
1055 if (kvm_is_error_hva(hva)) { 1056 if (kvm_is_error_hva(hva)) {
1056 r = -EFAULT; 1057 r = -EFAULT;
1057 goto out; 1058 break;
1058 } 1059 }
1059 1060
1060 curkey = get_guest_storage_key(current->mm, hva); 1061 curkey = get_guest_storage_key(current->mm, hva);
1061 if (IS_ERR_VALUE(curkey)) { 1062 if (IS_ERR_VALUE(curkey)) {
1062 r = curkey; 1063 r = curkey;
1063 goto out; 1064 break;
1064 } 1065 }
1065 keys[i] = curkey; 1066 keys[i] = curkey;
1066 } 1067 }
1068 up_read(&current->mm->mmap_sem);
1069
1070 if (!r) {
1071 r = copy_to_user((uint8_t __user *)args->skeydata_addr, keys,
1072 sizeof(uint8_t) * args->count);
1073 if (r)
1074 r = -EFAULT;
1075 }
1067 1076
1068 r = copy_to_user((uint8_t __user *)args->skeydata_addr, keys,
1069 sizeof(uint8_t) * args->count);
1070 if (r)
1071 r = -EFAULT;
1072out:
1073 kvfree(keys); 1077 kvfree(keys);
1074 return r; 1078 return r;
1075} 1079}
@@ -1106,24 +1110,26 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
1106 if (r) 1110 if (r)
1107 goto out; 1111 goto out;
1108 1112
1113 down_read(&current->mm->mmap_sem);
1109 for (i = 0; i < args->count; i++) { 1114 for (i = 0; i < args->count; i++) {
1110 hva = gfn_to_hva(kvm, args->start_gfn + i); 1115 hva = gfn_to_hva(kvm, args->start_gfn + i);
1111 if (kvm_is_error_hva(hva)) { 1116 if (kvm_is_error_hva(hva)) {
1112 r = -EFAULT; 1117 r = -EFAULT;
1113 goto out; 1118 break;
1114 } 1119 }
1115 1120
1116 /* Lowest order bit is reserved */ 1121 /* Lowest order bit is reserved */
1117 if (keys[i] & 0x01) { 1122 if (keys[i] & 0x01) {
1118 r = -EINVAL; 1123 r = -EINVAL;
1119 goto out; 1124 break;
1120 } 1125 }
1121 1126
1122 r = set_guest_storage_key(current->mm, hva, 1127 r = set_guest_storage_key(current->mm, hva,
1123 (unsigned long)keys[i], 0); 1128 (unsigned long)keys[i], 0);
1124 if (r) 1129 if (r)
1125 goto out; 1130 break;
1126 } 1131 }
1132 up_read(&current->mm->mmap_sem);
1127out: 1133out:
1128 kvfree(keys); 1134 kvfree(keys);
1129 return r; 1135 return r;
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 95916fa7c670..c6deed782c61 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -728,9 +728,12 @@ static int handle_pfmf(struct kvm_vcpu *vcpu)
728 728
729 if (rc) 729 if (rc)
730 return rc; 730 return rc;
731 if (set_guest_storage_key(current->mm, useraddr, 731 down_read(&current->mm->mmap_sem);
732 rc = set_guest_storage_key(current->mm, useraddr,
732 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY, 733 vcpu->run->s.regs.gprs[reg1] & PFMF_KEY,
733 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ)) 734 vcpu->run->s.regs.gprs[reg1] & PFMF_NQ);
735 up_read(&current->mm->mmap_sem);
736 if (rc)
734 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); 737 return kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING);
735 } 738 }
736 739