All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Rosato <mjrosato@linux.ibm.com>
To: linux-s390@vger.kernel.org
Cc: alex.williamson@redhat.com, cohuck@redhat.com,
	schnelle@linux.ibm.com, farman@linux.ibm.com,
	pmorel@linux.ibm.com, borntraeger@linux.ibm.com,
	hca@linux.ibm.com, gor@linux.ibm.com,
	gerald.schaefer@linux.ibm.com, agordeev@linux.ibm.com,
	frankja@linux.ibm.com, david@redhat.com, imbrenda@linux.ibm.com,
	vneethv@linux.ibm.com, oberpar@linux.ibm.com,
	freude@linux.ibm.com, thuth@redhat.com, pasic@linux.ibm.com,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 23/32] KVM: s390: pci: handle refresh of PCI translations
Date: Tue,  7 Dec 2021 15:57:34 -0500	[thread overview]
Message-ID: <20211207205743.150299-24-mjrosato@linux.ibm.com> (raw)
In-Reply-To: <20211207205743.150299-1-mjrosato@linux.ibm.com>

Add a routine that will perform a shadow operation between a guest
and host IOAT.  A subsequent patch will invoke this in response to
an 04 RPCIT instruction intercept.

Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
---
 arch/s390/include/asm/kvm_pci.h |   1 +
 arch/s390/include/asm/pci_dma.h |   1 +
 arch/s390/kvm/pci.c             | 191 ++++++++++++++++++++++++++++++++
 arch/s390/kvm/pci.h             |   4 +-
 4 files changed, 196 insertions(+), 1 deletion(-)

