diff options
33 files changed, 655 insertions, 335 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 9bd307fb10..7d17f83868 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -158,7 +158,6 @@ Guest CPU Cores (KVM): ---------------------- Overall -M: Gleb Natapov <gleb@redhat.com> M: Paolo Bonzini <pbonzini@redhat.com> L: kvm@vger.kernel.org S: Supported @@ -184,7 +183,6 @@ 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 @@ -1117,8 +1117,13 @@ void resume_all_vcpus(void) } } +/* 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 @@ static void qemu_tcg_init_vcpu(CPUState *cpu) 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_tcg_init_vcpu(CPUState *cpu) 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_kvm_start_vcpu(CPUState *cpu) 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 2237edb4eb..d1c7ad4574 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -358,7 +358,7 @@ static void start_data_plane_bh(void *opaque) 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 b1a7ebb8e3..b667d31de5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -643,6 +643,21 @@ static inline char acpi_get_hex(uint32_t val) #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 @@ static void patch_pcihp(int slot, uint8_t *ssdt_ptr) 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 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) 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 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state) 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); } - /* 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 (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); } } + 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 @@ build_ssdt(GArray *table_data, GArray *linker, { 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 b23d5e0eac..0a1e252d21 100644 --- a/hw/i386/acpi-dsdt.dsl +++ b/hw/i386/acpi-dsdt.dsl @@ -80,6 +80,8 @@ DefinitionBlock ( Name(_HID, EisaId("PNP0A03")) Name(_ADR, 0x00) Name(_UID, 1) +//#define PX13 S0B_ +// External(PX13, DeviceObj) } } @@ -88,34 +90,6 @@ DefinitionBlock ( /**************************************************************** - * 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 @@ DefinitionBlock ( ****************************************************************/ 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 1e58801b2a..94c6e8e114 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, -0x87, +0x85, 0x11, 0x0, 0x0, 0x1, -0xb8, +0x8b, 0x42, 0x58, 0x50, @@ -146,7 +146,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x1, 0x10, 0x4e, -0x15, +0x18, 0x2e, 0x5f, 0x53, @@ -163,9 +163,9 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x11, 0x42, -0x7, 0xa, -0x6e, +0xa, +0x9e, 0x88, 0xd, 0x0, @@ -217,11 +217,59 @@ static unsigned char AcpiDsdtAmlCode[] = { 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, -0xf3, +0x0, +0x20, +0xaf, +0xdf, +0xaf, +0x0, +0x0, +0xc0, +0x0, +0x88, +0xd, +0x0, +0x1, +0xc, +0x3, +0x0, +0x0, +0xe4, +0xaf, +0xff, +0xff, +0x0, +0x0, +0x1c, +0x50, 0x87, 0x17, 0x0, @@ -347,7 +395,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x45, 0x53, 0xa, -0x5c, +0x8c, 0x50, 0x53, 0x33, @@ -358,7 +406,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x45, 0x53, 0xa, -0x60, +0x90, 0x50, 0x45, 0x33, @@ -369,7 +417,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x45, 0x53, 0xa, -0x68, +0x98, 0x50, 0x4c, 0x33, @@ -638,103 +686,6 @@ static unsigned char AcpiDsdtAmlCode[] = { 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 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x4e, 0x1, 0x10, -0x4b, +0x4a, 0x1e, 0x2f, 0x3, @@ -878,7 +829,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x5f, 0x5b, 0x82, -0x2d, +0x2c, 0x53, 0x4d, 0x43, @@ -898,9 +849,8 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x53, 0x54, 0x41, -0xb, -0x0, -0xff, +0xa, +0xf0, 0x8, 0x5f, 0x43, @@ -4061,7 +4011,7 @@ static unsigned char AcpiDsdtAmlCode[] = { 0x1, 0x10, 0x47, -0xe, +0x11, 0x5f, 0x53, 0x42, @@ -4291,6 +4241,54 @@ static unsigned char AcpiDsdtAmlCode[] = { 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 @@ static unsigned char AcpiDsdtAmlCode[] = { 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 d618e9e2d2..f4d2a2daee 100644 --- a/hw/i386/q35-acpi-dsdt.dsl +++ b/hw/i386/q35-acpi-dsdt.dsl @@ -72,6 +72,8 @@ DefinitionBlock ( 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 @@ DefinitionBlock ( /**************************************************************** - * 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 6d885a9055..6c29f3b6d2 100644 --- a/hw/i386/q35-acpi-dsdt.hex.generated +++ b/hw/i386/q35-acpi-dsdt.hex.generated @@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x44, 0x54, -0xdf, +0xd7, 0x1c, 0x0, 0x0, 0x1, -0xff, +0x3e, 0x42, 0x58, 0x50, @@ -415,11 +415,11 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x0, 0x0, 0x0, -0xf7, +0xd7, 0xc, 0x0, 0x0, -0xf8, +0xd8, 0xc, 0x88, 0xd, @@ -853,61 +853,6 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 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 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x4e, 0x1, 0x10, -0x4b, +0x4a, 0x1e, 0x2f, 0x3, @@ -1051,7 +996,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x5f, 0x5b, 0x82, -0x2d, +0x2c, 0x53, 0x4d, 0x43, @@ -1071,9 +1016,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x53, 0x54, 0x41, -0xb, -0x0, -0xff, +0xa, +0xf0, 0x8, 0x5f, 0x43, @@ -7016,7 +6960,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x1, 0x10, 0x47, -0xe, +0x11, 0x5f, 0x53, 0x42, @@ -7121,8 +7065,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 0x54, 0x1, 0xb, -0x0, -0xaf, +0xd8, +0xc, 0xa, 0x20, 0x5b, @@ -7246,6 +7190,54 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 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 @@ static unsigned char Q35AcpiDsdtAmlCode[] = { 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 cc245c3e7c..ac91c05836 100644 --- a/hw/i386/ssdt-pcihp.dsl +++ b/hw/i386/ssdt-pcihp.dsl @@ -46,5 +46,55 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1) } } + 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 610a631fd1..b599b4663c 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 @@ static unsigned char ssdp_pcihp_aml[] = { 0x13, 0x20, 0x10, -0x36, +0x41, +0xa, 0x5c, 0x2e, 0x5f, @@ -98,11 +114,138 @@ static unsigned char ssdp_pcihp_aml[] = { 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 655b8c5011..29af3d741f 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -281,7 +281,7 @@ static void kbd_write_command(void *opaque, hwaddr addr, 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 652dd47a1c..b527932382 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -93,9 +93,6 @@ static void ioapic_set_irq(void *opaque, int vector, int level) 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 3c0342e17a..fd23c4627e 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -397,12 +397,15 @@ static int peer_detach(VirtIONet *n, int index) 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 ec6be4676c..e1e95aabcd 100644 --- a/hw/pci-host/pam.c +++ b/hw/pci-host/pam.c @@ -68,7 +68,7 @@ void init_pam(DeviceState *dev, MemoryRegion *ram_memory, /* 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 8ecd11eca2..02cde6f96c 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -221,29 +221,23 @@ static void pcie_cap_slot_hotplug_common(PCIDevice *hotplug_dev, 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 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, 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 aa913df853..7213c8909c 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -546,10 +546,10 @@ static int emulated_initfn(CCIDCardState *base) 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 9101fc3a55..c084db2d9d 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -836,13 +836,13 @@ void memory_region_set_alias_offset(MemoryRegion *mr, 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 3e32c6531c..f7e3b9b290 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -52,12 +52,13 @@ void qemu_event_reset(QemuEvent *ev); 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 24f7088ecf..3477ab3e1b 100644 --- a/libcacard/vscclient.c +++ b/libcacard/vscclient.c @@ -269,7 +269,7 @@ on_host_init(VSCMsgHeader *mhHeader, VSCMsgInit *incoming) 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; } @@ -1562,7 +1562,7 @@ static FlatRange *flatview_lookup(FlatView *view, AddrRange addr) 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 14235b280a..00f465ea46 100644 --- a/migration.c +++ b/migration.c @@ -695,6 +695,6 @@ void migrate_fd_connect(MigrationState *s) /* 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/qemu-options.hx b/qemu-options.hx index 56e5fdf1e0..068da2df09 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -328,9 +328,11 @@ possible drivers and properties, use @code{-device help} and 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 @@ Sets the @var{name} of the guest. 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/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT Binary files differindex fbf1c3e6e8..8b14a5f6f2 100644 --- a/tests/acpi-test-data/pc/DSDT +++ b/tests/acpi-test-data/pc/DSDT diff --git a/tests/acpi-test-data/pc/SSDT b/tests/acpi-test-data/pc/SSDT Binary files differindex a51c68e21b..c1a4589db0 100644 --- a/tests/acpi-test-data/pc/SSDT +++ b/tests/acpi-test-data/pc/SSDT diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT Binary files differindex 5086b839a6..a76ea9a418 100644 --- a/tests/acpi-test-data/q35/DSDT +++ b/tests/acpi-test-data/q35/DSDT diff --git a/tests/acpi-test-data/q35/SSDT b/tests/acpi-test-data/q35/SSDT Binary files differindex 9c6cad8b0b..9915dbe5b1 100644 --- a/tests/acpi-test-data/q35/SSDT +++ b/tests/acpi-test-data/q35/SSDT diff --git a/tests/acpi-test.c b/tests/acpi-test.c index 31f5359787..185309a241 100644 --- a/tests/acpi-test.c +++ b/tests/acpi-test.c @@ -34,7 +34,7 @@ typedef struct { 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 @@ static void free_test_data(test_data *data) 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 @@ static void free_test_data(test_data *data) 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 @@ static bool compare_signature(AcpiSdtTable *sdt, uint32_t signature) 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 @@ static void load_asl(GArray *sdts, AcpiSdtTable *sdt) 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 @@ static void test_acpi_asl(test_data *data) 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 @@ static void test_acpi_asl(test_data *data) 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 3735fd34bc..fbdd3ffa3a 100644 --- a/thread-pool.c +++ b/thread-pool.c @@ -140,7 +140,7 @@ static void do_spawn_thread(ThreadPool *pool) 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/ui/vnc-jobs.c b/ui/vnc-jobs.c index 2d3fce8155..3f3c47b9a5 100644 --- a/ui/vnc-jobs.c +++ b/ui/vnc-jobs.c @@ -333,7 +333,8 @@ void vnc_start_worker_thread(void) 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 430a41c855..341ada638f 100644 --- a/util/compatfd.c +++ b/util/compatfd.c @@ -88,7 +88,8 @@ static int qemu_signalfd_compat(const sigset_t *mask) 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 37dd298631..45113b464d 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_event_wait(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) { @@ -414,6 +420,12 @@ void qemu_thread_create(QemuThread *thread, 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 27a5217769..b9c957b6a0 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 @@ void *qemu_thread_join(QemuThread *thread) 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) { @@ -479,6 +479,33 @@ static QemuOptsList qemu_msg_opts = { }, }; +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 @@ static int parse_sandbox(QemuOpts *opts, void *opaque) 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); @@ -2889,6 +2931,7 @@ int main(int argc, char **argv, char **envp) 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(); @@ -3634,19 +3677,11 @@ int main(int argc, char **argv, char **envp) "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) { |