From e8ad4d16808690e9c0d68b140218ca466c9309fc Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:45 +0300 Subject: [PATCH 01/35] ide: move headers to include folder The patch moves "hw/ide/achi.h", "hw/ide/pci.h" and "hw/ide/internal.h" headers to corresponding folders inside "include" folder alike other Qemu headers. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/ide/ahci.c | 2 +- {hw => include/hw}/ide/ahci.h | 0 {hw => include/hw}/ide/internal.h | 0 {hw => include/hw}/ide/pci.h | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename {hw => include/hw}/ide/ahci.h (100%) rename {hw => include/hw}/ide/internal.h (100%) rename {hw => include/hw}/ide/pci.h (100%) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 502d4f1c7b..b1a7b65a7b 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -30,7 +30,7 @@ #include "qemu/error-report.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" -#include "internal.h" +#include #include #include diff --git a/hw/ide/ahci.h b/include/hw/ide/ahci.h similarity index 100% rename from hw/ide/ahci.h rename to include/hw/ide/ahci.h diff --git a/hw/ide/internal.h b/include/hw/ide/internal.h similarity index 100% rename from hw/ide/internal.h rename to include/hw/ide/internal.h diff --git a/hw/ide/pci.h b/include/hw/ide/pci.h similarity index 100% rename from hw/ide/pci.h rename to include/hw/ide/pci.h From 873b4d3f0571a1e415cf089a67a230ea8a12d059 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:46 +0300 Subject: [PATCH 02/35] pcspk: convert "pit" property type from ptr to link The speaker device needs pointer to ISA PIT device to operate. But according to qdev-properties.h, properties of pointer type should be avoided. It seems a link type property is a good substitution. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/audio/pcspk.c | 9 +++++++-- include/hw/audio/pcspk.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index d2599604d1..a7aa4e9c26 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -31,6 +31,7 @@ #include "qemu/timer.h" #include "hw/timer/i8254.h" #include "hw/audio/pcspk.h" +#include "qapi/error.h" #define PCSPK_BUF_LEN 1792 #define PCSPK_SAMPLE_RATE 32000 @@ -169,6 +170,11 @@ static void pcspk_initfn(Object *obj) PCSpkState *s = PC_SPEAKER(obj); memory_region_init_io(&s->ioport, OBJECT(s), &pcspk_io_ops, s, "pcspk", 1); + + object_property_add_link(obj, "pit", TYPE_I8254, + (Object **)&s->pit, + qdev_prop_allow_set_link_before_realize, + 0, &error_abort); } static void pcspk_realizefn(DeviceState *dev, Error **errp) @@ -183,7 +189,6 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp) static Property pcspk_properties[] = { DEFINE_PROP_UINT32("iobase", PCSpkState, iobase, -1), - DEFINE_PROP_PTR("pit", PCSpkState, pit), DEFINE_PROP_END_OF_LIST(), }; @@ -194,7 +199,7 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); dc->props = pcspk_properties; - /* Reason: pointer property "pit", realize sets global pcspk_state */ + /* Reason: realize sets global pcspk_state */ dc->cannot_instantiate_with_device_add_yet = true; } diff --git a/include/hw/audio/pcspk.h b/include/hw/audio/pcspk.h index ef95dd1360..33e46a53d0 100644 --- a/include/hw/audio/pcspk.h +++ b/include/hw/audio/pcspk.h @@ -38,7 +38,7 @@ static inline ISADevice *pcspk_init(ISABus *bus, ISADevice *pit) isadev = isa_create(bus, TYPE_PC_SPEAKER); dev = DEVICE(isadev); qdev_prop_set_uint32(dev, "iobase", 0x61); - qdev_prop_set_ptr(dev, "pit", pit); + object_property_set_link(OBJECT(dev), OBJECT(pit), "pit", NULL); qdev_init_nofail(dev); return isadev; From 936a6447c8dbb7bfeb41b1007394f8ee34e69d34 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:47 +0300 Subject: [PATCH 03/35] vmport: identify vmport type by macro TYPE_VMPORT Currently vmport device is identified by the string literal. Using a preprocessor alias instead is preferable. Signed-off-by: Efimov Vasily Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini --- hw/misc/vmport.c | 1 - include/hw/i386/pc.h | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c index 6896789801..c763811a9f 100644 --- a/hw/misc/vmport.c +++ b/hw/misc/vmport.c @@ -36,7 +36,6 @@ #define VMPORT_ENTRIES 0x2c #define VMPORT_MAGIC 0x564D5868 -#define TYPE_VMPORT "vmport" #define VMPORT(obj) OBJECT_CHECK(VMPortState, (obj), TYPE_VMPORT) typedef struct VMPortState diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 948ed0c277..bc85054561 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -201,11 +201,12 @@ typedef struct GSIState { void gsi_handler(void *opaque, int n, int level); /* vmport.c */ +#define TYPE_VMPORT "vmport" typedef uint32_t (VMPortReadFunc)(void *opaque, uint32_t address); static inline void vmport_init(ISABus *bus) { - isa_create_simple(bus, "vmport"); + isa_create_simple(bus, TYPE_VMPORT); } void vmport_register(unsigned char command, VMPortReadFunc *func, void *opaque); From 1a004c7fc8d9c9a4a4eb71b5717181f6fe5cf636 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:48 +0300 Subject: [PATCH 04/35] pflash: make TYPE_CFI_PFLASH0{1,2} macros public qdev API can be used to create CFI pflash devices despite existance of helper functions. The type name is needed in course of such creation. Using the preprocessor alias instead of the string literal itself is preferable. The patch makes the aliases accessible through the header. Signed-off-by: Efimov Vasily Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini --- hw/block/pflash_cfi01.c | 1 - hw/block/pflash_cfi02.c | 1 - include/hw/block/flash.h | 3 +++ 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index 31585e3aa1..62d7a5661d 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -65,7 +65,6 @@ do { \ #define DPRINTF(fmt, ...) do { } while (0) #endif -#define TYPE_CFI_PFLASH01 "cfi.pflash01" #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01) #define PFLASH_BE 0 diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 5f106102c5..4f6105cc58 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -57,7 +57,6 @@ do { \ #define PFLASH_LAZY_ROMD_THRESHOLD 42 -#define TYPE_CFI_PFLASH02 "cfi.pflash02" #define CFI_PFLASH02(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH02) struct pflash_t { diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h index 50ccbbcf13..a088baa4e4 100644 --- a/include/hw/block/flash.h +++ b/include/hw/block/flash.h @@ -5,6 +5,9 @@ #include "exec/memory.h" +#define TYPE_CFI_PFLASH01 "cfi.pflash01" +#define TYPE_CFI_PFLASH02 "cfi.pflash02" + typedef struct pflash_t pflash_t; /* pflash_cfi01.c */ From 401f2f3ef10037bdeda4549ed4cd5b06af3d1c6a Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:49 +0300 Subject: [PATCH 05/35] Q35: implement property interfece to several parameters During creation of Q35 instance several parameters are set using direct access. It violates Qemu device model. Correctly, the parameters should be handled as object properties. The patch adds four link type properties for fields: mch.ram_memory mch.pci_address_space mch.system_memory mch.address_space_io And, it adds two size type properties for fields: mch.below_4g_mem_size mch.above_4g_mem_size Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/pci-host/q35.c | 20 ++++++++++++++++++++ include/hw/i386/pc.h | 2 ++ include/hw/pci-host/q35.h | 9 +++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 70f897e3a9..03be05dc0d 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -127,6 +127,10 @@ static Property mch_props[] = { DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost, mch.pci_hole64_size, DEFAULT_PCI_HOLE64_SIZE), DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0), + DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost, + mch.below_4g_mem_size, 0), + DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost, + mch.above_4g_mem_size, 0), DEFINE_PROP_END_OF_LIST(), }; @@ -177,6 +181,22 @@ static void q35_host_initfn(Object *obj) q35_host_get_mmcfg_size, NULL, NULL, NULL, NULL); + object_property_add_link(obj, MCH_HOST_PROP_RAM_MEM, TYPE_MEMORY_REGION, + (Object **) &s->mch.ram_memory, + qdev_prop_allow_set_link_before_realize, 0, NULL); + + object_property_add_link(obj, MCH_HOST_PROP_PCI_MEM, TYPE_MEMORY_REGION, + (Object **) &s->mch.pci_address_space, + qdev_prop_allow_set_link_before_realize, 0, NULL); + + object_property_add_link(obj, MCH_HOST_PROP_SYSTEM_MEM, TYPE_MEMORY_REGION, + (Object **) &s->mch.system_memory, + qdev_prop_allow_set_link_before_realize, 0, NULL); + + object_property_add_link(obj, MCH_HOST_PROP_IO_MEM, TYPE_MEMORY_REGION, + (Object **) &s->mch.address_space_io, + qdev_prop_allow_set_link_before_realize, 0, NULL); + /* Leave enough space for the biggest MCFG BAR */ /* TODO: this matches current bios behaviour, but * it's not a power of two, which means an MTRR diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index bc85054561..f806be4b0b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -240,6 +240,8 @@ void pc_guest_info_init(PCMachineState *pcms); #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start" #define PCI_HOST_PROP_PCI_HOLE64_END "pci-hole64-end" #define PCI_HOST_PROP_PCI_HOLE64_SIZE "pci-hole64-size" +#define PCI_HOST_BELOW_4G_MEM_SIZE "below-4g-mem-size" +#define PCI_HOST_ABOVE_4G_MEM_SIZE "above-4g-mem-size" #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL) diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h index c5c073ddea..1075f3ea50 100644 --- a/include/hw/pci-host/q35.h +++ b/include/hw/pci-host/q35.h @@ -56,8 +56,8 @@ typedef struct MCHPCIState { MemoryRegion smram, low_smram, high_smram; MemoryRegion tseg_blackhole, tseg_window; PcPciInfo pci_info; - ram_addr_t below_4g_mem_size; - ram_addr_t above_4g_mem_size; + uint64_t below_4g_mem_size; + uint64_t above_4g_mem_size; uint64_t pci_hole64_size; uint32_t short_root_bus; IntelIOMMUState *iommu; @@ -78,6 +78,11 @@ typedef struct Q35PCIHost { * gmch part */ +#define MCH_HOST_PROP_RAM_MEM "ram-mem" +#define MCH_HOST_PROP_PCI_MEM "pci-mem" +#define MCH_HOST_PROP_SYSTEM_MEM "system-mem" +#define MCH_HOST_PROP_IO_MEM "io-mem" + /* PCI configuration */ #define MCH_HOST_BRIDGE "MCH" From 8d1c7158a059e9a55181517aa61faf422831b8f8 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:50 +0300 Subject: [PATCH 06/35] pc_q35: configure Q35 instance using properties Currently, Q35 instance is configured using direct access to structure fields. The patch uses property interface to set the fields. Signed-off-by: Efimov Vasily Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini --- hw/i386/pc_q35.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 97a8835eea..65ae78a270 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -159,12 +159,18 @@ static void pc_q35_init(MachineState *machine) q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE)); object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL); - q35_host->mch.ram_memory = ram_memory; - q35_host->mch.pci_address_space = pci_memory; - q35_host->mch.system_memory = get_system_memory(); - q35_host->mch.address_space_io = system_io; - q35_host->mch.below_4g_mem_size = pcms->below_4g_mem_size; - q35_host->mch.above_4g_mem_size = pcms->above_4g_mem_size; + object_property_set_link(OBJECT(q35_host), OBJECT(ram_memory), + MCH_HOST_PROP_RAM_MEM, NULL); + object_property_set_link(OBJECT(q35_host), OBJECT(pci_memory), + MCH_HOST_PROP_PCI_MEM, NULL); + object_property_set_link(OBJECT(q35_host), OBJECT(get_system_memory()), + MCH_HOST_PROP_SYSTEM_MEM, NULL); + object_property_set_link(OBJECT(q35_host), OBJECT(system_io), + MCH_HOST_PROP_IO_MEM, NULL); + object_property_set_int(OBJECT(q35_host), pcms->below_4g_mem_size, + PCI_HOST_BELOW_4G_MEM_SIZE, NULL); + object_property_set_int(OBJECT(q35_host), pcms->above_4g_mem_size, + PCI_HOST_ABOVE_4G_MEM_SIZE, NULL); /* pci */ qdev_init_nofail(DEVICE(q35_host)); phb = PCI_HOST_BRIDGE(q35_host); From 3115b9e2d286188a54d6f415186ae556046b68a3 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:51 +0300 Subject: [PATCH 07/35] pckbd: handle A20 IRQ as GPIO The i8042 device has outgouing IRQ line A20. Currently the IRQ is referenced by a pointer which normally is set during machine initialization. The pointer is never changed at runtime. So common GPIO model can be applied to A20 IRQ line. Note that checking for IRQ to be connected as in previous version of code is not required because qemu_set_irq will do it. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/input/pckbd.c | 21 +++++++-------------- include/hw/i386/pc.h | 1 + 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index 1d932ec19f..dc57e2c762 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -146,7 +146,7 @@ typedef struct KBDState { qemu_irq irq_kbd; qemu_irq irq_mouse; - qemu_irq *a20_out; + qemu_irq a20_out; hwaddr mask; } KBDState; @@ -224,9 +224,7 @@ static void outport_write(KBDState *s, uint32_t val) { DPRINTF("kbd: write outport=0x%02x\n", val); s->outport = val; - if (s->a20_out) { - qemu_set_irq(*s->a20_out, (val >> 1) & 1); - } + qemu_set_irq(s->a20_out, (val >> 1) & 1); if (!(val & 1)) { qemu_system_reset_request(); } @@ -295,15 +293,11 @@ static void kbd_write_command(void *opaque, hwaddr addr, kbd_queue(s, s->outport, 0); break; case KBD_CCMD_ENABLE_A20: - if (s->a20_out) { - qemu_irq_raise(*s->a20_out); - } + qemu_irq_raise(s->a20_out); s->outport |= KBD_OUT_A20; break; case KBD_CCMD_DISABLE_A20: - if (s->a20_out) { - qemu_irq_lower(*s->a20_out); - } + qemu_irq_lower(s->a20_out); s->outport &= ~KBD_OUT_A20; break; case KBD_CCMD_RESET: @@ -507,10 +501,7 @@ void i8042_isa_mouse_fake_event(void *opaque) void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out) { - ISAKBDState *isa = I8042(dev); - KBDState *s = &isa->kbd; - - s->a20_out = a20_out; + qdev_connect_gpio_out_named(DEVICE(dev), I8042_A20_LINE, 0, *a20_out); } static const VMStateDescription vmstate_kbd_isa = { @@ -552,6 +543,8 @@ static void i8042_initfn(Object *obj) "i8042-data", 1); memory_region_init_io(isa_s->io + 1, obj, &i8042_cmd_ops, s, "i8042-cmd", 1); + + qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, I8042_A20_LINE, 1); } static void i8042_realizefn(DeviceState *dev, Error **errp) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index f806be4b0b..729784879f 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -214,6 +214,7 @@ void vmmouse_get_data(uint32_t *data); void vmmouse_set_data(const uint32_t *data); /* pckbd.c */ +#define I8042_A20_LINE "a20" void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base); void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq, From d812b3d68ddf0efe91a088ecc8b177865b0bab8d Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:52 +0300 Subject: [PATCH 08/35] port92: handle A20 IRQ as GPIO The port92 device has outgouing IRQ line A20. Currently the IRQ is referenced by a pointer which normally is set during machine initialization. The pointer is never changed at runtime. Hence, common GPIO model can be applied to A20 IRQ line. Note that checking for IRQ to be connected as in previous version of code is not required qemu_set_irq will do it. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 10 +++++----- include/hw/i386/pc.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b8fead37e2..44a8f3bcbd 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -505,7 +505,7 @@ typedef struct Port92State { MemoryRegion io; uint8_t outport; - qemu_irq *a20_out; + qemu_irq a20_out; } Port92State; static void port92_write(void *opaque, hwaddr addr, uint64_t val, @@ -516,7 +516,7 @@ static void port92_write(void *opaque, hwaddr addr, uint64_t val, DPRINTF("port92: write 0x%02" PRIx64 "\n", val); s->outport = val; - qemu_set_irq(*s->a20_out, (val >> 1) & 1); + qemu_set_irq(s->a20_out, (val >> 1) & 1); if ((val & 1) && !(oldval & 1)) { qemu_system_reset_request(); } @@ -535,9 +535,7 @@ static uint64_t port92_read(void *opaque, hwaddr addr, static void port92_init(ISADevice *dev, qemu_irq *a20_out) { - Port92State *s = PORT92(dev); - - s->a20_out = a20_out; + qdev_connect_gpio_out_named(DEVICE(dev), PORT92_A20_LINE, 0, *a20_out); } static const VMStateDescription vmstate_port92_isa = { @@ -574,6 +572,8 @@ static void port92_initfn(Object *obj) memory_region_init_io(&s->io, OBJECT(s), &port92_ops, s, "port92", 1); s->outport = 0; + + qdev_init_gpio_out_named(DEVICE(obj), &s->a20_out, PORT92_A20_LINE, 1); } static void port92_realizefn(DeviceState *dev, Error **errp) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 729784879f..7e43b20b4b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -277,6 +277,8 @@ int cmos_get_fd_drive_type(FloppyDriveType fd0); #define FW_CFG_IO_BASE 0x510 +#define PORT92_A20_LINE "a20" + /* acpi_piix.c */ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, From f2dd8ebdf40e3cf3863b9022ccb3c3489c2d1c76 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:53 +0300 Subject: [PATCH 09/35] ICH9 SMB: make TYPE_ICH9_SMB_DEVICE macro public ICH9 SMB bridge can be created using qdev API despite existence of helper function. The type name is needed for such creation. Using a preprocessor alias instead the string type name itself is preferable. The patch makes the alias accessible through the header. Signed-off-by: Efimov Vasily Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini --- hw/i2c/smbus_ich9.c | 1 - include/hw/i386/ich9.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c index 498f03e835..48fab22625 100644 --- a/hw/i2c/smbus_ich9.c +++ b/hw/i2c/smbus_ich9.c @@ -35,7 +35,6 @@ #include "hw/i386/ich9.h" -#define TYPE_ICH9_SMB_DEVICE "ICH9 SMB" #define ICH9_SMB_DEVICE(obj) \ OBJECT_CHECK(ICH9SMBState, (obj), TYPE_ICH9_SMB_DEVICE) diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index 88233c3077..f1294bc505 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -208,6 +208,8 @@ Object *ich9_lpc_find(void); /* D31:F3 SMBus controller */ +#define TYPE_ICH9_SMB_DEVICE "ICH9 SMB" + #define ICH9_A2_SMB_REVISION 0x02 #define ICH9_SMB_PI 0x00 From f62efcacfab114d0fae016dd9c0cd500f70dd70d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 17 Jun 2016 17:01:21 +0200 Subject: [PATCH 10/35] ich9: call ich9_lpc_update_pic for disabled pirqs An asserted pirq can be disabled and the corresponding GSIs should then go down to 0. However, because of the conditional in ich9_lpc_update_by_pirq, the legacy 8259 pin could remain stuck to 1. Reviewed-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/isa/lpc_ich9.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index c1a4f1b34c..f7aed231e6 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -234,9 +234,6 @@ static void ich9_lpc_update_by_pirq(ICH9LPCState *lpc, int pirq) ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis); assert(pic_irq < ICH9_LPC_PIC_NUM_PINS); - if (pic_dis) { - return; - } ich9_lpc_update_pic(lpc, pic_irq); } From a94dd6a9d693829bf8fb04cd6d85c797ed90a5d7 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 17 Jun 2016 17:07:31 +0200 Subject: [PATCH 11/35] ich9: clean up ich9_lpc_update_pic/ich9_lpc_update_apic and callers Make ich9_lpc_update_pic take care only of GSIs 0-15, and ich9_lpc_update_apic take care only of GSIs 16-23. Assert that they are called with the correct GSI indices. Reviewed-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/isa/lpc_ich9.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index f7aed231e6..2caa5e9691 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -204,38 +204,28 @@ static void ich9_lpc_pic_irq(ICH9LPCState *lpc, int pirq_num, abort(); } -/* pic_irq: i8254 irq 0-15 */ -static void ich9_lpc_update_pic(ICH9LPCState *lpc, int pic_irq) +/* gsi: i8259+ioapic irq 0-15, otherwise assert */ +static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi) { int i, pic_level; + assert(gsi < ICH9_LPC_PIC_NUM_PINS); + /* The pic level is the logical OR of all the PCI irqs mapped to it */ pic_level = 0; for (i = 0; i < ICH9_LPC_NB_PIRQS; i++) { int tmp_irq; int tmp_dis; ich9_lpc_pic_irq(lpc, i, &tmp_irq, &tmp_dis); - if (!tmp_dis && pic_irq == tmp_irq) { + if (!tmp_dis && tmp_irq == gsi) { pic_level |= pci_bus_get_irq_level(lpc->d.bus, i); } } - if (pic_irq == ich9_lpc_sci_irq(lpc)) { + if (gsi == ich9_lpc_sci_irq(lpc)) { pic_level |= lpc->sci_level; } - qemu_set_irq(lpc->pic[pic_irq], pic_level); -} - -/* pirq: pirq[A-H] 0-7*/ -static void ich9_lpc_update_by_pirq(ICH9LPCState *lpc, int pirq) -{ - int pic_irq; - int pic_dis; - - ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis); - assert(pic_irq < ICH9_LPC_PIC_NUM_PINS); - - ich9_lpc_update_pic(lpc, pic_irq); + qemu_set_irq(lpc->pic[gsi], pic_level); } /* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */ @@ -249,13 +239,14 @@ static int ich9_gsi_to_pirq(int gsi) return gsi - ICH9_LPC_PIC_NUM_PINS; } +/* gsi: ioapic irq 16-23, otherwise assert */ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi) { int level = 0; - if (gsi >= ICH9_LPC_PIC_NUM_PINS) { - level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi)); - } + assert(gsi >= ICH9_LPC_PIC_NUM_PINS); + + level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi)); if (gsi == ich9_lpc_sci_irq(lpc)) { level |= lpc->sci_level; } @@ -266,12 +257,14 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi) void ich9_lpc_set_irq(void *opaque, int pirq, int level) { ICH9LPCState *lpc = opaque; + int pic_irq, pic_dis; assert(0 <= pirq); assert(pirq < ICH9_LPC_NB_PIRQS); ich9_lpc_update_apic(lpc, ich9_pirq_to_gsi(pirq)); - ich9_lpc_update_by_pirq(lpc, pirq); + ich9_lpc_pic_irq(lpc, pirq, &pic_irq, &pic_dis); + ich9_lpc_update_pic(lpc, pic_irq); } /* return the pirq number (PIRQ[A-H]:0-7) corresponding to @@ -362,8 +355,9 @@ static void ich9_set_sci(void *opaque, int irq_num, int level) return; } - ich9_lpc_update_apic(lpc, irq); - if (irq < ICH9_LPC_PIC_NUM_PINS) { + if (irq >= ICH9_LPC_PIC_NUM_PINS) { + ich9_lpc_update_apic(lpc, irq); + } else { ich9_lpc_update_pic(lpc, irq); } } From 35a6b23c824e54055f1a2ab30fa5b051a82cdda6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 17 Jun 2016 17:12:09 +0200 Subject: [PATCH 12/35] ich9: unify pic and ioapic IRQ vectors ich9->pic and ich9->ioapic differ for the first 16 GSIs (because ich9->pic is wired to 8259+IOAPIC but ich9->ioapic is wired to IOAPIC only). However, ich9->ioapic is never used for the first 16 GSIs, so the two vectors can be merged. Reviewed-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/i386/pc_q35.c | 3 +-- hw/isa/lpc_ich9.c | 4 ++-- include/hw/i386/ich9.h | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 65ae78a270..6e296c0c32 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -190,8 +190,7 @@ static void pc_q35_init(MachineState *machine) PC_MACHINE_ACPI_DEVICE_PROP, &error_abort); ich9_lpc = ICH9_LPC_DEVICE(lpc); - ich9_lpc->pic = gsi; - ich9_lpc->ioapic = gsi_state->ioapic_irq; + ich9_lpc->gsi = gsi; pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc, ICH9_LPC_NB_PIRQS); pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 2caa5e9691..3bdb78d255 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -225,7 +225,7 @@ static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi) pic_level |= lpc->sci_level; } - qemu_set_irq(lpc->pic[gsi], pic_level); + qemu_set_irq(lpc->gsi[gsi], pic_level); } /* APIC mode: GSIx: PIRQ[A-H] -> GSI 16, ... no pirq shares same APIC pins. */ @@ -251,7 +251,7 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi) level |= lpc->sci_level; } - qemu_set_irq(lpc->ioapic[gsi], level); + qemu_set_irq(lpc->gsi[gsi], level); } void ich9_lpc_set_irq(void *opaque, int pirq, int level) diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index f1294bc505..a09a4459e7 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -68,8 +68,7 @@ typedef struct ICH9LPCState { MemoryRegion rcrb_mem; /* root complex register block */ Notifier machine_ready; - qemu_irq *pic; - qemu_irq *ioapic; + qemu_irq *gsi; } ICH9LPCState; Object *ich9_lpc_find(void); From f999c0de05103ccd91b3efff282eaa1c0ea93015 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:54 +0300 Subject: [PATCH 13/35] ICH9 LPC: handle GSI as qdev GPIO The ICH9 LPC bridge has 24 output IRQs connected to GSI. Currently the IRQs are referenced by pointers. The pointers are initialized at startup by direct access to the structure fields. This violates Qemu device model. The patch makes the IRQs handling to use GPIO model. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/i386/pc_q35.c | 6 +++++- hw/isa/lpc_ich9.c | 3 +++ include/hw/i386/ich9.h | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 6e296c0c32..17634dd5a1 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -60,6 +60,7 @@ static void pc_q35_init(MachineState *machine) PCIHostState *phb; PCIBus *host_bus; PCIDevice *lpc; + DeviceState *lpc_dev; BusState *idebus[MAX_SATA_PORTS]; ISADevice *rtc_state; MemoryRegion *system_io = get_system_io(); @@ -190,7 +191,10 @@ static void pc_q35_init(MachineState *machine) PC_MACHINE_ACPI_DEVICE_PROP, &error_abort); ich9_lpc = ICH9_LPC_DEVICE(lpc); - ich9_lpc->gsi = gsi; + lpc_dev = DEVICE(lpc); + for (i = 0; i < GSI_NUM_PINS; i++) { + qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i, gsi[i]); + } pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc, ICH9_LPC_NB_PIRQS); pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 3bdb78d255..59f15a121e 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -599,6 +599,7 @@ static void ich9_lpc_initfn(Object *obj) static void ich9_lpc_realize(PCIDevice *d, Error **errp) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(d); + DeviceState *dev = DEVICE(d); ISABus *isa_bus; isa_bus = isa_bus_new(DEVICE(d), get_system_memory(), get_system_io(), @@ -626,6 +627,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) memory_region_add_subregion_overlap(pci_address_space_io(d), ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem, 1); + + qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS); } static bool ich9_rst_cnt_needed(void *opaque) diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index a09a4459e7..c14490b434 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -68,7 +68,7 @@ typedef struct ICH9LPCState { MemoryRegion rcrb_mem; /* root complex register block */ Notifier machine_ready; - qemu_irq *gsi; + qemu_irq gsi[GSI_NUM_PINS]; } ICH9LPCState; Object *ich9_lpc_find(void); @@ -176,6 +176,8 @@ Object *ich9_lpc_find(void); #define ICH9_LPC_PIC_NUM_PINS 16 #define ICH9_LPC_IOAPIC_NUM_PINS 24 +#define ICH9_GPIO_GSI "gsi" + /* D31:F2 SATA Controller #1 */ #define ICH9_SATA1_DEV 31 #define ICH9_SATA1_FUNC 2 From ea5d42508c16947e84d020751e739c59262051de Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:55 +0300 Subject: [PATCH 14/35] ICH9 LPC: move call of isa_bus_irqs to 'realize' method The isa_bus_irqs function initializes ISA bus IRQ array pointer with specified value. Previously the ICH9 LPC bridge model did not have its own IRQs but only IRQ pointer cache. And same GSI were used for ISA bus and other sources behind the bridge (PCI, SCI). Hence, the pc_q35_init was only possible place to setup both ISA bus IRQs and the bridge IRQ cache. As a result, the call of isa_bus_irqs was made from pc_q35_init. Now the ICH9 LPC bridge has its own output IRQs which are connected to GSI. The output IRQs are already used to route IRQs from PCI and SCI. The patch makes the ICH9 LPC bridge output IRQs to used for ISA bus too. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/i386/pc_q35.c | 3 --- hw/isa/lpc_ich9.c | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 17634dd5a1..04b2684d37 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -200,9 +200,6 @@ static void pc_q35_init(MachineState *machine) pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq); isa_bus = ich9_lpc->isa_bus; - /*end early*/ - isa_bus_irqs(isa_bus, gsi); - if (kvm_pic_in_kernel()) { i8259 = kvm_i8259_init(isa_bus); } else if (xen_enabled()) { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 59f15a121e..fe0ba83fe8 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -629,6 +629,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) 1); qdev_init_gpio_out_named(dev, lpc->gsi, ICH9_GPIO_GSI, GSI_NUM_PINS); + + isa_bus_irqs(isa_bus, lpc->gsi); } static bool ich9_rst_cnt_needed(void *opaque) From 250263033c5343012b2cd6f01210ffb5b908a159 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:56 +0300 Subject: [PATCH 15/35] isa: introduce wrapper isa_connect_gpio_out Currently a direct access to the device structure field is used to connect ISA device IRQ to the bus. GPIO access should be used instead if possible. The patch adds wrapper isa_connect_gpio_out. The function connects specified output GPIO to specified ISA IRQ. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/isa/isa-bus.c | 7 +++++++ include/hw/isa/isa.h | 1 + 2 files changed, 8 insertions(+) diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index 7aa115caf2..ce74db232a 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -97,6 +97,13 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq) dev->nirqs++; } +void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq) +{ + qemu_irq irq; + isa_init_irq(isadev, &irq, isairq); + qdev_connect_gpio_out(DEVICE(isadev), gpioirq, irq); +} + void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16) { assert(bus && dma8 && dma16); diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h index c87fbad47a..7693ac5454 100644 --- a/include/hw/isa/isa.h +++ b/include/hw/isa/isa.h @@ -102,6 +102,7 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space, void isa_bus_irqs(ISABus *bus, qemu_irq *irqs); qemu_irq isa_get_irq(ISADevice *dev, int isairq); void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq); +void isa_connect_gpio_out(ISADevice *isadev, int gpioirq, int isairq); void isa_bus_dma(ISABus *bus, IsaDma *dma8, IsaDma *dma16); IsaDma *isa_get_dma(ISABus *bus, int nchan); MemoryRegion *isa_address_space(ISADevice *dev); From 3638439d541835f20fb76346f14549800046af76 Mon Sep 17 00:00:00 2001 From: Efimov Vasily Date: Wed, 22 Jun 2016 15:24:57 +0300 Subject: [PATCH 16/35] MC146818 RTC: add GPIO access to output IRQ The MC146818 RTC device has output IRQ line. Currently the corresponding field is only accessible through direct access. Such access violates Qemu model. The patch makes the field accessible through GPIO. It also updates the setting of the IRQ during initialization. Signed-off-by: Efimov Vasily Signed-off-by: Paolo Bonzini --- hw/timer/mc146818rtc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index f4e333eb8f..ea625f25ce 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -906,6 +906,8 @@ static void rtc_realizefn(DeviceState *dev, Error **errp) object_property_add_alias(qdev_get_machine(), "rtc-time", OBJECT(s), "date", NULL); + + qdev_init_gpio_out(dev, &s->irq, 1); } ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq) @@ -920,9 +922,9 @@ ISADevice *rtc_init(ISABus *bus, int base_year, qemu_irq intercept_irq) qdev_prop_set_int32(dev, "base_year", base_year); qdev_init_nofail(dev); if (intercept_irq) { - s->irq = intercept_irq; + qdev_connect_gpio_out(dev, 0, intercept_irq); } else { - isa_init_irq(isadev, &s->irq, RTC_ISA_IRQ); + isa_connect_gpio_out(isadev, 0, RTC_ISA_IRQ); } QLIST_INSERT_HEAD(&rtc_devices, s, link); From cc96677469388bad3d66479379735cf75db069e3 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 20 Jun 2016 16:32:39 +0200 Subject: [PATCH 17/35] scsi: esp: fix migration Commit 926cde5 ("scsi: esp: make cmdbuf big enough for maximum CDB size", 2016-06-16) changed the size of a migrated field. Split it in two parts, and only migrate the second part in a new vmstate version. Signed-off-by: Paolo Bonzini --- hw/scsi/esp.c | 5 +++-- include/migration/vmstate.h | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index baa0a2cfdf..1f2f2d33dd 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -574,7 +574,7 @@ static bool esp_mem_accepts(void *opaque, hwaddr addr, const VMStateDescription vmstate_esp = { .name ="esp", - .version_id = 3, + .version_id = 4, .minimum_version_id = 3, .fields = (VMStateField[]) { VMSTATE_BUFFER(rregs, ESPState), @@ -585,7 +585,8 @@ const VMStateDescription vmstate_esp = { VMSTATE_BUFFER(ti_buf, ESPState), VMSTATE_UINT32(status, ESPState), VMSTATE_UINT32(dma, ESPState), - VMSTATE_BUFFER(cmdbuf, ESPState), + VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16), + VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4), VMSTATE_UINT32(cmdlen, ESPState), VMSTATE_UINT32(do_cmd, ESPState), VMSTATE_UINT32(dma_left, ESPState), diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h index 25ea58a77f..15ea7679bd 100644 --- a/include/migration/vmstate.h +++ b/include/migration/vmstate.h @@ -904,8 +904,11 @@ extern const VMStateInfo vmstate_info_bitmap; #define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \ VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size) +#define VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, _v) \ + VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, _start, sizeof(typeof_field(_s, _f))) + #define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \ - VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f))) + VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0) #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \ VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size) From 33df7bf3bf43ffa3001cadfe5d5faef2774522d0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 31 May 2016 14:59:08 +0200 Subject: [PATCH 18/35] vnc: generalize "VNC server running on ..." message The message is useful whenever the user specifies "-vnc to=XX". Move it to ui/vnc.c. Signed-off-by: Paolo Bonzini --- include/ui/console.h | 7 ------- ui/vnc.c | 23 ++++++++++++----------- vl.c | 7 ------- 3 files changed, 12 insertions(+), 25 deletions(-) diff --git a/include/ui/console.h b/include/ui/console.h index 52a5f65673..7c1fdbad6f 100644 --- a/include/ui/console.h +++ b/include/ui/console.h @@ -460,7 +460,6 @@ void vnc_display_add_client(const char *id, int csock, bool skipauth); #ifdef CONFIG_VNC int vnc_display_password(const char *id, const char *password); int vnc_display_pw_expire(const char *id, time_t expires); -char *vnc_display_local_addr(const char *id); QemuOpts *vnc_parse(const char *str, Error **errp); int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp); #else @@ -482,12 +481,6 @@ static inline int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp) error_setg(errp, "VNC support is disabled"); return -1; } -static inline char *vnc_display_local_addr(const char *id) -{ - /* This must never be called if CONFIG_VNC is disabled */ - error_report("VNC support is disabled"); - abort(); -} #endif /* curses.c */ diff --git a/ui/vnc.c b/ui/vnc.c index 95e4db763b..18c0b56c3a 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -3205,29 +3205,24 @@ int vnc_display_pw_expire(const char *id, time_t expires) return 0; } -char *vnc_display_local_addr(const char *id) +static void vnc_display_print_local_addr(VncDisplay *vs) { - VncDisplay *vs = vnc_display_find(id); SocketAddress *addr; - char *ret; Error *err = NULL; - assert(vs); - addr = qio_channel_socket_get_local_address(vs->lsock, &err); if (!addr) { - return NULL; + return; } if (addr->type != SOCKET_ADDRESS_KIND_INET) { qapi_free_SocketAddress(addr); - return NULL; + return; } - ret = g_strdup_printf("%s:%s", addr->u.inet.data->host, - addr->u.inet.data->port); + error_printf_unless_qmp("VNC server running on %s:%s\n", + addr->u.inet.data->host, + addr->u.inet.data->port); qapi_free_SocketAddress(addr); - - return ret; } static QemuOptsList qemu_vnc_opts = { @@ -3513,6 +3508,7 @@ void vnc_display_open(const char *id, Error **errp) const char *vnc; char *h; const char *credid; + int show_vnc_port = 0; bool sasl = false; #ifdef CONFIG_VNC_SASL int saslErr; @@ -3592,6 +3588,7 @@ void vnc_display_open(const char *id, Error **errp) if (to) { inet->has_to = true; inet->to = to + 5900; + show_vnc_port = 1; } inet->ipv4 = ipv4; inet->has_ipv4 = has_ipv4; @@ -3836,6 +3833,10 @@ void vnc_display_open(const char *id, Error **errp) } } + if (show_vnc_port) { + vnc_display_print_local_addr(vs); + } + qapi_free_SocketAddress(saddr); qapi_free_SocketAddress(wsaddr); return; diff --git a/vl.c b/vl.c index c85833a63c..64cfa968c9 100644 --- a/vl.c +++ b/vl.c @@ -2947,7 +2947,6 @@ int main(int argc, char **argv, char **envp) const char *qtest_log = NULL; const char *pid_file = NULL; const char *incoming = NULL; - int show_vnc_port = 0; bool defconfig = true; bool userconfig = true; bool nographic = false; @@ -4216,7 +4215,6 @@ int main(int argc, char **argv, char **envp) display_type = DT_COCOA; #elif defined(CONFIG_VNC) vnc_parse("localhost:0,to=99,id=default", &error_abort); - show_vnc_port = 1; #else display_type = DT_NONE; #endif @@ -4565,11 +4563,6 @@ int main(int argc, char **argv, char **envp) qemu_opts_foreach(qemu_find_opts("vnc"), vnc_init_func, NULL, NULL); #endif - if (show_vnc_port) { - char *ret = vnc_display_local_addr("default"); - printf("VNC server running on '%s'\n", ret); - g_free(ret); - } if (using_spice) { qemu_spice_display_init(); From be968c721ee9df49708691ab58f0e66b394dea82 Mon Sep 17 00:00:00 2001 From: Lin Ma Date: Thu, 16 Jun 2016 01:05:27 +0800 Subject: [PATCH 19/35] pci-assign: Move "Invalid ROM" error message to pci-assign-load-rom.c In function pci_assign_dev_load_option_rom, For those pci devices don't have 'rom' file under sysfs or if loading ROM from external file, The function returns NULL, and won't set the passed 'size' variable. In these 2 cases, qemu still reports "Invalid ROM" error message, Users may be confused by it. Signed-off-by: Lin Ma Message-Id: <1466010327-22368-1-git-send-email-lma@suse.com> Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- hw/i386/kvm/pci-assign.c | 4 ---- hw/i386/pci-assign-load-rom.c | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index 98997d167c..3623aa1965 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -1891,8 +1891,4 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev) pci_assign_dev_load_option_rom(&dev->dev, OBJECT(dev), &size, dev->host.domain, dev->host.bus, dev->host.slot, dev->host.function); - - if (!size) { - error_report("pci-assign: Invalid ROM."); - } } diff --git a/hw/i386/pci-assign-load-rom.c b/hw/i386/pci-assign-load-rom.c index 4bbb08c955..0d8e4b2826 100644 --- a/hw/i386/pci-assign-load-rom.c +++ b/hw/i386/pci-assign-load-rom.c @@ -40,6 +40,9 @@ void *pci_assign_dev_load_option_rom(PCIDevice *dev, struct Object *owner, domain, bus, slot, function); if (stat(rom_file, &st)) { + if (errno != ENOENT) { + error_report("pci-assign: Invalid ROM."); + } return NULL; } From 8642c1b81e0418df066a7960a7426d85a923a253 Mon Sep 17 00:00:00 2001 From: Peter Crosthwaite Date: Sat, 18 Jul 2015 02:40:28 -0700 Subject: [PATCH 20/35] target-*: Don't redefine cpu_exec() This function needs to be converted to QOM hook and virtualised for multi-arch. This rename interferes, as cpu-qom will not have access to the renaming causing name divergence. This rename doesn't really do anything anyway so just delete it. Signed-off-by: Peter Crosthwaite Message-Id: <69bd25a8678b8b31b91cd9760c777bed1aafb44e.1437212383.git.crosthwaite.peter@gmail.com> Signed-off-by: Paolo Bonzini Signed-off-by: Peter Crosthwaite --- include/exec/cpu-all.h | 2 ++ linux-user/main.c | 32 ++++++++++++++++---------------- target-alpha/cpu.h | 2 -- target-arm/cpu.h | 2 -- target-cris/cpu.h | 2 -- target-i386/cpu.h | 2 -- target-lm32/cpu.h | 2 -- target-m68k/cpu.h | 2 -- target-microblaze/cpu.h | 2 -- target-mips/cpu.h | 2 -- target-moxie/cpu.h | 2 -- target-openrisc/cpu.h | 2 -- target-ppc/cpu.h | 2 -- target-s390x/cpu.h | 2 -- target-sh4/cpu.h | 2 -- target-sparc/cpu.h | 2 -- target-tilegx/cpu.h | 2 -- target-tricore/cpu.h | 2 -- target-unicore32/cpu.h | 3 --- target-xtensa/cpu.h | 2 -- 20 files changed, 18 insertions(+), 53 deletions(-) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 9f38edf419..6a6796d0c9 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -304,4 +304,6 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf); int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, uint8_t *buf, int len, int is_write); +int cpu_exec(CPUState *cpu); + #endif /* CPU_ALL_H */ diff --git a/linux-user/main.c b/linux-user/main.c index fd88e22fe3..d9420cf7b5 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -157,7 +157,7 @@ static inline void exclusive_idle(void) } /* Start an exclusive operation. - Must only be called from outside cpu_arm_exec. */ + Must only be called from outside cpu_exec. */ static inline void start_exclusive(void) { CPUState *other_cpu; @@ -291,7 +291,7 @@ void cpu_loop(CPUX86State *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_x86_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch(trapnr) { case 0x80: @@ -732,7 +732,7 @@ void cpu_loop(CPUARMState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_arm_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_UDEF: @@ -1068,7 +1068,7 @@ void cpu_loop(CPUARMState *env) for (;;) { cpu_exec_start(cs); - trapnr = cpu_arm_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { @@ -1156,7 +1156,7 @@ void cpu_loop(CPUUniCore32State *env) for (;;) { cpu_exec_start(cs); - trapnr = uc32_cpu_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case UC32_EXCP_PRIV: @@ -1361,7 +1361,7 @@ void cpu_loop (CPUSPARCState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_sparc_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); /* Compute PSR before exposing state. */ @@ -1633,7 +1633,7 @@ void cpu_loop(CPUPPCState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_ppc_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch(trapnr) { case POWERPC_EXCP_NONE: @@ -2490,7 +2490,7 @@ void cpu_loop(CPUMIPSState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_mips_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_SYSCALL: @@ -2730,7 +2730,7 @@ void cpu_loop(CPUOpenRISCState *env) for (;;) { cpu_exec_start(cs); - trapnr = cpu_openrisc_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); gdbsig = 0; @@ -2824,7 +2824,7 @@ void cpu_loop(CPUSH4State *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_sh4_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { @@ -2890,7 +2890,7 @@ void cpu_loop(CPUCRISState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_cris_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case 0xaa: @@ -2955,7 +2955,7 @@ void cpu_loop(CPUMBState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_mb_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case 0xaa: @@ -3072,7 +3072,7 @@ void cpu_loop(CPUM68KState *env) for(;;) { cpu_exec_start(cs); - trapnr = cpu_m68k_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch(trapnr) { case EXCP_ILLEGAL: @@ -3215,7 +3215,7 @@ void cpu_loop(CPUAlphaState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_alpha_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); /* All of the traps imply a transition through PALcode, which @@ -3407,7 +3407,7 @@ void cpu_loop(CPUS390XState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_s390x_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case EXCP_INTERRUPT: @@ -3716,7 +3716,7 @@ void cpu_loop(CPUTLGState *env) while (1) { cpu_exec_start(cs); - trapnr = cpu_tilegx_exec(cs); + trapnr = cpu_exec(cs); cpu_exec_end(cs); switch (trapnr) { case TILEGX_EXCP_SYSCALL: diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index e71ea70ea1..ce8d2965b2 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -326,7 +326,6 @@ void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, int is_write, int is_user, uintptr_t retaddr); #define cpu_list alpha_cpu_list -#define cpu_exec cpu_alpha_exec #define cpu_signal_handler cpu_alpha_signal_handler #include "exec/cpu-all.h" @@ -467,7 +466,6 @@ AlphaCPU *cpu_alpha_init(const char *cpu_model); #define cpu_init(cpu_model) CPU(cpu_alpha_init(cpu_model)) void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf); -int cpu_alpha_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 7938ddc91c..e2fac46909 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -703,7 +703,6 @@ int aarch64_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); #endif ARMCPU *cpu_arm_init(const char *cpu_model); -int cpu_arm_exec(CPUState *cpu); target_ulong do_arm_semihosting(CPUARMState *env); void aarch64_sync_32_to_64(CPUARMState *env); void aarch64_sync_64_to_32(CPUARMState *env); @@ -1891,7 +1890,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, #define cpu_init(cpu_model) CPU(cpu_arm_init(cpu_model)) -#define cpu_exec cpu_arm_exec #define cpu_signal_handler cpu_arm_signal_handler #define cpu_list arm_cpu_list diff --git a/target-cris/cpu.h b/target-cris/cpu.h index d8c47a6c2e..e6046d20ca 100644 --- a/target-cris/cpu.h +++ b/target-cris/cpu.h @@ -213,7 +213,6 @@ int cris_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); CRISCPU *cpu_cris_init(const char *cpu_model); -int cpu_cris_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -260,7 +259,6 @@ enum { #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model)) -#define cpu_exec cpu_cris_exec #define cpu_signal_handler cpu_cris_signal_handler /* MMU modes definitions */ diff --git a/target-i386/cpu.h b/target-i386/cpu.h index d9ab884c2b..474b0b937d 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1235,7 +1235,6 @@ void x86_cpu_exec_exit(CPUState *cpu); X86CPU *cpu_x86_init(const char *cpu_model); X86CPU *cpu_x86_create(const char *cpu_model, Error **errp); -int cpu_x86_exec(CPUState *cpu); void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf); int cpu_x86_support_mca_broadcast(CPUX86State *env); @@ -1411,7 +1410,6 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define cpu_init(cpu_model) CPU(cpu_x86_init(cpu_model)) -#define cpu_exec cpu_x86_exec #define cpu_signal_handler cpu_x86_signal_handler #define cpu_list x86_cpu_list diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h index 62880f7e4b..4efe98d828 100644 --- a/target-lm32/cpu.h +++ b/target-lm32/cpu.h @@ -236,7 +236,6 @@ static inline lm32_wp_t lm32_wp_type(uint32_t dc, int idx) } LM32CPU *cpu_lm32_init(const char *cpu_model); -int cpu_lm32_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -257,7 +256,6 @@ bool lm32_cpu_do_semihosting(CPUState *cs); #define cpu_init(cpu_model) CPU(cpu_lm32_init(cpu_model)) #define cpu_list lm32_cpu_list -#define cpu_exec cpu_lm32_exec #define cpu_signal_handler cpu_lm32_signal_handler int lm32_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 008a057a97..9087769997 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -146,7 +146,6 @@ void m68k_cpu_exec_exit(CPUState *cs); void m68k_tcg_init(void); void m68k_cpu_init_gdb(M68kCPU *cpu); M68kCPU *cpu_m68k_init(const char *cpu_model); -int cpu_m68k_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -243,7 +242,6 @@ void register_m68k_insns (CPUM68KState *env); #define cpu_init(cpu_model) CPU(cpu_m68k_init(cpu_model)) -#define cpu_exec cpu_m68k_exec #define cpu_signal_handler cpu_m68k_signal_handler #define cpu_list m68k_cpu_list diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h index d17cf1e301..16815dfc6a 100644 --- a/target-microblaze/cpu.h +++ b/target-microblaze/cpu.h @@ -321,7 +321,6 @@ int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void mb_tcg_init(void); MicroBlazeCPU *cpu_mb_init(const char *cpu_model); -int cpu_mb_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -336,7 +335,6 @@ int cpu_mb_signal_handler(int host_signum, void *pinfo, #define cpu_init(cpu_model) CPU(cpu_mb_init(cpu_model)) -#define cpu_exec cpu_mb_exec #define cpu_signal_handler cpu_mb_signal_handler /* MMU modes definitions */ diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 4ce9d47661..30b4712c71 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -674,7 +674,6 @@ void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr, void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf); -#define cpu_exec cpu_mips_exec #define cpu_signal_handler cpu_mips_signal_handler #define cpu_list mips_cpu_list @@ -800,7 +799,6 @@ enum { */ #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 -int cpu_mips_exec(CPUState *cpu); void mips_tcg_init(void); MIPSCPU *cpu_mips_init(const char *cpu_model); int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h index c10898eba7..63d5cafc55 100644 --- a/target-moxie/cpu.h +++ b/target-moxie/cpu.h @@ -109,7 +109,6 @@ static inline MoxieCPU *moxie_env_get_cpu(CPUMoxieState *env) #define ENV_OFFSET offsetof(MoxieCPU, env) MoxieCPU *cpu_moxie_init(const char *cpu_model); -int cpu_moxie_exec(CPUState *cpu); void moxie_cpu_do_interrupt(CPUState *cs); void moxie_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf, int flags); @@ -120,7 +119,6 @@ int cpu_moxie_signal_handler(int host_signum, void *pinfo, #define cpu_init(cpu_model) CPU(cpu_moxie_init(cpu_model)) -#define cpu_exec cpu_moxie_exec #define cpu_signal_handler cpu_moxie_signal_handler static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index 810a280061..9451a7cca6 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -344,7 +344,6 @@ static inline OpenRISCCPU *openrisc_env_get_cpu(CPUOpenRISCState *env) OpenRISCCPU *cpu_openrisc_init(const char *cpu_model); void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf); -int cpu_openrisc_exec(CPUState *cpu); void openrisc_cpu_do_interrupt(CPUState *cpu); bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, @@ -358,7 +357,6 @@ int openrisc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_list cpu_openrisc_list -#define cpu_exec cpu_openrisc_exec #define cpu_signal_handler cpu_openrisc_signal_handler #ifndef CONFIG_USER_ONLY diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index b1354a4791..534381e422 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1189,7 +1189,6 @@ extern const struct VMStateDescription vmstate_ppc_cpu; PowerPCCPU *cpu_ppc_init(const char *cpu_model); void ppc_translate_init(void); void gen_update_current_nip(void *opaque); -int cpu_ppc_exec (CPUState *s); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero is returned if the signal was handled by the virtual CPU. */ @@ -1268,7 +1267,6 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val); #define cpu_init(cpu_model) CPU(cpu_ppc_init(cpu_model)) -#define cpu_exec cpu_ppc_exec #define cpu_signal_handler cpu_ppc_signal_handler #define cpu_list ppc_cpu_list diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h index bd6b2e57ef..8bcb0f75f3 100644 --- a/target-s390x/cpu.h +++ b/target-s390x/cpu.h @@ -463,7 +463,6 @@ S390CPU *cpu_s390x_init(const char *cpu_model); S390CPU *s390x_new_cpu(const char *cpu_model, int64_t id, Error **errp); S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp); void s390x_translate_init(void); -int cpu_s390x_exec(CPUState *cpu); /* you can call this signal handler from your SIGBUS and SIGSEGV signal handlers to inform the virtual CPU of exceptions. non zero @@ -627,7 +626,6 @@ void cpu_unlock(void); extern void subsystem_reset(void); #define cpu_init(model) CPU(cpu_s390x_init(model)) -#define cpu_exec cpu_s390x_exec #define cpu_signal_handler cpu_s390x_signal_handler void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf); diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index 3f5c689eb3..3f9dae2d1f 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -221,7 +221,6 @@ int superh_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void sh4_translate_init(void); SuperHCPU *cpu_sh4_init(const char *cpu_model); -int cpu_sh4_exec(CPUState *s); int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc); int superh_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw, @@ -254,7 +253,6 @@ void cpu_load_tlb(CPUSH4State * env); #define cpu_init(cpu_model) CPU(cpu_sh4_init(cpu_model)) -#define cpu_exec cpu_sh4_exec #define cpu_signal_handler cpu_sh4_signal_handler #define cpu_list sh4_cpu_list diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index ba37f4b94e..f78fabfe7b 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -565,7 +565,6 @@ int sparc_cpu_memory_rw_debug(CPUState *cpu, vaddr addr, void gen_intermediate_code_init(CPUSPARCState *env); /* cpu-exec.c */ -int cpu_sparc_exec(CPUState *cpu); /* win_helper.c */ target_ulong cpu_get_psr(CPUSPARCState *env1); @@ -626,7 +625,6 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_init(cpu_model) CPU(cpu_sparc_init(cpu_model)) #endif -#define cpu_exec cpu_sparc_exec #define cpu_signal_handler cpu_sparc_signal_handler #define cpu_list sparc_cpu_list diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h index b9b588de53..d74032925b 100644 --- a/target-tilegx/cpu.h +++ b/target-tilegx/cpu.h @@ -158,14 +158,12 @@ static inline TileGXCPU *tilegx_env_get_cpu(CPUTLGState *env) #include "exec/cpu-all.h" void tilegx_tcg_init(void); -int cpu_tilegx_exec(CPUState *s); int cpu_tilegx_signal_handler(int host_signum, void *pinfo, void *puc); TileGXCPU *cpu_tilegx_init(const char *cpu_model); #define cpu_init(cpu_model) CPU(cpu_tilegx_init(cpu_model)) -#define cpu_exec cpu_tilegx_exec #define cpu_signal_handler cpu_tilegx_signal_handler static inline void cpu_get_tb_cpu_state(CPUTLGState *env, target_ulong *pc, diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h index 3c6f7b75b8..a298d63eea 100644 --- a/target-tricore/cpu.h +++ b/target-tricore/cpu.h @@ -374,7 +374,6 @@ void fpu_set_state(CPUTriCoreState *env); void tricore_cpu_list(FILE *f, fprintf_function cpu_fprintf); -#define cpu_exec cpu_tricore_exec #define cpu_signal_handler cpu_tricore_signal_handler #define cpu_list tricore_cpu_list @@ -400,7 +399,6 @@ enum { }; void cpu_state_reset(CPUTriCoreState *s); -int cpu_tricore_exec(CPUState *cpu); void tricore_tcg_init(void); int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc); diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index f3e877bbc0..83f758496a 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -149,7 +149,6 @@ void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask) #define UC32_HWCAP_CMOV 4 /* 1 << 2 */ #define UC32_HWCAP_UCF64 8 /* 1 << 3 */ -#define cpu_exec uc32_cpu_exec #define cpu_signal_handler uc32_cpu_signal_handler int uc32_cpu_signal_handler(int host_signum, void *pinfo, void *puc); @@ -165,8 +164,6 @@ static inline int cpu_mmu_index(CPUUniCore32State *env, bool ifetch) #include "exec/cpu-all.h" -int uc32_cpu_exec(CPUState *s); - UniCore32CPU *uc32_cpu_init(const char *cpu_model); #define cpu_init(cpu_model) CPU(uc32_cpu_init(cpu_model)) diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 442176a2b2..8477ec963a 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -416,7 +416,6 @@ int xtensa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr, int is_write, int is_user, uintptr_t retaddr); -#define cpu_exec cpu_xtensa_exec #define cpu_signal_handler cpu_xtensa_signal_handler #define cpu_list xtensa_cpu_list @@ -432,7 +431,6 @@ XtensaCPU *cpu_xtensa_init(const char *cpu_model); void xtensa_translate_init(void); void xtensa_breakpoint_handler(CPUState *cs); -int cpu_xtensa_exec(CPUState *cpu); void xtensa_finalize_config(XtensaConfig *config); void xtensa_register_core(XtensaConfigList *node); void check_interrupts(CPUXtensaState *s); From 0ead93120eb7bd770b32adc00b5ec1ee721626dc Mon Sep 17 00:00:00 2001 From: Peter Lieven Date: Mon, 20 Jun 2016 11:24:40 +0200 Subject: [PATCH 21/35] iscsi: fix assertion in is_sector_request_lun_aligned Commit 94d047a added an assertion the the request alignment check. This introduced 2 issues: a) A off-by-one error since a request of BDRV_REQUEST_MAX_SECTORS is actually allowed. b) The bdrv_get_block_status call in the read path to check the allocation status requests up to INT_MAX sectors which triggers the assertion. Fixes: 94d047a35bf663e28f8fef137544d8ea78165add Signed-off-by: Peter Lieven Message-Id: <1466414680-18383-1-git-send-email-pl@kamp.de> Signed-off-by: Paolo Bonzini --- block/iscsi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index 7e78adea15..9bb5ff6216 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -417,7 +417,7 @@ static bool is_byte_request_lun_aligned(int64_t offset, int count, static bool is_sector_request_lun_aligned(int64_t sector_num, int nb_sectors, IscsiLun *iscsilun) { - assert(nb_sectors < BDRV_REQUEST_MAX_SECTORS); + assert(nb_sectors <= BDRV_REQUEST_MAX_SECTORS); return is_byte_request_lun_aligned(sector_num << BDRV_SECTOR_BITS, nb_sectors << BDRV_SECTOR_BITS, iscsilun); @@ -661,7 +661,8 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs, int64_t ret; int pnum; BlockDriverState *file; - ret = iscsi_co_get_block_status(bs, sector_num, INT_MAX, &pnum, &file); + ret = iscsi_co_get_block_status(bs, sector_num, + BDRV_REQUEST_MAX_SECTORS, &pnum, &file); if (ret < 0) { return ret; } From 807464d8a7326e1025a2f392bf41636b0809d6da Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 14 Jun 2016 14:17:16 +0200 Subject: [PATCH 22/35] serial: make tsr_retry unsigned It can never become negative; reflect this in the type of the field and simplify the conditions. Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 12 ++++++++---- include/hw/char/serial.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 6d815b5c69..e65e9e0b4c 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -229,7 +229,7 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) do { assert(!(s->lsr & UART_LSR_TEMT)); - if (s->tsr_retry <= 0) { + if (s->tsr_retry == 0) { assert(!(s->lsr & UART_LSR_THRE)); if (s->fcr & UART_FCR_FE) { @@ -252,7 +252,7 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { - if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY && + if (s->tsr_retry < MAX_XMIT_RETRY && qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, serial_xmit, s) > 0) { s->tsr_retry++; @@ -330,7 +330,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, s->lsr &= ~UART_LSR_THRE; s->lsr &= ~UART_LSR_TEMT; serial_update_irq(s); - if (s->tsr_retry <= 0) { + if (s->tsr_retry == 0) { serial_xmit(NULL, G_IO_OUT, s); } } @@ -639,6 +639,10 @@ static int serial_post_load(void *opaque, int version_id) if (s->thr_ipending == -1) { s->thr_ipending = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); } + if (s->tsr_retry > MAX_XMIT_RETRY) { + s->tsr_retry = MAX_XMIT_RETRY; + } + s->last_break_enable = (s->lcr >> 6) & 1; /* Initialize fcr via setter to perform essential side-effects */ serial_write_fcr(s, s->fcr_vmstate); @@ -685,7 +689,7 @@ static const VMStateDescription vmstate_serial_tsr = { .minimum_version_id = 1, .needed = serial_tsr_needed, .fields = (VMStateField[]) { - VMSTATE_INT32(tsr_retry, SerialState), + VMSTATE_UINT32(tsr_retry, SerialState), VMSTATE_UINT8(thr, SerialState), VMSTATE_UINT8(tsr, SerialState), VMSTATE_END_OF_LIST() diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 15beb6b45c..6a322eb22e 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -55,7 +55,7 @@ struct SerialState { int last_break_enable; int it_shift; int baudbase; - int tsr_retry; + uint32_t tsr_retry; uint32_t wakeup; /* Time when the last byte was successfully sent out of the tsr */ From bce933b85a34514fe34fa559be1d8ccd1f39f954 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 14 Jun 2016 14:20:50 +0200 Subject: [PATCH 23/35] serial: simplify tsr_retry reset Move common code outside the if, and reset tsr_retry even in loopback mode. Right now it cannot become non-zero, but it will be possible as soon as we start respecting the baud rate. Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index e65e9e0b4c..904b218c21 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -258,10 +258,8 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) s->tsr_retry++; return FALSE; } - s->tsr_retry = 0; - } else { - s->tsr_retry = 0; } + s->tsr_retry = 0; /* Transmit another byte if it is already available. It is only possible when FIFO is enabled and not empty. */ From b0585e7e07982daa578c3bfef7f6843c89f110a8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 20 Jun 2016 15:08:20 +0200 Subject: [PATCH 24/35] serial: separate serial_xmit and serial_watch_cb serial_xmit starts transmission of whatever is in the transmitter register, THR or FIFO; serial_watch_cb is a wrapper around it and is only used as a qemu_chr_fe_add_watch callback. Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 904b218c21..0b09094c0c 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -106,6 +106,7 @@ do {} while (0) #endif static void serial_receive1(void *opaque, const uint8_t *buf, int size); +static void serial_xmit(SerialState *s); static inline void recv_fifo_put(SerialState *s, uint8_t chr) { @@ -223,10 +224,16 @@ static void serial_update_msl(SerialState *s) } } -static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) +static gboolean serial_watch_cb(GIOChannel *chan, GIOCondition cond, + void *opaque) { SerialState *s = opaque; + serial_xmit(s); + return FALSE; +} +static void serial_xmit(SerialState *s) +{ do { assert(!(s->lsr & UART_LSR_TEMT)); if (s->tsr_retry == 0) { @@ -254,9 +261,9 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { if (s->tsr_retry < MAX_XMIT_RETRY && qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, - serial_xmit, s) > 0) { + serial_watch_cb, s) > 0) { s->tsr_retry++; - return FALSE; + return; } } s->tsr_retry = 0; @@ -267,11 +274,8 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque) s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); s->lsr |= UART_LSR_TEMT; - - return FALSE; } - /* Setter for FCR. is_load flag means, that value is set while loading VM state and interrupt should not be invoked */ @@ -329,7 +333,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val, s->lsr &= ~UART_LSR_TEMT; serial_update_irq(s); if (s->tsr_retry == 0) { - serial_xmit(NULL, G_IO_OUT, s); + serial_xmit(s); } } break; From 6f1de6b70d857d5e316ae6fd908f52818b827b08 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 20 Jun 2016 15:02:40 +0200 Subject: [PATCH 25/35] char: change qemu_chr_fe_add_watch to return unsigned g_source_attach can return any value between 1 and UINT_MAX if you let QEMU run long enough. However, qemu_chr_fe_add_watch can also return a negative errno value when the device is disconnected or does not support chr_add_watch. Change it to return zero to avoid overloading these values. Fix the cadence_uart which asserts in this case (easily obtained with "-serial pty"). Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/cadence_uart.c | 9 ++++++--- include/sysemu/char.h | 16 ++++++++++++++-- net/vhost-user.c | 2 +- qemu-char.c | 8 ++++---- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index c856fc30b2..65179fa500 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -292,9 +292,12 @@ static gboolean cadence_uart_xmit(GIOChannel *chan, GIOCondition cond, memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_count); if (s->tx_count) { - int r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, - cadence_uart_xmit, s); - assert(r); + guint r = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + cadence_uart_xmit, s); + if (!r) { + s->tx_count = 0; + return FALSE; + } } uart_update_status(s); diff --git a/include/sysemu/char.h b/include/sysemu/char.h index 1eb2d0f309..57df10aa00 100644 --- a/include/sysemu/char.h +++ b/include/sysemu/char.h @@ -221,8 +221,20 @@ void qemu_chr_fe_event(CharDriverState *s, int event); void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, - GIOFunc func, void *user_data); +/** + * @qemu_chr_fe_add_watch: + * + * If the backend is connected, create and add a #GSource that fires + * when the given condition (typically G_IO_OUT|G_IO_HUP or G_IO_HUP) + * is active; return the #GSource's tag. If it is disconnected, + * return 0. + * + * @cond the condition to poll for + * @func the function to call when the condition happens + * @user_data the opaque pointer to pass to @func + */ +guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, + GIOFunc func, void *user_data); /** * @qemu_chr_fe_write: diff --git a/net/vhost-user.c b/net/vhost-user.c index d72ce9b490..636899a877 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -22,7 +22,7 @@ typedef struct VhostUserState { NetClientState nc; CharDriverState *chr; VHostNetState *vhost_net; - int watch; + guint watch; uint64_t acked_features; } VhostUserState; diff --git a/qemu-char.c b/qemu-char.c index 84f49acbac..8575c54c98 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3966,19 +3966,19 @@ void qemu_chr_fe_event(struct CharDriverState *chr, int event) } } -int qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, - GIOFunc func, void *user_data) +guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond, + GIOFunc func, void *user_data) { GSource *src; guint tag; if (s->chr_add_watch == NULL) { - return -ENOSYS; + return 0; } src = s->chr_add_watch(s, cond); if (!src) { - return -EINVAL; + return 0; } g_source_set_callback(src, (GSourceFunc)func, user_data, NULL); From a1df76da57aa8772a75e7c49f8e3829d07b4c46c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 14 Jun 2016 14:35:20 +0200 Subject: [PATCH 26/35] serial: remove watch on reset Otherwise, this can cause serial_xmit to be entered with LSR.TEMT=0, which is invalid and causes an assertion failure. Reported-by: Bret Ketchum Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 16 ++++++++++++---- include/hw/char/serial.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index 0b09094c0c..af39e8f867 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -228,6 +228,7 @@ static gboolean serial_watch_cb(GIOChannel *chan, GIOCondition cond, void *opaque) { SerialState *s = opaque; + s->watch_tag = 0; serial_xmit(s); return FALSE; } @@ -258,10 +259,12 @@ static void serial_xmit(SerialState *s) if (s->mcr & UART_MCR_LOOP) { /* in loopback mode, say that we just received a char */ serial_receive1(s, &s->tsr, 1); - } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) { - if (s->tsr_retry < MAX_XMIT_RETRY && - qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, - serial_watch_cb, s) > 0) { + } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1 && + s->tsr_retry < MAX_XMIT_RETRY) { + assert(s->watch_tag == 0); + s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + serial_watch_cb, s); + if (s->watch_tag > 0) { s->tsr_retry++; return; } @@ -821,6 +824,11 @@ static void serial_reset(void *opaque) { SerialState *s = opaque; + if (s->watch_tag > 0) { + g_source_remove(s->watch_tag); + s->watch_tag = 0; + } + s->rbr = 0; s->ier = 0; s->iir = UART_IIR_NO_INT; diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h index 6a322eb22e..9feddc613c 100644 --- a/include/hw/char/serial.h +++ b/include/hw/char/serial.h @@ -56,6 +56,7 @@ struct SerialState { int it_shift; int baudbase; uint32_t tsr_retry; + guint watch_tag; uint32_t wakeup; /* Time when the last byte was successfully sent out of the tsr */ From 9f34a35e0020b0b2b2e21c086a486d7dfd18df4f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 14 Jun 2016 14:46:51 +0200 Subject: [PATCH 27/35] serial: reinstate watch after migration Otherwise, a serial port can get stuck if it is migrated while flow control is in effect. Tested-by: Bret Ketchum Reviewed-by: Dr. David Alan Gilbert Signed-off-by: Paolo Bonzini --- hw/char/serial.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/hw/char/serial.c b/hw/char/serial.c index af39e8f867..3442f47d36 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -644,8 +644,29 @@ static int serial_post_load(void *opaque, int version_id) if (s->thr_ipending == -1) { s->thr_ipending = ((s->iir & UART_IIR_ID) == UART_IIR_THRI); } - if (s->tsr_retry > MAX_XMIT_RETRY) { - s->tsr_retry = MAX_XMIT_RETRY; + + if (s->tsr_retry > 0) { + /* tsr_retry > 0 implies LSR.TEMT = 0 (transmitter not empty). */ + if (s->lsr & UART_LSR_TEMT) { + error_report("inconsistent state in serial device " + "(tsr empty, tsr_retry=%d", s->tsr_retry); + return -1; + } + + if (s->tsr_retry > MAX_XMIT_RETRY) { + s->tsr_retry = MAX_XMIT_RETRY; + } + + assert(s->watch_tag == 0); + s->watch_tag = qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, + serial_watch_cb, s); + } else { + /* tsr_retry == 0 implies LSR.TEMT = 1 (transmitter empty). */ + if (!(s->lsr & UART_LSR_TEMT)) { + error_report("inconsistent state in serial device " + "(tsr not empty, tsr_retry=0"); + return -1; + } } s->last_break_enable = (s->lcr >> 6) & 1; From 6d356c8c9e36bd532d14b940ad17ca2f37a2ee71 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 23 Jun 2016 07:49:16 +0200 Subject: [PATCH 28/35] ich9: implement ACPI_EN register Signed-off-by: Paolo Bonzini --- hw/isa/lpc_ich9.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index fe0ba83fe8..f8e6fb84cc 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -394,10 +394,16 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg) /* config:PMBASE */ static void -ich9_lpc_pmbase_update(ICH9LPCState *lpc) +ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc) { uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE); - pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK; + uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL); + + if (acpi_cntl & ICH9_LPC_ACPI_CTRL_ACPI_EN) { + pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK; + } else { + pm_io_base = 0; + } ich9_pm_iospace_update(&lpc->pm, pm_io_base); } @@ -449,7 +455,8 @@ static void ich9_lpc_config_write(PCIDevice *d, uint32_t rcba_old = pci_get_long(d->config + ICH9_LPC_RCBA); pci_default_write_config(d, addr, val, len); - if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4)) { + if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4) || + ranges_overlap(addr, len, ICH9_LPC_ACPI_CTRL, 1)) { ich9_lpc_pmbase_update(lpc); } if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) { @@ -610,6 +617,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) pci_set_long(d->wmask + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_BASE_ADDRESS_MASK); + pci_set_byte(d->wmask + ICH9_LPC_PMBASE, + ICH9_LPC_ACPI_CTRL_ACPI_EN); memory_region_init_io(&lpc->rcrb_mem, OBJECT(d), &rcrb_mmio_ops, lpc, "lpc-rcrb-mmio", ICH9_CC_SIZE); From 8f242cb724cad4a3996e4634e55b7c03ed508a69 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 23 Jun 2016 07:54:22 +0200 Subject: [PATCH 29/35] ich9: implement SCI_IRQ_SEL register Signed-off-by: Paolo Bonzini --- hw/isa/lpc_ich9.c | 28 ++++++++++++++++++---------- include/hw/i386/ich9.h | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index f8e6fb84cc..10d1ee8b93 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -49,8 +49,6 @@ #include "sysemu/sysemu.h" #include "qom/cpu.h" -static int ich9_lpc_sci_irq(ICH9LPCState *lpc); - /*****************************************************************************/ /* ICH9 LPC PCI to ISA bridge */ @@ -221,7 +219,7 @@ static void ich9_lpc_update_pic(ICH9LPCState *lpc, int gsi) pic_level |= pci_bus_get_irq_level(lpc->d.bus, i); } } - if (gsi == ich9_lpc_sci_irq(lpc)) { + if (gsi == lpc->sci_gsi) { pic_level |= lpc->sci_level; } @@ -247,7 +245,7 @@ static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi) assert(gsi >= ICH9_LPC_PIC_NUM_PINS); level |= pci_bus_get_irq_level(lpc->d.bus, ich9_gsi_to_pirq(gsi)); - if (gsi == ich9_lpc_sci_irq(lpc)) { + if (gsi == lpc->sci_gsi) { level |= lpc->sci_level; } @@ -350,7 +348,7 @@ static void ich9_set_sci(void *opaque, int irq_num, int level) } lpc->sci_level = level; - irq = ich9_lpc_sci_irq(lpc); + irq = lpc->sci_gsi; if (irq < 0) { return; } @@ -398,6 +396,7 @@ ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc) { uint32_t pm_io_base = pci_get_long(lpc->d.config + ICH9_LPC_PMBASE); uint8_t acpi_cntl = pci_get_long(lpc->d.config + ICH9_LPC_ACPI_CTRL); + uint8_t new_gsi; if (acpi_cntl & ICH9_LPC_ACPI_CTRL_ACPI_EN) { pm_io_base &= ICH9_LPC_PMBASE_BASE_ADDRESS_MASK; @@ -406,6 +405,14 @@ ich9_lpc_pmbase_sci_update(ICH9LPCState *lpc) } ich9_pm_iospace_update(&lpc->pm, pm_io_base); + + new_gsi = ich9_lpc_sci_irq(lpc); + if (lpc->sci_level && new_gsi != lpc->sci_gsi) { + qemu_set_irq(lpc->pm.irq, 0); + lpc->sci_gsi = new_gsi; + qemu_set_irq(lpc->pm.irq, 1); + } + lpc->sci_gsi = new_gsi; } /* config:RCBA */ @@ -442,7 +449,7 @@ static int ich9_lpc_post_load(void *opaque, int version_id) { ICH9LPCState *lpc = opaque; - ich9_lpc_pmbase_update(lpc); + ich9_lpc_pmbase_sci_update(lpc); ich9_lpc_rcba_update(lpc, 0 /* disabled ICH9_LPC_RCBA_EN */); ich9_lpc_pmcon_update(lpc); return 0; @@ -457,7 +464,7 @@ static void ich9_lpc_config_write(PCIDevice *d, pci_default_write_config(d, addr, val, len); if (ranges_overlap(addr, len, ICH9_LPC_PMBASE, 4) || ranges_overlap(addr, len, ICH9_LPC_ACPI_CTRL, 1)) { - ich9_lpc_pmbase_update(lpc); + ich9_lpc_pmbase_sci_update(lpc); } if (ranges_overlap(addr, len, ICH9_LPC_RCBA, 4)) { ich9_lpc_rcba_update(lpc, rcba_old); @@ -495,7 +502,7 @@ static void ich9_lpc_reset(DeviceState *qdev) ich9_cc_reset(lpc); - ich9_lpc_pmbase_update(lpc); + ich9_lpc_pmbase_sci_update(lpc); ich9_lpc_rcba_update(lpc, rcba_old); lpc->sci_level = 0; @@ -575,7 +582,7 @@ static void ich9_lpc_get_sci_int(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj); - uint32_t value = ich9_lpc_sci_irq(lpc); + uint32_t value = lpc->sci_gsi; visit_type_uint32(v, name, &value, errp); } @@ -618,7 +625,8 @@ static void ich9_lpc_realize(PCIDevice *d, Error **errp) pci_set_long(d->wmask + ICH9_LPC_PMBASE, ICH9_LPC_PMBASE_BASE_ADDRESS_MASK); pci_set_byte(d->wmask + ICH9_LPC_PMBASE, - ICH9_LPC_ACPI_CTRL_ACPI_EN); + ICH9_LPC_ACPI_CTRL_ACPI_EN | + ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK); memory_region_init_io(&lpc->rcrb_mem, OBJECT(d), &rcrb_mmio_ops, lpc, "lpc-rcrb-mmio", ICH9_CC_SIZE); diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h index c14490b434..5fd7e97d23 100644 --- a/include/hw/i386/ich9.h +++ b/include/hw/i386/ich9.h @@ -45,6 +45,7 @@ typedef struct ICH9LPCState { APMState apm; ICH9LPCPMRegs pm; uint32_t sci_level; /* track sci level */ + uint8_t sci_gsi; /* 2.24 Pin Straps */ struct { From 66f37d360b3fc91275ab6ca3de81f0d356c24b4a Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Tue, 21 Jun 2016 18:34:04 +0200 Subject: [PATCH 30/35] vl: smp_parse: fix regression Commit 0544edd88a "vl: smp_parse: cleanups" regressed any -smp config that left either cores or threads unspecified, and specified a topology supporting more cpus than the given online cpus. The correct way to calculate the missing parameter would be to use maxcpus, but it's too late to change that now. Restore the old way, which is to calculate it with the online cpus (as is still done), but then, if the result is zero, just set it to one. Signed-off-by: Andrew Jones Message-Id: <1466526844-29245-1-git-send-email-drjones@redhat.com> Signed-off-by: Paolo Bonzini --- vl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vl.c b/vl.c index 64cfa968c9..0367647204 100644 --- a/vl.c +++ b/vl.c @@ -1234,8 +1234,10 @@ static void smp_parse(QemuOpts *opts) } else if (cores == 0) { threads = threads > 0 ? threads : 1; cores = cpus / (sockets * threads); + cores = cores > 0 ? cores : 1; } else if (threads == 0) { threads = cpus / (cores * sockets); + threads = threads > 0 ? threads : 1; } else if (sockets * cores * threads < cpus) { error_report("cpu topology: " "sockets (%u) * cores (%u) * threads (%u) < " From 634d39b4e3e5736b73c55b0fcc113e81246a7057 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 28 Jun 2016 18:32:42 +0200 Subject: [PATCH 31/35] vhost-user-test: fix g_cond_wait_until compat implementation This fixes compilation with glib versions up to 2.30, such as the one in CentOS 6. Signed-off-by: Paolo Bonzini --- include/glib-compat.h | 26 ++++++++++++++++++++++++++ tests/vhost-user-test.c | 17 ++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/include/glib-compat.h b/include/glib-compat.h index 03d8b12675..01aa7b37a5 100644 --- a/include/glib-compat.h +++ b/include/glib-compat.h @@ -149,6 +149,32 @@ static inline void (g_cond_signal)(CompatGCond *cond) } #undef g_cond_signal +static inline gboolean (g_cond_timed_wait)(CompatGCond *cond, + CompatGMutex *mutex, + GTimeVal *time) +{ + g_assert(mutex->once.status != G_ONCE_STATUS_PROGRESS); + g_once(&cond->once, do_g_cond_new, NULL); + return g_cond_timed_wait((GCond *) cond->once.retval, + (GMutex *) mutex->once.retval, time); +} +#undef g_cond_timed_wait + +/* This is not a macro, because it didn't exist until 2.32. */ +static inline gboolean g_cond_wait_until(CompatGCond *cond, CompatGMutex *mutex, + gint64 end_time) +{ + GTimeVal time; + + /* Convert from monotonic to CLOCK_REALTIME. */ + end_time -= g_get_monotonic_time(); + g_get_current_time(&time); + end_time += time.tv_sec * G_TIME_SPAN_SECOND + time.tv_usec; + + time.tv_sec = end_time / G_TIME_SPAN_SECOND; + time.tv_usec = end_time % G_TIME_SPAN_SECOND; + return g_cond_timed_wait(cond, mutex, &time); +} /* before 2.31 there was no g_thread_new() */ static inline GThread *g_thread_new(const char *name, diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 8b2164b99d..421d432f44 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -127,25 +127,12 @@ typedef struct TestServer { int fds_num; int fds[VHOST_MEMORY_MAX_NREGIONS]; VhostUserMemory memory; - GMutex data_mutex; - GCond data_cond; + CompatGMutex data_mutex; + CompatGCond data_cond; int log_fd; uint64_t rings; } TestServer; -#if !GLIB_CHECK_VERSION(2, 32, 0) -static gboolean g_cond_wait_until(CompatGCond cond, CompatGMutex mutex, - gint64 end_time) -{ - gboolean ret = FALSE; - end_time -= g_get_monotonic_time(); - GTimeVal time = { end_time / G_TIME_SPAN_SECOND, - end_time % G_TIME_SPAN_SECOND }; - ret = g_cond_timed_wait(cond, mutex, &time); - return ret; -} -#endif - static const char *tmpfs; static const char *root; From 25f0d2aa5e3d21caa1bc622b21368cc2e383f02c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 29 Jun 2016 15:15:33 +0200 Subject: [PATCH 32/35] vhost-user: disable chardev handlers on close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This otherwise causes a use-after-free if network backend cleanup is performed before character device cleanup. Cc: Marc-André Lureau Signed-off-by: Paolo Bonzini --- net/vhost-user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/vhost-user.c b/net/vhost-user.c index 636899a877..92f4cfd1b1 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -151,6 +151,11 @@ static void vhost_user_cleanup(NetClientState *nc) vhost_net_cleanup(s->vhost_net); s->vhost_net = NULL; } + if (s->chr) { + qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL); + qemu_chr_fe_release(s->chr); + s->chr = NULL; + } qemu_purge_queued_packets(nc); } From c1111a24a3358ecd2f17be7c8b117cfe8bc5e5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 16 Jun 2016 21:28:50 +0200 Subject: [PATCH 33/35] char: clean up remaining chardevs when leaving MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This helps to remove various chardev resources leaks when leaving qemu. Signed-off-by: Marc-André Lureau Message-Id: <1466105332-10285-2-git-send-email-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-char.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/qemu-char.c b/qemu-char.c index 8575c54c98..b73969ddbd 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -4549,6 +4549,15 @@ void qmp_chardev_remove(const char *id, Error **errp) qemu_chr_delete(chr); } +static void qemu_chr_cleanup(void) +{ + CharDriverState *chr, *tmp; + + QTAILQ_FOREACH_SAFE(chr, &chardevs, next, tmp) { + qemu_chr_delete(chr); + } +} + static void register_types(void) { register_char_driver("null", CHARDEV_BACKEND_KIND_NULL, NULL, @@ -4595,6 +4604,8 @@ static void register_types(void) * is specified */ qemu_add_machine_init_done_notifier(&muxes_realize_notify); + + atexit(qemu_chr_cleanup); } type_init(register_types); From 3fa27a9a1e20e8fb2bf4358d6873177d5d5c049a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 16 Jun 2016 21:28:51 +0200 Subject: [PATCH 34/35] socket: add listen feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a flag to tell whether the channel socket is listening. Signed-off-by: Marc-André Lureau Message-Id: <1466105332-10285-3-git-send-email-marcandre.lureau@redhat.com> Acked-by: Daniel P. Berrange Signed-off-by: Paolo Bonzini Signed-off-by: Marc-André Lureau --- include/io/channel.h | 1 + io/channel-socket.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/io/channel.h b/include/io/channel.h index d37acd29e0..e52f059310 100644 --- a/include/io/channel.h +++ b/include/io/channel.h @@ -42,6 +42,7 @@ typedef enum QIOChannelFeature QIOChannelFeature; enum QIOChannelFeature { QIO_CHANNEL_FEATURE_FD_PASS = (1 << 0), QIO_CHANNEL_FEATURE_SHUTDOWN = (1 << 1), + QIO_CHANNEL_FEATURE_LISTEN = (1 << 2), }; diff --git a/io/channel-socket.c b/io/channel-socket.c index ca8bc20b17..1cd58487b0 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -71,6 +71,9 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc, int fd, Error **errp) { + int val; + socklen_t len = sizeof(val); + if (sioc->fd != -1) { error_setg(errp, "Socket is already open"); return -1; @@ -106,6 +109,10 @@ qio_channel_socket_set_fd(QIOChannelSocket *sioc, ioc->features |= (1 << QIO_CHANNEL_FEATURE_FD_PASS); } #endif /* WIN32 */ + if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &val, &len) == 0 && val) { + QIOChannel *ioc = QIO_CHANNEL(sioc); + ioc->features |= (1 << QIO_CHANNEL_FEATURE_LISTEN); + } return 0; From 74b6ce43e3aacbb101018407196fc963e2c39fea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Date: Thu, 16 Jun 2016 21:28:52 +0200 Subject: [PATCH 35/35] socket: unlink unix socket on remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit qemu leaves unix socket files behind when removing a listening chardev or leaving. qemu could clean that up, even if doing so isn't race-free. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1347077 Signed-off-by: Marc-André Lureau Message-Id: <1466105332-10285-4-git-send-email-marcandre.lureau@redhat.com> Signed-off-by: Paolo Bonzini --- include/qemu/sockets.h | 1 + io/channel-socket.c | 10 ++++++++++ tests/test-io-channel-socket.c | 2 +- util/qemu-sockets.c | 18 ++++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index 1bd92180f3..5dd2648169 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -51,6 +51,7 @@ SocketAddress *socket_parse(const char *str, Error **errp); int socket_connect(SocketAddress *addr, Error **errp, NonBlockingConnectHandler *callback, void *opaque); int socket_listen(SocketAddress *addr, Error **errp); +void socket_listen_cleanup(int fd, Error **errp); int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp); /* Old, ipv4 only bits. Don't use for new code. */ diff --git a/io/channel-socket.c b/io/channel-socket.c index 1cd58487b0..6ec87f8cdb 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -400,7 +400,17 @@ static void qio_channel_socket_init(Object *obj) static void qio_channel_socket_finalize(Object *obj) { QIOChannelSocket *ioc = QIO_CHANNEL_SOCKET(obj); + if (ioc->fd != -1) { + if (QIO_CHANNEL(ioc)->features & QIO_CHANNEL_FEATURE_LISTEN) { + Error *err = NULL; + + socket_listen_cleanup(ioc->fd, &err); + if (err) { + error_report_err(err); + err = NULL; + } + } #ifdef WIN32 WSAEventSelect(ioc->fd, NULL, 0); #endif diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c index 855306b8dd..f73e063d7d 100644 --- a/tests/test-io-channel-socket.c +++ b/tests/test-io-channel-socket.c @@ -383,7 +383,7 @@ static void test_io_channel_unix(bool async) qapi_free_SocketAddress(listen_addr); qapi_free_SocketAddress(connect_addr); - unlink(TEST_SOCKET); + g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE); } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 0d6cd1f4ef..5d03695d10 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -997,6 +997,24 @@ int socket_listen(SocketAddress *addr, Error **errp) return fd; } +void socket_listen_cleanup(int fd, Error **errp) +{ + SocketAddress *addr; + + addr = socket_local_address(fd, errp); + + if (addr->type == SOCKET_ADDRESS_KIND_UNIX + && addr->u.q_unix.data->path) { + if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) { + error_setg_errno(errp, errno, + "Failed to unlink socket %s", + addr->u.q_unix.data->path); + } + } + + g_free(addr); +} + int socket_dgram(SocketAddress *remote, SocketAddress *local, Error **errp) { int fd;