diff --git a/arch/s390/include/asm/kvm_pci.h b/arch/s390/include/asm/kvm_pci.h
index 254275399f21..97e3a369135d 100644
--- a/arch/s390/include/asm/kvm_pci.h
+++ b/arch/s390/include/asm/kvm_pci.h
@@ -30,6 +30,7 @@ struct kvm_zdev_ioat {
 struct kvm_zdev {
 	struct zpci_dev *zdev;
 	struct kvm *kvm;
+	u64 rpcit_count;
 	struct kvm_zdev_ioat ioat;
 	struct zpci_fib fib;
 };
diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h
index e1d3c1d3fc8a..0ca15e5db3d9 100644
--- a/arch/s390/include/asm/pci_dma.h
+++ b/arch/s390/include/asm/pci_dma.h
@@ -52,6 +52,7 @@ enum zpci_ioat_dtype {
 #define ZPCI_TABLE_ENTRIES		(ZPCI_TABLE_SIZE / ZPCI_TABLE_ENTRY_SIZE)
 #define ZPCI_TABLE_PAGES		(ZPCI_TABLE_SIZE >> PAGE_SHIFT)
 #define ZPCI_TABLE_ENTRIES_PAGES	(ZPCI_TABLE_ENTRIES * ZPCI_TABLE_PAGES)
+#define ZPCI_TABLE_ENTRIES_PER_PAGE	(ZPCI_TABLE_ENTRIES / ZPCI_TABLE_PAGES)
 
 #define ZPCI_TABLE_BITS			11
 #define ZPCI_PT_BITS			8
diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c
index a1c0c0881332..858c5ecdc8b9 100644
--- a/arch/s390/kvm/pci.c
+++ b/arch/s390/kvm/pci.c
@@ -123,6 +123,195 @@ int kvm_s390_pci_aen_init(u8 nisc)
 	return rc;
 }
 
+static int dma_shadow_cpu_trans(struct kvm_vcpu *vcpu, unsigned long *entry,
+				unsigned long *gentry)
+{
+	unsigned long idx;
+	struct page *page;
+	void *gaddr = NULL;
+	kvm_pfn_t pfn;
+	gpa_t addr;
+	int rc = 0;
+
+	if (pt_entry_isvalid(*gentry)) {
+		/* pin and validate */
+		addr = *gentry & ZPCI_PTE_ADDR_MASK;
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		page = gfn_to_page(vcpu->kvm, gpa_to_gfn(addr));
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+		if (is_error_page(page))
+			return -EIO;
+		gaddr = page_to_virt(page) + (addr & ~PAGE_MASK);
+	}
+
+	if (pt_entry_isvalid(*entry)) {
+		/* Either we are invalidating, replacing or no-op */
+		if (gaddr) {
+			if ((*entry & ZPCI_PTE_ADDR_MASK) ==
+			    (unsigned long)gaddr) {
+				/* Duplicate */
+				kvm_release_pfn_dirty(*entry >> PAGE_SHIFT);
+			} else {
+				/* Replace */
+				pfn = (*entry >> PAGE_SHIFT);
+				invalidate_pt_entry(entry);
+				set_pt_pfaa(entry, gaddr);
+				validate_pt_entry(entry);
+				kvm_release_pfn_dirty(pfn);
+				rc = 1;
+			}
+		} else {
+			/* Invalidate */
+			pfn = (*entry >> PAGE_SHIFT);
+			invalidate_pt_entry(entry);
+			kvm_release_pfn_dirty(pfn);
+			rc = 1;
+		}
+	} else if (gaddr) {
+		/* New Entry */
+		set_pt_pfaa(entry, gaddr);
+		validate_pt_entry(entry);
+	}
+
+	return rc;
+}
+
+unsigned long *dma_walk_guest_cpu_trans(struct kvm_vcpu *vcpu,
+					struct kvm_zdev_ioat *ioat,
+					dma_addr_t dma_addr)
+{
+	unsigned long *rto, *sto, *pto;
+	unsigned int rtx, rts, sx, px, idx;
+	struct page *page;
+	gpa_t addr;
+	int i;
+
+	/* Pin guest segment table if needed */
+	rtx = calc_rtx(dma_addr);
+	rto = ioat->head[(rtx / ZPCI_TABLE_ENTRIES_PER_PAGE)];
+	rts = rtx * ZPCI_TABLE_PAGES;
+	if (!ioat->seg[rts]) {
+		if (!reg_entry_isvalid(rto[rtx % ZPCI_TABLE_ENTRIES_PER_PAGE]))
+			return NULL;
+		sto = get_rt_sto(rto[rtx % ZPCI_TABLE_ENTRIES_PER_PAGE]);
+		addr = ((u64)sto & ZPCI_RTE_ADDR_MASK);
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		for (i = 0; i < ZPCI_TABLE_PAGES; i++) {
+			page = gfn_to_page(vcpu->kvm, gpa_to_gfn(addr));
+			if (is_error_page(page)) {
+				srcu_read_unlock(&vcpu->kvm->srcu, idx);
+				return NULL;
+			}
+			ioat->seg[rts + i] = page_to_virt(page) +
+					     (addr & ~PAGE_MASK);
+			addr += PAGE_SIZE;
+		}
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+	}
+
+	/* Allocate pin pointers for another segment table if needed */
+	if (!ioat->pt[rtx]) {
+		ioat->pt[rtx] = kcalloc(ZPCI_TABLE_ENTRIES,
+					(sizeof(unsigned long *)), GFP_KERNEL);
+		if (!ioat->pt[rtx])
+			return NULL;
+	}
+	/* Pin guest page table if needed */
+	sx = calc_sx(dma_addr);
+	sto = ioat->seg[(rts + (sx / ZPCI_TABLE_ENTRIES_PER_PAGE))];
+	if (!ioat->pt[rtx][sx]) {
+		if (!reg_entry_isvalid(sto[sx % ZPCI_TABLE_ENTRIES_PER_PAGE]))
+			return NULL;
+		pto = get_st_pto(sto[sx % ZPCI_TABLE_ENTRIES_PER_PAGE]);
+		if (!pto)
+			return NULL;
+		addr = ((u64)pto & ZPCI_STE_ADDR_MASK);
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		page = gfn_to_page(vcpu->kvm, gpa_to_gfn(addr));
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+		if (is_error_page(page))
+			return NULL;
+		ioat->pt[rtx][sx] = page_to_virt(page) + (addr & ~PAGE_MASK);
+	}
+	pto = ioat->pt[rtx][sx];
+
+	/* Return guest PTE */
+	px = calc_px(dma_addr);
+	return &pto[px];
+}
+
+
+static int dma_table_shadow(struct kvm_vcpu *vcpu, struct zpci_dev *zdev,
+			    dma_addr_t dma_addr, size_t size)
+{
+	unsigned int nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+	struct kvm_zdev *kzdev = zdev->kzdev;
+	unsigned long *entry, *gentry;
+	int i, rc = 0, rc2;
+
+	if (!nr_pages || !kzdev)
+		return -EINVAL;
+
+	mutex_lock(&kzdev->ioat.lock);
+	if (!zdev->dma_table || !kzdev->ioat.head[0]) {
+		rc = -EINVAL;
+		goto out_unlock;
+	}
+
+	for (i = 0; i < nr_pages; i++) {
+		gentry = dma_walk_guest_cpu_trans(vcpu, &kzdev->ioat, dma_addr);
+		if (!gentry)
+			continue;
+		entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+
+		if (!entry) {
+			rc = -ENOMEM;
+			goto out_unlock;
+		}
+
+		rc2 = dma_shadow_cpu_trans(vcpu, entry, gentry);
+		if (rc2 < 0) {
+			rc = -EIO;
+			goto out_unlock;
+		}
+		dma_addr += PAGE_SIZE;
+		rc += rc2;
+	}
+
+out_unlock:
+	mutex_unlock(&kzdev->ioat.lock);
+	return rc;
+}
+
+int kvm_s390_pci_refresh_trans(struct kvm_vcpu *vcpu, unsigned long req,
+			       unsigned long start, unsigned long size)
+{
+	struct zpci_dev *zdev;
+	u32 fh;
+	int rc;
+
+	/* If the device has a SHM bit on, let userspace take care of this */
+	fh = req >> 32;
+	if ((fh & aift.mdd) != 0)
+		return -EOPNOTSUPP;
+
+	/* Make sure this is a valid device associated with this guest */
+	zdev = get_zdev_by_fh(fh);
+	if (!zdev || !zdev->kzdev || zdev->kzdev->kvm != vcpu->kvm)
+		return -EINVAL;
+
+	/* Only proceed if the device is using the assist */
+	if (zdev->kzdev->ioat.head[0] == 0)
+		return -EOPNOTSUPP;
+
+	rc = dma_table_shadow(vcpu, zdev, start, size);
+	if (rc > 0)
+		rc = zpci_refresh_trans((u64) zdev->fh << 32, start, size);
+	zdev->kzdev->rpcit_count++;
+
+	return rc;
+}
+
 /* Modify PCI: Register floating adapter interruption forwarding */
 static int kvm_zpci_set_airq(struct zpci_dev *zdev)
 {
@@ -590,4 +779,6 @@ void kvm_s390_pci_init(void)
 {
 	spin_lock_init(&aift.gait_lock);
 	mutex_init(&aift.lock);
+
+	WARN_ON(zpci_get_mdd(&aift.mdd));
 }
diff --git a/arch/s390/kvm/pci.h b/arch/s390/kvm/pci.h
index 3c86888fe1b3..d252a631b693 100644
--- a/arch/s390/kvm/pci.h
+++ b/arch/s390/kvm/pci.h
@@ -33,6 +33,7 @@ struct zpci_aift {
 	struct kvm_zdev **kzdev;
 	spinlock_t gait_lock; /* Protects the gait, used during AEN forward */
 	struct mutex lock; /* Protects the other structures in aift */
+	u32 mdd;
 };
 
 static inline struct kvm *kvm_s390_pci_si_to_kvm(struct zpci_aift *aift,
@@ -47,7 +48,8 @@ struct zpci_aift *kvm_s390_pci_get_aift(void);
 
 int kvm_s390_pci_aen_init(u8 nisc);
 void kvm_s390_pci_aen_exit(void);
-
+int kvm_s390_pci_refresh_trans(struct kvm_vcpu *vcpu, unsigned long req,
+			       unsigned long start, unsigned long end);
 void kvm_s390_pci_init(void);
 
 #endif /* __KVM_S390_PCI_H */
-- 
2.27.0


  parent reply	other threads:[~2021-12-07 21:00 UTC|newest]

Thread overview: 122+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-07 20:57 [PATCH 00/32] KVM: s390: enable zPCI for interpretive execution Matthew Rosato
2021-12-07 20:57 ` [PATCH 01/32] s390/sclp: detect the zPCI interpretation facility Matthew Rosato
2021-12-08 11:12   ` Christian Borntraeger
2021-12-08 14:33     ` Eric Farman
2021-12-08 13:06   ` Claudio Imbrenda
2021-12-07 20:57 ` [PATCH 02/32] s390/sclp: detect the AISII facility Matthew Rosato
2021-12-08 11:13   ` Christian Borntraeger
2021-12-08 13:07   ` Claudio Imbrenda
2021-12-07 20:57 ` [PATCH 03/32] s390/sclp: detect the AENI facility Matthew Rosato
2021-12-08 11:17   ` Christian Borntraeger
2021-12-08 13:08   ` Claudio Imbrenda
2021-12-07 20:57 ` [PATCH 04/32] s390/sclp: detect the AISI facility Matthew Rosato
2021-12-08 11:18   ` Christian Borntraeger
2021-12-08 13:09   ` Claudio Imbrenda
2021-12-07 20:57 ` [PATCH 05/32] s390/airq: pass more TPI info to airq handlers Matthew Rosato
2021-12-08 11:25   ` Christian Borntraeger
2021-12-08 13:14   ` Claudio Imbrenda
2021-12-13 14:35   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 06/32] s390/airq: allow for airq structure that uses an input vector Matthew Rosato
2021-12-08 10:04   ` Thomas Huth
2021-12-08 12:59   ` Christian Borntraeger
2021-12-07 20:57 ` [PATCH 07/32] s390/pci: externalize the SIC operation controls and routine Matthew Rosato
2021-12-08 13:09   ` Christian Borntraeger
2021-12-08 13:53     ` Niklas Schnelle
2021-12-08 15:33       ` Matthew Rosato
2021-12-08 15:59         ` Niklas Schnelle
2021-12-08 16:20           ` Matthew Rosato
2021-12-08 16:41             ` Niklas Schnelle
2021-12-08 18:18               ` Niklas Schnelle
2021-12-07 20:57 ` [PATCH 08/32] s390/pci: stash associated GISA designation Matthew Rosato
2021-12-09 15:07   ` Christian Borntraeger
2021-12-10 19:01   ` Eric Farman
2021-12-13 14:59   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 09/32] s390/pci: export some routines related to RPCIT processing Matthew Rosato
2021-12-09 15:20   ` Christian Borntraeger
2021-12-07 20:57 ` [PATCH 10/32] s390/pci: stash dtsm and maxstbl Matthew Rosato
2021-12-08 16:18   ` Niklas Schnelle
2021-12-09  9:13   ` Pierre Morel
2021-12-09 15:25   ` Christian Borntraeger
2021-12-07 20:57 ` [PATCH 11/32] s390/pci: add helper function to find device by handle Matthew Rosato
2021-12-09 15:28   ` Christian Borntraeger
2021-12-10 19:04   ` Eric Farman
2021-12-07 20:57 ` [PATCH 12/32] s390/pci: get SHM information from list pci Matthew Rosato
2021-12-08 12:21   ` Niklas Schnelle
2021-12-09 18:25     ` Matthew Rosato
2021-12-09 15:47   ` Christian Borntraeger
2021-12-10  8:45     ` Niklas Schnelle
2021-12-07 20:57 ` [PATCH 13/32] KVM: s390: pci: add basic kvm_zdev structure Matthew Rosato
2021-12-09 15:54   ` Christian Borntraeger
2021-12-10 19:04   ` Eric Farman
2021-12-13 15:19   ` Pierre Morel
2021-12-14  9:15   ` Pierre Morel
2021-12-17 20:26   ` Matthew Rosato
2021-12-20 17:26     ` Pierre Morel
2021-12-07 20:57 ` [PATCH 14/32] KVM: s390: pci: do initial setup for AEN interpretation Matthew Rosato
2021-12-08  7:53   ` kernel test robot
2021-12-08  7:53     ` kernel test robot
2021-12-09 19:54   ` Christian Borntraeger
2021-12-09 20:20     ` Matthew Rosato
2021-12-09 20:23       ` Christian Borntraeger
2021-12-10  8:36       ` Niklas Schnelle
2021-12-10  9:54   ` Pierre Morel
2021-12-10 10:55     ` Pierre Morel
2021-12-07 20:57 ` [PATCH 15/32] KVM: s390: pci: enable host forwarding of Adapter Event Notifications Matthew Rosato
2021-12-10 21:51   ` Eric Farman
2021-12-17 16:56   ` Christian Borntraeger
2021-12-17 17:42     ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 16/32] KVM: s390: expose the guest zPCI interpretation facility Matthew Rosato
2021-12-17 15:05   ` Christian Borntraeger
2021-12-17 15:19     ` Matthew Rosato
2021-12-17 16:58       ` Christian Borntraeger
2021-12-17 17:13         ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 17/32] KVM: s390: expose the guest Adapter Interruption Source ID facility Matthew Rosato
2021-12-17 15:06   ` Christian Borntraeger
2021-12-07 20:57 ` [PATCH 18/32] KVM: s390: expose guest Adapter Event Notification Interpretation facility Matthew Rosato
2021-12-07 20:57 ` [PATCH 19/32] KVM: s390: mechanism to enable guest zPCI Interpretation Matthew Rosato
2021-12-10 13:27   ` Christian Borntraeger
2021-12-10 14:21     ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 20/32] KVM: s390: pci: provide routines for enabling/disabling interpretation Matthew Rosato
2021-12-08  9:44   ` Niklas Schnelle
2021-12-08 15:04     ` Matthew Rosato
2021-12-14  9:16   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 21/32] KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding Matthew Rosato
2021-12-08 10:58   ` kernel test robot
2021-12-08 10:58     ` kernel test robot
2021-12-14  9:26   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 22/32] KVM: s390: pci: provide routines for enabling/disabling IOAT assist Matthew Rosato
2021-12-14 17:46   ` Pierre Morel
2021-12-14 18:13     ` Matthew Rosato
2021-12-07 20:57 ` Matthew Rosato [this message]
2021-12-08  8:04   ` [PATCH 23/32] KVM: s390: pci: handle refresh of PCI translations kernel test robot
2021-12-08  8:04     ` kernel test robot
2021-12-08 10:30   ` Niklas Schnelle
2021-12-08 18:04     ` Matthew Rosato
2021-12-14 16:59   ` Pierre Morel
2021-12-14 17:54     ` Matthew Rosato
2021-12-16 14:39       ` Niklas Schnelle
2021-12-16 14:51         ` Matthew Rosato
2021-12-17  9:41           ` Niklas Schnelle
2021-12-07 20:57 ` [PATCH 24/32] KVM: s390: intercept the rpcit instruction Matthew Rosato
2021-12-14 17:04   ` Pierre Morel
2021-12-14 18:00     ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 25/32] vfio/pci: re-introduce CONFIG_VFIO_PCI_ZDEV Matthew Rosato
2021-12-17 16:49   ` Christian Borntraeger
2021-12-17 17:54     ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 26/32] vfio-pci/zdev: wire up group notifier Matthew Rosato
2021-12-21 18:47   ` Alex Williamson
2021-12-07 20:57 ` [PATCH 27/32] vfio-pci/zdev: wire up zPCI interpretive execution support Matthew Rosato
2021-12-14 16:30   ` Pierre Morel
2021-12-21 18:48   ` Alex Williamson
2021-12-07 20:57 ` [PATCH 28/32] vfio-pci/zdev: wire up zPCI adapter interrupt forwarding support Matthew Rosato
2021-12-14  9:48   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 29/32] vfio-pci/zdev: wire up zPCI IOAT assist support Matthew Rosato
2021-12-14  9:46   ` Pierre Morel
2021-12-07 20:57 ` [PATCH 30/32] vfio-pci/zdev: add DTSM to clp group capability Matthew Rosato
2021-12-14  9:58   ` Pierre Morel
2021-12-14 14:59     ` Matthew Rosato
2021-12-07 20:57 ` [PATCH 31/32] KVM: s390: introduce CPU feature for zPCI Interpretation Matthew Rosato
2021-12-07 20:57 ` [PATCH 32/32] MAINTAINERS: additional files related kvm s390 pci passthrough Matthew Rosato
2021-12-17 14:55   ` Christian Borntraeger
2021-12-21 19:11     ` Alex Williamson
2021-12-07 21:16 ` [PATCH 00/32] KVM: s390: enable zPCI for interpretive execution Matthew Rosato

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=20211207205743.150299-24-mjrosato@linux.ibm.com \
    --to=mjrosato@linux.ibm.com \
    --cc=agordeev@linux.ibm.com \
    --cc=alex.williamson@redhat.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=cohuck@redhat.com \
    --cc=david@redhat.com \
    --cc=farman@linux.ibm.com \
    --cc=frankja@linux.ibm.com \
    --cc=freude@linux.ibm.com \
    --cc=gerald.schaefer@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=oberpar@linux.ibm.com \
    --cc=pasic@linux.ibm.com \
    --cc=pmorel@linux.ibm.com \
    --cc=schnelle@linux.ibm.com \
    --cc=thuth@redhat.com \
    --cc=vneethv@linux.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.