diff options
Diffstat (limited to 'hw')
| -rw-r--r-- | hw/arm/boot.c | 8 | ||||
| -rw-r--r-- | hw/arm/virt.c | 16 | ||||
| -rw-r--r-- | hw/i386/acpi-build.c | 99 | ||||
| -rw-r--r-- | hw/i386/acpi-dsdt.dsl | 90 | ||||
| -rw-r--r-- | hw/i386/acpi-dsdt.hex.generated | 1870 | ||||
| -rw-r--r-- | hw/i386/pc.c | 25 | ||||
| -rw-r--r-- | hw/i386/pc_piix.c | 27 | ||||
| -rw-r--r-- | hw/i386/pc_q35.c | 5 | ||||
| -rw-r--r-- | hw/i386/xen/xen_apic.c | 1 | ||||
| -rw-r--r-- | hw/misc/vfio.c | 46 | ||||
| -rw-r--r-- | hw/sd/sdhci.c | 3 | ||||
| -rw-r--r-- | hw/virtio/virtio-rng.c | 25 |
12 files changed, 335 insertions, 1880 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 3d1f4a255b..12417617a3 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -417,8 +417,12 @@ static void do_cpu_reset(void *opaque) if (info) { if (!info->is_linux) { /* Jump to the entry point. */ - env->regs[15] = info->entry & 0xfffffffe; - env->thumb = info->entry & 1; + if (env->aarch64) { + env->pc = info->entry; + } else { + env->regs[15] = info->entry & 0xfffffffe; + env->thumb = info->entry & 1; + } } else { if (CPU(cpu) == first_cpu) { if (env->aarch64) { diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 405c61d39c..ba94298555 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -98,17 +98,17 @@ typedef struct VirtBoardInfo { */ static const MemMapEntry a15memmap[] = { /* Space up to 0x8000000 is reserved for a boot ROM */ - [VIRT_FLASH] = { 0, 0x8000000 }, - [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 }, + [VIRT_FLASH] = { 0, 0x08000000 }, + [VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 }, /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */ - [VIRT_GIC_DIST] = { 0x8000000, 0x10000 }, - [VIRT_GIC_CPU] = { 0x8010000, 0x10000 }, - [VIRT_UART] = { 0x9000000, 0x1000 }, - [VIRT_RTC] = { 0x90010000, 0x1000 }, - [VIRT_MMIO] = { 0xa000000, 0x200 }, + [VIRT_GIC_DIST] = { 0x08000000, 0x00010000 }, + [VIRT_GIC_CPU] = { 0x08010000, 0x00010000 }, + [VIRT_UART] = { 0x09000000, 0x00001000 }, + [VIRT_RTC] = { 0x09010000, 0x00001000 }, + [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* 0x10000000 .. 0x40000000 reserved for PCI */ - [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 }, + [VIRT_MEM] = { 0x40000000, 30ULL * 1024 * 1024 * 1024 }, }; static const int a15irqmap[] = { diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index ebc5f034e3..816c6d9b47 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -25,7 +25,9 @@ #include <glib.h> #include "qemu-common.h" #include "qemu/bitmap.h" +#include "qemu/osdep.h" #include "qemu/range.h" +#include "qemu/error-report.h" #include "hw/pci/pci.h" #include "qom/cpu.h" #include "hw/i386/pc.h" @@ -52,6 +54,16 @@ #include "qapi/qmp/qint.h" #include "qom/qom-qobject.h" +/* These are used to size the ACPI tables for -M pc-i440fx-1.7 and + * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows + * a little bit, there should be plenty of free space since the DSDT + * shrunk by ~1.5k between QEMU 2.0 and QEMU 2.1. + */ +#define ACPI_BUILD_LEGACY_CPU_AML_SIZE 97 +#define ACPI_BUILD_ALIGN_SIZE 0x1000 + +#define ACPI_BUILD_TABLE_SIZE 0x20000 + typedef struct AcpiCpuInfo { DECLARE_BITMAP(found_cpus, ACPI_CPU_HOTPLUG_ID_LIMIT); } AcpiCpuInfo; @@ -64,6 +76,7 @@ typedef struct AcpiMcfgInfo { typedef struct AcpiPmInfo { bool s3_disabled; bool s4_disabled; + bool pcihp_bridge_en; uint8_t s4_val; uint16_t sci_int; uint8_t acpi_enable_cmd; @@ -85,6 +98,7 @@ typedef struct AcpiBuildPciBusHotplugState { GArray *device_table; GArray *notify_table; struct AcpiBuildPciBusHotplugState *parent; + bool pcihp_bridge_en; } AcpiBuildPciBusHotplugState; static void acpi_get_dsdt(AcpiMiscInfo *info) @@ -188,6 +202,9 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) NULL); pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN, NULL); + pm->pcihp_bridge_en = + object_property_get_bool(obj, "acpi-pci-hotplug-with-bridge-support", + NULL); } static void acpi_get_misc_info(AcpiMiscInfo *info) @@ -768,11 +785,13 @@ static void acpi_set_pci_info(void) } static void build_pci_bus_state_init(AcpiBuildPciBusHotplugState *state, - AcpiBuildPciBusHotplugState *parent) + AcpiBuildPciBusHotplugState *parent, + bool pcihp_bridge_en) { state->parent = parent; state->device_table = build_alloc_array(); state->notify_table = build_alloc_array(); + state->pcihp_bridge_en = pcihp_bridge_en; } static void build_pci_bus_state_cleanup(AcpiBuildPciBusHotplugState *state) @@ -786,7 +805,7 @@ static void *build_pci_bus_begin(PCIBus *bus, void *parent_state) AcpiBuildPciBusHotplugState *parent = parent_state; AcpiBuildPciBusHotplugState *child = g_malloc(sizeof *child); - build_pci_bus_state_init(child, parent); + build_pci_bus_state_init(child, parent, parent->pcihp_bridge_en); return child; } @@ -807,6 +826,14 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) GArray *method; bool bus_hotplug_support = false; + /* + * Skip bridge subtree creation if bridge hotplug is disabled + * to make acpi tables compatible with legacy machine types. + */ + if (!child->pcihp_bridge_en && bus->parent_dev) { + return; + } + if (bus->parent_dev) { op = 0x82; /* DeviceOp */ build_append_nameseg(bus_table, "S%.02X_", @@ -844,6 +871,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) PCIDeviceClass *pc; PCIDevice *pdev = bus->devices[i]; int slot = PCI_SLOT(i); + bool bridge_in_acpi; if (!pdev) { continue; @@ -853,7 +881,13 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) pc = PCI_DEVICE_GET_CLASS(pdev); dc = DEVICE_GET_CLASS(pdev); - if (pc->class_id == PCI_CLASS_BRIDGE_ISA || pc->is_bridge) { + /* When hotplug for bridges is enabled, bridges are + * described in ACPI separately (see build_pci_bus_end). + * In this case they aren't themselves hot-pluggable. + */ + bridge_in_acpi = pc->is_bridge && child->pcihp_bridge_en; + + if (pc->class_id == PCI_CLASS_BRIDGE_ISA || bridge_in_acpi) { set_bit(slot, slot_device_system); } @@ -865,7 +899,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) } } - if (!dc->hotpluggable || pc->is_bridge) { + if (!dc->hotpluggable || bridge_in_acpi) { clear_bit(slot, slot_hotplug_enable); } } @@ -1130,7 +1164,7 @@ build_ssdt(GArray *table_data, GArray *linker, bus = PCI_HOST_BRIDGE(pci_host)->bus; } - build_pci_bus_state_init(&hotplug_state, NULL); + build_pci_bus_state_init(&hotplug_state, NULL, pm->pcihp_bridge_en); if (bus) { /* Scan all PCI buses. Generate tables to support hotplug. */ @@ -1440,13 +1474,14 @@ static void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) { GArray *table_offsets; - unsigned facs, dsdt, rsdt; + unsigned facs, ssdt, dsdt, rsdt; AcpiCpuInfo cpu; AcpiPmInfo pm; AcpiMiscInfo misc; AcpiMcfgInfo mcfg; PcPciInfo pci; uint8_t *u; + size_t aml_len = 0; acpi_get_cpu_info(&cpu); acpi_get_pm_info(&pm); @@ -1474,13 +1509,20 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) dsdt = tables->table_data->len; build_dsdt(tables->table_data, tables->linker, &misc); + /* Count the size of the DSDT and SSDT, we will need it for legacy + * sizing of ACPI tables. + */ + aml_len += tables->table_data->len - dsdt; + /* ACPI tables pointed to by RSDT */ acpi_add_table(table_offsets, tables->table_data); build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt); + ssdt = tables->table_data->len; acpi_add_table(table_offsets, tables->table_data); build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci, guest_info); + aml_len += tables->table_data->len - ssdt; acpi_add_table(table_offsets, tables->table_data); build_madt(tables->table_data, tables->linker, &cpu, guest_info); @@ -1513,14 +1555,53 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) /* RSDP is in FSEG memory, so allocate it separately */ build_rsdp(tables->rsdp, tables->linker, rsdt); - /* We'll expose it all to Guest so align size to reduce + /* We'll expose it all to Guest so we want to reduce * chance of size changes. * RSDP is small so it's easy to keep it immutable, no need to * bother with alignment. + * + * We used to align the tables to 4k, but of course this would + * too simple to be enough. 4k turned out to be too small an + * alignment very soon, and in fact it is almost impossible to + * keep the table size stable for all (max_cpus, max_memory_slots) + * combinations. So the table size is always 64k for pc-i440fx-2.1 + * and we give an error if the table grows beyond that limit. + * + * We still have the problem of migrating from "-M pc-i440fx-2.0". For + * that, we exploit the fact that QEMU 2.1 generates _smaller_ tables + * than 2.0 and we can always pad the smaller tables with zeros. We can + * then use the exact size of the 2.0 tables. + * + * All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration. */ - acpi_align_size(tables->table_data, 0x1000); + if (guest_info->legacy_acpi_table_size) { + /* Subtracting aml_len gives the size of fixed tables. Then add the + * size of the PIIX4 DSDT/SSDT in QEMU 2.0. + */ + int legacy_aml_len = + guest_info->legacy_acpi_table_size + + ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus; + int legacy_table_size = + ROUND_UP(tables->table_data->len - aml_len + legacy_aml_len, + ACPI_BUILD_ALIGN_SIZE); + if (tables->table_data->len > legacy_table_size) { + /* Should happen only with PCI bridges and -M pc-i440fx-2.0. */ + error_report("Warning: migration may not work."); + } + g_array_set_size(tables->table_data, legacy_table_size); + } else { + /* Make sure we have a buffer in case we need to resize the tables. */ + if (tables->table_data->len > ACPI_BUILD_TABLE_SIZE / 2) { + /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots. */ + error_report("Warning: ACPI tables are larger than 64k."); + error_report("Warning: migration may not work."); + error_report("Warning: please remove CPUs, NUMA nodes, " + "memory slots or PCI bridges."); + } + acpi_align_size(tables->table_data, ACPI_BUILD_TABLE_SIZE); + } - acpi_align_size(tables->linker, 0x1000); + acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE); /* Cleanup memory that's no longer used. */ g_array_free(table_offsets, true); diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index 3cc0ea0f9a..6ba017014a 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -181,57 +181,45 @@ DefinitionBlock ( Scope(\_SB) { Scope(PCI0) { - Name(_PRT, Package() { - /* PCI IRQ routing table, example from ACPI 2.0a specification, - section 6.2.8.1 */ - /* Note: we provide the same info as the PCI routing - table of the Bochs BIOS */ - -#define prt_slot(nr, lnk0, lnk1, lnk2, lnk3) \ - Package() { nr##ffff, 0, lnk0, 0 }, \ - Package() { nr##ffff, 1, lnk1, 0 }, \ - Package() { nr##ffff, 2, lnk2, 0 }, \ - Package() { nr##ffff, 3, lnk3, 0 } - -#define prt_slot0(nr) prt_slot(nr, LNKD, LNKA, LNKB, LNKC) -#define prt_slot1(nr) prt_slot(nr, LNKA, LNKB, LNKC, LNKD) -#define prt_slot2(nr) prt_slot(nr, LNKB, LNKC, LNKD, LNKA) -#define prt_slot3(nr) prt_slot(nr, LNKC, LNKD, LNKA, LNKB) - - prt_slot0(0x0000), - /* Device 1 is power mgmt device, and can only use irq 9 */ - prt_slot(0x0001, LNKS, LNKB, LNKC, LNKD), - prt_slot2(0x0002), - prt_slot3(0x0003), - prt_slot0(0x0004), - prt_slot1(0x0005), - prt_slot2(0x0006), - prt_slot3(0x0007), - prt_slot0(0x0008), - prt_slot1(0x0009), - prt_slot2(0x000a), - prt_slot3(0x000b), - prt_slot0(0x000c), - prt_slot1(0x000d), - prt_slot2(0x000e), - prt_slot3(0x000f), - prt_slot0(0x0010), - prt_slot1(0x0011), - prt_slot2(0x0012), - prt_slot3(0x0013), - prt_slot0(0x0014), - prt_slot1(0x0015), - prt_slot2(0x0016), - prt_slot3(0x0017), - prt_slot0(0x0018), - prt_slot1(0x0019), - prt_slot2(0x001a), - prt_slot3(0x001b), - prt_slot0(0x001c), - prt_slot1(0x001d), - prt_slot2(0x001e), - prt_slot3(0x001f), - }) + Method (_PRT, 0) { + Store(Package(128) {}, Local0) + Store(Zero, Local1) + While(LLess(Local1, 128)) { + // slot = pin >> 2 + Store(ShiftRight(Local1, 2), Local2) + + // lnk = (slot + pin) & 3 + Store(And(Add(Local1, Local2), 3), Local3) + If (LEqual(Local3, 0)) { + Store(Package(4) { Zero, Zero, LNKD, Zero }, Local4) + } + If (LEqual(Local3, 1)) { + // device 1 is the power-management device, needs SCI + If (LEqual(Local1, 4)) { + Store(Package(4) { Zero, Zero, LNKS, Zero }, Local4) + } Else { + Store(Package(4) { Zero, Zero, LNKA, Zero }, Local4) + } + } + If (LEqual(Local3, 2)) { + Store(Package(4) { Zero, Zero, LNKB, Zero }, Local4) + } + If (LEqual(Local3, 3)) { + Store(Package(4) { Zero, Zero, LNKC, Zero }, Local4) + } + + // Complete the interrupt routing entry: + // Package(4) { 0x[slot]FFFF, [pin], [link], 0) } + + Store(Or(ShiftLeft(Local2, 16), 0xFFFF), Index(Local4, 0)) + Store(And(Local1, 3), Index(Local4, 1)) + Store(Local4, Index(Local0, Local1)) + + Increment(Local1) + } + + Return(Local0) + } } Field(PCI0.ISA.P40C, ByteAcc, NoLock, Preserve) { diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index ee490e89c3..6c8a1fcdfb 100644 --- a/hw/i386/acpi-dsdt.hex.generated +++ b/hw/i386/acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0x93, -0x11, +0xf7, +0xa, 0x0, 0x0, 0x1, -0xf5, +0x2e, 0x42, 0x58, 0x50, @@ -31,9 +31,9 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x4e, 0x54, 0x4c, -0x15, -0x11, 0x13, +0x9, +0x12, 0x20, 0x10, 0x49, @@ -1439,1419 +1439,68 @@ static unsigned char AcpiDsdtAmlCode[] = { 0xa4, 0x0, 0x10, -0x4a, -0xa0, +0x4e, +0x36, 0x5f, 0x53, 0x42, 0x5f, 0x10, -0x47, -0x74, +0x4b, +0xa, 0x50, 0x43, 0x49, 0x30, -0x8, +0x14, +0x44, +0xa, 0x5f, 0x50, 0x52, 0x54, -0x12, -0x4b, -0x73, -0x80, -0x12, -0xb, -0x4, -0xb, -0xff, -0xff, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xb, -0x4, -0xb, -0xff, -0xff, -0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xc, -0x4, -0xb, -0xff, -0xff, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xc, -0x4, -0xb, -0xff, -0xff, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x53, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x2, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x2, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x2, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x2, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x3, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x3, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x3, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x3, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x4, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x4, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x4, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x4, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x5, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x5, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x5, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x5, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x6, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x6, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x6, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x6, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x7, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x7, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x7, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x7, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x8, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x8, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, 0x0, +0x70, 0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x8, -0x0, -0xa, 0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x8, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x9, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x9, +0x80, +0x60, +0x70, 0x0, -0x1, -0x4c, -0x4e, -0x4b, +0x61, +0xa2, 0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, 0x9, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x9, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xa, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xa, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xa, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xa, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xb, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xb, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xb, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xb, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xc, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xc, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xc, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xc, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xd, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xd, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xd, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xd, -0x0, +0x95, +0x61, 0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xe, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xe, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xe, -0x0, +0x80, +0x70, +0x7a, +0x61, 0xa, 0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xe, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xf, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0xf, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xf, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0xf, +0x62, +0x70, +0x7b, +0x72, +0x61, +0x62, 0x0, 0xa, 0x3, -0x4c, -0x4e, -0x4b, -0x42, 0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x10, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x10, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x10, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, +0x63, +0xa0, 0x10, +0x93, +0x63, 0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x11, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x11, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x11, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x11, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x12, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x12, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x12, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x12, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x13, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x13, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x13, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x13, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x14, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x14, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x14, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x14, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x15, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x15, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x15, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x15, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x16, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x16, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x16, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x16, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x17, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x17, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x17, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x17, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, +0x70, 0x12, -0xd, +0x9, 0x4, -0xc, -0xff, -0xff, -0x18, 0x0, 0x0, 0x4c, @@ -2859,456 +1508,115 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x4b, 0x44, 0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x18, -0x0, +0x64, +0xa0, +0x24, +0x93, +0x63, 0x1, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x18, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x18, -0x0, +0xa0, +0x11, +0x93, +0x61, 0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x19, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, 0x4, -0xc, -0xff, -0xff, -0x19, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x19, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x19, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, +0x70, 0x12, -0xd, +0x9, 0x4, -0xc, -0xff, -0xff, -0x1a, 0x0, 0x0, 0x4c, 0x4e, 0x4b, -0x42, +0x53, 0x0, -0x12, +0x64, +0xa1, 0xd, -0x4, -0xc, -0xff, -0xff, -0x1a, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, -0x0, +0x70, 0x12, -0xe, +0x9, 0x4, -0xc, -0xff, -0xff, -0x1a, -0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1a, 0x0, -0xa, -0x3, 0x4c, 0x4e, 0x4b, 0x41, 0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1b, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1b, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1b, -0x0, +0x64, +0xa0, +0x11, +0x93, +0x63, 0xa, 0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1b, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1c, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x44, -0x0, +0x70, 0x12, -0xd, +0x9, 0x4, -0xc, -0xff, -0xff, -0x1c, 0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x41, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1c, -0x0, -0xa, -0x2, 0x4c, 0x4e, 0x4b, 0x42, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1c, -0x0, +0x64, +0xa0, +0x11, +0x93, +0x63, 0xa, 0x3, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1d, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x41, -0x0, +0x70, 0x12, -0xd, +0x9, 0x4, -0xc, -0xff, -0xff, -0x1d, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x42, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1d, 0x0, -0xa, -0x2, 0x4c, 0x4e, 0x4b, 0x43, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1d, -0x0, +0x64, +0x70, +0x7d, +0x79, +0x62, 0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1e, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x42, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1e, -0x0, -0x1, -0x4c, -0x4e, -0x4b, -0x43, +0x10, 0x0, -0x12, -0xe, -0x4, -0xc, +0xb, 0xff, 0xff, -0x1e, 0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x44, +0x88, +0x64, 0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1e, 0x0, +0x70, +0x7b, +0x61, 0xa, 0x3, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1f, -0x0, -0x0, -0x4c, -0x4e, -0x4b, -0x43, -0x0, -0x12, -0xd, -0x4, -0xc, -0xff, -0xff, -0x1f, 0x0, +0x88, +0x64, 0x1, -0x4c, -0x4e, -0x4b, -0x44, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1f, 0x0, -0xa, -0x2, -0x4c, -0x4e, -0x4b, -0x41, -0x0, -0x12, -0xe, -0x4, -0xc, -0xff, -0xff, -0x1f, -0x0, -0xa, -0x3, -0x4c, -0x4e, -0x4b, -0x42, +0x70, +0x64, +0x88, +0x60, +0x61, 0x0, +0x75, +0x61, +0xa4, +0x60, 0x5b, 0x81, 0x24, diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 2cf22b1293..9e589825f0 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1190,6 +1190,31 @@ void pc_acpi_init(const char *default_dsdt) } } +FWCfgState *xen_load_linux(const char *kernel_filename, + const char *kernel_cmdline, + const char *initrd_filename, + ram_addr_t below_4g_mem_size, + PcGuestInfo *guest_info) +{ + int i; + FWCfgState *fw_cfg; + + assert(kernel_filename != NULL); + + fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0); + rom_set_fw(fw_cfg); + + load_linux(fw_cfg, kernel_filename, initrd_filename, + kernel_cmdline, below_4g_mem_size); + for (i = 0; i < nb_option_roms; i++) { + assert(!strcmp(option_rom[i].name, "linuxboot.bin") || + !strcmp(option_rom[i].name, "multiboot.bin")); + rom_add_option(option_rom[i].name, option_rom[i].bootindex); + } + guest_info->fw_cfg = fw_cfg; + return fw_cfg; +} + FWCfgState *pc_memory_init(MachineState *machine, MemoryRegion *system_memory, ram_addr_t below_4g_mem_size, diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 7081c08a69..4f22be85da 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -61,6 +61,7 @@ static const int ide_irq[MAX_IDE_BUS] = { 14, 15 }; static bool has_pci_info; static bool has_acpi_build = true; +static int legacy_acpi_table_size; static bool smbios_defaults = true; static bool smbios_legacy_mode; /* Make sure that guest addresses aligned at 1Gbyte boundaries get mapped to @@ -163,6 +164,7 @@ static void pc_init1(MachineState *machine, guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size); guest_info->has_acpi_build = has_acpi_build; + guest_info->legacy_acpi_table_size = legacy_acpi_table_size; guest_info->has_pci_info = has_pci_info; guest_info->isapc_ram_fw = !pci_enabled; @@ -180,6 +182,13 @@ static void pc_init1(MachineState *machine, fw_cfg = pc_memory_init(machine, system_memory, below_4g_mem_size, above_4g_mem_size, rom_memory, &ram_memory, guest_info); + } else if (machine->kernel_filename != NULL) { + /* For xen HVM direct kernel boot, load linux here */ + fw_cfg = xen_load_linux(machine->kernel_filename, + machine->kernel_cmdline, + machine->initrd_filename, + below_4g_mem_size, + guest_info); } gsi_state = g_malloc0(sizeof(*gsi_state)); @@ -297,6 +306,23 @@ static void pc_init_pci(MachineState *machine) static void pc_compat_2_0(MachineState *machine) { + /* This value depends on the actual DSDT and SSDT compiled into + * the source QEMU; unfortunately it depends on the binary and + * not on the machine type, so we cannot make pc-i440fx-1.7 work on + * both QEMU 1.7 and QEMU 2.0. + * + * Large variations cause migration to fail for more than one + * consecutive value of the "-smp" maxcpus option. + * + * For small variations of the kind caused by different iasl versions, + * the 4k rounding usually leaves slack. However, there could be still + * one or two values that break. For QEMU 1.7 and QEMU 2.0 the + * slack is only ~10 bytes before one "-smp maxcpus" value breaks! + * + * 6652 is valid for QEMU 2.0, the right value for pc-i440fx-1.7 on + * QEMU 1.7 it is 6414. For RHEL/CentOS 7.0 it is 6418. + */ + legacy_acpi_table_size = 6652; smbios_legacy_mode = true; has_reserved_memory = false; } @@ -307,6 +333,7 @@ static void pc_compat_1_7(MachineState *machine) smbios_defaults = false; gigabyte_align = false; option_rom_has_mr = true; + legacy_acpi_table_size = 6414; x86_cpu_compat_disable_kvm_features(FEAT_1_ECX, CPUID_EXT_X2APIC); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index f55196150c..c39ee98933 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -155,6 +155,11 @@ static void pc_q35_init(MachineState *machine) guest_info->has_acpi_build = has_acpi_build; guest_info->has_reserved_memory = has_reserved_memory; + /* Migration was not supported in 2.0 for Q35, so do not bother + * with this hack (see hw/i386/acpi-build.c). + */ + guest_info->legacy_acpi_table_size = 0; + if (smbios_defaults) { MachineClass *mc = MACHINE_GET_CLASS(machine); /* These values are guest ABI, do not change */ diff --git a/hw/i386/xen/xen_apic.c b/hw/i386/xen/xen_apic.c index 63bb7f77c6..f5acd6a096 100644 --- a/hw/i386/xen/xen_apic.c +++ b/hw/i386/xen/xen_apic.c @@ -40,6 +40,7 @@ static void xen_apic_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); + s->vapic_control = 0; memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s, "xen-apic-msi", APIC_SPACE_SIZE); diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index 0b9eba0c84..ba08adbd99 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -120,11 +120,19 @@ typedef struct VFIOINTx { } VFIOINTx; typedef struct VFIOMSIVector { - EventNotifier interrupt; /* eventfd triggered on interrupt */ - EventNotifier kvm_interrupt; /* eventfd triggered for KVM irqfd bypass */ + /* + * Two interrupt paths are configured per vector. The first, is only used + * for interrupts injected via QEMU. This is typically the non-accel path, + * but may also be used when we want QEMU to handle masking and pending + * bits. The KVM path bypasses QEMU and is therefore higher performance, + * but requires masking at the device. virq is used to track the MSI route + * through KVM, thus kvm_interrupt is only available when virq is set to a + * valid (>= 0) value. + */ + EventNotifier interrupt; + EventNotifier kvm_interrupt; struct VFIODevice *vdev; /* back pointer to device */ - MSIMessage msg; /* cache the MSI message so we know when it changes */ - int virq; /* KVM irqchip route for QEMU bypass */ + int virq; bool use; } VFIOMSIVector; @@ -681,13 +689,24 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix) fds = (int32_t *)&irq_set->data; for (i = 0; i < vdev->nr_vectors; i++) { - if (!vdev->msi_vectors[i].use) { - fds[i] = -1; - } else if (vdev->msi_vectors[i].virq >= 0) { - fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt); - } else { - fds[i] = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt); + int fd = -1; + + /* + * MSI vs MSI-X - The guest has direct access to MSI mask and pending + * bits, therefore we always use the KVM signaling path when setup. + * MSI-X mask and pending bits are emulated, so we want to use the + * KVM signaling path only when configured and unmasked. + */ + if (vdev->msi_vectors[i].use) { + if (vdev->msi_vectors[i].virq < 0 || + (msix && msix_is_masked(&vdev->pdev, i))) { + fd = event_notifier_get_fd(&vdev->msi_vectors[i].interrupt); + } else { + fd = event_notifier_get_fd(&vdev->msi_vectors[i].kvm_interrupt); + } } + + fds[i] = fd; } ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set); @@ -724,7 +743,6 @@ static void vfio_add_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage *msg, return; } - vector->msg = *msg; vector->virq = virq; } @@ -740,7 +758,6 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector) static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg) { kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg); - vector->msg = msg; } static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, @@ -919,6 +936,7 @@ retry: for (i = 0; i < vdev->nr_vectors; i++) { VFIOMSIVector *vector = &vdev->msi_vectors[i]; + MSIMessage msg = msi_get_message(&vdev->pdev, i); vector->vdev = vdev; vector->virq = -1; @@ -931,13 +949,11 @@ retry: qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), vfio_msi_interrupt, NULL, vector); - vector->msg = msi_get_message(&vdev->pdev, i); - /* * Attempt to enable route through KVM irqchip, * default to userspace handling if unavailable. */ - vfio_add_kvm_msi_virq(vector, &vector->msg, false); + vfio_add_kvm_msi_virq(vector, &msg, false); } /* Set interrupt type prior to possible interrupts */ diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index b5a9eee3e2..f9fe700add 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -702,7 +702,8 @@ static void sdhci_do_adma(SDHCIState *s) length -= block_size - begin; } dma_memory_read(&address_space_memory, dscr.addr, - &s->fifo_buffer[begin], s->data_count); + &s->fifo_buffer[begin], + s->data_count - begin); dscr.addr += s->data_count - begin; if (s->data_count == block_size) { for (n = 0; n < block_size; n++) { diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 7c5a675674..03fd04a1e5 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -142,8 +142,15 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) Error *local_err = NULL; if (!vrng->conf.period_ms > 0) { - error_set(errp, QERR_INVALID_PARAMETER_VALUE, "period", - "a positive number"); + error_setg(errp, "'period' parameter expects a positive integer"); + return; + } + + /* Workaround: Property parsing does not enforce unsigned integers, + * So this is a hack to reject such numbers. */ + if (vrng->conf.max_bytes > INT64_MAX) { + error_setg(errp, "'max-bytes' parameter must be non-negative, " + "and less than 2^63"); return; } @@ -171,23 +178,15 @@ static void virtio_rng_device_realize(DeviceState *dev, Error **errp) "rng", NULL); } - virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0); - vrng->rng = vrng->conf.rng; if (vrng->rng == NULL) { - error_set(errp, QERR_INVALID_PARAMETER_VALUE, "rng", "a valid object"); + error_setg(errp, "'rng' parameter expects a valid object"); return; } - vrng->vq = virtio_add_queue(vdev, 8, handle_input); + virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0); - /* Workaround: Property parsing does not enforce unsigned integers, - * So this is a hack to reject such numbers. */ - if (vrng->conf.max_bytes > INT64_MAX) { - error_set(errp, QERR_INVALID_PARAMETER_VALUE, "max-bytes", - "a non-negative integer below 2^63"); - return; - } + vrng->vq = virtio_add_queue(vdev, 8, handle_input); vrng->quota_remaining = vrng->conf.max_bytes; vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, |