aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>2016-01-27 11:24:03 -0500
committerChristian Borntraeger <borntraeger@de.ibm.com>2016-06-20 03:54:40 -0400
commitf4debb40903978bbddfb9e877ca4d2f27e26567f (patch)
treeb2002d9cc11358bbf937695d8344d7ed2441c2f0
parent7a6741576b268820c8bd2b66288e6ff3bc57d4a7 (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.c11
-rw-r--r--arch/s390/kvm/gaccess.h3
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 */
1085int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr) 1086int 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);
361int ipte_lock_held(struct kvm_vcpu *vcpu); 361int ipte_lock_held(struct kvm_vcpu *vcpu);
362int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra); 362int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra);
363 363
364int kvm_s390_shadow_fault(struct gmap *shadow, unsigned long saddr); 364int 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 */