All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Xingang Wang <wangxingang5@huawei.com>,
	Richard Henderson <richard.henderson@linaro.org>,
	Igor Mammedov <imammedo@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Eduardo Habkost <ehabkost@redhat.com>
Subject: [PULL 20/23] hw/i386/acpi-build: Add DMAR support to bypass iommu
Date: Tue, 13 Jul 2021 18:11:10 -0400	[thread overview]
Message-ID: <20210713220946.212562-21-mst@redhat.com> (raw)
In-Reply-To: <20210713220946.212562-1-mst@redhat.com>

From: Xingang Wang <wangxingang5@huawei.com>

In DMAR table, the drhd is set to cover all PCI devices when intel_iommu
is on. To support bypass iommu feature, we need to walk the PCI bus with
bypass_iommu disabled and add explicit scope data in DMAR drhd structure.

/mnt/sdb/wxg/qemu-next/qemu/build/x86_64-softmmu/qemu-system-x86_64 \
 -machine q35,accel=kvm,default_bus_bypass_iommu=true \
 -cpu host \
 -m 16G \
 -smp 36,sockets=2,cores=18,threads=1 \
 -device pxb-pcie,bus_nr=0x10,id=pci.10,bus=pcie.0,addr=0x3 \
 -device pxb-pcie,bus_nr=0x20,id=pci.20,bus=pcie.0,addr=0x4,bypass_iommu=true \
 -device pcie-root-port,port=0x1,chassis=1,id=pci.11,bus=pci.10,addr=0x0 \
 -device pcie-root-port,port=0x2,chassis=2,id=pci.21,bus=pci.20,addr=0x0 \
 -device virtio-scsi-pci,id=scsi0,bus=pci.11,addr=0x0 \
 -device virtio-scsi-pci,id=scsi1,bus=pci.21,addr=0x0 \
 -drive file=/mnt/sdb/wxg/fedora-48g.qcow2,format=qcow2,if=none,id=drive-scsi0-0-0-0,cache=none,aio=native \
 -device scsi-hd,bus=scsi1.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,id=scsi0-0-0-0,bootindex=1 \
 -device intel-iommu \
 -nographic \

And we get the guest configuration:

~ lspci -vt
-+-[0000:20]---00.0-[21]----00.0  Red Hat, Inc. Virtio SCSI
 +-[0000:10]---00.0-[11]----00.0  Red Hat, Inc. Virtio SCSI
 \-[0000:00]-+-00.0  Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller
             +-01.0  Device 1234:1111
             +-02.0  Intel Corporation 82574L Gigabit Network Connection
             +-03.0  Red Hat, Inc. QEMU PCIe Expander bridge
             +-04.0  Red Hat, Inc. QEMU PCIe Expander bridge
             +-1f.0  Intel Corporation 82801IB (ICH9) LPC Interface Controller
             +-1f.2  Intel Corporation 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode]
             \-1f.3  Intel Corporation 82801I (ICH9 Family) SMBus Controller

With bypass_iommu enabled on root bus, the attached devices will bypass iommu:

/sys/class/iommu/dmar0
├── devices
│   ├── 0000:10:00.0 -> ../../../../pci0000:10/0000:10:00.0
│   └── 0000:11:00.0 -> ../../../../pci0000:10/0000:10:00.0/0000:11:00.0

Signed-off-by: Xingang Wang <wangxingang5@huawei.com>
Message-Id: <1625748919-52456-8-git-send-email-wangxingang5@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/acpi-build.c | 68 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bc966a4110..7efc6285ac 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2022,6 +2022,56 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
                  x86ms->oem_table_id);
 }
 
+/*
+ * Insert DMAR scope for PCI bridges and endpoint devcie
+ */
+static void
+insert_scope(PCIBus *bus, PCIDevice *dev, void *opaque)
+{
+    GArray *scope_blob = opaque;
+    AcpiDmarDeviceScope *scope = NULL;
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
+        /* Dmar Scope Type: 0x02 for PCI Bridge */
+        build_append_int_noprefix(scope_blob, 0x02, 1);
+    } else {
+        /* Dmar Scope Type: 0x01 for PCI Endpoint Device */
+        build_append_int_noprefix(scope_blob, 0x01, 1);
+    }
+
+    /* length */
+    build_append_int_noprefix(scope_blob,
+                              sizeof(*scope) + sizeof(scope->path[0]), 1);
+    /* reserved */
+    build_append_int_noprefix(scope_blob, 0, 2);
+    /* enumeration_id */
+    build_append_int_noprefix(scope_blob, 0, 1);
+    /* bus */
+    build_append_int_noprefix(scope_blob, pci_bus_num(bus), 1);
+    /* device */
+    build_append_int_noprefix(scope_blob, PCI_SLOT(dev->devfn), 1);
+    /* function */
+    build_append_int_noprefix(scope_blob, PCI_FUNC(dev->devfn), 1);
+}
+
+/* For a given PCI host bridge, walk and insert DMAR scope */
+static int
+dmar_host_bridges(Object *obj, void *opaque)
+{
+    GArray *scope_blob = opaque;
+
+    if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) {
+        PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus;
+
+        if (bus && !pci_bus_bypass_iommu(bus)) {
+            pci_for_each_device(bus, pci_bus_num(bus), insert_scope,
+                                scope_blob);
+        }
+    }
+
+    return 0;
+}
+
 /*
  * VT-d spec 8.1 DMA Remapping Reporting Structure
  * (version Oct. 2014 or later)
@@ -2041,6 +2091,15 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id,
     /* Root complex IOAPIC use one path[0] only */
     size_t ioapic_scope_size = sizeof(*scope) + sizeof(scope->path[0]);
     IntelIOMMUState *intel_iommu = INTEL_IOMMU_DEVICE(iommu);
