[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v8 04/25] acpi: add DMAR scope definition for ro
From: |
Igor Mammedov |
Subject: |
Re: [Qemu-devel] [PATCH v8 04/25] acpi: add DMAR scope definition for root IOAPIC |
Date: |
Wed, 1 Jun 2016 14:56:38 +0200 |
On Mon, 30 May 2016 18:31:17 +0800
Peter Xu <address@hidden> wrote:
> To enable interrupt remapping for intel IOMMU device, each IOAPIC device
> in the system reported via ACPI MADT must be explicitly enumerated under
> one specific remapping hardware unit. This patch adds the root-complex
> IOAPIC into the default DMAR device.
>
> Please refer to VT-d spec 8.3.1.1 for more information.
>
> Signed-off-by: Peter Xu <address@hidden>
> ---
> hw/i386/acpi-build.c | 17 +++++++++++++++--
> include/hw/acpi/acpi-defs.h | 15 +++++++++++++++
> include/hw/pci-host/q35.h | 9 +++++++++
> 3 files changed, 39 insertions(+), 2 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index ddc6f16..6c572a3 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -77,6 +77,9 @@
> #define ACPI_BUILD_DPRINTF(fmt, ...)
> #endif
>
> +/* Default IOAPIC ID */
> +#define ACPI_BUILD_IOAPIC_ID 0x0
> +
> typedef struct AcpiMcfgInfo {
> uint64_t mcfg_base;
> uint32_t mcfg_size;
> @@ -375,7 +378,6 @@ build_madt(GArray *table_data, GArray *linker,
> PCMachineState *pcms)
> io_apic = acpi_data_push(table_data, sizeof *io_apic);
> io_apic->type = ACPI_APIC_IO;
> io_apic->length = sizeof(*io_apic);
> -#define ACPI_BUILD_IOAPIC_ID 0x0
> io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;
> io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);
> io_apic->interrupt = cpu_to_le32(0);
> @@ -2561,6 +2563,9 @@ build_dmar_q35(MachineState *ms, GArray *table_data,
> GArray *linker)
> AcpiTableDmar *dmar;
> AcpiDmarHardwareUnit *drhd;
> uint8_t dmar_flags = 0;
> + AcpiDmarDeviceScope *scope = NULL;
> + /* Root complex IOAPIC use one path[0] only */
> + uint16_t scope_size = sizeof(*scope) + sizeof(uint16_t);
ioapic_scope_size
sizeof(scope->path[0]) /* space for IOxAPIC path */
> if (ms->iommu_intr) {
> /* enable INTR for the IOMMU device */
> @@ -2574,11 +2579,19 @@ build_dmar_q35(MachineState *ms, GArray *table_data,
> GArray *linker)
> /* DMAR Remapping Hardware Unit Definition structure */
> drhd = acpi_data_push(table_data, sizeof(*drhd));
sizeof(*drhd) + ioapic_scope_size
> drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
> - drhd->length = cpu_to_le16(sizeof(*drhd)); /* No device scope now */
> + drhd->length = cpu_to_le16(sizeof(*drhd) + scope_size);
> drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
> drhd->pci_segment = cpu_to_le16(0);
> drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);
>
> + /* Scope definition for the root-complex IOAPIC */
> + scope = acpi_data_push(table_data, scope_size);
no need for this as previous push took care about all space we need for scope
ioapic_scope = &drhd->scope[0];
> + scope->entry_type = cpu_to_le16(ACPI_DMAR_DEV_SCOPE_TYPE_IOAPIC);
entry_type is 1 byte long, doing cpu_to_le16 on bigendian host
will always result in 0 being written there
> + scope->length = scope_size;
> + scope->enumeration_id = cpu_to_le16(ACPI_BUILD_IOAPIC_ID);
> + scope->bus = cpu_to_le16(Q35_PSEUDO_BUS_PLATFORM);
ditto for above 2 fields
> + scope->path[0] = cpu_to_le16(Q35_PSEUDO_DEVFN_IOAPIC);
> +
> build_header(linker, table_data, (void *)(table_data->data + dmar_start),
> "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
> }
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index 850a962..b46e472 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -569,6 +569,20 @@ enum {
> /*
> * Sub-structures for DMAR
> */
> +
> +#define ACPI_DMAR_DEV_SCOPE_TYPE_IOAPIC (0x03)
> +
> +/* Device scope structure for DRHD. */
> +struct AcpiDmarDeviceScope {
> + uint8_t entry_type;
> + uint8_t length;
> + uint16_t reserved;
> + uint8_t enumeration_id;
> + uint8_t bus;
> + uint16_t path[0]; /* list of dev:func pairs */
> +} QEMU_PACKED;
> +typedef struct AcpiDmarDeviceScope AcpiDmarDeviceScope;
> +
> /* Type 0: Hardware Unit Definition */
> struct AcpiDmarHardwareUnit {
> uint16_t type;
> @@ -577,6 +591,7 @@ struct AcpiDmarHardwareUnit {
> uint8_t reserved;
> uint16_t pci_segment; /* The PCI Segment associated with this unit */
> uint64_t address; /* Base address of remapping hardware register-set */
> + AcpiDmarDeviceScope scope[0];
> } QEMU_PACKED;
> typedef struct AcpiDmarHardwareUnit AcpiDmarHardwareUnit;
>
> diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
> index c5c073d..9afc221 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -175,4 +175,13 @@ typedef struct Q35PCIHost {
>
> uint64_t mch_mcfg_base(void);
>
> +/*
> + * Arbitary but unique BNF number for IOAPIC device. This is only
> + * used when interrupt remapping is enabled.
you encode it in DMAR unconditionally so not "only"
> + *
> + * TODO: make sure there would have no conflict with real PCI bus
> + */
> +#define Q35_PSEUDO_BUS_PLATFORM (0xff)
> +#define Q35_PSEUDO_DEVFN_IOAPIC (0x00)
> +
> #endif /* HW_Q35_H */
- Re: [Qemu-devel] [PATCH v8 04/25] acpi: add DMAR scope definition for root IOAPIC,
Igor Mammedov <=