linux-s390.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Borntraeger <borntraeger@de.ibm.com>
To: "Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>
Cc: KVM <kvm@vger.kernel.org>,
	Cornelia Huck <cornelia.huck@de.ibm.com>,
	linux-s390 <linux-s390@vger.kernel.org>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	David Hildenbrand <dahi@linux.vnet.ibm.com>,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [GIT PULL 06/51] s390/mm: add kvm shadow fault function
Date: Tue, 21 Jun 2016 15:12:44 +0200	[thread overview]
Message-ID: <1466514809-146638-7-git-send-email-borntraeger@de.ibm.com> (raw)
In-Reply-To: <1466514809-146638-1-git-send-email-borntraeger@de.ibm.com>

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

This patch introduces function kvm_s390_shadow_fault() used to resolve a
fault on a shadow gmap. This function will do validity checking and
build up the shadow page table hierarchy in order to fault in the
requested page into the shadow page table structure.

If an exception occurs while shadowing, guest 2 has to be notified about
it using either an exception or a program interrupt intercept. If
concurrent unshadowing occurres, this function will simply return with
-EAGAIN and the caller has to retry.

Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
---
 arch/s390/kvm/gaccess.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++
 arch/s390/kvm/gaccess.h |   2 +
 2 files changed, 170 insertions(+)

diff --git a/arch/s390/kvm/gaccess.c b/arch/s390/kvm/gaccess.c
index 8e245e7..ba49852 100644
--- a/arch/s390/kvm/gaccess.c
+++ b/arch/s390/kvm/gaccess.c
@@ -8,6 +8,7 @@
 #include <linux/vmalloc.h>
 #include <linux/err.h>
 #include <asm/pgtable.h>
+#include <asm/gmap.h>
 #include "kvm-s390.h"
 #include "gaccess.h"
 #include <asm/switch_to.h>
@@ -946,3 +947,170 @@ int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra)
 		return 0;
 	return trans_exc(vcpu, PGM_PROTECTION, gra, 0, GACC_STORE, PROT_TYPE_LA);
 }