+    GArray *scope_blob = g_array_new(false, true, 1);
+
+    /*
+     * A PCI bus walk, for each PCI host bridge.
+     * Insert scope for each PCI bridge and endpoint device which
+     * is attached to a bus with iommu enabled.
+     */
+    object_child_foreach_recursive(object_get_root(),
+                                   dmar_host_bridges, scope_blob);
 
     assert(iommu);
     if (x86_iommu_ir_supported(iommu)) {
@@ -2054,8 +2113,9 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id,
     /* DMAR Remapping Hardware Unit Definition structure */
     drhd = acpi_data_push(table_data, sizeof(*drhd) + ioapic_scope_size);
     drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
-    drhd->length = cpu_to_le16(sizeof(*drhd) + ioapic_scope_size);
-    drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
+    drhd->length =
+        cpu_to_le16(sizeof(*drhd) + ioapic_scope_size + scope_blob->len);
+    drhd->flags = 0;            /* Don't include all pci device */
     drhd->pci_segment = cpu_to_le16(0);
     drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
 
@@ -2069,6 +2129,10 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id,
     scope->path[0].device = PCI_SLOT(Q35_PSEUDO_DEVFN_IOAPIC);
     scope->path[0].function = PCI_FUNC(Q35_PSEUDO_DEVFN_IOAPIC);
 
+    /* Add scope found above */
+    g_array_append_vals(table_data, scope_blob->data, scope_blob->len);
+    g_array_free(scope_blob, true);
+
     if (iommu->dt_supported) {
         atsr = acpi_data_push(table_data, sizeof(*atsr));
         atsr->type = cpu_to_le16(ACPI_DMAR_TYPE_ATSR);
-- 
MST



  parent reply	other threads:[~2021-07-13 22:18 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-13 22:10 [PULL 00/23] pc,pci,virtio: lots of new features Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 01/23] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35 Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 02/23] hw/acpi/ich9: Enable ACPI PCI hot-plug Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 03/23] hw/pci/pcie: Do not set HPC flag if acpihp is used Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 04/23] bios-tables-test: Allow changes in DSDT ACPI tables Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 05/23] hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35 Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 06/23] bios-tables-test: Update golden binaries Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 07/23] vhost-user-rng: Add vhost-user-rng implementation Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 08/23] vhost-user-rng-pci: Add vhost-user-rng-pci implementation Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 09/23] vhost-user-rng: backend: Add RNG vhost-user daemon implementation Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 10/23] docs: Add documentation for vhost based RNG implementation Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 11/23] hw/virtio: add boilerplate for vhost-user-i2c device Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 12/23] hw/virtio: add vhost-user-i2c-pci boilerplate Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 13/23] docs: Add '-device intel-iommu' entry Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 14/23] hw/pci/pci_host: Allow PCI host to bypass iommu Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 15/23] hw/pxb: Add a bypass iommu property Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 16/23] hw/arm/virt: Add default_bus_bypass_iommu machine option Michael S. Tsirkin
2021-07-13 22:10 ` [PULL 17/23] hw/i386: Add a default_bus_bypass_iommu pc " Michael S. Tsirkin
2021-07-13 22:11 ` [PULL 18/23] hw/pci: Add pci_bus_range() to get PCI bus number range Michael S. Tsirkin
2021-07-13 22:11 ` [PULL 19/23] hw/arm/virt-acpi-build: Add IORT support to bypass SMMUv3 Michael S. Tsirkin
2021-07-13 22:11 ` Michael S. Tsirkin [this message]
2021-07-13 22:11 ` [PULL 21/23] hw/i386/acpi-build: Add IVRS support to bypass iommu Michael S. Tsirkin
2021-07-13 22:11 ` [PULL 22/23] docs: Add documentation for iommu bypass Michael S. Tsirkin
2021-07-13 22:11 ` [PULL 23/23] vhost-vsock: SOCK_SEQPACKET feature bit support Michael S. Tsirkin
2021-07-14 20:31 ` [PULL 00/23] pc,pci,virtio: lots of new features Peter Maydell
2021-07-15  8:54   ` Marcel Apfelbaum
2021-07-15 14:38     ` Michael S. Tsirkin
2021-07-15 21:21   ` Michael S. Tsirkin
2021-07-16  6:41     ` Peter Maydell
2021-07-16  8:41       ` Michael S. Tsirkin
2021-07-16 14:12         ` Peter Maydell
2021-07-16 15:09           ` Michael S. Tsirkin
2021-07-16 15:13           ` Michael S. Tsirkin

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=20210713220946.212562-21-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=wangxingang5@huawei.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.