qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v10 08/26] acpi: add DMAR scope definition for r


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH v10 08/26] acpi: add DMAR scope definition for root IOAPIC
Date: Mon, 4 Jul 2016 18:22:56 +0300

On Tue, Jun 21, 2016 at 03:47:36PM +0800, Peter Xu 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        | 19 ++++++++++++++++---
>  include/hw/acpi/acpi-defs.h | 15 +++++++++++++++
>  include/hw/pci-host/q35.h   |  8 ++++++++
>  3 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 961ccd6a..eec022e 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;
> @@ -370,7 +373,6 @@ build_madt(GArray *table_data, BIOSLinker *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);
> @@ -2425,6 +2427,9 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
>      AcpiDmarHardwareUnit *drhd;
>      uint8_t dmar_flags = 0;
>      X86IOMMUState *iommu = x86_iommu_get_default();
> +    AcpiDmarDeviceScope *scope = NULL;
> +    /* Root complex IOAPIC use one path[0] only */
> +    uint8_t ioapic_scope_size = sizeof(*scope) + sizeof(scope->path[0]);

just use int or unsigned or size_t for types like this.

>  
>      assert(iommu);
>      if (iommu->intr_supported) {
> @@ -2437,13 +2442,21 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
>      dmar->flags = dmar_flags;
>  
>      /* DMAR Remapping Hardware Unit Definition structure */
> -    drhd = acpi_data_push(table_data, sizeof(*drhd));
> +    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));   /* No device scope now */
> +    drhd->length = cpu_to_le16(sizeof(*drhd) + ioapic_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 = &drhd->scope[0];
> +    scope->entry_type = ACPI_DMAR_DEV_SCOPE_TYPE_IOAPIC;
> +    scope->length = ioapic_scope_size;
> +    scope->enumeration_id = ACPI_BUILD_IOAPIC_ID;
> +    scope->bus = Q35_PSEUDO_BUS_PLATFORM;
> +    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 ea9be0b..0dbdde3 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -571,6 +571,20 @@ enum {
>  /*
>   * Sub-structures for DMAR
>   */
> +
> +#define ACPI_DMAR_DEV_SCOPE_TYPE_IOAPIC     (0x03)

Again, pls use literal with comment in code.

> +
> +/* 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;
> @@ -579,6 +593,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..312b47f 100644
> --- a/include/hw/pci-host/q35.h
> +++ b/include/hw/pci-host/q35.h
> @@ -175,4 +175,12 @@ typedef struct Q35PCIHost {
>  
>  uint64_t mch_mcfg_base(void);
>  
> +/*
> + * Arbitary but unique BNF number for IOAPIC device.
> + *
> + * TODO: make sure there would have no conflict with real PCI bus

How are you going to do this?

> + */
> +#define Q35_PSEUDO_BUS_PLATFORM         (0xff)
> +#define Q35_PSEUDO_DEVFN_IOAPIC         (0x00)
> +
>  #endif /* HW_Q35_H */
> -- 
> 2.4.11



reply via email to

[Prev in Thread] Current Thread [Next in Thread]