From: Cornelia Huck <cohuck@redhat.com>
To: peter.maydell@linaro.org
Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org,
borntraeger@de.ibm.com, rth@twiddle.net, agraf@suse.de,
david@redhat.com, thuth@redhat.com,
Yi Min Zhao <zyimin@linux.vnet.ibm.com>,
Cornelia Huck <cohuck@redhat.com>
Subject: [Qemu-devel] [PULL 25/29] s390x/pci: fixup global refresh
Date: Fri, 9 Feb 2018 10:25:20 +0100 [thread overview]
Message-ID: <20180209092524.31348-26-cohuck@redhat.com> (raw)
In-Reply-To: <20180209092524.31348-1-cohuck@redhat.com>
From: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
The VFIO common code doesn't provide the possibility to modify a
previous mapping entry in another way than unmapping and mapping again
with new properties.
To avoid -EEXIST DMA mapping error, we introduce a GHashTable to store
S390IOTLBEntry instances in order to cache the mapped entries. When
intercepting rpcit instruction, ignore the identical mapped entries to
avoid doing map operations multiple times and do unmap and re-map
operations for the case of updating the valid entries.
Acked-by: Pierre Morel <pmorel@linux.vnet.ibm.com>
Signed-off-by: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Message-Id: <20180205072258.5968-3-zyimin@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
hw/s390x/s390-pci-bus.c | 24 +++++++++++++++-------
hw/s390x/s390-pci-bus.h | 1 +
hw/s390x/s390-pci-inst.c | 53 ++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 63 insertions(+), 15 deletions(-)
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index e7ef7d28d9..77a50cab36 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -487,7 +487,8 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
IOMMUAccessFlags flag)
{
S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr);
- S390IOTLBEntry entry;
+ S390IOTLBEntry *entry;
+ uint64_t iova = addr & PAGE_MASK;
uint16_t error = 0;
IOMMUTLBEntry ret = {
.target_as = &address_space_memory,
@@ -515,12 +516,17 @@ static IOMMUTLBEntry s390_translate_iommu(IOMMUMemoryRegion *mr, hwaddr addr,
goto err;
}
- error = s390_guest_io_table_walk(iommu->g_iota, addr, &entry);
-
- ret.iova = entry.iova;
- ret.translated_addr = entry.translated_addr;
- ret.addr_mask = entry.len - 1;
- ret.perm = entry.perm;
+ entry = g_hash_table_lookup(iommu->iotlb, &iova);
+ if (entry) {
+ ret.iova = entry->iova;
+ ret.translated_addr = entry->translated_addr;
+ ret.addr_mask = entry->len - 1;
+ ret.perm = entry->perm;
+ } else {
+ ret.iova = iova;
+ ret.addr_mask = ~PAGE_MASK;
+ ret.perm = IOMMU_NONE;
+ }
if (flag != IOMMU_NONE && !(flag & ret.perm)) {
error = ERR_EVENT_TPROTE;
@@ -572,6 +578,8 @@ static S390PCIIOMMU *s390_pci_get_iommu(S390pciState *s, PCIBus *bus,
PCI_FUNC(devfn));
memory_region_init(&iommu->mr, OBJECT(iommu), mr_name, UINT64_MAX);
address_space_init(&iommu->as, &iommu->mr, as_name);
+ iommu->iotlb = g_hash_table_new_full(g_int64_hash, g_int64_equal,
+ NULL, g_free);
table->iommu[PCI_SLOT(devfn)] = iommu;
g_free(mr_name);
@@ -661,6 +669,7 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
void s390_pci_iommu_disable(S390PCIIOMMU *iommu)
{
iommu->enabled = false;
+ g_hash_table_remove_all(iommu->iotlb);
memory_region_del_subregion(&iommu->mr, MEMORY_REGION(&iommu->iommu_mr));
object_unparent(OBJECT(&iommu->iommu_mr));
}
@@ -676,6 +685,7 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
}
table->iommu[PCI_SLOT(devfn)] = NULL;
+ g_hash_table_destroy(iommu->iotlb);
address_space_destroy(&iommu->as);
object_unparent(OBJECT(&iommu->mr));
object_unparent(OBJECT(iommu));
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 7ed577c806..1f7f9b5814 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -278,6 +278,7 @@ typedef struct S390PCIIOMMU {
uint64_t g_iota;
uint64_t pba;
uint64_t pal;
+ GHashTable *iotlb;
} S390PCIIOMMU;
typedef struct S390PCIIOMMUTable {
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 1d33a89351..997a9cc2e9 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -571,6 +571,45 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
return 0;
}
+static void s390_pci_update_iotlb(S390PCIIOMMU *iommu, S390IOTLBEntry *entry)
+{
+ S390IOTLBEntry *cache = g_hash_table_lookup(iommu->iotlb, &entry->iova);
+ IOMMUTLBEntry notify = {
+ .target_as = &address_space_memory,
+ .iova = entry->iova,
+ .translated_addr = entry->translated_addr,
+ .perm = entry->perm,
+ .addr_mask = ~PAGE_MASK,
+ };
+
+ if (entry->perm == IOMMU_NONE) {
+ if (!cache) {
+ return;
+ }
+ g_hash_table_remove(iommu->iotlb, &entry->iova);
+ } else {
+ if (cache) {
+ if (cache->perm == entry->perm &&
+ cache->translated_addr == entry->translated_addr) {
+ return;
+ }
+
+ notify.perm = IOMMU_NONE;
+ memory_region_notify_iommu(&iommu->iommu_mr, notify);
+ notify.perm = entry->perm;
+ }
+
+ cache = g_new(S390IOTLBEntry, 1);
+ cache->iova = entry->iova;
+ cache->translated_addr = entry->translated_addr;
+ cache->len = PAGE_SIZE;
+ cache->perm = entry->perm;
+ g_hash_table_replace(iommu->iotlb, &cache->iova, cache);
+ }
+
+ memory_region_notify_iommu(&iommu->iommu_mr, notify);
+}
+
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
{
CPUS390XState *env = &cpu->env;
@@ -580,7 +619,6 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
S390PCIIOMMU *iommu;
S390IOTLBEntry entry;
hwaddr start, end;
- IOMMUTLBEntry notify;
cpu_synchronize_state(CPU(cpu));
@@ -636,15 +674,14 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
if (error) {
break;
}
- notify.target_as = &address_space_memory;
- notify.iova = entry.iova;
- notify.translated_addr = entry.translated_addr;
- notify.addr_mask = entry.len - 1;
- notify.perm = entry.perm;
- memory_region_notify_iommu(&iommu->iommu_mr, notify);
+
start += entry.len;
+ while (entry.iova < start && entry.iova < end) {
+ s390_pci_update_iotlb(iommu, &entry);
+ entry.iova += PAGE_SIZE;
+ entry.translated_addr += PAGE_SIZE;
+ }
}
-
err:
if (error) {
pbdev->state = ZPCI_FS_ERROR;
--
2.13.6
next prev parent reply other threads:[~2018-02-09 9:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-09 9:24 [Qemu-devel] [PULL 00/29] s390x: assorted updates Cornelia Huck
2018-02-09 9:24 ` [Qemu-devel] [PULL 01/29] Fix configure for s390 qemu on alpine and other busybox environments Cornelia Huck
2018-02-09 9:24 ` [Qemu-devel] [PULL 02/29] s390x/tcg: deliver multiple interrupts in a row Cornelia Huck
2018-02-09 9:24 ` [Qemu-devel] [PULL 03/29] s390x/flic: simplify flic initialization Cornelia Huck
2018-02-09 9:24 ` [Qemu-devel] [PULL 04/29] s390x/tcg: simplify lookup of flic Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 05/29] s390x/tcg: simplify machine check handling Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 06/29] s390x/flic: factor out injection of floating interrupts Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 07/29] s390x/flic: no need to call s390_io_interrupt() from flic Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 08/29] s390x/tcg: tolerate wrong wakeups due to floating interrupts Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 09/29] s390x/flic: make floating interrupts on TCG actually floating Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 10/29] s390x/tcg: implement TEST PENDING INTERRUPTION Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 11/29] s390x/flic: implement qemu_s390_clear_io_flic() Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 12/29] s390x/flic: optimize CPU wakeup for TCG Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 13/29] s390x: fix size + content of STSI blocks Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 14/29] s390x/tcg: STSI overhaul Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 15/29] s390x/tcg: remove SMP warning Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 16/29] configure: s390x supports mttcg now Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 17/29] s390x/tcg: cache the qemu flic in a central function Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 18/29] s390x/kvm: cache the kvm " Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 19/29] s390x/flic: cache the common flic class " Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 20/29] s390x/sclp: fix event mask handling Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 21/29] s390x/tcg: wire up pci instructions Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 22/29] s390x/cpumodel: allow zpci features in qemu model Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 23/29] s390x/cpumodel: model PTFF subfunctions for Multiple-epoch facility Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 24/29] s390x/pci: fixup the code walking IOMMU tables Cornelia Huck
2018-02-09 9:25 ` Cornelia Huck [this message]
2018-02-09 9:25 ` [Qemu-devel] [PULL 26/29] s390x/pci: use the right pal and pba in reg_ioat() Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 27/29] MAINTAINERS: add myself as overall s390x maintainer Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 28/29] MAINTAINERS: reorganize s390-ccw bios maintainership Cornelia Huck
2018-02-09 9:25 ` [Qemu-devel] [PULL 29/29] MAINTAINERS: add David as additional tcg/s390 maintainer Cornelia Huck
2018-02-09 9:59 ` [Qemu-devel] [PULL 00/29] s390x: assorted updates no-reply
2018-02-09 13:27 ` Peter Maydell
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=20180209092524.31348-26-cohuck@redhat.com \
--to=cohuck@redhat.com \
--cc=agraf@suse.de \
--cc=borntraeger@de.ibm.com \
--cc=david@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=rth@twiddle.net \
--cc=thuth@redhat.com \
--cc=zyimin@linux.vnet.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).