Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-1' into staging vnc dirty tracking optinizations. various vnc bugfixes. # gpg: Signature made Mon 10 Mar 2014 12:39:54 GMT using RSA key ID D3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" * remotes/kraxel/tags/pull-vnc-1: ui/vnc: disable adaptive update calculations if not needed ui/vnc: optimize setting in vnc_dpy_update() ui/vnc: optimize clearing in find_and_clear_dirty_height() ui/vnc: optimize dirty bitmap tracking ui/vnc: derive cmp_bytes from VNC_DIRTY_PIXELS_PER_BIT ui/vnc: introduce VNC_DIRTY_PIXELS_PER_BIT macro vnc: fix use-after-free in vnc_update_client_sync vnc: Fix qemu crashed when vnc client disconnect suddenly vnc: Fix tight_detect_smooth_image() for lossless case Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/MAINTAINERS b/MAINTAINERS index 7efaccf..7d17f83 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -158,7 +158,6 @@ ---------------------- Overall -M: Gleb Natapov <gleb@redhat.com> M: Paolo Bonzini <pbonzini@redhat.com> L: kvm@vger.kernel.org S: Supported @@ -176,12 +175,14 @@ F: target-ppc/kvm.c S390 +M: Christian Borntraeger <borntraeger@de.ibm.com> +M: Cornelia Huck <cornelia.huck@de.ibm.com> M: Alexander Graf <agraf@suse.de> S: Maintained F: target-s390x/kvm.c +F: hw/intc/s390_flic.[hc] X86 -M: Gleb Natapov <gleb@redhat.com> M: Marcelo Tosatti <mtosatti@redhat.com> L: kvm@vger.kernel.org S: Supported @@ -495,10 +496,13 @@ S390 Virtio-ccw M: Cornelia Huck <cornelia.huck@de.ibm.com> +M: Christian Borntraeger <borntraeger@de.ibm.com> M: Alexander Graf <agraf@suse.de> S: Supported F: hw/s390x/s390-virtio-ccw.c F: hw/s390x/css.[hc] +F: hw/s390x/sclp*.[hc] +F: hw/s390x/ipl*.[hc] T: git git://github.com/cohuck/qemu virtio-ccw-upstr UniCore32 Machines @@ -629,6 +633,7 @@ virtio-ccw M: Cornelia Huck <cornelia.huck@de.ibm.com> +M: Christian Borntraeger <borntraeger@de.ibm.com> S: Supported F: hw/s390x/virtio-ccw.[hc] T: git git://github.com/cohuck/qemu virtio-ccw-upstr
diff --git a/arch_init.c b/arch_init.c index fe17279..60c975d 100644 --- a/arch_init.c +++ b/arch_init.c
@@ -164,8 +164,9 @@ uint8_t *encoded_buf; /* buffer for storing page content */ uint8_t *current_buf; - /* Cache for XBZRLE */ + /* Cache for XBZRLE, Protected by lock. */ PageCache *cache; + QemuMutex lock; } XBZRLE = { .encoded_buf = NULL, .current_buf = NULL, @@ -174,16 +175,52 @@ /* buffer used for XBZRLE decoding */ static uint8_t *xbzrle_decoded_buf; +static void XBZRLE_cache_lock(void) +{ + if (migrate_use_xbzrle()) + qemu_mutex_lock(&XBZRLE.lock); +} + +static void XBZRLE_cache_unlock(void) +{ + if (migrate_use_xbzrle()) + qemu_mutex_unlock(&XBZRLE.lock); +} + int64_t xbzrle_cache_resize(int64_t new_size) { + PageCache *new_cache, *cache_to_free; + if (new_size < TARGET_PAGE_SIZE) { return -1; } + /* no need to lock, the current thread holds qemu big lock */ if (XBZRLE.cache != NULL) { - return cache_resize(XBZRLE.cache, new_size / TARGET_PAGE_SIZE) * - TARGET_PAGE_SIZE; + /* check XBZRLE.cache again later */ + if (pow2floor(new_size) == migrate_xbzrle_cache_size()) { + return pow2floor(new_size); + } + new_cache = cache_init(new_size / TARGET_PAGE_SIZE, + TARGET_PAGE_SIZE); + if (!new_cache) { + DPRINTF("Error creating cache\n"); + return -1; + } + + XBZRLE_cache_lock(); + /* the XBZRLE.cache may have be destroyed, check it again */ + if (XBZRLE.cache != NULL) { + cache_to_free = XBZRLE.cache; + XBZRLE.cache = new_cache; + } else { + cache_to_free = new_cache; + } + XBZRLE_cache_unlock(); + + cache_fini(cache_to_free); } + return pow2floor(new_size); } @@ -539,6 +576,8 @@ ret = ram_control_save_page(f, block->offset, offset, TARGET_PAGE_SIZE, &bytes_sent); + XBZRLE_cache_lock(); + current_addr = block->offset + offset; if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { if (ret != RAM_SAVE_CONTROL_DELAYED) { @@ -587,6 +626,7 @@ acct_info.norm_pages++; } + XBZRLE_cache_unlock(); /* if page is unmodified, continue to the next */ if (bytes_sent > 0) { last_sent_block = block; @@ -654,6 +694,7 @@ migration_bitmap = NULL; } + XBZRLE_cache_lock(); if (XBZRLE.cache) { cache_fini(XBZRLE.cache); g_free(XBZRLE.cache); @@ -663,6 +704,7 @@ XBZRLE.encoded_buf = NULL; XBZRLE.current_buf = NULL; } + XBZRLE_cache_unlock(); } static void ram_migration_cancel(void *opaque) @@ -693,13 +735,17 @@ dirty_rate_high_cnt = 0; if (migrate_use_xbzrle()) { + qemu_mutex_lock_iothread(); XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() / TARGET_PAGE_SIZE, TARGET_PAGE_SIZE); if (!XBZRLE.cache) { + qemu_mutex_unlock_iothread(); DPRINTF("Error creating cache\n"); return -1; } + qemu_mutex_init(&XBZRLE.lock); + qemu_mutex_unlock_iothread(); /* We prefer not to abort if there is no memory */ XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
diff --git a/configure b/configure index 8689435..af44b6a 100755 --- a/configure +++ b/configure
@@ -4968,6 +4968,12 @@ echo "CONFIG_ALPHA_DIS=y" >> $config_target_mak echo "CONFIG_ALPHA_DIS=y" >> config-all-disas.mak ;; + aarch64) + if test -n "${cxx}"; then + echo "CONFIG_ARM_A64_DIS=y" >> $config_target_mak + echo "CONFIG_ARM_A64_DIS=y" >> config-all-disas.mak + fi + ;; arm) echo "CONFIG_ARM_DIS=y" >> $config_target_mak echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak
diff --git a/cpus.c b/cpus.c index 945d85b..b6421fd 100644 --- a/cpus.c +++ b/cpus.c
@@ -1117,8 +1117,13 @@ } } +/* For temporary buffers for forming a name */ +#define VCPU_THREAD_NAME_SIZE 16 + static void qemu_tcg_init_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + tcg_cpu_address_space_init(cpu, cpu->as); /* share a single thread for all cpus with TCG */ @@ -1127,8 +1132,10 @@ cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); tcg_halt_cond = cpu->halt_cond; - qemu_thread_create(cpu->thread, qemu_tcg_cpu_thread_fn, cpu, - QEMU_THREAD_JOINABLE); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif @@ -1144,11 +1151,15 @@ static void qemu_kvm_start_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); - qemu_thread_create(cpu->thread, qemu_kvm_cpu_thread_fn, cpu, - QEMU_THREAD_JOINABLE); + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/KVM", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_kvm_cpu_thread_fn, + cpu, QEMU_THREAD_JOINABLE); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } @@ -1156,10 +1167,14 @@ static void qemu_dummy_start_vcpu(CPUState *cpu) { + char thread_name[VCPU_THREAD_NAME_SIZE]; + cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); - qemu_thread_create(cpu->thread, qemu_dummy_cpu_thread_fn, cpu, + snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/DUMMY", + cpu->cpu_index); + qemu_thread_create(cpu->thread, thread_name, qemu_dummy_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index 2237edb..d1c7ad4 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c
@@ -358,7 +358,7 @@ qemu_bh_delete(s->start_bh); s->start_bh = NULL; - qemu_thread_create(&s->thread, data_plane_thread, + qemu_thread_create(&s->thread, "data_plane", data_plane_thread, s, QEMU_THREAD_JOINABLE); }
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index b1a7ebb..b667d31 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c
@@ -643,6 +643,21 @@ #define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start) #define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_start) +#define ACPI_PCINOHP_OFFSET_HEX (*ssdt_pcinohp_name - *ssdt_pcinohp_start + 1) +#define ACPI_PCINOHP_OFFSET_ADR (*ssdt_pcinohp_adr - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_SIZEOF (*ssdt_pcinohp_end - *ssdt_pcinohp_start) +#define ACPI_PCINOHP_AML (ssdp_pcihp_aml + *ssdt_pcinohp_start) + +#define ACPI_PCIVGA_OFFSET_HEX (*ssdt_pcivga_name - *ssdt_pcivga_start + 1) +#define ACPI_PCIVGA_OFFSET_ADR (*ssdt_pcivga_adr - *ssdt_pcivga_start) +#define ACPI_PCIVGA_SIZEOF (*ssdt_pcivga_end - *ssdt_pcivga_start) +#define ACPI_PCIVGA_AML (ssdp_pcihp_aml + *ssdt_pcivga_start) + +#define ACPI_PCIQXL_OFFSET_HEX (*ssdt_pciqxl_name - *ssdt_pciqxl_start + 1) +#define ACPI_PCIQXL_OFFSET_ADR (*ssdt_pciqxl_adr - *ssdt_pciqxl_start) +#define ACPI_PCIQXL_SIZEOF (*ssdt_pciqxl_end - *ssdt_pciqxl_start) +#define ACPI_PCIQXL_AML (ssdp_pcihp_aml + *ssdt_pciqxl_start) + #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */ #define ACPI_SSDT_HEADER_LENGTH 36 @@ -677,6 +692,33 @@ ssdt_ptr[ACPI_PCIHP_OFFSET_ADR + 2] = slot; } +static void patch_pcinohp(int slot, uint8_t *ssdt_ptr) +{ + unsigned devfn = PCI_DEVFN(slot, 0); + + ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX] = acpi_get_hex(devfn >> 4); + ssdt_ptr[ACPI_PCINOHP_OFFSET_HEX + 1] = acpi_get_hex(devfn); + ssdt_ptr[ACPI_PCINOHP_OFFSET_ADR + 2] = slot; +} + +static void patch_pcivga(int slot, uint8_t *ssdt_ptr) +{ + unsigned devfn = PCI_DEVFN(slot, 0); + + ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX] = acpi_get_hex(devfn >> 4); + ssdt_ptr[ACPI_PCIVGA_OFFSET_HEX + 1] = acpi_get_hex(devfn); + ssdt_ptr[ACPI_PCIVGA_OFFSET_ADR + 2] = slot; +} + +static void patch_pciqxl(int slot, uint8_t *ssdt_ptr) +{ + unsigned devfn = PCI_DEVFN(slot, 0); + + ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX] = acpi_get_hex(devfn >> 4); + ssdt_ptr[ACPI_PCIQXL_OFFSET_HEX + 1] = acpi_get_hex(devfn); + ssdt_ptr[ACPI_PCIQXL_OFFSET_ADR + 2] = slot; +} + /* Assign BSEL property to all buses. In the future, this can be changed * to only assign to buses that support hotplug. */ @@ -737,6 +779,10 @@ AcpiBuildPciBusHotplugState *parent = child->parent; GArray *bus_table = build_alloc_array(); DECLARE_BITMAP(slot_hotplug_enable, PCI_SLOT_MAX); + DECLARE_BITMAP(slot_device_present, PCI_SLOT_MAX); + DECLARE_BITMAP(slot_device_system, PCI_SLOT_MAX); + DECLARE_BITMAP(slot_device_vga, PCI_SLOT_MAX); + DECLARE_BITMAP(slot_device_qxl, PCI_SLOT_MAX); uint8_t op; int i; QObject *bsel; @@ -764,40 +810,82 @@ build_append_byte(bus_table, 0x08); /* NameOp */ build_append_nameseg(bus_table, "BSEL"); build_append_int(bus_table, qint_get_int(qobject_to_qint(bsel))); - memset(slot_hotplug_enable, 0xff, sizeof slot_hotplug_enable); + } else { + /* No bsel - no slots are hot-pluggable */ + memset(slot_hotplug_enable, 0x00, sizeof slot_hotplug_enable); + } - for (i = 0; i < ARRAY_SIZE(bus->devices); ++i) { - DeviceClass *dc; - PCIDeviceClass *pc; - PCIDevice *pdev = bus->devices[i]; + memset(slot_device_present, 0x00, sizeof slot_device_present); + memset(slot_device_system, 0x00, sizeof slot_device_present); + memset(slot_device_vga, 0x00, sizeof slot_device_vga); + memset(slot_device_qxl, 0x00, sizeof slot_device_qxl); - if (!pdev) { - continue; - } + for (i = 0; i < ARRAY_SIZE(bus->devices); i += PCI_FUNC_MAX) { + DeviceClass *dc; + PCIDeviceClass *pc; + PCIDevice *pdev = bus->devices[i]; + int slot = PCI_SLOT(i); - pc = PCI_DEVICE_GET_CLASS(pdev); - dc = DEVICE_GET_CLASS(pdev); + if (!pdev) { + continue; + } - if (!dc->hotpluggable || pc->is_bridge) { - int slot = PCI_SLOT(i); + set_bit(slot, slot_device_present); + pc = PCI_DEVICE_GET_CLASS(pdev); + dc = DEVICE_GET_CLASS(pdev); - clear_bit(slot, slot_hotplug_enable); + if (pc->class_id == PCI_CLASS_BRIDGE_ISA) { + set_bit(slot, slot_device_system); + } + + if (pc->class_id == PCI_CLASS_DISPLAY_VGA) { + set_bit(slot, slot_device_vga); + + if (object_dynamic_cast(OBJECT(pdev), "qxl-vga")) { + set_bit(slot, slot_device_qxl); } } - /* Append Device object for each slot which supports eject */ - for (i = 0; i < PCI_SLOT_MAX; i++) { - bool can_eject = test_bit(i, slot_hotplug_enable); - if (can_eject) { - void *pcihp = acpi_data_push(bus_table, - ACPI_PCIHP_SIZEOF); - memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); - patch_pcihp(i, pcihp); - bus_hotplug_support = true; - } + if (!dc->hotpluggable || pc->is_bridge) { + clear_bit(slot, slot_hotplug_enable); } + } + /* Append Device object for each slot */ + for (i = 0; i < PCI_SLOT_MAX; i++) { + bool can_eject = test_bit(i, slot_hotplug_enable); + bool present = test_bit(i, slot_device_present); + bool vga = test_bit(i, slot_device_vga); + bool qxl = test_bit(i, slot_device_qxl); + bool system = test_bit(i, slot_device_system); + if (can_eject) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIHP_SIZEOF); + memcpy(pcihp, ACPI_PCIHP_AML, ACPI_PCIHP_SIZEOF); + patch_pcihp(i, pcihp); + bus_hotplug_support = true; + } else if (qxl) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIQXL_SIZEOF); + memcpy(pcihp, ACPI_PCIQXL_AML, ACPI_PCIQXL_SIZEOF); + patch_pciqxl(i, pcihp); + } else if (vga) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCIVGA_SIZEOF); + memcpy(pcihp, ACPI_PCIVGA_AML, ACPI_PCIVGA_SIZEOF); + patch_pcivga(i, pcihp); + } else if (system) { + /* Nothing to do: system devices are in DSDT. */ + } else if (present) { + void *pcihp = acpi_data_push(bus_table, + ACPI_PCINOHP_SIZEOF); + memcpy(pcihp, ACPI_PCINOHP_AML, ACPI_PCINOHP_SIZEOF); + patch_pcinohp(i, pcihp); + } + } + + if (bsel) { method = build_alloc_method("DVNT", 2); for (i = 0; i < PCI_SLOT_MAX; i++) { @@ -976,7 +1064,14 @@ { AcpiBuildPciBusHotplugState hotplug_state; - PCIBus *bus = find_i440fx(); /* TODO: Q35 support */ + Object *pci_host; + PCIBus *bus = NULL; + bool ambiguous; + + pci_host = object_resolve_path_type("", TYPE_PCI_HOST_BRIDGE, &ambiguous); + if (!ambiguous && pci_host) { + bus = PCI_HOST_BRIDGE(pci_host)->bus; + } build_pci_bus_state_init(&hotplug_state, NULL);
diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl index b23d5e0..0a1e252 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl
@@ -80,6 +80,8 @@ Name(_HID, EisaId("PNP0A03")) Name(_ADR, 0x00) Name(_UID, 1) +//#define PX13 S0B_ +// External(PX13, DeviceObj) } } @@ -88,34 +90,6 @@ /**************************************************************** - * VGA - ****************************************************************/ - - Scope(\_SB.PCI0) { - Device(VGA) { - Name(_ADR, 0x00020000) - OperationRegion(PCIC, PCI_Config, Zero, 0x4) - Field(PCIC, DWordAcc, NoLock, Preserve) { - VEND, 32 - } - Method(_S1D, 0, NotSerialized) { - Return (0x00) - } - Method(_S2D, 0, NotSerialized) { - Return (0x00) - } - Method(_S3D, 0, NotSerialized) { - If (LEqual(VEND, 0x1001b36)) { - Return (0x03) // QXL - } Else { - Return (0x00) - } - } - } - } - - -/**************************************************************** * PIIX4 PM ****************************************************************/ @@ -132,6 +106,9 @@ ****************************************************************/ Scope(\_SB.PCI0) { + + External(ISA, DeviceObj) + Device(ISA) { Name(_ADR, 0x00010000)
diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated index 1e58801..94c6e8e 100644 --- a/hw/i386/acpi-dsdt.hex.generated +++ b/hw/i386/acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ 0x53, 0x44, 0x54, -0x87, +0x85, 0x11, 0x0, 0x0, 0x1, -0xb8, +0x8b, 0x42, 0x58, 0x50, @@ -146,7 +146,7 @@ 0x1, 0x10, 0x4e, -0x15, +0x18, 0x2e, 0x5f, 0x53, @@ -163,9 +163,9 @@ 0x53, 0x11, 0x42, -0x7, 0xa, -0x6e, +0xa, +0x9e, 0x88, 0xd, 0x0, @@ -217,11 +217,59 @@ 0x0, 0xd, 0xff, +0xad, +0x0, +0x0, +0x0, +0xa1, +0x88, +0xd, +0x0, +0x1, +0xc, +0x3, +0x0, +0x0, +0xf, +0xae, +0xff, +0xae, +0x0, +0x0, +0xf1, +0x0, +0x88, +0xd, +0x0, +0x1, +0xc, +0x3, +0x0, +0x0, +0x20, +0xaf, +0xdf, +0xaf, +0x0, +0x0, +0xc0, +0x0, +0x88, +0xd, +0x0, +0x1, +0xc, +0x3, +0x0, +0x0, +0xe4, +0xaf, +0xff, 0xff, 0x0, 0x0, -0x0, -0xf3, +0x1c, +0x50, 0x87, 0x17, 0x0, @@ -347,7 +395,7 @@ 0x45, 0x53, 0xa, -0x5c, +0x8c, 0x50, 0x53, 0x33, @@ -358,7 +406,7 @@ 0x45, 0x53, 0xa, -0x60, +0x90, 0x50, 0x45, 0x33, @@ -369,7 +417,7 @@ 0x45, 0x53, 0xa, -0x68, +0x98, 0x50, 0x4c, 0x33, @@ -638,103 +686,6 @@ 0x79, 0x0, 0x10, -0x40, -0x6, -0x2e, -0x5f, -0x53, -0x42, -0x5f, -0x50, -0x43, -0x49, -0x30, -0x5b, -0x82, -0x43, -0x5, -0x56, -0x47, -0x41, -0x5f, -0x8, -0x5f, -0x41, -0x44, -0x52, -0xc, -0x0, -0x0, -0x2, -0x0, -0x5b, -0x80, -0x50, -0x43, -0x49, -0x43, -0x2, -0x0, -0xa, -0x4, -0x5b, -0x81, -0xb, -0x50, -0x43, -0x49, -0x43, -0x3, -0x56, -0x45, -0x4e, -0x44, -0x20, -0x14, -0x8, -0x5f, -0x53, -0x31, -0x44, -0x0, -0xa4, -0x0, -0x14, -0x8, -0x5f, -0x53, -0x32, -0x44, -0x0, -0xa4, -0x0, -0x14, -0x19, -0x5f, -0x53, -0x33, -0x44, -0x0, -0xa0, -0xe, -0x93, -0x56, -0x45, -0x4e, -0x44, -0xc, -0x36, -0x1b, -0x0, -0x1, -0xa4, -0xa, -0x3, -0xa1, -0x3, -0xa4, -0x0, -0x10, 0x25, 0x2e, 0x5f, @@ -860,7 +811,7 @@ 0x4e, 0x1, 0x10, -0x4b, +0x4a, 0x1e, 0x2f, 0x3, @@ -878,7 +829,7 @@ 0x5f, 0x5b, 0x82, -0x2d, +0x2c, 0x53, 0x4d, 0x43, @@ -898,9 +849,8 @@ 0x53, 0x54, 0x41, -0xb, -0x0, -0xff, +0xa, +0xf0, 0x8, 0x5f, 0x43, @@ -4061,7 +4011,7 @@ 0x1, 0x10, 0x47, -0xe, +0x11, 0x5f, 0x53, 0x42, @@ -4291,6 +4241,54 @@ 0x3, 0x75, 0x60, +0x5b, +0x82, +0x2e, +0x50, +0x52, +0x45, +0x53, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xd, +0x41, +0x43, +0x50, +0x49, +0x30, +0x30, +0x30, +0x34, +0x0, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0xd, +0xa, +0xa, +0x47, +0x1, +0x0, +0xaf, +0x0, +0xaf, +0x0, +0x20, +0x79, +0x0, +0x8, +0x5f, +0x53, +0x54, +0x41, +0xa, +0xb, 0x10, 0x42, 0xc, @@ -4488,5 +4486,5 @@ 0x0 }; static unsigned short piix_dsdt_applesmc_sta[] = { -0x384 +0x353 };
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl index d618e9e..f4d2a2d 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -72,6 +72,8 @@ Name(_ADR, 0x00) Name(_UID, 1) + External(ISA, DeviceObj) + // _OSC: based on sample of ACPI3.0b spec Name(SUPP, 0) // PCI _OSC Support Field value Name(CTRL, 0) // PCI _OSC Control Field value @@ -134,34 +136,13 @@ /**************************************************************** - * VGA - ****************************************************************/ - - Scope(\_SB.PCI0) { - Device(VGA) { - Name(_ADR, 0x00010000) - Method(_S1D, 0, NotSerialized) { - Return (0x00) - } - Method(_S2D, 0, NotSerialized) { - Return (0x00) - } - Method(_S3D, 0, NotSerialized) { - Return (0x00) - } - } - } - - -/**************************************************************** * LPC ISA bridge ****************************************************************/ Scope(\_SB.PCI0) { /* PCI D31:f0 LPC ISA bridge */ Device(ISA) { - /* PCI D31:f0 */ - Name(_ADR, 0x001f0000) + Name (_ADR, 0x001F0000) // _ADR: Address /* ICH9 PCI to ISA irq remapping */ OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated index 6d885a9..6c29f3b 100644 --- a/hw/i386/q35-acpi-dsdt.hex.generated +++ b/hw/i386/q35-acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ 0x53, 0x44, 0x54, -0xdf, +0xd7, 0x1c, 0x0, 0x0, 0x1, -0xff, +0x3e, 0x42, 0x58, 0x50, @@ -415,11 +415,11 @@ 0x0, 0x0, 0x0, -0xf7, +0xd7, 0xc, 0x0, 0x0, -0xf8, +0xd8, 0xc, 0x88, 0xd, @@ -853,61 +853,6 @@ 0x79, 0x0, 0x10, -0x36, -0x2e, -0x5f, -0x53, -0x42, -0x5f, -0x50, -0x43, -0x49, -0x30, -0x5b, -0x82, -0x2a, -0x56, -0x47, -0x41, -0x5f, -0x8, -0x5f, -0x41, -0x44, -0x52, -0xc, -0x0, -0x0, -0x1, -0x0, -0x14, -0x8, -0x5f, -0x53, -0x31, -0x44, -0x0, -0xa4, -0x0, -0x14, -0x8, -0x5f, -0x53, -0x32, -0x44, -0x0, -0xa4, -0x0, -0x14, -0x8, -0x5f, -0x53, -0x33, -0x44, -0x0, -0xa4, -0x0, -0x10, 0x4c, 0x7, 0x2e, @@ -1033,7 +978,7 @@ 0x4e, 0x1, 0x10, -0x4b, +0x4a, 0x1e, 0x2f, 0x3, @@ -1051,7 +996,7 @@ 0x5f, 0x5b, 0x82, -0x2d, +0x2c, 0x53, 0x4d, 0x43, @@ -1071,9 +1016,8 @@ 0x53, 0x54, 0x41, -0xb, -0x0, -0xff, +0xa, +0xf0, 0x8, 0x5f, 0x43, @@ -7016,7 +6960,7 @@ 0x1, 0x10, 0x47, -0xe, +0x11, 0x5f, 0x53, 0x42, @@ -7121,8 +7065,8 @@ 0x54, 0x1, 0xb, -0x0, -0xaf, +0xd8, +0xc, 0xa, 0x20, 0x5b, @@ -7246,6 +7190,54 @@ 0x3, 0x75, 0x60, +0x5b, +0x82, +0x2e, +0x50, +0x52, +0x45, +0x53, +0x8, +0x5f, +0x48, +0x49, +0x44, +0xd, +0x41, +0x43, +0x50, +0x49, +0x30, +0x30, +0x30, +0x34, +0x0, +0x8, +0x5f, +0x43, +0x52, +0x53, +0x11, +0xd, +0xa, +0xa, +0x47, +0x1, +0xd8, +0xc, +0xd8, +0xc, +0x0, +0x20, +0x79, +0x0, +0x8, +0x5f, +0x53, +0x54, +0x41, +0xa, +0xb, 0x10, 0x4f, 0x8, @@ -7392,5 +7384,5 @@ 0x0 }; static unsigned short q35_dsdt_applesmc_sta[] = { -0x431 +0x3fa };
diff --git a/hw/i386/ssdt-pcihp.dsl b/hw/i386/ssdt-pcihp.dsl index cc245c3..ac91c05 100644 --- a/hw/i386/ssdt-pcihp.dsl +++ b/hw/i386/ssdt-pcihp.dsl
@@ -46,5 +46,55 @@ } } + ACPI_EXTRACT_DEVICE_START ssdt_pcinohp_start + ACPI_EXTRACT_DEVICE_END ssdt_pcinohp_end + ACPI_EXTRACT_DEVICE_STRING ssdt_pcinohp_name + + // Extract the offsets of the device name, address dword and the slot + // name byte - we fill them in for each device. + Device(SBB) { + ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcinohp_adr + Name(_ADR, 0xAA0000) + } + + ACPI_EXTRACT_DEVICE_START ssdt_pcivga_start + ACPI_EXTRACT_DEVICE_END ssdt_pcivga_end + ACPI_EXTRACT_DEVICE_STRING ssdt_pcivga_name + + // Extract the offsets of the device name, address dword and the slot + // name byte - we fill them in for each device. + Device(SCC) { + ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pcivga_adr + Name(_ADR, 0xAA0000) + Method(_S1D, 0, NotSerialized) { + Return (0x00) + } + Method(_S2D, 0, NotSerialized) { + Return (0x00) + } + Method(_S3D, 0, NotSerialized) { + Return (0x00) + } + } + + ACPI_EXTRACT_DEVICE_START ssdt_pciqxl_start + ACPI_EXTRACT_DEVICE_END ssdt_pciqxl_end + ACPI_EXTRACT_DEVICE_STRING ssdt_pciqxl_name + + // Extract the offsets of the device name, address dword and the slot + // name byte - we fill them in for each device. + Device(SDD) { + ACPI_EXTRACT_NAME_DWORD_CONST ssdt_pciqxl_adr + Name(_ADR, 0xAA0000) + Method(_S1D, 0, NotSerialized) { + Return (0x00) + } + Method(_S2D, 0, NotSerialized) { + Return (0x00) + } + Method(_S3D, 0, NotSerialized) { + Return (0x03) // QXL + } + } } }
diff --git a/hw/i386/ssdt-pcihp.hex.generated b/hw/i386/ssdt-pcihp.hex.generated index 610a631..b599b46 100644 --- a/hw/i386/ssdt-pcihp.hex.generated +++ b/hw/i386/ssdt-pcihp.hex.generated
@@ -1,23 +1,38 @@ static unsigned char ssdt_pcihp_name[] = { -0x33 +0x34 +}; +static unsigned char ssdt_pcivga_end[] = { +0x99 +}; +static unsigned char ssdt_pcivga_name[] = { +0x70 }; static unsigned char ssdt_pcihp_adr[] = { -0x44 +0x45 +}; +static unsigned char ssdt_pcinohp_end[] = { +0x6d }; static unsigned char ssdt_pcihp_end[] = { -0x5b +0x5c +}; +static unsigned char ssdt_pciqxl_start[] = { +0x99 +}; +static unsigned char ssdt_pcinohp_name[] = { +0x5f }; static unsigned char ssdp_pcihp_aml[] = { 0x53, 0x53, 0x44, 0x54, -0x5b, +0xc6, 0x0, 0x0, 0x0, 0x1, -0xe8, +0x6b, 0x42, 0x58, 0x50, @@ -45,7 +60,8 @@ 0x13, 0x20, 0x10, -0x36, +0x41, +0xa, 0x5c, 0x2e, 0x5f, @@ -98,11 +114,138 @@ 0x5f, 0x53, 0x55, -0x4e +0x4e, +0x5b, +0x82, +0xf, +0x53, +0x42, +0x42, +0x5f, +0x8, +0x5f, +0x41, +0x44, +0x52, +0xc, +0x0, +0x0, +0xaa, +0x0, +0x5b, +0x82, +0x2a, +0x53, +0x43, +0x43, +0x5f, +0x8, +0x5f, +0x41, +0x44, +0x52, +0xc, +0x0, +0x0, +0xaa, +0x0, +0x14, +0x8, +0x5f, +0x53, +0x31, +0x44, +0x0, +0xa4, +0x0, +0x14, +0x8, +0x5f, +0x53, +0x32, +0x44, +0x0, +0xa4, +0x0, +0x14, +0x8, +0x5f, +0x53, +0x33, +0x44, +0x0, +0xa4, +0x0, +0x5b, +0x82, +0x2b, +0x53, +0x44, +0x44, +0x5f, +0x8, +0x5f, +0x41, +0x44, +0x52, +0xc, +0x0, +0x0, +0xaa, +0x0, +0x14, +0x8, +0x5f, +0x53, +0x31, +0x44, +0x0, +0xa4, +0x0, +0x14, +0x8, +0x5f, +0x53, +0x32, +0x44, +0x0, +0xa4, +0x0, +0x14, +0x9, +0x5f, +0x53, +0x33, +0x44, +0x0, +0xa4, +0xa, +0x3 +}; +static unsigned char ssdt_pciqxl_adr[] = { +0xa6 +}; +static unsigned char ssdt_pcinohp_adr[] = { +0x69 +}; +static unsigned char ssdt_pcivga_adr[] = { +0x7a +}; +static unsigned char ssdt_pciqxl_name[] = { +0x9c +}; +static unsigned char ssdt_pcivga_start[] = { +0x6d +}; +static unsigned char ssdt_pciqxl_end[] = { +0xc6 }; static unsigned char ssdt_pcihp_start[] = { -0x30 +0x31 }; static unsigned char ssdt_pcihp_id[] = { -0x3d +0x3e +}; +static unsigned char ssdt_pcinohp_start[] = { +0x5c };
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 655b8c5..29af3d7 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c
@@ -281,7 +281,7 @@ kbd_update_irq(s); break; case KBD_CCMD_READ_INPORT: - kbd_queue(s, 0x00, 0); + kbd_queue(s, 0x80, 0); break; case KBD_CCMD_READ_OUTPORT: kbd_queue(s, s->outport, 0);
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index 652dd47..b527932 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c
@@ -93,9 +93,6 @@ uint32_t mask = 1 << vector; uint64_t entry = s->ioredtbl[vector]; - if (entry & (1 << IOAPIC_LVT_POLARITY_SHIFT)) { - level = !level; - } if (((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1) == IOAPIC_TRIGGER_LEVEL) { /* level triggered */
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 3c0342e..fd23c46 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c
@@ -397,12 +397,15 @@ static void virtio_net_set_queues(VirtIONet *n) { int i; + int r; for (i = 0; i < n->max_queues; i++) { if (i < n->curr_queues) { - assert(!peer_attach(n, i)); + r = peer_attach(n, i); + assert(!r); } else { - assert(!peer_detach(n, i)); + r = peer_detach(n, i); + assert(!r); } } }
diff --git a/hw/pci-host/pam.c b/hw/pci-host/pam.c index ec6be46..e1e95aa 100644 --- a/hw/pci-host/pam.c +++ b/hw/pci-host/pam.c
@@ -68,7 +68,7 @@ /* XXX: should distinguish read/write cases */ memory_region_init_alias(&mem->alias[0], OBJECT(dev), "pam-pci", pci_address_space, start, size); - memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", pci_address_space, + memory_region_init_alias(&mem->alias[2], OBJECT(dev), "pam-pci", ram_memory, start, size); for (i = 0; i < 4; ++i) {
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 8ecd11e..02cde6f 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c
@@ -221,29 +221,23 @@ DeviceState *dev, uint8_t **exp_cap, Error **errp) { - PCIDevice *pci_dev = PCI_DEVICE(dev); *exp_cap = hotplug_dev->config + hotplug_dev->exp.exp_cap; uint16_t sltsta = pci_get_word(*exp_cap + PCI_EXP_SLTSTA); - PCIE_DEV_PRINTF(pci_dev, "hotplug state: %d\n", state); + PCIE_DEV_PRINTF(PCI_DEVICE(dev), "hotplug state: %d\n", state); if (sltsta & PCI_EXP_SLTSTA_EIS) { /* the slot is electromechanically locked. * This error is propagated up to qdev and then to HMP/QMP. */ error_setg_errno(errp, -EBUSY, "slot is electromechanically locked"); } - - /* TODO: multifunction hot-plug. - * Right now, only a device of function = 0 is allowed to be - * hot plugged/unplugged. - */ - assert(PCI_FUNC(pci_dev->devfn) == 0); } void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { uint8_t *exp_cap; + PCIDevice *pci_dev = PCI_DEVICE(dev); pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp); @@ -256,6 +250,12 @@ return; } + /* TODO: multifunction hot-plug. + * Right now, only a device of function = 0 is allowed to be + * hot plugged/unplugged. + */ + assert(PCI_FUNC(pci_dev->devfn) == 0); + pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, PCI_EXP_SLTSTA_PDS); pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index aa913df..7213c89 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c
@@ -546,10 +546,10 @@ printf("%s: failed to initialize vcard\n", EMULATED_DEV_NAME); return -1; } - qemu_thread_create(&card->event_thread_id, event_thread, card, - QEMU_THREAD_JOINABLE); - qemu_thread_create(&card->apdu_thread_id, handle_apdu_thread, card, - QEMU_THREAD_JOINABLE); + qemu_thread_create(&card->event_thread_id, "ccid/event", event_thread, + card, QEMU_THREAD_JOINABLE); + qemu_thread_create(&card->apdu_thread_id, "ccid/apdu", handle_apdu_thread, + card, QEMU_THREAD_JOINABLE); return 0; }
diff --git a/include/exec/memory.h b/include/exec/memory.h index 9101fc3..c084db2 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h
@@ -836,13 +836,13 @@ hwaddr offset); /** - * memory_region_present: translate an address/size relative to a - * MemoryRegion into a #MemoryRegionSection. + * memory_region_present: checks if an address relative to a @parent + * translates into #MemoryRegion within @parent * * Answer whether a #MemoryRegion within @parent covers the address * @addr. * - * @parent: a MemoryRegion within which @addr is a relative address + * @parent: a #MemoryRegion within which @addr is a relative address * @addr: the area within @parent to be searched */ bool memory_region_present(MemoryRegion *parent, hwaddr addr);
diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 3e32c65..f7e3b9b 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h
@@ -52,12 +52,13 @@ void qemu_event_wait(QemuEvent *ev); void qemu_event_destroy(QemuEvent *ev); -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode); void *qemu_thread_join(QemuThread *thread); void qemu_thread_get_self(QemuThread *thread); bool qemu_thread_is_self(QemuThread *thread); void qemu_thread_exit(void *retval); +void qemu_thread_naming(bool enable); #endif
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c index 24f7088..3477ab3 100644 --- a/libcacard/vscclient.c +++ b/libcacard/vscclient.c
@@ -269,7 +269,7 @@ send_msg(VSC_ReaderRemove, VSCARD_MINIMAL_READER_ID, NULL, 0); /* launch the event_thread. This will trigger reader adds for all the * existing readers */ - qemu_thread_create(&thread_id, event_thread, NULL, 0); + qemu_thread_create(&thread_id, "vsc/event", event_thread, NULL, 0); return 0; }
diff --git a/linux-user/alpha/syscall.h b/linux-user/alpha/syscall.h index 15a0100..ed13d9a 100644 --- a/linux-user/alpha/syscall.h +++ b/linux-user/alpha/syscall.h
@@ -39,6 +39,7 @@ }; #define UNAME_MACHINE "alpha" +#define UNAME_MINIMUM_RELEASE "2.6.32" #undef TARGET_EDEADLK #define TARGET_EDEADLK 11
diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h index 73f2931..ce2c2a8 100644 --- a/linux-user/arm/syscall.h +++ b/linux-user/arm/syscall.h
@@ -40,5 +40,6 @@ #else #define UNAME_MACHINE "armv5tel" #endif +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS
diff --git a/linux-user/cris/syscall.h b/linux-user/cris/syscall.h index 832ee64..f5783c0 100644 --- a/linux-user/cris/syscall.h +++ b/linux-user/cris/syscall.h
@@ -1,8 +1,8 @@ #ifndef CRIS_SYSCALL_H #define CRIS_SYSCALL_H 1 - #define UNAME_MACHINE "cris" +#define UNAME_MINIMUM_RELEASE "2.6.32" /* pt_regs not only specifices the format in the user-struct during * ptrace but is also the frame format used in the kernel prologue/epilogues
diff --git a/linux-user/i386/syscall.h b/linux-user/i386/syscall.h index 12b8c3b..9bfc1ad 100644 --- a/linux-user/i386/syscall.h +++ b/linux-user/i386/syscall.h
@@ -144,5 +144,6 @@ }; #define UNAME_MACHINE "i686" +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS
diff --git a/linux-user/m68k/syscall.h b/linux-user/m68k/syscall.h index 2618793..889eaf7 100644 --- a/linux-user/m68k/syscall.h +++ b/linux-user/m68k/syscall.h
@@ -15,7 +15,7 @@ uint16_t __fill; }; - #define UNAME_MACHINE "m68k" +#define UNAME_MINIMUM_RELEASE "2.6.32" void do_m68k_simcall(CPUM68KState *, int);
diff --git a/linux-user/main.c b/linux-user/main.c index be9491b..dee1084 100644 --- a/linux-user/main.c +++ b/linux-user/main.c
@@ -2400,6 +2400,10 @@ ret = 0; break; default: + info->si_signo = TARGET_SIGTRAP; + info->si_errno = 0; + queue_signal(env, info->si_signo, &*info); + ret = 0; break; }
diff --git a/linux-user/microblaze/syscall.h b/linux-user/microblaze/syscall.h index d550989..5b5f6b4 100644 --- a/linux-user/microblaze/syscall.h +++ b/linux-user/microblaze/syscall.h
@@ -1,8 +1,8 @@ #ifndef MICROBLAZE_SYSCALLS_H #define MICROBLAZE_SYSCALLS_H 1 - #define UNAME_MACHINE "microblaze" +#define UNAME_MINIMUM_RELEASE "2.6.32" /* We use microblaze_reg_t to keep things similar to the kernel sources. */ typedef uint32_t microblaze_reg_t;
diff --git a/linux-user/mips/syscall.h b/linux-user/mips/syscall.h index 9d437d9..5bc5696 100644 --- a/linux-user/mips/syscall.h +++ b/linux-user/mips/syscall.h
@@ -225,5 +225,6 @@ #define TARGET_QEMU_ESIGRETURN 255 #define UNAME_MACHINE "mips" +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS
diff --git a/linux-user/mips64/syscall.h b/linux-user/mips64/syscall.h index 1710f76..a7f5a58 100644 --- a/linux-user/mips64/syscall.h +++ b/linux-user/mips64/syscall.h
@@ -222,5 +222,6 @@ #define TARGET_QEMU_ESIGRETURN 255 #define UNAME_MACHINE "mips64" +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS
diff --git a/linux-user/openrisc/syscall.h b/linux-user/openrisc/syscall.h index bdbb577..c3b36da 100644 --- a/linux-user/openrisc/syscall.h +++ b/linux-user/openrisc/syscall.h
@@ -22,3 +22,4 @@ }; #define UNAME_MACHINE "openrisc" +#define UNAME_MINIMUM_RELEASE "2.6.32"
diff --git a/linux-user/ppc/syscall.h b/linux-user/ppc/syscall.h index ba36acb..6514c63 100644 --- a/linux-user/ppc/syscall.h +++ b/linux-user/ppc/syscall.h
@@ -62,5 +62,6 @@ #else #define UNAME_MACHINE "ppc" #endif +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS
diff --git a/linux-user/s390x/syscall.h b/linux-user/s390x/syscall.h index e5ce30b..aaad512 100644 --- a/linux-user/s390x/syscall.h +++ b/linux-user/s390x/syscall.h
@@ -21,5 +21,6 @@ }; #define UNAME_MACHINE "s390x" +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_CLONE_BACKWARDS2
diff --git a/linux-user/sh4/syscall.h b/linux-user/sh4/syscall.h index 014bf58..ccd2216 100644 --- a/linux-user/sh4/syscall.h +++ b/linux-user/sh4/syscall.h
@@ -10,3 +10,4 @@ }; #define UNAME_MACHINE "sh4" +#define UNAME_MINIMUM_RELEASE "2.6.32"
diff --git a/linux-user/signal.c b/linux-user/signal.c index 04638e2..c8a1da0 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c
@@ -1233,8 +1233,14 @@ return 1; } - for (i = 0; i < 32 * 2; i++) { - __get_user(env->vfp.regs[i], &aux->fpsimd.vregs[i]); + for (i = 0; i < 32; i++) { +#ifdef TARGET_WORDS_BIGENDIAN + __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]); + __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]); +#else + __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]); + __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]); +#endif } __get_user(fpsr, &aux->fpsimd.fpsr); vfp_set_fpsr(env, fpsr); @@ -1267,7 +1273,7 @@ CPUARMState *env) { struct target_rt_sigframe *frame; - abi_ulong frame_addr; + abi_ulong frame_addr, return_addr; frame_addr = get_sigframe(ka, env); if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { @@ -1284,15 +1290,19 @@ __put_user(target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size); target_setup_sigframe(frame, env, set); - /* mov x8,#__NR_rt_sigreturn; svc #0 */ - __put_user(0xd2801168, &frame->tramp[0]); - __put_user(0xd4000001, &frame->tramp[1]); + if (ka->sa_flags & TARGET_SA_RESTORER) { + return_addr = ka->sa_restorer; + } else { + /* mov x8,#__NR_rt_sigreturn; svc #0 */ + __put_user(0xd2801168, &frame->tramp[0]); + __put_user(0xd4000001, &frame->tramp[1]); + return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp); + } env->xregs[0] = usig; env->xregs[31] = frame_addr; env->xregs[29] = env->xregs[31] + offsetof(struct target_rt_sigframe, fp); env->pc = ka->_sa_handler; - env->xregs[30] = env->xregs[31] + - offsetof(struct target_rt_sigframe, tramp); + env->xregs[30] = return_addr; if (info) { if (copy_siginfo_to_user(&frame->info, info)) { goto give_sigsegv;
diff --git a/linux-user/sparc/syscall.h b/linux-user/sparc/syscall.h index 4cd64bf..9549ea0 100644 --- a/linux-user/sparc/syscall.h +++ b/linux-user/sparc/syscall.h
@@ -7,6 +7,7 @@ }; #define UNAME_MACHINE "sun4" +#define UNAME_MINIMUM_RELEASE "2.6.32" /* SPARC kernels don't define this in their Kconfig, but they have the * same ABI as if they did, implemented by sparc-specific code which fishes
diff --git a/linux-user/sparc64/syscall.h b/linux-user/sparc64/syscall.h index e60bf31..82b1680 100644 --- a/linux-user/sparc64/syscall.h +++ b/linux-user/sparc64/syscall.h
@@ -8,6 +8,7 @@ }; #define UNAME_MACHINE "sun4u" +#define UNAME_MINIMUM_RELEASE "2.6.32" /* SPARC kernels don't define this in their Kconfig, but they have the * same ABI as if they did, implemented by sparc-specific code which fishes
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 1407b7a..e2c10cc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c
@@ -1904,23 +1904,16 @@ return get_errno(connect(sockfd, addr, addrlen)); } -/* do_sendrecvmsg() Must return target values and target errnos. */ -static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, - int flags, int send) +/* do_sendrecvmsg_locked() Must return target values and target errnos. */ +static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, + int flags, int send) { abi_long ret, len; - struct target_msghdr *msgp; struct msghdr msg; int count; struct iovec *vec; abi_ulong target_vec; - /* FIXME */ - if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, - msgp, - target_msg, - send ? 1 : 0)) - return -TARGET_EFAULT; if (msgp->msg_name) { msg.msg_namelen = tswap32(msgp->msg_namelen); msg.msg_name = alloca(msg.msg_namelen); @@ -1975,10 +1968,75 @@ out: unlock_iovec(vec, target_vec, count, !send); out2: + return ret; +} + +static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, + int flags, int send) +{ + abi_long ret; + struct target_msghdr *msgp; + + if (!lock_user_struct(send ? VERIFY_READ : VERIFY_WRITE, + msgp, + target_msg, + send ? 1 : 0)) { + return -TARGET_EFAULT; + } + ret = do_sendrecvmsg_locked(fd, msgp, flags, send); unlock_user_struct(msgp, target_msg, send ? 0 : 1); return ret; } +#ifdef TARGET_NR_sendmmsg +/* We don't rely on the C library to have sendmmsg/recvmmsg support, + * so it might not have this *mmsg-specific flag either. + */ +#ifndef MSG_WAITFORONE +#define MSG_WAITFORONE 0x10000 +#endif + +static abi_long do_sendrecvmmsg(int fd, abi_ulong target_msgvec, + unsigned int vlen, unsigned int flags, + int send) +{ + struct target_mmsghdr *mmsgp; + abi_long ret = 0; + int i; + + if (vlen > UIO_MAXIOV) { + vlen = UIO_MAXIOV; + } + + mmsgp = lock_user(VERIFY_WRITE, target_msgvec, sizeof(*mmsgp) * vlen, 1); + if (!mmsgp) { + return -TARGET_EFAULT; + } + + for (i = 0; i < vlen; i++) { + ret = do_sendrecvmsg_locked(fd, &mmsgp[i].msg_hdr, flags, send); + if (is_error(ret)) { + break; + } + mmsgp[i].msg_len = tswap32(ret); + /* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ + if (flags & MSG_WAITFORONE) { + flags |= MSG_DONTWAIT; + } + } + + unlock_user(mmsgp, target_msgvec, sizeof(*mmsgp) * i); + + /* Return number of datagrams sent if we sent any at all; + * otherwise return the error. + */ + if (i) { + return i; + } + return ret; +} +#endif + /* If we don't have a system accept4() then just call accept. * The callsites to do_accept4() will ensure that they don't * pass a non-zero flags argument in this config. @@ -4528,6 +4586,9 @@ { return tswap16(id); } + +#define put_user_id(x, gaddr) put_user_u16(x, gaddr) + #else /* !USE_UID16 */ static inline int high2lowuid(int uid) { @@ -4549,6 +4610,9 @@ { return tswap32(id); } + +#define put_user_id(x, gaddr) put_user_u32(x, gaddr) + #endif /* USE_UID16 */ void syscall_init(void) @@ -6121,11 +6185,17 @@ puts = NULL; } ret = get_errno(sigtimedwait(&set, &uinfo, puts)); - if (!is_error(ret) && arg2) { - if (!(p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0))) - goto efault; - host_to_target_siginfo(p, &uinfo); - unlock_user(p, arg2, sizeof(target_siginfo_t)); + if (!is_error(ret)) { + if (arg2) { + p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), + 0); + if (!p) { + goto efault; + } + host_to_target_siginfo(p, &uinfo); + unlock_user(p, arg2, sizeof(target_siginfo_t)); + } + ret = host_to_target_signal(ret); } } break; @@ -6710,6 +6780,14 @@ ret = do_sendrecvmsg(arg1, arg2, arg3, 1); break; #endif +#ifdef TARGET_NR_sendmmsg + case TARGET_NR_sendmmsg: + ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 1); + break; + case TARGET_NR_recvmmsg: + ret = do_sendrecvmmsg(arg1, arg2, arg3, arg4, 0); + break; +#endif #ifdef TARGET_NR_sendto case TARGET_NR_sendto: ret = do_sendto(arg1, arg2, arg3, arg4, arg5, arg6); @@ -7805,9 +7883,9 @@ uid_t ruid, euid, suid; ret = get_errno(getresuid(&ruid, &euid, &suid)); if (!is_error(ret)) { - if (put_user_u16(high2lowuid(ruid), arg1) - || put_user_u16(high2lowuid(euid), arg2) - || put_user_u16(high2lowuid(suid), arg3)) + if (put_user_id(high2lowuid(ruid), arg1) + || put_user_id(high2lowuid(euid), arg2) + || put_user_id(high2lowuid(suid), arg3)) goto efault; } } @@ -7826,9 +7904,9 @@ gid_t rgid, egid, sgid; ret = get_errno(getresgid(&rgid, &egid, &sgid)); if (!is_error(ret)) { - if (put_user_u16(high2lowgid(rgid), arg1) - || put_user_u16(high2lowgid(egid), arg2) - || put_user_u16(high2lowgid(sgid), arg3)) + if (put_user_id(high2lowgid(rgid), arg1) + || put_user_id(high2lowgid(egid), arg2) + || put_user_id(high2lowgid(sgid), arg3)) goto efault; } }
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 3c8869e..732c9e3 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h
@@ -53,7 +53,8 @@ #define TARGET_IOC_NRBITS 8 #define TARGET_IOC_TYPEBITS 8 -#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) \ +#if defined(TARGET_I386) || (defined(TARGET_ARM) && defined(TARGET_ABI32)) \ + || defined(TARGET_SPARC) \ || defined(TARGET_M68K) || defined(TARGET_SH4) || defined(TARGET_CRIS) /* 16 bit uid wrappers emulation */ #define USE_UID16 @@ -239,6 +240,10 @@ return __cmsg; } +struct target_mmsghdr { + struct target_msghdr msg_hdr; /* Message header */ + unsigned int msg_len; /* Number of bytes transmitted */ +}; struct target_rusage { struct target_timeval ru_utime; /* user time used */
diff --git a/linux-user/unicore32/syscall.h b/linux-user/unicore32/syscall.h index 010cdd8..f7e5525 100644 --- a/linux-user/unicore32/syscall.h +++ b/linux-user/unicore32/syscall.h
@@ -51,5 +51,6 @@ #define UC32_SYSCALL_NR_set_tls (UC32_SYSCALL_ARCH_BASE + 5) #define UNAME_MACHINE "UniCore-II" +#define UNAME_MINIMUM_RELEASE "2.6.32" #endif /* __UC32_SYSCALL_H__ */
diff --git a/linux-user/x86_64/syscall.h b/linux-user/x86_64/syscall.h index 81314cf..e03b5a0 100644 --- a/linux-user/x86_64/syscall.h +++ b/linux-user/x86_64/syscall.h
@@ -91,6 +91,7 @@ }; #define UNAME_MACHINE "x86_64" +#define UNAME_MINIMUM_RELEASE "2.6.32" #define TARGET_ARCH_SET_GS 0x1001 #define TARGET_ARCH_SET_FS 0x1002
diff --git a/memory.c b/memory.c index 59ecc28..3f1df23 100644 --- a/memory.c +++ b/memory.c
@@ -1562,7 +1562,7 @@ bool memory_region_present(MemoryRegion *parent, hwaddr addr) { MemoryRegion *mr = memory_region_find(parent, addr, 1).mr; - if (!mr) { + if (!mr || (mr == parent)) { return false; } memory_region_unref(mr);
diff --git a/migration.c b/migration.c index 14235b2..00f465e 100644 --- a/migration.c +++ b/migration.c
@@ -695,6 +695,6 @@ /* Notify before starting migration thread */ notifier_list_notify(&migration_state_notifiers, s); - qemu_thread_create(&s->thread, migration_thread, s, + qemu_thread_create(&s->thread, "migration", migration_thread, s, QEMU_THREAD_JOINABLE); }
diff --git a/pc-bios/README b/pc-bios/README index 5914200..2bb6357 100644 --- a/pc-bios/README +++ b/pc-bios/README
@@ -12,7 +12,7 @@ 1275-1994 (referred to as Open Firmware) compliant firmware. The included images for PowerPC (for 32 and 64 bit PPC CPUs), Sparc32 (including QEMU,tcx.bin and QEMU,cgthree.bin) and Sparc64 are built - from OpenBIOS SVN revision 1246. + from OpenBIOS SVN revision 1280. - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc index f4a3a39..8a21389 100644 --- a/pc-bios/openbios-ppc +++ b/pc-bios/openbios-ppc Binary files differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32 index bb7cdfb..d4d00e5 100644 --- a/pc-bios/openbios-sparc32 +++ b/pc-bios/openbios-sparc32 Binary files differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 index 46b4fdd..4182052 100644 --- a/pc-bios/openbios-sparc64 +++ b/pc-bios/openbios-sparc64 Binary files differ
diff --git a/qemu-file.c b/qemu-file.c index f074af1..e5ec798 100644 --- a/qemu-file.c +++ b/qemu-file.c
@@ -105,7 +105,7 @@ res = fwrite(buf, 1, size, s->stdio_file); if (res != size) { - return -EIO; /* fake errno value */ + return -errno; } return res; }
diff --git a/qemu-options.hx b/qemu-options.hx index 56e5fdf..068da2d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx
@@ -328,9 +328,11 @@ ETEXI DEF("name", HAS_ARG, QEMU_OPTION_name, - "-name string1[,process=string2]\n" + "-name string1[,process=string2][,debug-threads=on|off]\n" " set the name of the guest\n" - " string1 sets the window title and string2 the process name (on Linux)\n", + " string1 sets the window title and string2 the process name (on Linux)\n" + " When debug-threads is enabled, individual threads are given a separate name (on Linux)\n" + " NOTE: The thread names are for debugging and not a stable API.\n", QEMU_ARCH_ALL) STEXI @item -name @var{name} @@ -339,6 +341,7 @@ This name will be displayed in the SDL window caption. The @var{name} will also be used for the VNC server. Also optionally set the top visible process name in Linux. +Naming of individual threads can also be enabled on Linux to aid debugging. ETEXI DEF("uuid", HAS_ARG, QEMU_OPTION_uuid,
diff --git a/roms/openbios b/roms/openbios index 8881262..1ac3fb9 160000 --- a/roms/openbios +++ b/roms/openbios
@@ -1 +1 @@ -Subproject commit 888126272f92294b0da45158393f1b862742cf6b +Subproject commit 1ac3fb92c109f5545d373a0576b87750c53cce19
diff --git a/savevm.c b/savevm.c index 7329fc5..d094fbb 100644 --- a/savevm.c +++ b/savevm.c
@@ -527,13 +527,13 @@ if (qemu_file_rate_limit(f)) { return 0; } - trace_savevm_section_start(); + trace_savevm_section_start(se->idstr, se->section_id); /* Section type */ qemu_put_byte(f, QEMU_VM_SECTION_PART); qemu_put_be32(f, se->section_id); ret = se->ops->save_live_iterate(f, se->opaque); - trace_savevm_section_end(se->section_id); + trace_savevm_section_end(se->idstr, se->section_id); if (ret < 0) { qemu_file_set_error(f, ret); @@ -565,13 +565,13 @@ continue; } } - trace_savevm_section_start(); + trace_savevm_section_start(se->idstr, se->section_id); /* Section type */ qemu_put_byte(f, QEMU_VM_SECTION_END); qemu_put_be32(f, se->section_id); ret = se->ops->save_live_complete(f, se->opaque); - trace_savevm_section_end(se->section_id); + trace_savevm_section_end(se->idstr, se->section_id); if (ret < 0) { qemu_file_set_error(f, ret); return; @@ -584,7 +584,7 @@ if ((!se->ops || !se->ops->save_state) && !se->vmsd) { continue; } - trace_savevm_section_start(); + trace_savevm_section_start(se->idstr, se->section_id); /* Section type */ qemu_put_byte(f, QEMU_VM_SECTION_FULL); qemu_put_be32(f, se->section_id); @@ -598,7 +598,7 @@ qemu_put_be32(f, se->version_id); vmstate_save(f, se); - trace_savevm_section_end(se->section_id); + trace_savevm_section_end(se->idstr, se->section_id); } qemu_put_byte(f, QEMU_VM_EOF);
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 04d7ae3..f43eb67 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c
@@ -13,6 +13,11 @@ #include "tcg-be-ldst.h" #include "qemu/bitops.h" +/* We're going to re-use TCGType in setting of the SF bit, which controls + the size of the operation performed. If we know the values match, it + makes things much cleaner. */ +QEMU_BUILD_BUG_ON(TCG_TYPE_I32 != 0 || TCG_TYPE_I64 != 1); + #ifndef NDEBUG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { "%x0", "%x1", "%x2", "%x3", "%x4", "%x5", "%x6", "%x7", @@ -66,24 +71,22 @@ # endif #endif -static inline void reloc_pc26(void *code_ptr, tcg_target_long target) +static inline void reloc_pc26(void *code_ptr, intptr_t target) { - tcg_target_long offset; uint32_t insn; - offset = (target - (tcg_target_long)code_ptr) / 4; + intptr_t offset = (target - (intptr_t)code_ptr) / 4; /* read instruction, mask away previous PC_REL26 parameter contents, set the proper offset, then write back the instruction. */ - insn = *(uint32_t *)code_ptr; + uint32_t insn = *(uint32_t *)code_ptr; insn = deposit32(insn, 0, 26, offset); *(uint32_t *)code_ptr = insn; } -static inline void reloc_pc19(void *code_ptr, tcg_target_long target) +static inline void reloc_pc19(void *code_ptr, intptr_t target) { - tcg_target_long offset; uint32_t insn; - offset = (target - (tcg_target_long)code_ptr) / 4; + intptr_t offset = (target - (intptr_t)code_ptr) / 4; /* read instruction, mask away previous PC_REL19 parameter contents, set the proper offset, then write back the instruction. */ - insn = *(uint32_t *)code_ptr; + uint32_t insn = *(uint32_t *)code_ptr; insn = deposit32(insn, 5, 19, offset); *(uint32_t *)code_ptr = insn; } @@ -302,18 +305,8 @@ TCGReg rd, TCGReg rn, tcg_target_long offset) { /* use LDUR with BASE register with 9bit signed unscaled offset */ - unsigned int mod, off; - - if (offset < 0) { - off = (256 + offset); - mod = 0x1; - } else { - off = offset; - mod = 0x0; - } - - mod |= op_type; - tcg_out32(s, op_data << 24 | mod << 20 | off << 12 | rn << 5 | rd); + tcg_out32(s, op_data << 24 | op_type << 20 + | (offset & 0x1ff) << 12 | rn << 5 | rd); } /* tcg_out_ldst_12 expects a scaled unsigned immediate offset */ @@ -327,7 +320,8 @@ | op_type << 20 | scaled_uimm << 10 | rn << 5 | rd); } -static inline void tcg_out_movr(TCGContext *s, int ext, TCGReg rd, TCGReg src) +static inline void tcg_out_movr(TCGContext *s, TCGType ext, + TCGReg rd, TCGReg src) { /* register to register move using MOV (shifted register with no shift) */ /* using MOV 0x2a0003e0 | (shift).. */ @@ -408,7 +402,8 @@ } /* mov alias implemented with add immediate, useful to move to/from SP */ -static inline void tcg_out_movr_sp(TCGContext *s, int ext, TCGReg rd, TCGReg rn) +static inline void tcg_out_movr_sp(TCGContext *s, TCGType ext, + TCGReg rd, TCGReg rn) { /* using ADD 0x11000000 | (ext) | rn << 5 | rd */ unsigned int base = ext ? 0x91000000 : 0x11000000; @@ -438,7 +433,7 @@ } static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc, - int ext, TCGReg rd, TCGReg rn, TCGReg rm, + TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, int shift_imm) { /* Using shifted register arithmetic operations */ @@ -454,7 +449,7 @@ tcg_out32(s, base | rm << 16 | shift | rn << 5 | rd); } -static inline void tcg_out_mul(TCGContext *s, int ext, +static inline void tcg_out_mul(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) { /* Using MADD 0x1b000000 with Ra = wzr alias MUL 0x1b007c00 */ @@ -463,7 +458,7 @@ } static inline void tcg_out_shiftrot_reg(TCGContext *s, - enum aarch64_srr_opc opc, int ext, + enum aarch64_srr_opc opc, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm) { /* using 2-source data processing instructions 0x1ac02000 */ @@ -471,23 +466,23 @@ tcg_out32(s, base | rm << 16 | opc << 8 | rn << 5 | rd); } -static inline void tcg_out_ubfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn, - unsigned int a, unsigned int b) +static inline void tcg_out_ubfm(TCGContext *s, TCGType ext, TCGReg rd, + TCGReg rn, unsigned int a, unsigned int b) { /* Using UBFM 0x53000000 Wd, Wn, a, b */ unsigned int base = ext ? 0xd3400000 : 0x53000000; tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd); } -static inline void tcg_out_sbfm(TCGContext *s, int ext, TCGReg rd, TCGReg rn, - unsigned int a, unsigned int b) +static inline void tcg_out_sbfm(TCGContext *s, TCGType ext, TCGReg rd, + TCGReg rn, unsigned int a, unsigned int b) { /* Using SBFM 0x13000000 Wd, Wn, a, b */ unsigned int base = ext ? 0x93400000 : 0x13000000; tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd); } -static inline void tcg_out_extr(TCGContext *s, int ext, TCGReg rd, +static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm, unsigned int a) { /* Using EXTR 0x13800000 Wd, Wn, Wm, a */ @@ -495,7 +490,7 @@ tcg_out32(s, base | rm << 16 | a << 10 | rn << 5 | rd); } -static inline void tcg_out_shl(TCGContext *s, int ext, +static inline void tcg_out_shl(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) { int bits, max; @@ -504,28 +499,28 @@ tcg_out_ubfm(s, ext, rd, rn, bits - (m & max), max - (m & max)); } -static inline void tcg_out_shr(TCGContext *s, int ext, +static inline void tcg_out_shr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) { int max = ext ? 63 : 31; tcg_out_ubfm(s, ext, rd, rn, m & max, max); } -static inline void tcg_out_sar(TCGContext *s, int ext, +static inline void tcg_out_sar(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) { int max = ext ? 63 : 31; tcg_out_sbfm(s, ext, rd, rn, m & max, max); } -static inline void tcg_out_rotr(TCGContext *s, int ext, +static inline void tcg_out_rotr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) { int max = ext ? 63 : 31; tcg_out_extr(s, ext, rd, rn, rn, m & max); } -static inline void tcg_out_rotl(TCGContext *s, int ext, +static inline void tcg_out_rotl(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int m) { int bits, max; @@ -534,24 +529,23 @@ tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max)); } -static inline void tcg_out_cmp(TCGContext *s, int ext, TCGReg rn, TCGReg rm, - int shift_imm) +static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg rn, TCGReg rm) { /* Using CMP alias SUBS wzr, Wn, Wm */ - tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, shift_imm); + tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, 0); } -static inline void tcg_out_cset(TCGContext *s, int ext, TCGReg rd, TCGCond c) +static inline void tcg_out_cset(TCGContext *s, TCGType ext, + TCGReg rd, TCGCond c) { /* Using CSET alias of CSINC 0x1a800400 Xd, XZR, XZR, invert(cond) */ unsigned int base = ext ? 0x9a9f07e0 : 0x1a9f07e0; tcg_out32(s, base | tcg_cond_to_aarch64[tcg_invert_cond(c)] << 12 | rd); } -static inline void tcg_out_goto(TCGContext *s, tcg_target_long target) +static inline void tcg_out_goto(TCGContext *s, intptr_t target) { - tcg_target_long offset; - offset = (target - (tcg_target_long)s->code_ptr) / 4; + intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; if (offset < -0x02000000 || offset >= 0x02000000) { /* out of 26bit range */ @@ -582,11 +576,9 @@ tcg_out32(s, insn); } -static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, - tcg_target_long target) +static inline void tcg_out_goto_cond(TCGContext *s, TCGCond c, intptr_t target) { - tcg_target_long offset; - offset = (target - (tcg_target_long)s->code_ptr) / 4; + intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; if (offset < -0x40000 || offset >= 0x40000) { /* out of 19bit range */ @@ -607,11 +599,9 @@ tcg_out32(s, 0xd61f0000 | reg << 5); } -static inline void tcg_out_call(TCGContext *s, tcg_target_long target) +static inline void tcg_out_call(TCGContext *s, intptr_t target) { - tcg_target_long offset; - - offset = (target - (tcg_target_long)s->code_ptr) / 4; + intptr_t offset = (target - (intptr_t)s->code_ptr) / 4; if (offset < -0x02000000 || offset >= 0x02000000) { /* out of 26bit rng */ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, target); @@ -638,7 +628,7 @@ to test a 32bit reg against 0xff000000, pass M = 8, R = 8. to test a 32bit reg against 0xff0000ff, pass M = 16, R = 8. */ -static inline void tcg_out_tst(TCGContext *s, int ext, TCGReg rn, +static inline void tcg_out_tst(TCGContext *s, TCGType ext, TCGReg rn, unsigned int m, unsigned int r) { /* using TST alias of ANDS XZR, Xn,#bimm64 0x7200001f */ @@ -647,8 +637,8 @@ } /* and a register with a bit pattern, similarly to TST, no flags change */ -static inline void tcg_out_andi(TCGContext *s, int ext, TCGReg rd, TCGReg rn, - unsigned int m, unsigned int r) +static inline void tcg_out_andi(TCGContext *s, TCGType ext, TCGReg rd, + TCGReg rn, unsigned int m, unsigned int r) { /* using AND 0x12000000 */ unsigned int base = ext ? 0x92400000 : 0x12000000; @@ -663,9 +653,8 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr) { - tcg_target_long target, offset; - target = (tcg_target_long)addr; - offset = (target - (tcg_target_long)jmp_addr) / 4; + intptr_t target = addr; + intptr_t offset = (target - (intptr_t)jmp_addr) / 4; if (offset < -0x02000000 || offset >= 0x02000000) { /* out of 26bit range */ @@ -701,21 +690,23 @@ } } -static inline void tcg_out_rev(TCGContext *s, int ext, TCGReg rd, TCGReg rm) +static inline void tcg_out_rev(TCGContext *s, TCGType ext, + TCGReg rd, TCGReg rm) { /* using REV 0x5ac00800 */ unsigned int base = ext ? 0xdac00c00 : 0x5ac00800; tcg_out32(s, base | rm << 5 | rd); } -static inline void tcg_out_rev16(TCGContext *s, int ext, TCGReg rd, TCGReg rm) +static inline void tcg_out_rev16(TCGContext *s, TCGType ext, + TCGReg rd, TCGReg rm) { /* using REV16 0x5ac00400 */ unsigned int base = ext ? 0xdac00400 : 0x5ac00400; tcg_out32(s, base | rm << 5 | rd); } -static inline void tcg_out_sxt(TCGContext *s, int ext, int s_bits, +static inline void tcg_out_sxt(TCGContext *s, TCGType ext, int s_bits, TCGReg rd, TCGReg rn) { /* using ALIASes SXTB 0x13001c00, SXTH 0x13003c00, SXTW 0x93407c00 @@ -733,7 +724,7 @@ tcg_out_ubfm(s, 0, rd, rn, 0, bits); } -static inline void tcg_out_addi(TCGContext *s, int ext, +static inline void tcg_out_addi(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int aimm) { /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */ @@ -753,7 +744,7 @@ tcg_out32(s, base | aimm | (rn << 5) | rd); } -static inline void tcg_out_subi(TCGContext *s, int ext, +static inline void tcg_out_subi(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn, unsigned int aimm) { /* sub immediate aimm unsigned 12bit value (with LSL 0 or 12) */ @@ -773,11 +764,6 @@ tcg_out32(s, base | aimm | (rn << 5) | rd); } -static inline void tcg_out_nop(TCGContext *s) -{ - tcg_out32(s, 0xd503201f); -} - #ifdef CONFIG_SOFTMMU /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr, * int mmu_idx, uintptr_t ra) @@ -801,7 +787,8 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - reloc_pc19(lb->label_ptr[0], (tcg_target_long)s->code_ptr); + reloc_pc19(lb->label_ptr[0], (intptr_t)s->code_ptr); + tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, lb->addrlo_reg); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, lb->mem_index); @@ -815,23 +802,21 @@ tcg_out_movr(s, 1, lb->datalo_reg, TCG_REG_X0); } - tcg_out_goto(s, (tcg_target_long)lb->raddr); + tcg_out_goto(s, (intptr_t)lb->raddr); } static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *lb) { - reloc_pc19(lb->label_ptr[0], (tcg_target_long)s->code_ptr); + reloc_pc19(lb->label_ptr[0], (intptr_t)s->code_ptr); tcg_out_movr(s, 1, TCG_REG_X0, TCG_AREG0); tcg_out_movr(s, (TARGET_LONG_BITS == 64), TCG_REG_X1, lb->addrlo_reg); tcg_out_movr(s, 1, TCG_REG_X2, lb->datalo_reg); tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, lb->mem_index); - tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_X4, (tcg_target_long)lb->raddr); + tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_X4, (intptr_t)lb->raddr); tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, - (tcg_target_long)qemu_st_helpers[lb->opc & 3]); + (intptr_t)qemu_st_helpers[lb->opc & 3]); tcg_out_callr(s, TCG_REG_TMP); - - tcg_out_nop(s); tcg_out_goto(s, (tcg_target_long)lb->raddr); } @@ -893,7 +878,7 @@ (is_read ? offsetof(CPUTLBEntry, addr_read) : offsetof(CPUTLBEntry, addr_write))); /* Perform the address comparison. */ - tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3, 0); + tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3); *label_ptr = s->code_ptr; /* If not equal, we jump to the slow path. */ tcg_out_goto_cond_noaddr(s, TCG_COND_NE); @@ -1088,16 +1073,23 @@ } static void tcg_out_op(TCGContext *s, TCGOpcode opc, - const TCGArg *args, const int *const_args) + const TCGArg args[TCG_MAX_OP_ARGS], + const int const_args[TCG_MAX_OP_ARGS]) { - /* ext will be set in the switch below, which will fall through to the - common code. It triggers the use of extended regs where appropriate. */ - int ext = 0; + /* 99% of the time, we can signal the use of extension registers + by looking to see if the opcode handles 64-bit data. */ + TCGType ext = (tcg_op_defs[opc].flags & TCG_OPF_64BIT) != 0; + + /* Hoist the loads of the most common arguments. */ + TCGArg a0 = args[0]; + TCGArg a1 = args[1]; + TCGArg a2 = args[2]; + int c2 = const_args[2]; switch (opc) { case INDEX_op_exit_tb: - tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, args[0]); - tcg_out_goto(s, (tcg_target_long)tb_ret_addr); + tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0); + tcg_out_goto(s, (intptr_t)tb_ret_addr); break; case INDEX_op_goto_tb: @@ -1105,23 +1097,23 @@ #error "USE_DIRECT_JUMP required for aarch64" #endif assert(s->tb_jmp_offset != NULL); /* consistency for USE_DIRECT_JUMP */ - s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf; + s->tb_jmp_offset[a0] = s->code_ptr - s->code_buf; /* actual branch destination will be patched by aarch64_tb_set_jmp_target later, beware retranslation. */ tcg_out_goto_noaddr(s); - s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf; + s->tb_next_offset[a0] = s->code_ptr - s->code_buf; break; case INDEX_op_call: if (const_args[0]) { - tcg_out_call(s, args[0]); + tcg_out_call(s, a0); } else { - tcg_out_callr(s, args[0]); + tcg_out_callr(s, a0); } break; case INDEX_op_br: - tcg_out_goto_label(s, args[0]); + tcg_out_goto_label(s, a0); break; case INDEX_op_ld_i32: @@ -1144,123 +1136,95 @@ case INDEX_op_st16_i64: case INDEX_op_st32_i64: tcg_out_ldst(s, aarch64_ldst_get_data(opc), aarch64_ldst_get_type(opc), - args[0], args[1], args[2]); - break; - - case INDEX_op_mov_i64: - ext = 1; /* fall through */ - case INDEX_op_mov_i32: - tcg_out_movr(s, ext, args[0], args[1]); - break; - - case INDEX_op_movi_i64: - tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]); - break; - case INDEX_op_movi_i32: - tcg_out_movi(s, TCG_TYPE_I32, args[0], args[1]); + a0, a1, a2); break; case INDEX_op_add_i64: - ext = 1; /* fall through */ case INDEX_op_add_i32: - tcg_out_arith(s, ARITH_ADD, ext, args[0], args[1], args[2], 0); + tcg_out_arith(s, ARITH_ADD, ext, a0, a1, a2, 0); break; case INDEX_op_sub_i64: - ext = 1; /* fall through */ case INDEX_op_sub_i32: - tcg_out_arith(s, ARITH_SUB, ext, args[0], args[1], args[2], 0); + tcg_out_arith(s, ARITH_SUB, ext, a0, a1, a2, 0); break; case INDEX_op_and_i64: - ext = 1; /* fall through */ case INDEX_op_and_i32: - tcg_out_arith(s, ARITH_AND, ext, args[0], args[1], args[2], 0); + tcg_out_arith(s, ARITH_AND, ext, a0, a1, a2, 0); break; case INDEX_op_or_i64: - ext = 1; /* fall through */ case INDEX_op_or_i32: - tcg_out_arith(s, ARITH_OR, ext, args[0], args[1], args[2], 0); + tcg_out_arith(s, ARITH_OR, ext, a0, a1, a2, 0); break; case INDEX_op_xor_i64: - ext = 1; /* fall through */ case INDEX_op_xor_i32: - tcg_out_arith(s, ARITH_XOR, ext, args[0], args[1], args[2], 0); + tcg_out_arith(s, ARITH_XOR, ext, a0, a1, a2, 0); break; case INDEX_op_mul_i64: - ext = 1; /* fall through */ case INDEX_op_mul_i32: - tcg_out_mul(s, ext, args[0], args[1], args[2]); + tcg_out_mul(s, ext, a0, a1, a2); break; case INDEX_op_shl_i64: - ext = 1; /* fall through */ case INDEX_op_shl_i32: - if (const_args[2]) { /* LSL / UBFM Wd, Wn, (32 - m) */ - tcg_out_shl(s, ext, args[0], args[1], args[2]); + if (c2) { /* LSL / UBFM Wd, Wn, (32 - m) */ + tcg_out_shl(s, ext, a0, a1, a2); } else { /* LSL / LSLV */ - tcg_out_shiftrot_reg(s, SRR_SHL, ext, args[0], args[1], args[2]); + tcg_out_shiftrot_reg(s, SRR_SHL, ext, a0, a1, a2); } break; case INDEX_op_shr_i64: - ext = 1; /* fall through */ case INDEX_op_shr_i32: - if (const_args[2]) { /* LSR / UBFM Wd, Wn, m, 31 */ - tcg_out_shr(s, ext, args[0], args[1], args[2]); + if (c2) { /* LSR / UBFM Wd, Wn, m, 31 */ + tcg_out_shr(s, ext, a0, a1, a2); } else { /* LSR / LSRV */ - tcg_out_shiftrot_reg(s, SRR_SHR, ext, args[0], args[1], args[2]); + tcg_out_shiftrot_reg(s, SRR_SHR, ext, a0, a1, a2); } break; case INDEX_op_sar_i64: - ext = 1; /* fall through */ case INDEX_op_sar_i32: - if (const_args[2]) { /* ASR / SBFM Wd, Wn, m, 31 */ - tcg_out_sar(s, ext, args[0], args[1], args[2]); + if (c2) { /* ASR / SBFM Wd, Wn, m, 31 */ + tcg_out_sar(s, ext, a0, a1, a2); } else { /* ASR / ASRV */ - tcg_out_shiftrot_reg(s, SRR_SAR, ext, args[0], args[1], args[2]); + tcg_out_shiftrot_reg(s, SRR_SAR, ext, a0, a1, a2); } break; case INDEX_op_rotr_i64: - ext = 1; /* fall through */ case INDEX_op_rotr_i32: - if (const_args[2]) { /* ROR / EXTR Wd, Wm, Wm, m */ - tcg_out_rotr(s, ext, args[0], args[1], args[2]); + if (c2) { /* ROR / EXTR Wd, Wm, Wm, m */ + tcg_out_rotr(s, ext, a0, a1, a2); } else { /* ROR / RORV */ - tcg_out_shiftrot_reg(s, SRR_ROR, ext, args[0], args[1], args[2]); + tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, a2); } break; case INDEX_op_rotl_i64: - ext = 1; /* fall through */ case INDEX_op_rotl_i32: /* same as rotate right by (32 - m) */ - if (const_args[2]) { /* ROR / EXTR Wd, Wm, Wm, 32 - m */ - tcg_out_rotl(s, ext, args[0], args[1], args[2]); + if (c2) { /* ROR / EXTR Wd, Wm, Wm, 32 - m */ + tcg_out_rotl(s, ext, a0, a1, a2); } else { - tcg_out_arith(s, ARITH_SUB, 0, - TCG_REG_TMP, TCG_REG_XZR, args[2], 0); - tcg_out_shiftrot_reg(s, SRR_ROR, ext, - args[0], args[1], TCG_REG_TMP); + tcg_out_arith(s, ARITH_SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2, 0); + tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, TCG_REG_TMP); } break; case INDEX_op_brcond_i64: - ext = 1; /* fall through */ - case INDEX_op_brcond_i32: /* CMP 0, 1, cond(2), label 3 */ - tcg_out_cmp(s, ext, args[0], args[1], 0); - tcg_out_goto_label_cond(s, args[2], args[3]); + case INDEX_op_brcond_i32: + tcg_out_cmp(s, ext, a0, a1); + tcg_out_goto_label_cond(s, a2, args[3]); break; case INDEX_op_setcond_i64: - ext = 1; /* fall through */ case INDEX_op_setcond_i32: - tcg_out_cmp(s, ext, args[1], args[2], 0); - tcg_out_cset(s, 0, args[0], args[3]); + tcg_out_cmp(s, ext, a1, a2); + tcg_out_cset(s, 0, a0, args[3]); break; case INDEX_op_qemu_ld8u: @@ -1300,44 +1264,50 @@ tcg_out_qemu_st(s, args, 3); break; - case INDEX_op_bswap64_i64: - ext = 1; /* fall through */ case INDEX_op_bswap32_i64: + /* Despite the _i64, this is a 32-bit bswap. */ + ext = 0; + /* FALLTHRU */ + case INDEX_op_bswap64_i64: case INDEX_op_bswap32_i32: - tcg_out_rev(s, ext, args[0], args[1]); + tcg_out_rev(s, ext, a0, a1); break; case INDEX_op_bswap16_i64: case INDEX_op_bswap16_i32: - tcg_out_rev16(s, 0, args[0], args[1]); + tcg_out_rev16(s, 0, a0, a1); break; case INDEX_op_ext8s_i64: - ext = 1; /* fall through */ case INDEX_op_ext8s_i32: - tcg_out_sxt(s, ext, 0, args[0], args[1]); + tcg_out_sxt(s, ext, 0, a0, a1); break; case INDEX_op_ext16s_i64: - ext = 1; /* fall through */ case INDEX_op_ext16s_i32: - tcg_out_sxt(s, ext, 1, args[0], args[1]); + tcg_out_sxt(s, ext, 1, a0, a1); break; case INDEX_op_ext32s_i64: - tcg_out_sxt(s, 1, 2, args[0], args[1]); + tcg_out_sxt(s, 1, 2, a0, a1); break; case INDEX_op_ext8u_i64: case INDEX_op_ext8u_i32: - tcg_out_uxt(s, 0, args[0], args[1]); + tcg_out_uxt(s, 0, a0, a1); break; case INDEX_op_ext16u_i64: case INDEX_op_ext16u_i32: - tcg_out_uxt(s, 1, args[0], args[1]); + tcg_out_uxt(s, 1, a0, a1); break; case INDEX_op_ext32u_i64: - tcg_out_movr(s, 0, args[0], args[1]); + tcg_out_movr(s, 0, a0, a1); break; + case INDEX_op_mov_i64: + case INDEX_op_mov_i32: + case INDEX_op_movi_i64: + case INDEX_op_movi_i32: + /* Always implemented with tcg_out_mov/i, never with tcg_out_op. */ default: - tcg_abort(); /* opcode not implemented */ + /* Opcode not implemented. */ + tcg_abort(); } } @@ -1441,12 +1411,6 @@ static void tcg_target_init(TCGContext *s) { -#if !defined(CONFIG_USER_ONLY) - /* fail safe */ - if ((1ULL << CPU_TLB_ENTRY_BITS) != sizeof(CPUTLBEntry)) { - tcg_abort(); - } -#endif tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff); tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT index fbf1c3e..8b14a5f 100644 --- a/tests/acpi-test-data/pc/DSDT +++ b/tests/acpi-test-data/pc/DSDT Binary files differ
diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT index a51c68e..c1a4589 100644 --- a/tests/acpi-test-data/pc/SSDT +++ b/tests/acpi-test-data/pc/SSDT Binary files differ
diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT index 5086b83..a76ea9a 100644 --- a/tests/acpi-test-data/q35/DSDT +++ b/tests/acpi-test-data/q35/DSDT Binary files differ
diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT index 9c6cad8..9915dbe 100644 --- a/tests/acpi-test-data/q35/SSDT +++ b/tests/acpi-test-data/q35/SSDT Binary files differ
diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 31f5359..185309a 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c
@@ -34,7 +34,7 @@ gchar *asl; /* asl code generated from aml */ gsize asl_len; gchar *asl_file; - bool asl_file_retain; /* do not delete the temp asl */ + bool tmp_files_retain; /* do not delete the temp asl/aml */ } QEMU_PACKED AcpiSdtTable; typedef struct { @@ -153,7 +153,8 @@ g_free(temp->aml); } if (temp->aml_file) { - if (g_strstr_len(temp->aml_file, -1, "aml-")) { + if (!temp->tmp_files_retain && + g_strstr_len(temp->aml_file, -1, "aml-")) { unlink(temp->aml_file); } g_free(temp->aml_file); @@ -162,7 +163,7 @@ g_free(temp->asl); } if (temp->asl_file) { - if (!temp->asl_file_retain) { + if (!temp->tmp_files_retain) { unlink(temp->asl_file); } g_free(temp->asl_file); @@ -410,7 +411,7 @@ return sdt->header.signature == signature; } -static void load_asl(GArray *sdts, AcpiSdtTable *sdt) +static bool load_asl(GArray *sdts, AcpiSdtTable *sdt) { AcpiSdtTable *temp; GError *error = NULL; @@ -439,18 +440,22 @@ g_string_append_printf(command_line, "-d %s", sdt->aml_file); /* pass 'out' and 'out_err' in order to be redirected */ - g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); + ret = g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); g_assert_no_error(error); - ret = g_file_get_contents(sdt->asl_file, (gchar **)&sdt->asl, - &sdt->asl_len, &error); - g_assert(ret); - g_assert_no_error(error); - g_assert(sdt->asl_len); + if (ret) { + ret = g_file_get_contents(sdt->asl_file, (gchar **)&sdt->asl, + &sdt->asl_len, &error); + g_assert(ret); + g_assert_no_error(error); + g_assert(sdt->asl_len); + } g_free(out); g_free(out_err); g_string_free(command_line, true); + + return !ret; } #define COMMENT_END "*/" @@ -517,6 +522,7 @@ int i; AcpiSdtTable *sdt, *exp_sdt; test_data exp_data; + gboolean exp_err, err; memset(&exp_data, 0, sizeof(exp_data)); exp_data.tables = load_expected_aml(data); @@ -527,20 +533,24 @@ sdt = &g_array_index(data->tables, AcpiSdtTable, i); exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); - load_asl(data->tables, sdt); + err = load_asl(data->tables, sdt); asl = normalize_asl(sdt->asl); - load_asl(exp_data.tables, exp_sdt); + exp_err = load_asl(exp_data.tables, exp_sdt); exp_asl = normalize_asl(exp_sdt->asl); + /* TODO: check for warnings */ + g_assert(!err || exp_err); + if (g_strcmp0(asl->str, exp_asl->str)) { - sdt->asl_file_retain = true; - exp_sdt->asl_file_retain = true; + sdt->tmp_files_retain = true; + exp_sdt->tmp_files_retain = true; fprintf(stderr, "acpi-test: Warning! %.4s mismatch. " - "Orig asl: %s, expected asl %s.\n", + "Actual [asl:%s, aml:%s], Expected [asl:%s, aml:%s].\n", (gchar *)&exp_sdt->header.signature, - sdt->asl_file, exp_sdt->asl_file); + sdt->asl_file, sdt->aml_file, + exp_sdt->asl_file, exp_sdt->aml_file); } g_string_free(asl, true); g_string_free(exp_asl, true);
diff --git a/thread-pool.c b/thread-pool.c index 3735fd3..fbdd3ff 100644 --- a/thread-pool.c +++ b/thread-pool.c
@@ -140,7 +140,7 @@ pool->new_threads--; pool->pending_threads++; - qemu_thread_create(&t, worker_thread, pool, QEMU_THREAD_DETACHED); + qemu_thread_create(&t, "worker", worker_thread, pool, QEMU_THREAD_DETACHED); } static void spawn_thread_bh_fn(void *opaque)
diff --git a/trace-events b/trace-events index aec4202..002c260 100644 --- a/trace-events +++ b/trace-events
@@ -486,6 +486,7 @@ g_malloc(size_t size, void *ptr) "size %zu ptr %p" g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p" g_free(void *ptr) "ptr %p" +system_wakeup_request(int reason) "reason=%d" # block/qcow2.c qcow2_writev_start_req(void *co, int64_t sector, int nb_sectors) "co %p sector %" PRIx64 " nb_sectors %d" @@ -1039,8 +1040,8 @@ vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp" # savevm.c -savevm_section_start(void) "" -savevm_section_end(unsigned int section_id) "section_id %u" +savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u" +savevm_section_end(const char *id, unsigned int section_id) "%s, section_id %u" # arch_init.c migration_bitmap_sync_start(void) ""
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c index a141f40..68f3d77 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c
@@ -338,7 +338,8 @@ return ; q = vnc_queue_init(); - qemu_thread_create(&q->thread, vnc_worker_thread, q, QEMU_THREAD_DETACHED); + qemu_thread_create(&q->thread, "vnc_worker", vnc_worker_thread, q, + QEMU_THREAD_DETACHED); queue = q; /* Set global queue */ }
diff --git a/util/compatfd.c b/util/compatfd.c index 430a41c..341ada6 100644 --- a/util/compatfd.c +++ b/util/compatfd.c
@@ -88,7 +88,8 @@ memcpy(&info->mask, mask, sizeof(*mask)); info->fd = fds[1]; - qemu_thread_create(&thread, sigwait_compat, info, QEMU_THREAD_DETACHED); + qemu_thread_create(&thread, "signalfd_compat", sigwait_compat, info, + QEMU_THREAD_DETACHED); return fds[0]; }
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 37dd298..45113b4 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c
@@ -27,6 +27,13 @@ #include "qemu/thread.h" #include "qemu/atomic.h" +static bool name_threads; + +void qemu_thread_naming(bool enable) +{ + name_threads = enable; +} + static void error_exit(int err, const char *msg) { fprintf(stderr, "qemu: %s: %s\n", msg, strerror(err)); @@ -387,8 +394,7 @@ } } - -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void*), void *arg, int mode) { @@ -414,6 +420,12 @@ if (err) error_exit(err, __func__); +#ifdef _GNU_SOURCE + if (name_threads) { + pthread_setname_np(thread->thread, name); + } +#endif + pthread_sigmask(SIG_SETMASK, &oldset, NULL); pthread_attr_destroy(&attr);
diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index 27a5217..b9c957b 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c
@@ -16,6 +16,14 @@ #include <assert.h> #include <limits.h> +static bool name_threads; + +void qemu_thread_naming(bool enable) +{ + /* But note we don't actually name them on Windows yet */ + name_threads = enable; +} + static void error_exit(int err, const char *msg) { char *pstr; @@ -325,7 +333,7 @@ return ret; } -void qemu_thread_create(QemuThread *thread, +void qemu_thread_create(QemuThread *thread, const char *name, void *(*start_routine)(void *), void *arg, int mode) {
diff --git a/vl.c b/vl.c index 41581c1..bca5c95 100644 --- a/vl.c +++ b/vl.c
@@ -479,6 +479,33 @@ }, }; +static QemuOptsList qemu_name_opts = { + .name = "name", + .implied_opt_name = "guest", + .merge_lists = true, + .head = QTAILQ_HEAD_INITIALIZER(qemu_name_opts.head), + .desc = { + { + .name = "guest", + .type = QEMU_OPT_STRING, + .help = "Sets the name of the guest.\n" + "This name will be displayed in the SDL window caption.\n" + "The name will also be used for the VNC server", + }, { + .name = "process", + .type = QEMU_OPT_STRING, + .help = "Sets the name of the QEMU process, as shown in top etc", + }, { + .name = "debug-threads", + .type = QEMU_OPT_BOOL, + .help = "When enabled, name the individual threads; defaults off.\n" + "NOTE: The thread names are for debugging and not a\n" + "stable API.", + }, + { /* End of list */ } + }, +}; + /** * Get machine options * @@ -929,6 +956,21 @@ return 0; } +static void parse_name(QemuOpts *opts) +{ + const char *proc_name; + + if (qemu_opt_get(opts, "debug-threads")) { + qemu_thread_naming(qemu_opt_get_bool(opts, "debug-threads", false)); + } + qemu_name = qemu_opt_get(opts, "guest"); + + proc_name = qemu_opt_get(opts, "process"); + if (proc_name) { + os_set_proc_name(proc_name); + } +} + bool usb_enabled(bool default_usb) { return qemu_opt_get_bool(qemu_get_machine_opts(), "usb", default_usb); @@ -1837,6 +1879,8 @@ void qemu_system_wakeup_request(WakeupReason reason) { + trace_system_wakeup_request(reason); + if (!runstate_check(RUN_STATE_SUSPENDED)) { return; } @@ -2887,6 +2931,7 @@ qemu_add_opts(&qemu_tpmdev_opts); qemu_add_opts(&qemu_realtime_opts); qemu_add_opts(&qemu_msg_opts); + qemu_add_opts(&qemu_name_opts); runstate_init(); @@ -3632,19 +3677,11 @@ "is no longer supported.\n"); break; case QEMU_OPTION_name: - qemu_name = g_strdup(optarg); - { - char *p = strchr(qemu_name, ','); - if (p != NULL) { - *p++ = 0; - if (strncmp(p, "process=", 8)) { - fprintf(stderr, "Unknown subargument %s to -name\n", p); - exit(1); - } - p += 8; - os_set_proc_name(p); - } - } + opts = qemu_opts_parse(qemu_find_opts("name"), optarg, 1); + if (!opts) { + exit(1); + } + parse_name(opts); break; case QEMU_OPTION_prom_env: if (nb_prom_envs >= MAX_PROM_ENVS) {