+
+/**
+ * kvm_s390_shadow_tables - walk the guest page table and create shadow tables
+ * @sg: pointer to the shadow guest address space structure
+ * @saddr: faulting address in the shadow gmap
+ * @pgt: pointer to the page table address result
+ */
+static int kvm_s390_shadow_tables(struct gmap *sg, unsigned long saddr,
+				  unsigned long *pgt, int *dat_protection)
+{
+	struct gmap *parent;
+	union asce asce;
+	union vaddress vaddr;
+	unsigned long ptr;
+	int rc;
+
+	parent = sg->parent;
+	vaddr.addr = saddr;
+	asce.val = sg->orig_asce;
+	ptr = asce.origin * 4096;
+	switch (asce.dt) {
+	case ASCE_TYPE_REGION1:
+		if (vaddr.rfx01 > asce.tl)
+			return PGM_REGION_FIRST_TRANS;
+		break;
+	case ASCE_TYPE_REGION2:
+		if (vaddr.rfx)
+			return PGM_ASCE_TYPE;
+		if (vaddr.rsx01 > asce.tl)
+			return PGM_REGION_SECOND_TRANS;
+		break;
+	case ASCE_TYPE_REGION3:
+		if (vaddr.rfx || vaddr.rsx)
+			return PGM_ASCE_TYPE;
+		if (vaddr.rtx01 > asce.tl)
+			return PGM_REGION_THIRD_TRANS;
+		break;
+	case ASCE_TYPE_SEGMENT:
+		if (vaddr.rfx || vaddr.rsx || vaddr.rtx)
+			return PGM_ASCE_TYPE;
+		if (vaddr.sx01 > asce.tl)
+			return PGM_SEGMENT_TRANSLATION;
+		break;
+	}
+
+	switch (asce.dt) {
+	case ASCE_TYPE_REGION1: {
+		union region1_table_entry rfte;
+
+		rc = gmap_read_table(parent, ptr + vaddr.rfx * 8, &rfte.val);
+		if (rc)
+			return rc;
+		if (rfte.i)
+			return PGM_REGION_FIRST_TRANS;
+		if (rfte.tt != TABLE_TYPE_REGION1)
+			return PGM_TRANSLATION_SPEC;
+		if (vaddr.rsx01 < rfte.tf || vaddr.rsx01 > rfte.tl)
+			return PGM_REGION_SECOND_TRANS;
+		rc = gmap_shadow_r2t(sg, saddr, rfte.val);
+		if (rc)
+			return rc;
+		ptr = rfte.rto * 4096;
+		/* fallthrough */
+	}
+	case ASCE_TYPE_REGION2: {
+		union region2_table_entry rste;
+
+		rc = gmap_read_table(parent, ptr + vaddr.rsx * 8, &rste.val);
+		if (rc)
+			return rc;
+		if (rste.i)
+			return PGM_REGION_SECOND_TRANS;
+		if (rste.tt != TABLE_TYPE_REGION2)
+			return PGM_TRANSLATION_SPEC;
+		if (vaddr.rtx01 < rste.tf || vaddr.rtx01 > rste.tl)
+			return PGM_REGION_THIRD_TRANS;
+		rc = gmap_shadow_r3t(sg, saddr, rste.val);
+		if (rc)
+			return rc;
+		ptr = rste.rto * 4096;
+		/* fallthrough */
+	}
+	case ASCE_TYPE_REGION3: {
+		union region3_table_entry rtte;
+
+		rc = gmap_read_table(parent, ptr + vaddr.rtx * 8, &rtte.val);
+		if (rc)
+			return rc;
+		if (rtte.i)
+			return PGM_REGION_THIRD_TRANS;
+		if (rtte.tt != TABLE_TYPE_REGION3)
+			return PGM_TRANSLATION_SPEC;
+		if (vaddr.sx01 < rtte.fc0.tf || vaddr.sx01 > rtte.fc0.tl)
+			return PGM_SEGMENT_TRANSLATION;
+		rc = gmap_shadow_sgt(sg, saddr, rtte.val);
+		if (rc)
+			return rc;
+		ptr = rtte.fc0.sto * 4096;
+		/* fallthrough */
+	}
+	case ASCE_TYPE_SEGMENT: {
+		union segment_table_entry ste;
+
+		rc = gmap_read_table(parent, ptr + vaddr.sx * 8, &ste.val);
+		if (rc)
+			return rc;
+		if (ste.i)
+			return PGM_SEGMENT_TRANSLATION;
+		if (ste.tt != TABLE_TYPE_SEGMENT)
+			return PGM_TRANSLATION_SPEC;
+		if (ste.cs && asce.p)
+			return PGM_TRANSLATION_SPEC;
+		*dat_protection = ste.fc0.p;
+		rc = gmap_shadow_pgt(sg, saddr, ste.val);
+		if (rc)
+			return rc;
+		ptr = ste.fc0.pto * 2048;
+	}
+	}
+	/* Return the parent address of the page table */
+	*pgt = ptr;
+	return 0;
+}
+
+/**
+ * kvm_s390_shadow_fault - handle fault on a shadow page table
+ * @sg: pointer to the shadow guest address space structure
+ * @saddr: faulting address in the shadow gmap
+ * @write: =1 map r/w, =0 map r/o
+ *
+ * Returns: - 0 if the shadow fault was successfully resolved
+ *	    - > 0 (pgm exception code) on exceptions while faulting
+ *	    - -EAGAIN if the caller can retry immediately
+ *	    - -EFAULT when accessing invalid guest addresses
+ *	    - -ENOMEM if out of memory
+ */
+int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr, int write)
+{
+	union vaddress vaddr;
+	union page_table_entry pte;
+	unsigned long pgt;
+	int dat_protection;
+	int rc;
+
+	rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection);
+	if (rc) {
+		rc = kvm_s390_shadow_tables(sg, saddr, &pgt, &dat_protection);
+		if (rc)
+			return rc;
+	}
+
+	vaddr.addr = saddr;
+	rc = gmap_read_table(sg->parent, pgt + vaddr.px * 8, &pte.val);
+	if (rc)
+		return rc;
+	if (pte.i)
+		return PGM_PAGE_TRANSLATION;
+	if (pte.z || pte.co)
+		return PGM_TRANSLATION_SPEC;
+	dat_protection |= pte.p;
+	if (write && dat_protection)
+		return PGM_PROTECTION;
+	rc = gmap_shadow_page(sg, saddr, pte.pfra * 4096, write);
+	if (rc)
+		return rc;
+	return 0;
+}
diff --git a/arch/s390/kvm/gaccess.h b/arch/s390/kvm/gaccess.h
index df0a79d..e5ec473 100644
--- a/arch/s390/kvm/gaccess.h
+++ b/arch/s390/kvm/gaccess.h
@@ -361,4 +361,6 @@ void ipte_unlock(struct kvm_vcpu *vcpu);
 int ipte_lock_held(struct kvm_vcpu *vcpu);
 int kvm_s390_check_low_addr_prot_real(struct kvm_vcpu *vcpu, unsigned long gra);
 
