Commit f2426947 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging



pci, pc fixes, features

A bunch of bugfixes - these will make sense for 2.1.1

Initial Intel IOMMU support.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Tue 02 Sep 2014 16:05:04 BST using RSA key ID D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>"

* remotes/mst/tags/for_upstream:
  vhost_net: start/stop guest notifiers properly
  pci: avoid losing config updates to MSI/MSIX cap regs
  virtio-net: don't run bh on vm stopped
  ioh3420: remove unused ioh3420_init() declaration
  vhost_net: cleanup start/stop condition
  intel-iommu: add IOTLB using hash table
  intel-iommu: add context-cache to cache context-entry
  intel-iommu: add supports for queued invalidation interface
  intel-iommu: fix coding style issues around in q35.c and machine.c
  intel-iommu: add Intel IOMMU emulation to q35 and add a machine option "iommu" as a switch
  intel-iommu: add DMAR table to ACPI tables
  intel-iommu: introduce Intel IOMMU (VT-d) emulation
  iommu: add is_write as a parameter to the translate function of MemoryRegionIOMMUOps

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 30eaca3a aad4dce9
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -373,7 +373,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
            break;
        }

        iotlb = mr->iommu_ops->translate(mr, addr);
        iotlb = mr->iommu_ops->translate(mr, addr, is_write);
        addr = ((iotlb.translated_addr & ~iotlb.addr_mask)
                | (addr & iotlb.addr_mask));
        len = MIN(len, (addr | iotlb.addr_mask) - addr + 1);
+2 −1
Original line number Diff line number Diff line
@@ -660,7 +660,8 @@ static bool window_translate(TyphoonWindow *win, hwaddr addr,
/* Handle PCI-to-system address translation.  */
/* TODO: A translation failure here ought to set PCI error codes on the
   Pchip and generate a machine check interrupt.  */
static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr)
static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr,
                                             bool is_write)
{
    TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
    IOMMUTLBEntry ret;
+24 −3
Original line number Diff line number Diff line
@@ -235,6 +235,20 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp)
    ms->firmware = g_strdup(value);
}

static bool machine_get_iommu(Object *obj, Error **errp)
{
    MachineState *ms = MACHINE(obj);

    return ms->iommu;
}

static void machine_set_iommu(Object *obj, bool value, Error **errp)
{
    MachineState *ms = MACHINE(obj);

    ms->iommu = value;
}

static void machine_initfn(Object *obj)
{
    object_property_add_str(obj, "accel",
@@ -270,10 +284,17 @@ static void machine_initfn(Object *obj)
                             machine_set_dump_guest_core,
                             NULL);
    object_property_add_bool(obj, "mem-merge",
                             machine_get_mem_merge, machine_set_mem_merge, NULL);
    object_property_add_bool(obj, "usb", machine_get_usb, machine_set_usb, NULL);
                             machine_get_mem_merge,
                             machine_set_mem_merge, NULL);
    object_property_add_bool(obj, "usb",
                             machine_get_usb,
                             machine_set_usb, NULL);
    object_property_add_str(obj, "firmware",
                            machine_get_firmware, machine_set_firmware, NULL);
                            machine_get_firmware,
                            machine_set_firmware, NULL);
    object_property_add_bool(obj, "iommu",
                             machine_get_iommu,
                             machine_set_iommu, NULL);
}

static void machine_finalize(Object *obj)
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ obj-$(CONFIG_KVM) += kvm/
obj-y += multiboot.o smbios.o
obj-y += pc.o pc_piix.o pc_q35.o
obj-y += pc_sysfw.o
obj-y += intel_iommu.o
obj-$(CONFIG_XEN) += ../xenpv/ xen/

obj-y += kvmvapic.o
+39 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include "hw/i386/ich9.h"
#include "hw/pci/pci_bus.h"
#include "hw/pci-host/q35.h"
#include "hw/i386/intel_iommu.h"

#include "hw/i386/q35-acpi-dsdt.hex"
#include "hw/i386/acpi-dsdt.hex"
@@ -1387,6 +1388,30 @@ build_mcfg_q35(GArray *table_data, GArray *linker, AcpiMcfgInfo *info)
    build_header(linker, table_data, (void *)mcfg, sig, len, 1);
}

static void
build_dmar_q35(GArray *table_data, GArray *linker)
{
    int dmar_start = table_data->len;

    AcpiTableDmar *dmar;
    AcpiDmarHardwareUnit *drhd;

    dmar = acpi_data_push(table_data, sizeof(*dmar));
    dmar->host_address_width = VTD_HOST_ADDRESS_WIDTH - 1;
    dmar->flags = 0;    /* No intr_remap for now */

    /* DMAR Remapping Hardware Unit Definition structure */
    drhd = acpi_data_push(table_data, sizeof(*drhd));
    drhd->type = cpu_to_le16(ACPI_DMAR_TYPE_HARDWARE_UNIT);
    drhd->length = cpu_to_le16(sizeof(*drhd));   /* No device scope now */
    drhd->flags = ACPI_DMAR_INCLUDE_PCI_ALL;
    drhd->pci_segment = cpu_to_le16(0);
    drhd->address = cpu_to_le64(Q35_HOST_BRIDGE_IOMMU_ADDR);

    build_header(linker, table_data, (void *)(table_data->data + dmar_start),
                 "DMAR", table_data->len - dmar_start, 1);
}

static void
build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc)
{
@@ -1508,6 +1533,16 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
    return true;
}

static bool acpi_has_iommu(void)
{
    bool ambiguous;
    Object *intel_iommu;

    intel_iommu = object_resolve_path_type("", TYPE_INTEL_IOMMU_DEVICE,
                                           &ambiguous);
    return intel_iommu && !ambiguous;
}

static
void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
{
@@ -1584,6 +1619,10 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
        acpi_add_table(table_offsets, tables->table_data);
        build_mcfg_q35(tables->table_data, tables->linker, &mcfg);
    }
    if (acpi_has_iommu()) {
        acpi_add_table(table_offsets, tables->table_data);
        build_dmar_q35(tables->table_data, tables->linker);
    }

    /* Add tables supplied by user (if any) */
    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
Loading