diff options
-rw-r--r-- | VERSION | 2 | ||||
-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 | ||||
-rw-r--r-- | include/hw/i386/pc.h | 6 | ||||
-rw-r--r-- | net/tap-bsd.c | 70 | ||||
-rw-r--r-- | po/fr_FR.po | 54 | ||||
-rw-r--r-- | po/it.po | 63 | ||||
-rwxr-xr-x | scripts/vmstate-static-checker.py | 70 | ||||
-rw-r--r-- | target-arm/cpu.c | 2 | ||||
-rw-r--r-- | target-arm/cpu.h | 4 | ||||
-rw-r--r-- | target-arm/helper-a64.c | 8 | ||||
-rw-r--r-- | target-arm/helper.c | 42 | ||||
-rw-r--r-- | target-arm/internals.h | 29 | ||||
-rw-r--r-- | target-arm/kvm64.c | 13 | ||||
-rw-r--r-- | target-arm/op_helper.c | 8 | ||||
-rw-r--r-- | tests/acpi-test-data/pc/DSDT | bin | 4499 -> 2807 bytes | |||
-rw-r--r-- | tests/bios-tables-test.c | 6 | ||||
-rw-r--r-- | xen-hvm.c | 7 |
28 files changed, 628 insertions, 1971 deletions
@@ -1 +1 @@ -2.0.93 +2.1.50 diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 3d1f4a2..1241761 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 405c61d..ba94298 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 ebc5f03..816c6d9 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 3cc0ea0..6ba0170 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 ee490e8..6c8a1fc 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 2cf22b1..9e58982 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 7081c08..4f22be8 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 f551961..c39ee98 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 63bb7f7..f5acd6a 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 0b9eba0..ba08adb 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 b5a9eee..f9fe700 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 7c5a675..03fd04a 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, diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 1c0c382..863eefb 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -94,6 +94,7 @@ struct PcGuestInfo { uint64_t *node_mem; uint64_t *node_cpu; FWCfgState *fw_cfg; + int legacy_acpi_table_size; bool has_acpi_build; bool has_reserved_memory; }; @@ -187,6 +188,11 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size, void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory, MemoryRegion *pci_address_space); +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); FWCfgState *pc_memory_init(MachineState *machine, MemoryRegion *system_memory, ram_addr_t below_4g_mem_size, diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 90f8a02..bf91bd0 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -27,12 +27,13 @@ #include "sysemu/sysemu.h" #include "qemu/error-report.h" -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include <sys/ioctl.h> #include <net/if.h> #include <net/if_tap.h> #endif +#ifndef __FreeBSD__ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required, int mq_required) { @@ -108,6 +109,73 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, return fd; } +#else /* __FreeBSD__ */ + +#define PATH_NET_TAP "/dev/tap" + +int tap_open(char *ifname, int ifname_size, int *vnet_hdr, + int vnet_hdr_required, int mq_required) +{ + int fd, s, ret; + struct ifreq ifr; + + TFR(fd = open(PATH_NET_TAP, O_RDWR)); + if (fd < 0) { + error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno)); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + ret = ioctl(fd, TAPGIFNAME, (void *)&ifr); + if (ret < 0) { + error_report("could not get tap interface name"); + goto error; + } + + if (ifname[0] != '\0') { + /* User requested the interface to have a specific name */ + s = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (s < 0) { + error_report("could not open socket to set interface name"); + goto error; + } + ifr.ifr_data = ifname; + ret = ioctl(s, SIOCSIFNAME, (void *)&ifr); + close(s); + if (ret < 0) { + error_report("could not set tap interface name"); + goto error; + } + } else { + pstrcpy(ifname, ifname_size, ifr.ifr_name); + } + + if (*vnet_hdr) { + /* BSD doesn't have IFF_VNET_HDR */ + *vnet_hdr = 0; + + if (vnet_hdr_required && !*vnet_hdr) { + error_report("vnet_hdr=1 requested, but no kernel " + "support for IFF_VNET_HDR available"); + goto error; + } + } + if (mq_required) { + error_report("mq_required requested, but not kernel support" + "for IFF_MULTI_QUEUE available"); + goto error; + } + + fcntl(fd, F_SETFL, O_NONBLOCK); + return fd; + +error: + close(fd); + return -1; +} +#endif /* __FreeBSD__ */ + int tap_set_sndbuf(int fd, const NetdevTapOptions *tap) { return 0; diff --git a/po/fr_FR.po b/po/fr_FR.po index ec54eb9..bbb5ef8 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -1,13 +1,13 @@ # French translation for QEMU. # This file is put in the public domain. # -# Aurelien Jarno <aurelien@aurel32.net>, 2013. +# Aurelien Jarno <aurelien@aurel32.net>, 2013, 2014. msgid "" msgstr "" "Project-Id-Version: QEMU 1.4.50\n" "Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n" -"POT-Creation-Date: 2013-07-05 22:36+0200\n" -"PO-Revision-Date: 2013-03-31 19:39+0200\n" +"POT-Creation-Date: 2014-07-28 23:14+0200\n" +"PO-Revision-Date: 2014-07-28 23:25+0200\n" "Last-Translator: Aurelien Jarno <aurelien@aurel32.net>\n" "Language-Team: French <FR@li.org>\n" "Language: fr\n" @@ -17,46 +17,70 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Lokalize 1.4\n" -#: ui/gtk.c:214 +#: ui/gtk.c:321 msgid " - Press Ctrl+Alt+G to release grab" msgstr "- Appuyer sur Ctrl+Alt+G pour arrêter la capture" -#: ui/gtk.c:218 +#: ui/gtk.c:325 msgid " [Paused]" msgstr " [En pause]" -#: ui/gtk.c:1318 +#: ui/gtk.c:1601 msgid "_Pause" msgstr "_Pause" -#: ui/gtk.c:1324 +#: ui/gtk.c:1607 msgid "_Reset" msgstr "_Réinitialiser" -#: ui/gtk.c:1327 +#: ui/gtk.c:1610 msgid "Power _Down" msgstr "_Éteindre" -#: ui/gtk.c:1381 +#: ui/gtk.c:1616 +msgid "_Quit" +msgstr "_Quitter" + +#: ui/gtk.c:1692 +msgid "_Fullscreen" +msgstr "Mode _plein écran" + +#: ui/gtk.c:1702 +msgid "Zoom _In" +msgstr "Zoom _avant" + +#: ui/gtk.c:1709 +msgid "Zoom _Out" +msgstr "_Zoom arrière" + +#: ui/gtk.c:1716 +msgid "Best _Fit" +msgstr "Zoom _idéal" + +#: ui/gtk.c:1723 msgid "Zoom To _Fit" -msgstr "Zoomer pour _ajuster" +msgstr "Zoomer pour a_juster" -#: ui/gtk.c:1387 +#: ui/gtk.c:1729 msgid "Grab On _Hover" msgstr "Capturer en _survolant" -#: ui/gtk.c:1390 +#: ui/gtk.c:1732 msgid "_Grab Input" msgstr "_Capturer les entrées" -#: ui/gtk.c:1416 +#: ui/gtk.c:1761 msgid "Show _Tabs" msgstr "Montrer les _onglets" -#: ui/gtk.c:1430 +#: ui/gtk.c:1764 +msgid "Detach Tab" +msgstr "_Détacher l'onglet" + +#: ui/gtk.c:1778 msgid "_Machine" msgstr "_Machine" -#: ui/gtk.c:1435 +#: ui/gtk.c:1783 msgid "_View" msgstr "_Vue" @@ -1,13 +1,13 @@ # Italian translation for QEMU. # This file is put in the public domain. -# Paolo Bonzini <pbonzini@redhat.com>, 2012. +# Paolo Bonzini <pbonzini@redhat.com>, 2012-2014. # msgid "" msgstr "" "Project-Id-Version: QEMU 1.4.50\n" "Report-Msgid-Bugs-To: qemu-devel@nongnu.org\n" -"POT-Creation-Date: 2013-07-05 22:36+0200\n" -"PO-Revision-Date: 2012-02-27 08:23+0100\n" +"POT-Creation-Date: 2014-07-29 08:14+0200\n" +"PO-Revision-Date: 2014-07-29 08:25+0200\n" "Last-Translator: Paolo Bonzini <pbonzini@redhat.com>\n" "Language-Team: Italian <it@li.org>\n" "Language: it\n" @@ -16,49 +16,66 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ui/gtk.c:214 +#: ui/gtk.c:321 msgid " - Press Ctrl+Alt+G to release grab" -msgstr "" +msgstr " - Premere Ctrl+Alt+G per rilasciare l'input" -#: ui/gtk.c:218 +#: ui/gtk.c:325 msgid " [Paused]" -msgstr "" +msgstr " [Pausa]" -#: ui/gtk.c:1318 +#: ui/gtk.c:1601 msgid "_Pause" -msgstr "" +msgstr "_Pausa" -#: ui/gtk.c:1324 +#: ui/gtk.c:1607 msgid "_Reset" -msgstr "" +msgstr "_Reset" -#: ui/gtk.c:1327 +#: ui/gtk.c:1610 msgid "Power _Down" -msgstr "" +msgstr "_Spegni" + +#: ui/gtk.c:1616 +msgid "_Quit" +msgstr "_Esci" -#: ui/gtk.c:1381 +#: ui/gtk.c:1702 +msgid "Zoom _In" +msgstr "_Aumenta zoom" + +#: ui/gtk.c:1709 +msgid "Zoom _Out" +msgstr "_Riduci zoom" + +#: ui/gtk.c:1716 +msgid "Best _Fit" +msgstr "A_nnulla zoom" + +#: ui/gtk.c:1723 msgid "Zoom To _Fit" msgstr "Adatta alla _finestra" -#: ui/gtk.c:1387 +#: ui/gtk.c:1729 msgid "Grab On _Hover" msgstr "Cattura _automatica input" -#: ui/gtk.c:1390 +#: ui/gtk.c:1732 msgid "_Grab Input" msgstr "_Cattura input" -#: ui/gtk.c:1416 +#: ui/gtk.c:1761 msgid "Show _Tabs" msgstr "Mostra _tab" -#: ui/gtk.c:1430 +#: ui/gtk.c:1764 +msgid "Detach Tab" +msgstr "_Sposta in una nuova finestra" + +#: ui/gtk.c:1778 msgid "_Machine" -msgstr "" +msgstr "_Macchina virtuale" -#: ui/gtk.c:1435 +#: ui/gtk.c:1783 msgid "_View" msgstr "_Visualizza" - -#~ msgid "_File" -#~ msgstr "_File" diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py index 3bae769..f7ce3fc 100755 --- a/scripts/vmstate-static-checker.py +++ b/scripts/vmstate-static-checker.py @@ -42,30 +42,44 @@ def check_fields_match(name, s_field, d_field): # Some fields changed names between qemu versions. This list # is used to whitelist such changes in each section / description. changed_names = { + 'apic': ['timer', 'timer_expiry'], 'e1000': ['dev', 'parent_obj'], 'ehci': ['dev', 'pcidev'], 'I440FX': ['dev', 'parent_obj'], 'ich9_ahci': ['card', 'parent_obj'], + 'ich9-ahci': ['ahci', 'ich9_ahci'], + 'ioh3420': ['PCIDevice', 'PCIEDevice'], 'ioh-3240-express-root-port': ['port.br.dev', 'parent_obj.parent_obj.parent_obj', 'port.br.dev.exp.aer_log', 'parent_obj.parent_obj.parent_obj.exp.aer_log'], + 'lsiscsi': ['dev', 'parent_obj'], 'mch': ['d', 'parent_obj'], 'pci_bridge': ['bridge.dev', 'parent_obj', 'bridge.dev.shpc', 'shpc'], 'pcnet': ['pci_dev', 'parent_obj'], 'PIIX3': ['pci_irq_levels', 'pci_irq_levels_vmstate'], 'piix4_pm': ['dev', 'parent_obj', 'pci0_status', - 'acpi_pci_hotplug.acpi_pcihp_pci_status[0x0]'], + 'acpi_pci_hotplug.acpi_pcihp_pci_status[0x0]', + 'pm1a.sts', 'ar.pm1.evt.sts', 'pm1a.en', 'ar.pm1.evt.en', + 'pm1_cnt.cnt', 'ar.pm1.cnt.cnt', + 'tmr.timer', 'ar.tmr.timer', + 'tmr.overflow_time', 'ar.tmr.overflow_time', + 'gpe', 'ar.gpe'], 'rtl8139': ['dev', 'parent_obj'], 'qxl': ['num_surfaces', 'ssd.num_surfaces'], + 'usb-ccid': ['abProtocolDataStructure', 'abProtocolDataStructure.data'], 'usb-host': ['dev', 'parent_obj'], 'usb-mouse': ['usb-ptr-queue', 'HIDPointerEventQueue'], 'usb-tablet': ['usb-ptr-queue', 'HIDPointerEventQueue'], + 'vmware_vga': ['card', 'parent_obj'], + 'vmware_vga_internal': ['depth', 'new_depth'], 'xhci': ['pci_dev', 'parent_obj'], + 'x3130-upstream': ['PCIDevice', 'PCIEDevice'], 'xio3130-express-downstream-port': ['port.br.dev', 'parent_obj.parent_obj.parent_obj', 'port.br.dev.exp.aer_log', 'parent_obj.parent_obj.parent_obj.exp.aer_log'], + 'xio3130-downstream': ['PCIDevice', 'PCIEDevice'], 'xio3130-express-upstream-port': ['br.dev', 'parent_obj.parent_obj', 'br.dev.exp.aer_log', 'parent_obj.parent_obj.exp.aer_log'], @@ -130,6 +144,7 @@ def check_fields(src_fields, dest_fields, desc, sec): advance_src = True advance_dest = True + unused_count = 0 while True: if advance_src: @@ -142,9 +157,10 @@ def check_fields(src_fields, dest_fields, desc, sec): s_iter = s_iter_list.pop() continue else: - # We want to avoid advancing just once -- when entering a - # dest substruct, or when exiting one. - advance_src = True + if unused_count == 0: + # We want to avoid advancing just once -- when entering a + # dest substruct, or when exiting one. + advance_src = True if advance_dest: try: @@ -163,7 +179,37 @@ def check_fields(src_fields, dest_fields, desc, sec): advance_src = False continue else: - advance_dest = True + if unused_count == 0: + advance_dest = True + + if unused_count > 0: + if advance_dest == False: + unused_count = unused_count - s_item["size"] + if unused_count == 0: + advance_dest = True + continue + if unused_count < 0: + print "Section \"" + sec + "\",", + print "Description \"" + desc + "\":", + print "unused size mismatch near \"", + print s_item["field"] + "\"" + bump_taint() + break + continue + + if advance_src == False: + unused_count = unused_count - d_item["size"] + if unused_count == 0: + advance_src = True + continue + if unused_count < 0: + print "Section \"" + sec + "\",", + print "Description \"" + desc + "\":", + print "unused size mismatch near \"", + print d_item["field"] + "\"" + bump_taint() + break + continue if not check_fields_match(desc, s_item["field"], d_item["field"]): # Some fields were put in substructs, keeping the @@ -194,6 +240,20 @@ def check_fields(src_fields, dest_fields, desc, sec): advance_dest = False continue + if s_item["field"] == "unused" or d_item["field"] == "unused": + if s_item["size"] == d_item["size"]: + continue + + if d_item["field"] == "unused": + advance_dest = False + unused_count = d_item["size"] - s_item["size"] + continue + + if s_item["field"] == "unused": + advance_src = False + unused_count = s_item["size"] - d_item["size"] + continue + print "Section \"" + sec + "\",", print "Description \"" + desc + "\":", print "expected field \"" + s_item["field"] + "\",", diff --git a/target-arm/cpu.c b/target-arm/cpu.c index 05e52e0..7cebb76 100644 --- a/target-arm/cpu.c +++ b/target-arm/cpu.c @@ -447,7 +447,7 @@ static void arm1026_initfn(Object *obj) ARMCPRegInfo ifar = { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW, - .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1), + .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]), .resetvalue = 0 }; define_one_arm_cp_reg(cpu, &ifar); diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 369d472..79205ba 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -185,9 +185,9 @@ typedef struct CPUARMState { uint32_t pmsav5_data_ap; /* PMSAv5 MPU data access permissions */ uint32_t pmsav5_insn_ap; /* PMSAv5 MPU insn access permissions */ uint32_t ifsr_el2; /* Fault status registers. */ - uint64_t esr_el[2]; + uint64_t esr_el[4]; uint32_t c6_region[8]; /* MPU base/size registers. */ - uint64_t far_el1; /* Fault address registers. */ + uint64_t far_el[4]; /* Fault address registers. */ uint64_t par_el1; /* Translation result. */ uint32_t c9_insn; /* Cache lockdown registers. */ uint32_t c9_data; diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c index 2b4ce6a..2e9ef64 100644 --- a/target-arm/helper-a64.c +++ b/target-arm/helper-a64.c @@ -465,13 +465,13 @@ void aarch64_cpu_do_interrupt(CPUState *cs) } env->cp15.esr_el[1] = env->exception.syndrome; - env->cp15.far_el1 = env->exception.vaddress; + env->cp15.far_el[1] = env->exception.vaddress; switch (cs->exception_index) { case EXCP_PREFETCH_ABORT: case EXCP_DATA_ABORT: qemu_log_mask(CPU_LOG_INT, "...with FAR 0x%" PRIx64 "\n", - env->cp15.far_el1); + env->cp15.far_el[1]); break; case EXCP_BKPT: case EXCP_UDEF: @@ -489,8 +489,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs) if (is_a64(env)) { env->banked_spsr[aarch64_banked_spsr_index(1)] = pstate_read(env); - env->sp_el[arm_current_pl(env)] = env->xregs[31]; - env->xregs[31] = env->sp_el[1]; + aarch64_save_sp(env, arm_current_pl(env)); env->elr_el[1] = env->pc; } else { env->banked_spsr[0] = cpsr_read(env); @@ -508,6 +507,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs) pstate_write(env, PSTATE_DAIF | PSTATE_MODE_EL1h); env->aarch64 = 1; + aarch64_restore_sp(env, 1); env->pc = addr; cs->interrupt_request |= CPU_INTERRUPT_EXITTB; diff --git a/target-arm/helper.c b/target-arm/helper.c index d343856..f630d96 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -521,7 +521,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = { .access = PL0_W, .type = ARM_CP_NOP }, { .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 2, .access = PL1_RW, - .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1), + .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]), .resetvalue = 0, }, /* Watchpoint Fault Address Register : should actually only be present * for 1136, 1176, 11MPCore. @@ -1516,7 +1516,7 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { /* 64-bit FAR; this entry also gives us the AArch32 DFAR */ { .name = "FAR_EL1", .state = ARM_CP_STATE_BOTH, .opc0 = 3, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 0, - .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el1), + .access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[1]), .resetvalue = 0, }, REGINFO_SENTINEL }; @@ -1801,12 +1801,17 @@ static CPAccessResult aa64_cacheop_access(CPUARMState *env, return CP_ACCESS_OK; } +/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions + * Page D4-1736 (DDI0487A.b) + */ + static void tlbi_aa64_va_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { /* Invalidate by VA (AArch64 version) */ ARMCPU *cpu = arm_env_get_cpu(env); - uint64_t pageaddr = value << 12; + uint64_t pageaddr = sextract64(value << 12, 0, 56); + tlb_flush_page(CPU(cpu), pageaddr); } @@ -1815,7 +1820,8 @@ static void tlbi_aa64_vaa_write(CPUARMState *env, const ARMCPRegInfo *ri, { /* Invalidate by VA, all ASIDs (AArch64 version) */ ARMCPU *cpu = arm_env_get_cpu(env); - uint64_t pageaddr = value << 12; + uint64_t pageaddr = sextract64(value << 12, 0, 56); + tlb_flush_page(CPU(cpu), pageaddr); } @@ -1853,7 +1859,7 @@ static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri) static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri) { - if (!env->pstate & PSTATE_SP) { + if (!(env->pstate & PSTATE_SP)) { /* Access to SP_EL0 is undefined if it's being used as * the stack pointer. */ @@ -2127,6 +2133,13 @@ static const ARMCPRegInfo v8_el2_cp_reginfo[] = { .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1, .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, elr_el[2]) }, + { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_NO_MIGRATE, + .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) }, + { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) }, { .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64, .type = ARM_CP_NO_MIGRATE, .opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0, @@ -2145,6 +2158,13 @@ static const ARMCPRegInfo v8_el3_cp_reginfo[] = { .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 1, .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, elr_el[3]) }, + { .name = "ESR_EL3", .state = ARM_CP_STATE_AA64, + .type = ARM_CP_NO_MIGRATE, + .opc0 = 3, .opc1 = 6, .crn = 5, .crm = 2, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[3]) }, + { .name = "FAR_EL3", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 0, + .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[3]) }, { .name = "SPSR_EL3", .state = ARM_CP_STATE_AA64, .type = ARM_CP_NO_MIGRATE, .opc0 = 3, .opc1 = 6, .crn = 4, .crm = 0, .opc2 = 0, @@ -3425,8 +3445,8 @@ void arm_cpu_do_interrupt(CPUState *cs) /* Fall through to prefetch abort. */ case EXCP_PREFETCH_ABORT: env->cp15.ifsr_el2 = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 32, 32, - env->exception.vaddress); + env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 32, 32, + env->exception.vaddress); qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n", env->cp15.ifsr_el2, (uint32_t)env->exception.vaddress); new_mode = ARM_CPU_MODE_ABT; @@ -3436,8 +3456,8 @@ void arm_cpu_do_interrupt(CPUState *cs) break; case EXCP_DATA_ABORT: env->cp15.esr_el[1] = env->exception.fsr; - env->cp15.far_el1 = deposit64(env->cp15.far_el1, 0, 32, - env->exception.vaddress); + env->cp15.far_el[1] = deposit64(env->cp15.far_el[1], 0, 32, + env->exception.vaddress); qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n", (uint32_t)env->cp15.esr_el[1], (uint32_t)env->exception.vaddress); @@ -4142,8 +4162,8 @@ int arm_cpu_handle_mmu_fault(CPUState *cs, vaddr address, &page_size); if (ret == 0) { /* Map a single [sub]page. */ - phys_addr &= ~(hwaddr)0x3ff; - address &= ~(target_ulong)0x3ff; + phys_addr &= TARGET_PAGE_MASK; + address &= TARGET_PAGE_MASK; tlb_set_page(cs, address, phys_addr, prot, mmu_idx, page_size); return 0; } diff --git a/target-arm/internals.h b/target-arm/internals.h index 564b5fa..08fa697 100644 --- a/target-arm/internals.h +++ b/target-arm/internals.h @@ -105,6 +105,24 @@ enum arm_fprounding { int arm_rmode_to_sf(int rmode); +static inline void aarch64_save_sp(CPUARMState *env, int el) +{ + if (env->pstate & PSTATE_SP) { + env->sp_el[el] = env->xregs[31]; + } else { + env->sp_el[0] = env->xregs[31]; + } +} + +static inline void aarch64_restore_sp(CPUARMState *env, int el) +{ + if (env->pstate & PSTATE_SP) { + env->xregs[31] = env->sp_el[el]; + } else { + env->xregs[31] = env->sp_el[0]; + } +} + static inline void update_spsel(CPUARMState *env, uint32_t imm) { unsigned int cur_el = arm_current_pl(env); @@ -114,21 +132,14 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm) if (!((imm ^ env->pstate) & PSTATE_SP)) { return; } + aarch64_save_sp(env, cur_el); env->pstate = deposit32(env->pstate, 0, 1, imm); /* We rely on illegal updates to SPsel from EL0 to get trapped * at translation time. */ assert(cur_el >= 1 && cur_el <= 3); - if (env->pstate & PSTATE_SP) { - /* Switch from using SP_EL0 to using SP_ELx */ - env->sp_el[0] = env->xregs[31]; - env->xregs[31] = env->sp_el[cur_el]; - } else { - /* Switch from SP_EL0 to SP_ELx */ - env->sp_el[cur_el] = env->xregs[31]; - env->xregs[31] = env->sp_el[0]; - } + aarch64_restore_sp(env, cur_el); } /* Valid Syndrome Register EC field values */ diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c index 5d217ca..c615286 100644 --- a/target-arm/kvm64.c +++ b/target-arm/kvm64.c @@ -21,6 +21,7 @@ #include "sysemu/kvm.h" #include "kvm_arm.h" #include "cpu.h" +#include "internals.h" #include "hw/arm/arm.h" static inline void set_feature(uint64_t *features, int feature) @@ -132,11 +133,7 @@ int kvm_arch_put_registers(CPUState *cs, int level) /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the * QEMU side we keep the current SP in xregs[31] as well. */ - if (env->pstate & PSTATE_SP) { - env->sp_el[1] = env->xregs[31]; - } else { - env->sp_el[0] = env->xregs[31]; - } + aarch64_save_sp(env, 1); reg.id = AARCH64_CORE_REG(regs.sp); reg.addr = (uintptr_t) &env->sp_el[0]; @@ -235,11 +232,7 @@ int kvm_arch_get_registers(CPUState *cs) /* KVM puts SP_EL0 in regs.sp and SP_EL1 in regs.sp_el1. On the * QEMU side we keep the current SP in xregs[31] as well. */ - if (env->pstate & PSTATE_SP) { - env->xregs[31] = env->sp_el[1]; - } else { - env->xregs[31] = env->sp_el[0]; - } + aarch64_restore_sp(env, 1); reg.id = AARCH64_CORE_REG(regs.pc); reg.addr = (uintptr_t) &env->pc; diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 9c1ef52..25ad902 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -376,11 +376,7 @@ void HELPER(exception_return)(CPUARMState *env) uint32_t spsr = env->banked_spsr[spsr_idx]; int new_el, i; - if (env->pstate & PSTATE_SP) { - env->sp_el[cur_el] = env->xregs[31]; - } else { - env->sp_el[0] = env->xregs[31]; - } + aarch64_save_sp(env, cur_el); env->exclusive_addr = -1; @@ -414,7 +410,7 @@ void HELPER(exception_return)(CPUARMState *env) } env->aarch64 = 1; pstate_write(env, spsr); - env->xregs[31] = env->sp_el[new_el]; + aarch64_restore_sp(env, new_el); env->pc = env->elr_el[cur_el]; } diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT Binary files differindex 7ed03fd..d37ec34 100644 --- a/tests/acpi-test-data/pc/DSDT +++ b/tests/acpi-test-data/pc/DSDT diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 62771f7..045eb27 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -487,7 +487,11 @@ static GString *normalize_asl(gchar *asl_code) /* strip comments (different generation days) */ comment = g_strstr_len(asl->str, asl->len, COMMENT_END); if (comment) { - asl = g_string_erase(asl, 0, comment + sizeof(COMMENT_END) - asl->str); + comment += strlen(COMMENT_END); + while (*comment == '\n') { + comment++; + } + asl = g_string_erase(asl, 0, comment - asl->str); } /* strip def block name (it has file path in it) */ @@ -513,11 +513,14 @@ static void xen_sync_dirty_bitmap(XenIOState *state, start_addr >> TARGET_PAGE_BITS, npages, bitmap); if (rc < 0) { - if (rc != -ENODATA) { +#ifndef ENODATA +#define ENODATA ENOENT +#endif + if (errno == ENODATA) { memory_region_set_dirty(framebuffer, 0, size); DPRINTF("xen: track_dirty_vram failed (0x" TARGET_FMT_plx ", 0x" TARGET_FMT_plx "): %s\n", - start_addr, start_addr + size, strerror(-rc)); + start_addr, start_addr + size, strerror(errno)); } return; } |