diff options
author | David Hildenbrand <dahi@linux.vnet.ibm.com> | 2016-01-27 11:24:03 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2016-06-20 03:54:40 -0400 |
commit | f4debb40903978bbddfb9e877ca4d2f27e26567f (patch) | |
tree | b2002d9cc11358bbf937695d8344d7ed2441c2f0 | |
parent | 7a6741576b268820c8bd2b66288e6ff3bc57d4a7 (diff) |
s390/mm: take ipte_lock during shadow faults
Let's take the ipte_lock while working on guest 2 provided page table, just
like the other gaccess functions.
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
-rw-r--r-- | arch/s390/kvm/gaccess.c | 11 | ||||
-rw-r--r-- | arch/s390/kvm/gaccess.h | 3 |
2 files changed, 12 insertions, 2 deletions
diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c index b2783dd71854..e70f916c1079 100644 --- a/arch/s390/kvm/gaccess.c +++ b/arch/s390/kvm/gaccess.c | |||
@@ -1073,6 +1073,7 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, | |||
1073 | 1073 | ||
1074 | /** | 1074 | /** |
1075 | * kvm_s390_shadow_fault - handle fault on a shadow page table | 1075 | * kvm_s390_shadow_fault - handle fault on a shadow page table |
1076 | * @vcpu: virtual cpu | ||
1076 | * @sg: pointer to the shadow guest address space structure | 1077 | * @sg: pointer to the shadow guest address space structure |
1077 | * @saddr: faulting address in the shadow gmap | 1078 | * @saddr: faulting address in the shadow gmap |
1078 | * | 1079 | * |
@@ -1082,7 +1083,8 @@ static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr, | |||
1082 | * - -EFAULT when accessing invalid guest addresses | 1083 | * - -EFAULT when accessing invalid guest addresses |
1083 | * - -ENOMEM if out of memory | 1084 | * - -ENOMEM if out of memory |
1084 | */ | 1085 | */ |
1085 | int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr) | 1086 | int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg, |
1087 | unsigned long saddr) | ||
1086 | { | 1088 | { |
1087 | union vaddress vaddr; | 1089 | union vaddress vaddr; |
1088 | union page_table_entry pte; | 1090 | union page_table_entry pte; |
@@ -1091,6 +1093,12 @@ int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr) | |||
1091 | int rc; | 1093 | int rc; |
1092 | 1094 | ||
1093 | down_read(&sg->mm->mmap_sem); | 1095 | down_read(&sg->mm->mmap_sem); |
1096 | /* | ||
1097 | * We don't want any guest-2 tables to change - so the parent | ||
1098 | * tables/pointers we read stay valid - unshadowing is however | ||
1099 | * always possible - only guest_table_lock protects us. | ||
1100 | */ | ||
1101 | ipte_lock(vcpu); | ||
1094 | 1102 | ||
1095 | rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection); | 1103 | rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection); |
1096 | if (rc) | 1104 | if (rc) |
@@ -1105,6 +1113,7 @@ int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr) | |||
1105 | rc = PGM_TRANSLATION_SPEC; | 1113 | rc = PGM_TRANSLATION_SPEC; |
1106 | if (!rc) | 1114 | if (!rc) |
1107 | rc = gmap_shadow_page(sg, saddr, __pte(pte.val)); | 1115 | rc = gmap_shadow_page(sg, saddr, __pte(pte.val)); |
1116 | ipte_unlock(vcpu); | ||
1108 | up_read(&sg->mm->mmap_sem); | 1117 | up_read(&sg->mm->mmap_sem); |
1109 | return rc; | 1118 | return rc; |
1110 | } | 1119 | } |
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h index 0d044d09dbd8..8756569ad938 100644 --- a/arch/s390/kvm/gaccess.h +++ b/arch/s390/kvm/gaccess.h | |||
@@ -361,6 +361,7 @@ void ipte_unlock(struct kvm_vcpu *vcpu); | |||
361 | int ipte_lock_held(struct kvm_vcpu *vcpu); | 361 | int ipte_lock_held(struct kvm_vcpu *vcpu); |
362 | int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra); | 362 | int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra); |
363 | 363 | ||
364 | int kvm_s390_shadow_fault(struct gmap *shadow, unsigned long saddr); | 364 | int kvm_s390_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *shadow, |
365 | unsigned long saddr); | ||
365 | 366 | ||
366 | #endif /* __KVM_S390_GACCESS_H */ | 367 | #endif /* __KVM_S390_GACCESS_H */ |