diff options
author | Igor Mammedov <imammedo@redhat.com> | 2021-09-24 08:27:45 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2021-10-05 17:30:57 -0400 |
commit | 91a6b9756970f70d933ea3c01fb5306ea6e5b331 (patch) | |
tree | 9619fea40834520697a827ec1ab84c28ed0c8496 /hw | |
parent | e5b6d55a6e5e13002cf79a42a0b78b3188e88a1f (diff) | |
download | qemu-91a6b9756970f70d933ea3c01fb5306ea6e5b331.zip qemu-91a6b9756970f70d933ea3c01fb5306ea6e5b331.tar.gz qemu-91a6b9756970f70d933ea3c01fb5306ea6e5b331.tar.bz2 |
acpi: build_dmar_q35: use acpi_table_begin()/acpi_table_end() instead of build_header()
it replaces error-prone pointer arithmetic for build_header() API,
with 2 calls to start and finish table creation,
which hides offsets magic from API user.
While at it switch to build_append_int_noprefix() to build
table entries tables.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <20210924122802.1455362-19-imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/i386/acpi-build.c | 87 |
1 files changed, 48 insertions, 39 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 078097a..c65ab1d 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2086,8 +2086,9 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) static void insert_scope(PCIBus *bus, PCIDevice *dev, void *opaque) { + const size_t device_scope_size = 6 /* device scope structure */ + + 2 /* 1 path entry */; GArray *scope_blob = opaque; - AcpiDmarDeviceScope *scope = NULL; if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) { /* Dmar Scope Type: 0x02 for PCI Bridge */ @@ -2098,8 +2099,7 @@ insert_scope(PCIBus *bus, PCIDevice *dev, void *opaque) } /* length */ - build_append_int_noprefix(scope_blob, - sizeof(*scope) + sizeof(scope->path[0]), 1); + build_append_int_noprefix(scope_blob, device_scope_size, 1); /* reserved */ build_append_int_noprefix(scope_blob, 0, 2); /* enumeration_id */ @@ -2131,26 +2131,26 @@ dmar_host_bridges(Object *obj, void *opaque) } /* - * VT-d spec 8.1 DMA Remapping Reporting Structure - * (version Oct. 2014 or later) + * Intel ® Virtualization Technology for Directed I/O + * Architecture Specification. Revision 3.3 + * 8.1 DMA Remapping Reporting Structure */ static void build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id, const char *oem_table_id) { - int dmar_start = table_data->len; - - AcpiTableDmar *dmar; - AcpiDmarHardwareUnit *drhd; - AcpiDmarRootPortATS *atsr; uint8_t dmar_flags = 0; + uint8_t rsvd10[10] = {}; + /* Root complex IOAPIC uses one path only */ + const size_t ioapic_scope_size = 6 /* device scope structure */ + + 2 /* 1 path entry */; X86IOMMUState *iommu = x86_iommu_get_default(); - AcpiDmarDeviceScope *scope = NULL; - /* 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); + AcpiTable table = { .sig = "DMAR", .rev = 1, .oem_id = oem_id, + .oem_table_id = oem_table_id }; + /* * A PCI bus walk, for each PCI host bridge. * Insert scope for each PCI bridge and endpoint device which @@ -2164,43 +2164,52 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id, dmar_flags |= 0x1; /* Flags: 0x1: INT_REMAP */ } - dmar = acpi_data_push(table_data, sizeof(*dmar)); - dmar->host_address_width = intel_iommu->aw_bits - 1; - dmar->flags = dmar_flags; - - /* 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 + 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); + acpi_table_begin(&table, table_data); + /* Host Address Width */ + build_append_int_noprefix(table_data, intel_iommu->aw_bits - 1, 1); + build_append_int_noprefix(table_data, dmar_flags, 1); /* Flags */ + g_array_append_vals(table_data, rsvd10, sizeof(rsvd10)); /* Reserved */ + + /* 8.3 DMAR Remapping Hardware Unit Definition structure */ + build_append_int_noprefix(table_data, 0, 2); /* Type */ + /* Length */ + build_append_int_noprefix(table_data, + 16 + ioapic_scope_size + scope_blob->len, 2); + /* Flags */ + build_append_int_noprefix(table_data, 0 /* Don't include all pci device */ , + 1); + build_append_int_noprefix(table_data, 0 , 1); /* Reserved */ + build_append_int_noprefix(table_data, 0 , 2); /* Segment Number */ + /* Register Base Address */ + build_append_int_noprefix(table_data, Q35_HOST_BRIDGE_IOMMU_ADDR , 8); /* Scope definition for the root-complex IOAPIC. See VT-d spec * 8.3.1 (version Oct. 2014 or later). */ - scope = &drhd->scope[0]; - scope->entry_type = 0x03; /* Type: 0x03 for IOAPIC */ - scope->length = ioapic_scope_size; - scope->enumeration_id = ACPI_BUILD_IOAPIC_ID; - scope->bus = Q35_PSEUDO_BUS_PLATFORM; - scope->path[0].device = PCI_SLOT(Q35_PSEUDO_DEVFN_IOAPIC); - scope->path[0].function = PCI_FUNC(Q35_PSEUDO_DEVFN_IOAPIC); + build_append_int_noprefix(table_data, 0x03 /* IOAPIC */, 1); /* Type */ + build_append_int_noprefix(table_data, ioapic_scope_size, 1); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + /* Enumeration ID */ + build_append_int_noprefix(table_data, ACPI_BUILD_IOAPIC_ID, 1); + /* Start Bus Number */ + build_append_int_noprefix(table_data, Q35_PSEUDO_BUS_PLATFORM, 1); + /* Path, {Device, Function} pair */ + build_append_int_noprefix(table_data, PCI_SLOT(Q35_PSEUDO_DEVFN_IOAPIC), 1); + build_append_int_noprefix(table_data, PCI_FUNC(Q35_PSEUDO_DEVFN_IOAPIC), 1); /* 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); - atsr->length = cpu_to_le16(sizeof(*atsr)); - atsr->flags = ACPI_DMAR_ATSR_ALL_PORTS; - atsr->pci_segment = cpu_to_le16(0); + /* 8.5 Root Port ATS Capability Reporting Structure */ + build_append_int_noprefix(table_data, 2, 2); /* Type */ + build_append_int_noprefix(table_data, 8, 2); /* Length */ + build_append_int_noprefix(table_data, 1 /* ALL_PORTS */, 1); /* Flags */ + build_append_int_noprefix(table_data, 0, 1); /* Reserved */ + build_append_int_noprefix(table_data, 0, 2); /* Segment Number */ } - build_header(linker, table_data, (void *)(table_data->data + dmar_start), - "DMAR", table_data->len - dmar_start, 1, oem_id, oem_table_id); + acpi_table_end(linker, &table); } /* |