+int kvm_s390_shadow_fault(struct gmap *shadow, unsigned long saddr, int write);
+
 #endif /* __KVM_S390_GACCESS_H */
-- 
2.5.5

  parent reply	other threads:[~2016-06-21 13:12 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-21 13:12 [GIT PULL 00/51] KVM: s390: vSIE (nested virtualization) feature for 4.8 (kvm/next) Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 01/51] s390/kvm: page table invalidation notifier Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 02/51] s390/mm: use RCU for gmap notifier list and the per-mm gmap list Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 03/51] s390/mm: extended gmap pte notifier Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 04/51] s390/mm: add reference counter to gmap structure Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 05/51] s390/mm: add shadow gmap support Christian Borntraeger
2016-06-21 13:12 ` Christian Borntraeger [this message]
2016-06-21 13:12 ` [GIT PULL 07/51] s390/mm: flush tlb of shadows in all situations Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 08/51] s390/mm: shadow pages with real guest requested protection Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 09/51] s390/mm: avoid races on region/segment/page table shadowing Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 10/51] s390/mm: fix races on gmap_shadow creation Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 11/51] s390/mm: take the mmap_sem in kvm_s390_shadow_fault() Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 12/51] s390/mm: protection exceptions are corrrectly shadowed Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 13/51] s390/mm: take ipte_lock during shadow faults Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 14/51] s390/mm: push ste protection down to shadow pte Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 15/51] s390/mm: prepare for EDAT1/EDAT2 support in gmap shadow Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 16/51] s390/mm: support EDAT1 for gmap shadows Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 17/51] s390/mm: support EDAT2 " Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 18/51] s390/mm: push rte protection down to shadow pte Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 19/51] s390/mm: support real-space for gmap shadows Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 20/51] s390/mm: limit number of real-space " Christian Borntraeger
2016-06-21 13:12 ` [GIT PULL 21/51] s390/mm: remember the int code for the last gmap fault Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 22/51] s390/mm: allow to check if a gmap shadow is valid Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 23/51] s390/mm: don't fault everything in read-write in gmap_pte_op_fixup() Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 24/51] KVM: s390: fast path for shadow gmaps in gmap notifier Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 25/51] KVM: s390: backup the currently enabled gmap when scheduled out Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 26/51] s390: introduce page_to_virt() and pfn_to_virt() Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 27/51] mm/page_ref: introduce page_ref_inc_return Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 28/51] KVM: s390: vsie: initial support for nested virtualization Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 29/51] KVM: s390: vsie: optimize gmap prefix mapping Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 30/51] KVM: s390: vsie: support setting the ibc Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 31/51] KVM: s390: vsie: support edat1 / edat2 Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 32/51] KVM: s390: vsie: support host-protection-interruption Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 33/51] KVM: s390: vsie: support STFLE interpretation Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 34/51] KVM: s390: vsie: support aes dea wrapping keys Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 35/51] KVM: s390: vsie: support transactional execution Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 36/51] KVM: s390: vsie: support vectory facility (SIMD) Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 37/51] KVM: s390: vsie: support run-time-instrumentation Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 38/51] KVM: s390: vsie: support 64-bit-SCAO Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 39/51] KVM: s390: vsie: support shared IPTE-interlock facility Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 40/51] KVM: s390: vsie: support guest-PER-enhancement Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 41/51] KVM: s390: vsie: support guest-storage-limit-suppression Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 42/51] KVM: s390: vsie: support intervention-bypass Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 43/51] KVM: s390: vsie: support conditional-external-interception Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 44/51] KVM: s390: vsie: support IBS interpretation Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 45/51] KVM: s390: vsie: try to refault after a reported fault to g2 Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 46/51] KVM: s390: vsie: speed up VCPU irq delivery when handling vsie Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 47/51] KVM: s390: don't use CPUSTAT_WAIT to detect if a VCPU is idle Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 48/51] KVM: s390: vsie: speed up VCPU external calls Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 49/51] KVM: s390: vsie: correctly set and handle guest TOD Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 50/51] KVM: s390: vsie: add indication for future features Christian Borntraeger
2016-06-21 13:13 ` [GIT PULL 51/51] KVM: s390: vsie: add module parameter "nested" Christian Borntraeger
2016-06-21 13:22 ` [GIT PULL 00/51] KVM: s390: vSIE (nested virtualization) feature for 4.8 (kvm/next) Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1466514809-146638-7-git-send-email-borntraeger@de.ibm.com \
    --to=borntraeger@de.ibm.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=dahi@linux.vnet.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=schwidefsky@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).