On 24.01.25 21:21, Matthew Rosato wrote:
When receiving a guest mpcifc(4) or mpcifc(6) instruction without the T
bit set, treat this as a request to perform direct mapping instead of
address translation.  In order to facilitate this, pin the entirety of
guest memory into the host iommu.

Pinning for the direct mapping case is handled via vfio and its memory
listener.  Additionally, ram discard settings are inherited from vfio:
coordinated discards (e.g. virtio-mem) are allowed while uncoordinated
discards (e.g. virtio-balloon) are disabled.

Subsequent guest DMA operations are all expected to be of the format
guest_phys+sdma, allowing them to be used as lookup into the host
iommu table.

Signed-off-by: Matthew Rosato <mjros...@linux.ibm.com>
---
  hw/s390x/s390-pci-bus.c         | 36 +++++++++++++++++++++++++++++++--
  hw/s390x/s390-pci-inst.c        | 13 ++++++++++--
  hw/s390x/s390-pci-vfio.c        | 15 ++++++++++----
  hw/s390x/s390-virtio-ccw.c      |  5 +++++
  include/hw/s390x/s390-pci-bus.h |  4 ++++
  5 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index eead269cc2..8cf5aec1a2 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -18,6 +18,8 @@
  #include "hw/s390x/s390-pci-inst.h"
  #include "hw/s390x/s390-pci-kvm.h"
  #include "hw/s390x/s390-pci-vfio.h"
+#include "hw/s390x/s390-virtio-ccw.h"
+#include "hw/boards.h"
  #include "hw/pci/pci_bus.h"
  #include "hw/qdev-properties.h"
  #include "hw/pci/pci_bridge.h"
@@ -720,16 +722,44 @@ void s390_pci_iommu_enable(S390PCIIOMMU *iommu)
                               TYPE_S390_IOMMU_MEMORY_REGION, 
OBJECT(&iommu->mr),
                               name, iommu->pal + 1);
      iommu->enabled = true;
+    iommu->direct_map = false;
      memory_region_add_subregion(&iommu->mr, 0, 
MEMORY_REGION(&iommu->iommu_mr));
      g_free(name);
  }
+void s390_pci_iommu_dm_enable(S390PCIIOMMU *iommu)
+{
+    MachineState *ms = MACHINE(qdev_get_machine());
+    S390CcwMachineState *s390ms = S390_CCW_MACHINE(ms);
+
+    /*
+     * For direct-mapping we must map the entire guest address space.  Rather
+     * than using an iommu, create a memory region alias that maps GPA X to
+     * iova X + SDMA.  VFIO will handle pinning via its memory listener.
+     */
+    g_autofree char *name = g_strdup_printf("iommu-dm-s390-%04x",
+                                            iommu->pbdev->uid);
+    memory_region_init_alias(&iommu->dm_mr, OBJECT(&iommu->mr), name, ms->ram,
+                             0, s390_get_memory_limit(s390ms));

Hm, the memory limit can exceed  ms->ram.

Would it be possible to use get_system_memory() here, such that whatever is mapped into physical address space (including virtio-mem devices etc) would simply be aliased with an offset?

Or does that blow up elsewhere?

target/i386/kvm/kvm.c seems to do that:

memory_region_init_alias(&smram_as_mem, OBJECT(kvm_state), "mem-smram",
                         get_system_memory(), 0, ~0ull);

and target/i386/tcg/system/tcg-cpu.c

--
Cheers,

David / dhildenb


Reply via email to