From e222100afef786ed299e91ad55fb1f14d9da246a Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Sat, 5 Dec 2009 11:21:49 -0600 Subject: Update version to -rc1 Signed-off-by: Anthony Liguori --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 93d635abd..568d15238 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.50 +0.11.91 -- cgit v1.2.3 From ea6112b1659ea0f0879302288496c4e0dea6f723 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 6 Dec 2009 12:12:56 +0100 Subject: Update OpenBIOS images to r640 Signed-off-by: Aurelien Jarno --- pc-bios/openbios-ppc | Bin 295636 -> 312124 bytes pc-bios/openbios-sparc32 | Bin 209472 -> 217700 bytes pc-bios/openbios-sparc64 | Bin 1065872 -> 1065880 bytes 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 pc-bios/openbios-ppc diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc old mode 100755 new mode 100644 index 3941c0bf5..badcb9c04 Binary files a/pc-bios/openbios-ppc and b/pc-bios/openbios-ppc differ diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32 index 2454b4a2e..596e5eed9 100644 Binary files a/pc-bios/openbios-sparc32 and b/pc-bios/openbios-sparc32 differ diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64 index 271718123..017d68cbd 100644 Binary files a/pc-bios/openbios-sparc64 and b/pc-bios/openbios-sparc64 differ -- cgit v1.2.3 From 20c1a35211a2500935e15b5f30a98b555ebeb2ff Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Sun, 6 Dec 2009 15:51:24 +0100 Subject: kvm: x86: Fix initial kvm_has_msr_star KVM_GET_MSR_INDEX_LIST returns -E2BIG when the provided space is too small for all MSRs. But this is precisely the error we trigger with the initial request in order to obtain that size. Do not fail in that case. This caused a subtle corruption of the guest state as MSR_STAR was not properly saved/restored. The corruption became visible with latest kvm optimizing the MSR updates. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori (cherry picked from commit 6fb6d245546d3ae48c4cb764b3593e4739aa1364) --- target-i386/kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 3b61a7fc5..88b504c34 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -244,9 +244,9 @@ static int kvm_has_msr_star(CPUState *env) * save/restore */ msr_list.nmsrs = 0; ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list); - if (ret < 0) + if (ret < 0 && ret != -E2BIG) { return 0; - + } /* Old kernel modules had a bug and could write beyond the provided memory. Allocate at least a safe amount of 1K. */ kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) + -- cgit v1.2.3 From 066263f37701687c64af9d8825e3376d069ebfd4 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 7 Dec 2009 11:58:02 +0100 Subject: cpuid: Fix multicore setup on Intel The multicore CPUID code detects whether the guest is an Intel or an AMD CPU, because the Linux kernel is picky about the CmpLegacy bit. KVM by default passes through the host's vendor, which was not catched by the code. So fork out the vendor determining bits into a separate function to be used from both places and always get the real vendor. This fixes KVM's multicore setup on Intel CPUs. Signed-off-by: Andre Przywara Reported-by: Dietmar Maurer Signed-off-by: Anthony Liguori (cherry picked from commit 6d9fef1a02e6efd51e9ebd0130651ca61f75839b) --- target-i386/helper.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 957b3fc1f..08e6d6c39 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1638,6 +1638,24 @@ static void host_cpuid(uint32_t function, uint32_t count, #endif } +static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + *ebx = env->cpuid_vendor1; + *edx = env->cpuid_vendor2; + *ecx = env->cpuid_vendor3; + + /* sysenter isn't supported on compatibility mode on AMD, syscall + * isn't supported in compatibility mode on Intel. + * Normally we advertise the actual cpu vendor, but you can override + * this if you want to use KVM's sysenter/syscall emulation + * in compatibility mode and when doing cross vendor migration + */ + if (kvm_enabled() && env->cpuid_vendor_override) { + host_cpuid(0, 0, NULL, ebx, ecx, edx); + } +} + void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) @@ -1654,16 +1672,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, switch(index) { case 0: *eax = env->cpuid_level; - *ebx = env->cpuid_vendor1; - *edx = env->cpuid_vendor2; - *ecx = env->cpuid_vendor3; - - /* sysenter isn't supported on compatibility mode on AMD. and syscall - * isn't supported in compatibility mode on Intel. so advertise the - * actuall cpu, and say goodbye to migration between different vendors - * is you use compatibility mode. */ - if (kvm_enabled() && !env->cpuid_vendor_override) - host_cpuid(0, 0, NULL, ebx, ecx, edx); + get_cpuid_vendor(env, ebx, ecx, edx); break; case 1: *eax = env->cpuid_version; @@ -1759,11 +1768,18 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = env->cpuid_ext3_features; *edx = env->cpuid_ext2_features; - if (env->nr_cores * env->nr_threads > 1 && - env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 && - env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 && - env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) { - *ecx |= 1 << 1; /* CmpLegacy bit */ + /* The Linux kernel checks for the CMPLegacy bit and + * discards multiple thread information if it is set. + * So dont set it here for Intel to make Linux guests happy. + */ + if (env->nr_cores * env->nr_threads > 1) { + uint32_t tebx, tecx, tedx; + get_cpuid_vendor(env, &tebx, &tecx, &tedx); + if (tebx != CPUID_VENDOR_INTEL_1 || + tedx != CPUID_VENDOR_INTEL_2 || + tecx != CPUID_VENDOR_INTEL_3) { + *ecx |= 1 << 1; /* CmpLegacy bit */ + } } if (kvm_enabled()) { -- cgit v1.2.3 From 9fa7591beb036d6791a67a0175c1f5ae863c9660 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Nov 2009 12:18:00 +0200 Subject: msix: macro rename for function mask support rename ENABLE_OFFSET -> CONTROL_OFFSET, since same byte includes function mask. This is in preparation for function mask support. Signed-off-by: Michael S. Tsirkin (cherry picked from commit 2760952ba9610921586e7446d858e23308400391) --- hw/msix.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/msix.c b/hw/msix.c index 4bc614723..541b9d62c 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -27,8 +27,8 @@ #define MSIX_PBA_OFFSET 8 #define MSIX_CAP_LENGTH 12 -/* MSI enable bit is in byte 1 in FLAGS register */ -#define MSIX_ENABLE_OFFSET (PCI_MSIX_FLAGS + 1) +/* MSI enable bit and maskall bit are in byte 1 in FLAGS register */ +#define MSIX_CONTROL_OFFSET (PCI_MSIX_FLAGS + 1) #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8) /* MSI-X table format */ @@ -101,7 +101,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, bar_nr); pdev->msix_cap = config_offset; /* Make flags bit writeable. */ - pdev->wmask[config_offset + MSIX_ENABLE_OFFSET] |= MSIX_ENABLE_MASK; + pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK; return 0; } @@ -109,7 +109,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, void msix_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len) { - unsigned enable_pos = dev->msix_cap + MSIX_ENABLE_OFFSET; + unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET; if (addr + len <= enable_pos || addr > enable_pos) return; @@ -327,7 +327,7 @@ int msix_present(PCIDevice *dev) int msix_enabled(PCIDevice *dev) { return (dev->cap_present & QEMU_PCI_CAP_MSIX) && - (dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] & + (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_ENABLE_MASK); } @@ -363,8 +363,8 @@ void msix_reset(PCIDevice *dev) if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) return; msix_free_irq_entries(dev); - dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &= - ~dev->wmask[dev->msix_cap + MSIX_ENABLE_OFFSET]; + dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &= + ~dev->wmask[dev->msix_cap + MSIX_CONTROL_OFFSET]; memset(dev->msix_table_page, 0, MSIX_PAGE_SIZE); msix_mask_all(dev, dev->msix_entries_nr); } -- cgit v1.2.3 From 67a2698dacbabb40ec6ad1a9a9c839164170fedc Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Nov 2009 15:44:40 +0200 Subject: pci: interrupt status bit implementation interrupt status is a mandatory feature in PCI spec, so devices must implement it to be spec compliant. Signed-off-by: Michael S. Tsirkin Acked-by: Isaku Yamahata (cherry picked from commit f9bf77dd1f838b0061172fe41709b221956da2f5) --- hw/pci.c | 26 +++++++++++++++++++++++++- hw/pci.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/hw/pci.c b/hw/pci.c index a0df618e5..25dbb38bb 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -128,11 +128,23 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); } +/* Update interrupt status bit in config space on interrupt + * state change. */ +static void pci_update_irq_status(PCIDevice *dev) +{ + if (dev->irq_state) { + dev->config[PCI_STATUS] |= PCI_STATUS_INTERRUPT; + } else { + dev->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT; + } +} + static void pci_device_reset(PCIDevice *dev) { int r; dev->irq_state = 0; + pci_update_irq_status(dev); dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); dev->config[PCI_CACHE_LINE_SIZE] = 0x0; @@ -377,12 +389,23 @@ static inline const VMStateDescription *pci_get_vmstate(PCIDevice *s) void pci_device_save(PCIDevice *s, QEMUFile *f) { + /* Clear interrupt status bit: it is implicit + * in irq_state which we are saving. + * This makes us compatible with old devices + * which never set or clear this bit. */ + s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT; vmstate_save_state(f, pci_get_vmstate(s), s); + /* Restore the interrupt status bit. */ + pci_update_irq_status(s); } int pci_device_load(PCIDevice *s, QEMUFile *f) { - return vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id); + int ret; + ret = vmstate_load_state(f, pci_get_vmstate(s), s, s->version_id); + /* Restore the interrupt status bit. */ + pci_update_irq_status(s); + return ret; } static int pci_set_default_subsystem_id(PCIDevice *pci_dev) @@ -955,6 +978,7 @@ static void pci_set_irq(void *opaque, int irq_num, int level) return; pci_set_irq_state(pci_dev, irq_num, level); + pci_update_irq_status(pci_dev); pci_change_irq_level(pci_dev, irq_num, change); } diff --git a/hw/pci.h b/hw/pci.h index ebf6c39d5..dc9b8604f 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -102,6 +102,7 @@ typedef struct PCIIORegion { #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ #define PCI_COMMAND_MASTER 0x4 /* Enable bus master */ #define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_INTERRUPT 0x08 #define PCI_REVISION_ID 0x08 /* 8 bits */ #define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ #define PCI_CLASS_DEVICE 0x0a /* Device class */ -- cgit v1.2.3 From c99d32efe6970493c44fe410ee4a4aafc1a35428 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Nov 2009 12:19:32 +0200 Subject: msix: function mask support Function mask is a mandatory feature in MSIX spec so not implementing it is a spec violation. Implement. Signed-off-by: Michael S. Tsirkin (cherry picked from commit 5b5cb08683b6715a2aca5314168e68ff0665912b) --- hw/msix.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/hw/msix.c b/hw/msix.c index 541b9d62c..0baedef42 100644 --- a/hw/msix.c +++ b/hw/msix.c @@ -20,6 +20,7 @@ #define PCI_MSIX_FLAGS 2 /* Table at lower 11 bits */ #define PCI_MSIX_FLAGS_QSIZE 0x7FF #define PCI_MSIX_FLAGS_ENABLE (1 << 15) +#define PCI_MSIX_FLAGS_MASKALL (1 << 14) #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) /* MSI-X capability structure */ @@ -30,6 +31,7 @@ /* MSI enable bit and maskall bit are in byte 1 in FLAGS register */ #define MSIX_CONTROL_OFFSET (PCI_MSIX_FLAGS + 1) #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8) +#define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8) /* MSI-X table format */ #define MSIX_MSG_ADDR 0 @@ -101,22 +103,11 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries, bar_nr); pdev->msix_cap = config_offset; /* Make flags bit writeable. */ - pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK; + pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK | + MSIX_MASKALL_MASK; return 0; } -/* Handle MSI-X capability config write. */ -void msix_write_config(PCIDevice *dev, uint32_t addr, - uint32_t val, int len) -{ - unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET; - if (addr + len <= enable_pos || addr > enable_pos) - return; - - if (msix_enabled(dev)) - qemu_set_irq(dev->irq[0], 0); -} - static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr) { PCIDevice *dev = opaque; @@ -157,10 +148,50 @@ static void msix_clr_pending(PCIDevice *dev, int vector) *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector); } +static int msix_function_masked(PCIDevice *dev) +{ + return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK; +} + static int msix_is_masked(PCIDevice *dev, int vector) { unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL; - return dev->msix_table_page[offset] & MSIX_VECTOR_MASK; + return msix_function_masked(dev) || + dev->msix_table_page[offset] & MSIX_VECTOR_MASK; +} + +static void msix_handle_mask_update(PCIDevice *dev, int vector) +{ + if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) { + msix_clr_pending(dev, vector); + msix_notify(dev, vector); + } +} + +/* Handle MSI-X capability config write. */ +void msix_write_config(PCIDevice *dev, uint32_t addr, + uint32_t val, int len) +{ + unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET; + int vector; + + if (addr + len <= enable_pos || addr > enable_pos) { + return; + } + + if (!msix_enabled(dev)) { + return; + } + + qemu_set_irq(dev->irq[0], 0); + + if (msix_function_masked(dev)) { + return; + } + + for (vector = 0; vector < dev->msix_entries_nr; ++vector) { + msix_handle_mask_update(dev, vector); + } } static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, @@ -170,10 +201,7 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr, unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3; int vector = offset / MSIX_ENTRY_SIZE; pci_set_long(dev->msix_table_page + offset, val); - if (!msix_is_masked(dev, vector) && msix_is_pending(dev, vector)) { - msix_clr_pending(dev, vector); - msix_notify(dev, vector); - } + msix_handle_mask_update(dev, vector); } static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr, -- cgit v1.2.3 From eea4acfa5c1ef26439a718375475fe468b7f2fba Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Nov 2009 15:20:51 +0200 Subject: pci: prepare irq code for interrupt state This rearranges code in preparation for interrupt state implementation. Changes: - split up bus walk away from interrupt handling into a subroutine - change irq_state from an array to bitmask - verify that irq_state values are 0 or 1 on load There are no functional changes. Signed-off-by: Michael S. Tsirkin Acked-by: Isaku Yamahata (cherry picked from commit d036bb215e0ac1d1fd467239f1d3b7d904cac90a) --- hw/pci.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------ hw/pci.h | 2 +- 2 files changed, 74 insertions(+), 17 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index f2b6cff38..a0df618e5 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -103,11 +103,36 @@ static int pci_bar(PCIDevice *d, int reg) return type == PCI_HEADER_TYPE_BRIDGE ? PCI_ROM_ADDRESS1 : PCI_ROM_ADDRESS; } +static inline int pci_irq_state(PCIDevice *d, int irq_num) +{ + return (d->irq_state >> irq_num) & 0x1; +} + +static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level) +{ + d->irq_state &= ~(0x1 << irq_num); + d->irq_state |= level << irq_num; +} + +static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) +{ + PCIBus *bus; + for (;;) { + bus = pci_dev->bus; + irq_num = bus->map_irq(pci_dev, irq_num); + if (bus->set_irq) + break; + pci_dev = bus->parent_dev; + } + bus->irq_count[irq_num] += change; + bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); +} + static void pci_device_reset(PCIDevice *dev) { int r; - memset(dev->irq_state, 0, sizeof dev->irq_state); + dev->irq_state = 0; dev->config[PCI_COMMAND] &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); dev->config[PCI_CACHE_LINE_SIZE] = 0x0; @@ -274,6 +299,43 @@ static VMStateInfo vmstate_info_pci_config = { .put = put_pci_config_device, }; +static int get_pci_irq_state(QEMUFile *f, void *pv, size_t size) +{ + PCIDevice *s = container_of(pv, PCIDevice, config); + uint32_t irq_state[PCI_NUM_PINS]; + int i; + for (i = 0; i < PCI_NUM_PINS; ++i) { + irq_state[i] = qemu_get_be32(f); + if (irq_state[i] != 0x1 && irq_state[i] != 0) { + fprintf(stderr, "irq state %d: must be 0 or 1.\n", + irq_state[i]); + return -EINVAL; + } + } + + for (i = 0; i < PCI_NUM_PINS; ++i) { + pci_set_irq_state(s, i, irq_state[i]); + } + + return 0; +} + +static void put_pci_irq_state(QEMUFile *f, void *pv, size_t size) +{ + int i; + PCIDevice *s = container_of(pv, PCIDevice, config); + + for (i = 0; i < PCI_NUM_PINS; ++i) { + qemu_put_be32(f, pci_irq_state(s, i)); + } +} + +static VMStateInfo vmstate_info_pci_irq_state = { + .name = "pci irq state", + .get = get_pci_irq_state, + .put = put_pci_irq_state, +}; + const VMStateDescription vmstate_pci_device = { .name = "PCIDevice", .version_id = 2, @@ -284,7 +346,9 @@ const VMStateDescription vmstate_pci_device = { VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0, vmstate_info_pci_config, PCI_CONFIG_SPACE_SIZE), - VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2), + VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2, + vmstate_info_pci_irq_state, + PCI_NUM_PINS * sizeof(int32_t)), VMSTATE_END_OF_LIST() } }; @@ -299,7 +363,9 @@ const VMStateDescription vmstate_pcie_device = { VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0, vmstate_info_pci_config, PCIE_CONFIG_SPACE_SIZE), - VMSTATE_INT32_ARRAY_V(irq_state, PCIDevice, PCI_NUM_PINS, 2), + VMSTATE_BUFFER_UNSAFE_INFO(irq_state, PCIDevice, 2, + vmstate_info_pci_irq_state, + PCI_NUM_PINS * sizeof(int32_t)), VMSTATE_END_OF_LIST() } }; @@ -499,7 +565,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, pci_dev->bus = bus; pci_dev->devfn = devfn; pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); - memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state)); + pci_dev->irq_state = 0; pci_config_alloc(pci_dev); header_type &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; @@ -882,23 +948,14 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) static void pci_set_irq(void *opaque, int irq_num, int level) { PCIDevice *pci_dev = opaque; - PCIBus *bus; int change; - change = level - pci_dev->irq_state[irq_num]; + change = level - pci_irq_state(pci_dev, irq_num); if (!change) return; - pci_dev->irq_state[irq_num] = level; - for (;;) { - bus = pci_dev->bus; - irq_num = bus->map_irq(pci_dev, irq_num); - if (bus->set_irq) - break; - pci_dev = bus->parent_dev; - } - bus->irq_count[irq_num] += change; - bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); + pci_set_irq_state(pci_dev, irq_num, level); + pci_change_irq_level(pci_dev, irq_num, change); } /***********************************************************/ diff --git a/hw/pci.h b/hw/pci.h index 3e8abad22..ebf6c39d5 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -220,7 +220,7 @@ struct PCIDevice { qemu_irq *irq; /* Current IRQ levels. Used internally by the generic PCI code. */ - int irq_state[PCI_NUM_PINS]; + uint8_t irq_state; /* Capability bits */ uint32_t cap_present; -- cgit v1.2.3 From bcddbd0f6aff8e0061f2ab6686b29892544a076d Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 7 Dec 2009 21:36:59 +0100 Subject: QError: new class for device encrypted errors Signed-off-by: Luiz Capitulino Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 0df37c411ccf9f830f38f3f6405fac9320a70bac) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index eb4ce3331..d90529cd4 100644 --- a/qerror.c +++ b/qerror.c @@ -44,6 +44,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_COMMAND_NOT_FOUND, .desc = "The command %(name) has not been found", }, + { + .error_fmt = QERR_DEVICE_ENCRYPTED, + .desc = "The %(device) is encrypted", + }, { .error_fmt = QERR_DEVICE_NOT_FOUND, .desc = "The %(device) device has not been found", diff --git a/qerror.h b/qerror.h index 5198adf14..c9fcf973f 100644 --- a/qerror.h +++ b/qerror.h @@ -41,6 +41,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_COMMAND_NOT_FOUND \ "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }" +#define QERR_DEVICE_ENCRYPTED \ + "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }" + #define QERR_DEVICE_NOT_FOUND \ "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }" -- cgit v1.2.3 From 931a548be3cfb3a3473ece5ff59365963124d705 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Mon, 7 Dec 2009 21:37:00 +0100 Subject: monitor: do_cont(): Don't ask for passwords The do_cont() function will ask the user to enter a password if a device is encrypted. This is invalid under QMP, so we raise a QERR_DEVICE_ENCRYPTED error. Signed-off-by: Luiz Capitulino Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 94171e119cb6f7bab2578896643b0daff1d9b184) --- monitor.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/monitor.c b/monitor.c index 27c696b2d..bdf4b720a 100644 --- a/monitor.c +++ b/monitor.c @@ -148,7 +148,10 @@ static void monitor_read_command(Monitor *mon, int show_prompt) static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func, void *opaque) { - if (mon->rs) { + if (monitor_ctrl_mode(mon)) { + qemu_error_new(QERR_MISSING_PARAMETER, "password"); + return -EINVAL; + } else if (mon->rs) { readline_start(mon->rs, "Password: ", 1, readline_func, opaque); /* prompt is printed on return from the command handler */ return 0; @@ -4103,6 +4106,11 @@ void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs, return; } + if (monitor_ctrl_mode(mon)) { + qemu_error_new(QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs)); + return; + } + monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs), bdrv_get_encrypted_filename(bs)); -- cgit v1.2.3 From a7d5da885791d00a6bd730dca26c9806cbf996c5 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:01 +0100 Subject: monitor: Fix double-prompt after "change vnc passwd BLA" Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 2895e075c6dba0e66c72af781b1eed2bff0c3777) --- monitor.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index bdf4b720a..2db2a9851 100644 --- a/monitor.c +++ b/monitor.c @@ -815,12 +815,17 @@ static void do_change_block(Monitor *mon, const char *device, monitor_read_bdrv_key_start(mon, bs, NULL, NULL); } -static void change_vnc_password_cb(Monitor *mon, const char *password, - void *opaque) +static void change_vnc_password(Monitor *mon, const char *password) { if (vnc_display_password(NULL, password) < 0) monitor_printf(mon, "could not set VNC server password\n"); +} + +static void change_vnc_password_cb(Monitor *mon, const char *password, + void *opaque) +{ + change_vnc_password(mon, password); monitor_read_command(mon, 1); } @@ -832,7 +837,7 @@ static void do_change_vnc(Monitor *mon, const char *target, const char *arg) char password[9]; strncpy(password, arg, sizeof(password)); password[sizeof(password) - 1] = '\0'; - change_vnc_password_cb(mon, password, NULL); + change_vnc_password(mon, password); } else { monitor_read_password(mon, change_vnc_password_cb, NULL); } -- cgit v1.2.3 From 28acf422cb759369de8d86b04b6a65321b65caa1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:02 +0100 Subject: QError: Put error definitions in alphabetical order Also fix the odd typoe and clean up whitespace. Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit e16a18122212e86b87a0ca1dd79269918c7dc667) --- qerror.c | 28 ++++++++++++++-------------- qerror.h | 30 +++++++++++++++--------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/qerror.c b/qerror.c index d90529cd4..03e3b34c7 100644 --- a/qerror.c +++ b/qerror.c @@ -41,28 +41,32 @@ static const QType qerror_type = { */ static const QErrorStringTable qerror_table[] = { { - .error_fmt = QERR_COMMAND_NOT_FOUND, - .desc = "The command %(name) has not been found", + .error_fmt = QERR_COMMAND_NOT_FOUND, + .desc = "The command %(name) has not been found", }, { .error_fmt = QERR_DEVICE_ENCRYPTED, .desc = "The %(device) is encrypted", }, + { + .error_fmt = QERR_DEVICE_NOT_ACTIVE, + .desc = "The %(device) device has not been activated by the guest", + }, { .error_fmt = QERR_DEVICE_NOT_FOUND, .desc = "The %(device) device has not been found", }, { - .error_fmt = QERR_DEVICE_NOT_ACTIVE, - .desc = "The %(device) device has not been activated by the guest", + .error_fmt = QERR_INVALID_PARAMETER_TYPE, + .desc = "Invalid parameter type, expected: %(expected)", }, { - .error_fmt = QERR_INVALID_PARAMETER_TYPE, - .desc = "Invalid parameter type, expected: %(expected)", + .error_fmt = QERR_INVALID_PASSWORD, + .desc = "The entered password is invalid", }, { - .error_fmt = QERR_INVALID_PASSWORD, - .desc = "The entered password is invalid", + .error_fmt = QERR_JSON_PARSING, + .desc = "Invalid JSON syntax", }, { .error_fmt = QERR_KVM_MISSING_CAP, @@ -77,12 +81,8 @@ static const QErrorStringTable qerror_table[] = { .desc = "Bad QMP input object", }, { - .error_fmt = QERR_JSON_PARSING, - .desc = "Invalid JSON synaxt", - }, - { - .error_fmt = QERR_UNDEFINED_ERROR, - .desc = "An undefined error has ocurred", + .error_fmt = QERR_UNDEFINED_ERROR, + .desc = "An undefined error has ocurred", }, {} }; diff --git a/qerror.h b/qerror.h index c9fcf973f..062c0c409 100644 --- a/qerror.h +++ b/qerror.h @@ -39,36 +39,36 @@ QError *qobject_to_qerror(const QObject *obj); * QError class list */ #define QERR_COMMAND_NOT_FOUND \ - "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }" + "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }" #define QERR_DEVICE_ENCRYPTED \ - "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }" - -#define QERR_DEVICE_NOT_FOUND \ - "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }" + "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }" #define QERR_DEVICE_NOT_ACTIVE \ - "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }" + "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }" + +#define QERR_DEVICE_NOT_FOUND \ + "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }" #define QERR_INVALID_PARAMETER_TYPE \ - "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" + "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" #define QERR_INVALID_PASSWORD \ - "{ 'class': 'InvalidPassword', 'data': {} }" + "{ 'class': 'InvalidPassword', 'data': {} }" + +#define QERR_JSON_PARSING \ + "{ 'class': 'JSONParsing', 'data': {} }" #define QERR_KVM_MISSING_CAP \ - "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }" + "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }" #define QERR_MISSING_PARAMETER \ - "{ 'class': 'MissingParameter', 'data': { 'name': %s } }" + "{ 'class': 'MissingParameter', 'data': { 'name': %s } }" #define QERR_QMP_BAD_INPUT_OBJECT \ - "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }" - -#define QERR_JSON_PARSING \ - "{ 'class': 'JSONParsing', 'data': {} }" + "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }" #define QERR_UNDEFINED_ERROR \ - "{ 'class': 'UndefinedError', 'data': {} }" + "{ 'class': 'UndefinedError', 'data': {} }" #endif /* QERROR_H */ -- cgit v1.2.3 From a46657d185bb8f6e14bb9689dbd49c334d7bbf8b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:03 +0100 Subject: QError: New QERR_DEVICE_LOCKED Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit b086838090e32e05a60b21c2cabca8098c1562c4) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 03e3b34c7..37e807246 100644 --- a/qerror.c +++ b/qerror.c @@ -48,6 +48,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_DEVICE_ENCRYPTED, .desc = "The %(device) is encrypted", }, + { + .error_fmt = QERR_DEVICE_LOCKED, + .desc = "Device %(device) is locked", + }, { .error_fmt = QERR_DEVICE_NOT_ACTIVE, .desc = "The %(device) device has not been activated by the guest", diff --git a/qerror.h b/qerror.h index 062c0c409..be6cd6897 100644 --- a/qerror.h +++ b/qerror.h @@ -44,6 +44,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_DEVICE_ENCRYPTED \ "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }" +#define QERR_DEVICE_LOCKED \ + "{ 'class': 'DeviceLocked', 'data': { 'device': %s } }" + #define QERR_DEVICE_NOT_ACTIVE \ "{ 'class': 'DeviceNotActive', 'data': { 'device': %s } }" -- cgit v1.2.3 From 8cb1cec656f6a82f1bdecfbb8f3c85f80bb78092 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:04 +0100 Subject: QError: New QERR_DEVICE_NOT_REMOVABLE Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 5cfe026475f3233a4c42351001560450886feddb) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 37e807246..17532b066 100644 --- a/qerror.c +++ b/qerror.c @@ -60,6 +60,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_DEVICE_NOT_FOUND, .desc = "The %(device) device has not been found", }, + { + .error_fmt = QERR_DEVICE_NOT_REMOVABLE, + .desc = "Device %(device) is not removable", + }, { .error_fmt = QERR_INVALID_PARAMETER_TYPE, .desc = "Invalid parameter type, expected: %(expected)", diff --git a/qerror.h b/qerror.h index be6cd6897..2abff1e00 100644 --- a/qerror.h +++ b/qerror.h @@ -53,6 +53,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_DEVICE_NOT_FOUND \ "{ 'class': 'DeviceNotFound', 'data': { 'device': %s } }" +#define QERR_DEVICE_NOT_REMOVABLE \ + "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }" + #define QERR_INVALID_PARAMETER_TYPE \ "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" -- cgit v1.2.3 From 06921ec84f16558e8530feb84409950c41948443 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:05 +0100 Subject: monitor: convert do_eject() to QError Also affects do_change(), because the two share eject_device(). Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 2c2a6bb860c09a80f519cd6297f1c0585a1436ec) --- monitor.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index 2db2a9851..8a06bbeb4 100644 --- a/monitor.c +++ b/monitor.c @@ -748,11 +748,12 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force) if (bdrv_is_inserted(bs)) { if (!force) { if (!bdrv_is_removable(bs)) { - monitor_printf(mon, "device is not removable\n"); + qemu_error_new(QERR_DEVICE_NOT_REMOVABLE, + bdrv_get_device_name(bs)); return -1; } if (bdrv_is_locked(bs)) { - monitor_printf(mon, "device is locked\n"); + qemu_error_new(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); return -1; } } @@ -769,7 +770,7 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) bs = bdrv_find(filename); if (!bs) { - monitor_printf(mon, "device not found\n"); + qemu_error_new(QERR_DEVICE_NOT_FOUND, filename); return; } eject_device(mon, bs, force); -- cgit v1.2.3 From c756b1e76287081a2b75ca3dc1ebb5a386a5a106 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:06 +0100 Subject: QError: New QERR_INVALID_BLOCK_FORMAT Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 17901e75329fff369e26f2464a016e0797789256) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 17532b066..56083c489 100644 --- a/qerror.c +++ b/qerror.c @@ -64,6 +64,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_DEVICE_NOT_REMOVABLE, .desc = "Device %(device) is not removable", }, + { + .error_fmt = QERR_INVALID_BLOCK_FORMAT, + .desc = "Invalid block format %(name)", + }, { .error_fmt = QERR_INVALID_PARAMETER_TYPE, .desc = "Invalid parameter type, expected: %(expected)", diff --git a/qerror.h b/qerror.h index 2abff1e00..681390cf1 100644 --- a/qerror.h +++ b/qerror.h @@ -56,6 +56,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_DEVICE_NOT_REMOVABLE \ "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }" +#define QERR_INVALID_BLOCK_FORMAT \ + "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }" + #define QERR_INVALID_PARAMETER_TYPE \ "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" -- cgit v1.2.3 From 6ccc51fd20bbb016667a0ba06698f1cc71859917 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 4 Dec 2009 15:24:08 -0200 Subject: QError: Add class for invalid passwords Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit f6d855c50dfd68f33f6dee70e5ccdfb144a2da26) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index d00e5347e..eb4ce3331 100644 --- a/qerror.c +++ b/qerror.c @@ -56,6 +56,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_INVALID_PARAMETER_TYPE, .desc = "Invalid parameter type, expected: %(expected)", }, + { + .error_fmt = QERR_INVALID_PASSWORD, + .desc = "The entered password is invalid", + }, { .error_fmt = QERR_KVM_MISSING_CAP, .desc = "Using KVM without %(capability), %(feature) unavailable", diff --git a/qerror.h b/qerror.h index 5fd993146..5198adf14 100644 --- a/qerror.h +++ b/qerror.h @@ -50,6 +50,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_INVALID_PARAMETER_TYPE \ "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" +#define QERR_INVALID_PASSWORD \ + "{ 'class': 'InvalidPassword', 'data': {} }" + #define QERR_KVM_MISSING_CAP \ "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }" -- cgit v1.2.3 From 960a4b537a217d1df0982e3c694d20d118c21e6b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:07 +0100 Subject: QError: New QERR_SET_PASSWD_FAILED Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 7a84cb23c077488b0e1926b3e909ea128a80dc58) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 56083c489..1bb68c417 100644 --- a/qerror.c +++ b/qerror.c @@ -92,6 +92,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_QMP_BAD_INPUT_OBJECT, .desc = "Bad QMP input object", }, + { + .error_fmt = QERR_SET_PASSWD_FAILED, + .desc = "Could not set password", + }, { .error_fmt = QERR_UNDEFINED_ERROR, .desc = "An undefined error has ocurred", diff --git a/qerror.h b/qerror.h index 681390cf1..b85689933 100644 --- a/qerror.h +++ b/qerror.h @@ -77,6 +77,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_QMP_BAD_INPUT_OBJECT \ "{ 'class': 'QMPBadInputObject', 'data': { 'expected': %s } }" +#define QERR_SET_PASSWD_FAILED \ + "{ 'class': 'SetPasswdFailed', 'data': {} }" + #define QERR_UNDEFINED_ERROR \ "{ 'class': 'UndefinedError', 'data': {} }" -- cgit v1.2.3 From 0ea5709a32085f7d14901a09d12bd35f9b267607 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Wed, 25 Nov 2009 16:31:42 +0200 Subject: pci: interrupt disable bit support Interrupt disable bit is mandatory in PCI spec. Implement it to make devices spec compliant. Signed-off-by: Michael S. Tsirkin Acked-by: Isaku Yamahata (cherry picked from commit b6981cb57be5d66b1b7cf9009a122fb3cdd4b96b) --- hw/pci.c | 29 +++++++++++++++++++++++++++-- hw/pci.h | 1 + 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 25dbb38bb..4f662b769 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -518,7 +518,8 @@ static void pci_init_wmask(PCIDevice *dev) dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff; dev->wmask[PCI_INTERRUPT_LINE] = 0xff; pci_set_word(dev->wmask + PCI_COMMAND, - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_INTX_DISABLE); memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff, config_size - PCI_CONFIG_HEADER_SIZE); @@ -938,6 +939,25 @@ static void pci_update_mappings(PCIDevice *d) } } +static inline int pci_irq_disabled(PCIDevice *d) +{ + return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE; +} + +/* Called after interrupt disabled field update in config space, + * assert/deassert interrupts if necessary. + * Gets original interrupt disable bit value (before update). */ +static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled) +{ + int i, disabled = pci_irq_disabled(d); + if (disabled == was_irq_disabled) + return; + for (i = 0; i < PCI_NUM_PINS; ++i) { + int state = pci_irq_state(d, i); + pci_change_irq_level(d, i, disabled ? -state : state); + } +} + uint32_t pci_default_read_config(PCIDevice *d, uint32_t address, int len) { @@ -950,7 +970,7 @@ uint32_t pci_default_read_config(PCIDevice *d, void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) { - int i; + int i, was_irq_disabled = pci_irq_disabled(d); uint32_t config_size = pci_config_size(d); for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) { @@ -962,6 +982,9 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) || range_covers_byte(addr, l, PCI_COMMAND)) pci_update_mappings(d); + + if (range_covers_byte(addr, l, PCI_COMMAND)) + pci_update_irq_disabled(d, was_irq_disabled); } /***********************************************************/ @@ -979,6 +1002,8 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_set_irq_state(pci_dev, irq_num, level); pci_update_irq_status(pci_dev); + if (pci_irq_disabled(pci_dev)) + return; pci_change_irq_level(pci_dev, irq_num, change); } diff --git a/hw/pci.h b/hw/pci.h index dc9b8604f..d279e3f7f 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -101,6 +101,7 @@ typedef struct PCIIORegion { #define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ #define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ #define PCI_COMMAND_MASTER 0x4 /* Enable bus master */ +#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ #define PCI_STATUS 0x06 /* 16 bits */ #define PCI_STATUS_INTERRUPT 0x08 #define PCI_REVISION_ID 0x08 /* 8 bits */ -- cgit v1.2.3 From b3dfdb5a3bae5fb3170397440dfebd579a3fcb04 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Fri, 4 Dec 2009 15:24:09 -0200 Subject: monitor: Introduce 'block_passwd' command When using encrypted disk images, QEMU will prompt the user for passwords when started. This makes sense for the user protocol, but doesn't for QMP. The solution is to have Monitor command which allows the user or a Client to set passwords in advance, so that we avoid the prompt completely. This is what block_passwd does, for example: (QEMU) block_passwd ide0-hd0 foobar Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit a3a55a2edb7c0fd72bc62a8a4c719a1e1983e6ac) --- monitor.c | 16 ++++++++++++++++ qemu-monitor.hx | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/monitor.c b/monitor.c index ba76f3416..27c696b2d 100644 --- a/monitor.c +++ b/monitor.c @@ -772,6 +772,22 @@ static void do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) eject_device(mon, bs, force); } +static void do_block_set_passwd(Monitor *mon, const QDict *qdict, + QObject **ret_data) +{ + BlockDriverState *bs; + + bs = bdrv_find(qdict_get_str(qdict, "device")); + if (!bs) { + qemu_error_new(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device")); + return; + } + + if (bdrv_set_key(bs, qdict_get_str(qdict, "password")) < 0) { + qemu_error_new(QERR_INVALID_PASSWORD); + } +} + static void do_change_block(Monitor *mon, const char *device, const char *filename, const char *fmt) { diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 62e395bff..c2670ee1d 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1045,6 +1045,20 @@ STEXI Close the file descriptor previously assigned to @var{fdname} using the @code{getfd} command. This is only needed if the file descriptor was never used by another monitor command. +ETEXI + + { + .name = "block_passwd", + .args_type = "device:B,password:s", + .params = "block_passwd device password", + .help = "set the password of encrypted block devices", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_set_passwd, + }, + +STEXI +@item block_passwd @var{device} @var{password} +Set the encrypted device @var{device} password to @var{password} ETEXI STEXI -- cgit v1.2.3 From fe7c6c90a8d11bcba64380915e040c13e1fd7cdc Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:08 +0100 Subject: QError: New QERR_VNC_SERVER_FAILED Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit a6906e31a8d025a0dd626ee3c14dd58e7b9ab445) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 1bb68c417..128a91e56 100644 --- a/qerror.c +++ b/qerror.c @@ -100,6 +100,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_UNDEFINED_ERROR, .desc = "An undefined error has ocurred", }, + { + .error_fmt = QERR_VNC_SERVER_FAILED, + .desc = "Could not start VNC server on %(target)", + }, {} }; diff --git a/qerror.h b/qerror.h index b85689933..1a05d9a66 100644 --- a/qerror.h +++ b/qerror.h @@ -83,4 +83,7 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_UNDEFINED_ERROR \ "{ 'class': 'UndefinedError', 'data': {} }" +#define QERR_VNC_SERVER_FAILED \ + "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" + #endif /* QERROR_H */ -- cgit v1.2.3 From 06976f82e733a8157c716698b42f000b9f68caab Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:09 +0100 Subject: monitor: convert do_change() to QObject, QError Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit ec3b82afaa0c4c06689d6a6381d351eefc4ee171) --- monitor.c | 19 +++++++++++-------- qemu-monitor.hx | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/monitor.c b/monitor.c index 8a06bbeb4..b3a58b69f 100644 --- a/monitor.c +++ b/monitor.c @@ -800,13 +800,13 @@ static void do_change_block(Monitor *mon, const char *device, bs = bdrv_find(device); if (!bs) { - monitor_printf(mon, "device not found\n"); + qemu_error_new(QERR_DEVICE_NOT_FOUND, device); return; } if (fmt) { drv = bdrv_find_whitelisted_format(fmt); if (!drv) { - monitor_printf(mon, "invalid format %s\n", fmt); + qemu_error_new(QERR_INVALID_BLOCK_FORMAT, fmt); return; } } @@ -816,17 +816,17 @@ static void do_change_block(Monitor *mon, const char *device, monitor_read_bdrv_key_start(mon, bs, NULL, NULL); } -static void change_vnc_password(Monitor *mon, const char *password) +static void change_vnc_password(const char *password) { if (vnc_display_password(NULL, password) < 0) - monitor_printf(mon, "could not set VNC server password\n"); + qemu_error_new(QERR_SET_PASSWD_FAILED); } static void change_vnc_password_cb(Monitor *mon, const char *password, void *opaque) { - change_vnc_password(mon, password); + change_vnc_password(password); monitor_read_command(mon, 1); } @@ -838,17 +838,20 @@ static void do_change_vnc(Monitor *mon, const char *target, const char *arg) char password[9]; strncpy(password, arg, sizeof(password)); password[sizeof(password) - 1] = '\0'; - change_vnc_password(mon, password); + change_vnc_password(password); } else { monitor_read_password(mon, change_vnc_password_cb, NULL); } } else { if (vnc_display_open(NULL, target) < 0) - monitor_printf(mon, "could not start VNC server on %s\n", target); + qemu_error_new(QERR_VNC_SERVER_FAILED, target); } } -static void do_change(Monitor *mon, const QDict *qdict) +/** + * do_change(): Change a removable medium, or VNC configuration + */ +static void do_change(Monitor *mon, const QDict *qdict, QObject **ret_data) { const char *device = qdict_get_str(qdict, "device"); const char *target = qdict_get_str(qdict, "target"); diff --git a/qemu-monitor.hx b/qemu-monitor.hx index c2670ee1d..0657b2d16 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -147,7 +147,8 @@ ETEXI .args_type = "device:B,target:F,arg:s?", .params = "device filename [format]", .help = "change a removable medium, optional format", - .mhandler.cmd = do_change, + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_change, }, STEXI -- cgit v1.2.3 From 3e4cd634cce2c969255476c5f984c132b7f7449b Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:10 +0100 Subject: QError: New QERR_FD_NOT_FOUND Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit c7c338c49712eceef0ef584249856928de30cb45) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index 128a91e56..d75c69aa3 100644 --- a/qerror.c +++ b/qerror.c @@ -64,6 +64,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_DEVICE_NOT_REMOVABLE, .desc = "Device %(device) is not removable", }, + { + .error_fmt = QERR_FD_NOT_FOUND, + .desc = "Failed to find file descriptor named %(name)", + }, { .error_fmt = QERR_INVALID_BLOCK_FORMAT, .desc = "Invalid block format %(name)", diff --git a/qerror.h b/qerror.h index 1a05d9a66..bda764ff9 100644 --- a/qerror.h +++ b/qerror.h @@ -56,6 +56,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_DEVICE_NOT_REMOVABLE \ "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }" +#define QERR_FD_NOT_FOUND \ + "{ 'class': 'fd_not_found', 'data': { 'name': %s } }" + #define QERR_INVALID_BLOCK_FORMAT \ "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }" -- cgit v1.2.3 From e5fc266be517faeb71995913788ac93cdd710108 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:11 +0100 Subject: monitor: convert do_closefd() to QError Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 063c1a0918d5a08f7ba89300d022b3421174fbf7) --- monitor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/monitor.c b/monitor.c index b3a58b69f..91cb2ce35 100644 --- a/monitor.c +++ b/monitor.c @@ -2121,8 +2121,7 @@ static void do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data) return; } - monitor_printf(mon, "Failed to find file descriptor named %s\n", - fdname); + qemu_error_new(QERR_FD_NOT_FOUND, fdname); } static void do_loadvm(Monitor *mon, const QDict *qdict) -- cgit v1.2.3 From e36469149a2987e34cac572501daaed162ec82e2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:12 +0100 Subject: QError: New QERR_FD_NOT_SUPPLIED Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 41471a2338522d72955c20179e16cff4d546b32a) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index d75c69aa3..e6b7f62aa 100644 --- a/qerror.c +++ b/qerror.c @@ -68,6 +68,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_FD_NOT_FOUND, .desc = "Failed to find file descriptor named %(name)", }, + { + .error_fmt = QERR_FD_NOT_SUPPLIED, + .desc = "No file descriptor supplied via SCM_RIGHTS", + }, { .error_fmt = QERR_INVALID_BLOCK_FORMAT, .desc = "Invalid block format %(name)", diff --git a/qerror.h b/qerror.h index bda764ff9..2262619a6 100644 --- a/qerror.h +++ b/qerror.h @@ -59,6 +59,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_FD_NOT_FOUND \ "{ 'class': 'fd_not_found', 'data': { 'name': %s } }" +#define QERR_FD_NOT_SUPPLIED \ + "{ 'class': 'fd_not_supplied', 'data': {} }" + #define QERR_INVALID_BLOCK_FORMAT \ "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }" -- cgit v1.2.3 From 0b52786ce15f46a7783185522f465c0a97f6c549 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:13 +0100 Subject: New QERR_INVALID_PARAMETER Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 7a046f5f14d3de026197dc08c389cd1f23a3dddf) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index e6b7f62aa..aa89a3d7d 100644 --- a/qerror.c +++ b/qerror.c @@ -76,6 +76,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_INVALID_BLOCK_FORMAT, .desc = "Invalid block format %(name)", }, + { + .error_fmt = QERR_INVALID_PARAMETER, + .desc = "Invalid parameter %(name)", + }, { .error_fmt = QERR_INVALID_PARAMETER_TYPE, .desc = "Invalid parameter type, expected: %(expected)", diff --git a/qerror.h b/qerror.h index 2262619a6..48f1ab6b4 100644 --- a/qerror.h +++ b/qerror.h @@ -65,6 +65,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_INVALID_BLOCK_FORMAT \ "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }" +#define QERR_INVALID_PARAMETER \ + "{ 'class': 'invalid_parameter', 'data': { 'name': %s } }" + #define QERR_INVALID_PARAMETER_TYPE \ "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" -- cgit v1.2.3 From ea2b7d7079c9c630d017d407824a776cd95078df Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:14 +0100 Subject: QError: New QERR_TOO_MANY_FILES Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit a488be27e5fbfd78e3c7f98706e0c2f6af402061) --- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/qerror.c b/qerror.c index aa89a3d7d..8ffe4f673 100644 --- a/qerror.c +++ b/qerror.c @@ -108,6 +108,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_SET_PASSWD_FAILED, .desc = "Could not set password", }, + { + .error_fmt = QERR_TOO_MANY_FILES, + .desc = "Too many open files", + }, { .error_fmt = QERR_UNDEFINED_ERROR, .desc = "An undefined error has ocurred", diff --git a/qerror.h b/qerror.h index 48f1ab6b4..9462d5cb9 100644 --- a/qerror.h +++ b/qerror.h @@ -92,6 +92,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_UNDEFINED_ERROR \ "{ 'class': 'UndefinedError', 'data': {} }" +#define QERR_TOO_MANY_FILES \ + "{ 'class': 'fd_too_many_files', 'data': {} }" + #define QERR_VNC_SERVER_FAILED \ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" -- cgit v1.2.3 From 13a2ccc46f66ffb0a6434e3b1319bf0ebd81ac54 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:15 +0100 Subject: monitor: convert do_getfd() to QError Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 7cdfcfe18f0a9e8603e4a14770a84eb5649521c5) --- monitor.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index 91cb2ce35..16d611e5a 100644 --- a/monitor.c +++ b/monitor.c @@ -2071,19 +2071,21 @@ static void do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data) fd = qemu_chr_get_msgfd(mon->chr); if (fd == -1) { - monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n"); + qemu_error_new(QERR_FD_NOT_SUPPLIED); return; } if (qemu_isdigit(fdname[0])) { - monitor_printf(mon, "getfd: monitor names may not begin with a number\n"); + qemu_error_new(QERR_INVALID_PARAMETER, "fdname"); return; } fd = dup(fd); if (fd == -1) { - monitor_printf(mon, "Failed to dup() file descriptor: %s\n", - strerror(errno)); + if (errno == EMFILE) + qemu_error_new(QERR_TOO_MANY_FILES); + else + qemu_error_new(QERR_UNDEFINED_ERROR); return; } -- cgit v1.2.3 From 143d288cba95329e30c1c8c3403a53b35629ee72 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Mon, 7 Dec 2009 21:37:16 +0100 Subject: QMP: add human-readable description to error response Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 77e595e7c613c495714d04ce63fb9bce263c29ae) --- QMP/qmp-spec.txt | 5 ++++- monitor.c | 1 + qerror.c | 21 ++++++++++++++++----- qerror.h | 2 ++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/QMP/qmp-spec.txt b/QMP/qmp-spec.txt index 8429789a9..1cbd21cd4 100644 --- a/QMP/qmp-spec.txt +++ b/QMP/qmp-spec.txt @@ -102,13 +102,16 @@ completed because of an error condition. The format is: -{ "error": { "class": json-string, "data": json-value }, "id": json-value } +{ "error": { "class": json-string, "data": json-value, "desc": json-string }, + "id": json-value } Where, - The "class" member contains the error class name (eg. "ServiceUnavailable") - The "data" member contains specific error data and is defined in a per-command basis, it will be an empty json-object if the error has no data +- The "desc" member is a human-readable error message. Clients should + not attempt to parse this message. - The "id" member contains the transaction identification associated with the command execution (if issued by the Client) diff --git a/monitor.c b/monitor.c index 16d611e5a..a38a103e4 100644 --- a/monitor.c +++ b/monitor.c @@ -305,6 +305,7 @@ static void monitor_protocol_emitter(Monitor *mon, QObject *data) } } else { /* error response */ + qdict_put(mon->error->error, "desc", qerror_human(mon->error)); qdict_put(qmp, "error", mon->error->error); QINCREF(mon->error->error); QDECREF(mon->error); diff --git a/qerror.c b/qerror.c index 8ffe4f673..5f8fc5dec 100644 --- a/qerror.c +++ b/qerror.c @@ -283,13 +283,11 @@ static const char *append_field(QString *outstr, const QError *qerror, } /** - * qerror_print(): Print QError data + * qerror_human(): Format QError data into human-readable string. * - * This function will print the member 'desc' of the specified QError object, - * it uses qemu_error() for this, so that the output is routed to the right - * place (ie. stderr or Monitor's device). + * Formats according to member 'desc' of the specified QError object. */ -void qerror_print(const QError *qerror) +QString *qerror_human(const QError *qerror) { const char *p; QString *qstring; @@ -309,6 +307,19 @@ void qerror_print(const QError *qerror) } } + return qstring; +} + +/** + * qerror_print(): Print QError data + * + * This function will print the member 'desc' of the specified QError object, + * it uses qemu_error() for this, so that the output is routed to the right + * place (ie. stderr or Monitor's device). + */ +void qerror_print(const QError *qerror) +{ + QString *qstring = qerror_human(qerror); qemu_error("%s\n", qstring_get_str(qstring)); QDECREF(qstring); } diff --git a/qerror.h b/qerror.h index 9462d5cb9..09e32b9a3 100644 --- a/qerror.h +++ b/qerror.h @@ -13,6 +13,7 @@ #define QERROR_H #include "qdict.h" +#include "qstring.h" #include typedef struct QErrorStringTable { @@ -32,6 +33,7 @@ typedef struct QError { QError *qerror_new(void); QError *qerror_from_info(const char *file, int linenr, const char *func, const char *fmt, va_list *va); +QString *qerror_human(const QError *qerror); void qerror_print(const QError *qerror); QError *qobject_to_qerror(const QObject *obj); -- cgit v1.2.3 From 90f445e1c9a2ce05d0b68c3159892181cdd600d6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 7 Dec 2009 21:04:52 +0200 Subject: qemu: delete rule target on error Instruct make to remove any rule target on error. This prevetns situation where there was an error during build but generated file still stays behind. Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori (cherry picked from commit 7dbbbb0c9e4313cf2d2f6559b7899259fb09eb63) --- rules.mak | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rules.mak b/rules.mak index 16713bacd..5d9f684c2 100644 --- a/rules.mak +++ b/rules.mak @@ -47,3 +47,6 @@ cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \ %.h-timestamp: %.mak $(call quiet-command, sh $(SRC_PATH)/create_config < $< > $@, " GEN $*.h") @cmp $@ $*.h >/dev/null 2>&1 || cp $@ $*.h + +# will delete the target of a rule if commands exit with a nonzero exit status +.DELETE_ON_ERROR: -- cgit v1.2.3 From 2e51813417d2a60f0fa2e0e5a4707b47440b4361 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Fri, 11 Dec 2009 15:38:10 +0000 Subject: Fix ARM userspace strex implementation. Signed-off-by: Paul Brook --- linux-user/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/linux-user/main.c b/linux-user/main.c index 5fbcda2a3..e51539eff 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -593,6 +593,7 @@ static int do_strex(CPUARMState *env) } rc = 0; fail: + env->regs[15] += 4; env->regs[(env->exclusive_info >> 4) & 0xf] = rc; done: end_exclusive(); -- cgit v1.2.3 From d7b81937161232f0cfdefbbbc151bf43d1404aae Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Wed, 9 Dec 2009 12:59:36 -0600 Subject: Do not abort on qemu_malloc(0) in production builds qemu_malloc() does not allow size=0 to be passed in and aborts on this behavior. Unfortunately, there is good reason to believe that within qemu, there are a number of, so far, undetected places that assume size=0 can be safely passed. Since we do not want to abort unnecessarily in production builds, return qemu_malloc(1) whenever the version file indicates that this is a production build. Signed-off-by: Anthony Liguori (cherry picked from commit 20ff6c8066eb5346b9e066851cf8a1e0564a0f1a) --- configure | 18 +++++++++++++++++- qemu-malloc.c | 19 +++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/configure b/configure index a29839e6e..273b6b7c6 100755 --- a/configure +++ b/configure @@ -256,6 +256,7 @@ blobs="yes" pkgversion="" check_utests="no" user_pie="no" +zero_malloc="" # OS specific if check_define __linux__ ; then @@ -1792,8 +1793,9 @@ fi # Consult white-list to determine whether to enable werror # by default. Only enable by default for git builds +z_version=`cut -f3 -d. $source_path/VERSION` + if test -z "$werror" ; then - z_version=`cut -f3 -d. $source_path/VERSION` if test "$z_version" = "50" -a \ "$linux" = "yes" ; then werror="yes" @@ -1802,6 +1804,16 @@ if test -z "$werror" ; then fi fi +# Disable zero malloc errors for official releases unless explicitly told to +# enable/disable +if test -z "$zero_malloc" ; then + if test "$z_version" = "50" ; then + zero_malloc="no" + else + zero_malloc="yes" + fi +fi + if test "$werror" = "yes" ; then QEMU_CFLAGS="-Werror $QEMU_CFLAGS" fi @@ -2109,6 +2121,10 @@ fi echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak +if test "$zero_malloc" = "yes" ; then + echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak +fi + # USB host support case "$usb" in linux) diff --git a/qemu-malloc.c b/qemu-malloc.c index 295d1856e..5d9e34d69 100644 --- a/qemu-malloc.c +++ b/qemu-malloc.c @@ -42,22 +42,29 @@ void qemu_free(void *ptr) free(ptr); } +static int allow_zero_malloc(void) +{ +#if defined(CONFIG_ZERO_MALLOC) + return 1; +#else + return 0; +#endif +} + void *qemu_malloc(size_t size) { - if (!size) { + if (!size && !allow_zero_malloc()) { abort(); } - return oom_check(malloc(size)); + return oom_check(malloc(size ? size : 1)); } void *qemu_realloc(void *ptr, size_t size) { if (size) { return oom_check(realloc(ptr, size)); - } else { - if (ptr) { - return realloc(ptr, size); - } + } else if (allow_zero_malloc()) { + return oom_check(realloc(ptr, size ? size : 1)); } abort(); } -- cgit v1.2.3 From 4d687b13cf3dd6c1247bc723a2c50b66d470e19d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 Dec 2009 15:47:44 +1000 Subject: vmware_vga: add rom file so that it boots. This just adds the rom file to the vmware SVGA chipset so it boots. Signed-off-by: Dave Airlie Signed-off-by: Anthony Liguori (cherry picked from commit b3c3f123f785fb861d930080f083507b51f5ce79) --- hw/vmware_vga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 240731a1b..a7e42c6e1 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "hw.h" +#include "loader.h" #include "console.h" #include "pci.h" #include "vmware_vga.h" @@ -1124,6 +1125,7 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size) cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, vga_ram_size, s->vga.vram_offset); #endif + rom_add_vga(VGABIOS_FILENAME); } static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num, -- cgit v1.2.3 From 5e0c45584215c4ade73d8285da701ca445232286 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Tue, 8 Dec 2009 20:07:48 +0200 Subject: virtio: verify features on load migrating between hosts which have different features might break silently, if the migration destination does not support some features supported by source. Prevent this from happening by comparing acked feature bits with the mask supported by the device. Signed-off-by: Michael S. Tsirkin Signed-off-by: Anthony Liguori (cherry picked from commit 6d74ca5aa83b83fb52332f7735c61ecb7a5328c1) --- hw/syborg_virtio.c | 12 ++++++++++-- hw/virtio-pci.c | 14 +++++++++++--- hw/virtio.c | 11 ++++++++++- hw/virtio.h | 6 ++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c index 6cf5a15c2..a84206a11 100644 --- a/hw/syborg_virtio.c +++ b/hw/syborg_virtio.c @@ -87,7 +87,7 @@ static uint32_t syborg_virtio_readl(void *opaque, target_phys_addr_t offset) break; case SYBORG_VIRTIO_HOST_FEATURES: ret = vdev->get_features(vdev); - ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); + ret |= vdev->binding->get_features(s); break; case SYBORG_VIRTIO_GUEST_FEATURES: ret = vdev->features; @@ -242,8 +242,16 @@ static void syborg_virtio_update_irq(void *opaque, uint16_t vector) qemu_set_irq(proxy->irq, level != 0); } +static unsigned syborg_virtio_get_features(void *opaque) +{ + unsigned ret = 0; + ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); + return ret; +} + static VirtIOBindings syborg_virtio_bindings = { - .notify = syborg_virtio_update_irq + .notify = syborg_virtio_update_irq, + .get_features = syborg_virtio_get_features, }; static int syborg_virtio_init(SyborgVirtIOProxy *proxy, VirtIODevice *vdev) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index d222ce03f..450013091 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -236,9 +236,7 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) switch (addr) { case VIRTIO_PCI_HOST_FEATURES: ret = vdev->get_features(vdev); - ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); - ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC); - ret |= (1 << VIRTIO_F_BAD_FEATURE); + ret |= vdev->binding->get_features(proxy); break; case VIRTIO_PCI_GUEST_FEATURES: ret = vdev->features; @@ -382,12 +380,22 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, msix_write_config(pci_dev, address, val, len); } +static unsigned virtio_pci_get_features(void *opaque) +{ + unsigned ret = 0; + ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); + ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC); + ret |= (1 << VIRTIO_F_BAD_FEATURE); + return ret; +} + static const VirtIOBindings virtio_pci_bindings = { .notify = virtio_pci_notify, .save_config = virtio_pci_save_config, .load_config = virtio_pci_load_config, .save_queue = virtio_pci_save_queue, .load_queue = virtio_pci_load_queue, + .get_features = virtio_pci_get_features, }; static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, diff --git a/hw/virtio.c b/hw/virtio.c index 1f92171f6..cecd0dc04 100644 --- a/hw/virtio.c +++ b/hw/virtio.c @@ -651,6 +651,9 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f) int virtio_load(VirtIODevice *vdev, QEMUFile *f) { int num, i, ret; + uint32_t features; + uint32_t supported_features = vdev->get_features(vdev) | + vdev->binding->get_features(vdev->binding_opaque); if (vdev->binding->load_config) { ret = vdev->binding->load_config(vdev->binding_opaque, f); @@ -661,7 +664,13 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) qemu_get_8s(f, &vdev->status); qemu_get_8s(f, &vdev->isr); qemu_get_be16s(f, &vdev->queue_sel); - qemu_get_be32s(f, &vdev->features); + qemu_get_be32s(f, &features); + if (features & ~supported_features) { + fprintf(stderr, "Features 0x%x unsupported. Allowed features: 0x%x\n", + features, supported_features); + return -1; + } + vdev->features = features; vdev->config_len = qemu_get_be32(f); qemu_get_buffer(f, vdev->config, vdev->config_len); diff --git a/hw/virtio.h b/hw/virtio.h index 15ad91076..35532a6f2 100644 --- a/hw/virtio.h +++ b/hw/virtio.h @@ -31,6 +31,11 @@ /* We've given up on this device. */ #define VIRTIO_CONFIG_S_FAILED 0x80 +/* Some virtio feature bits (currently bits 28 through 31) are reserved for the + * transport being used (eg. virtio_ring), the rest are per-device feature bits. */ +#define VIRTIO_TRANSPORT_F_START 28 +#define VIRTIO_TRANSPORT_F_END 32 + /* We notify when the ring is completely used, even if the guest is suppressing * callbacks */ #define VIRTIO_F_NOTIFY_ON_EMPTY 24 @@ -82,6 +87,7 @@ typedef struct { void (*save_queue)(void * opaque, int n, QEMUFile *f); int (*load_config)(void * opaque, QEMUFile *f); int (*load_queue)(void * opaque, int n, QEMUFile *f); + unsigned (*get_features)(void * opaque); } VirtIOBindings; #define VIRTIO_PCI_QUEUE_MAX 16 -- cgit v1.2.3 From 5b6321a237e00e7642f0c205e13a1382988e59c2 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Tue, 8 Dec 2009 15:50:54 +0200 Subject: fix rtc-td-hack on host without high-res timers On hosts without high-res timers it is impossible to inject rtc interrupt faster then 1kHz. Windows sometimes configures RTC to generate 1kHz interrupts, so we can't inject missed interrupts when running on such hosts. Always injecting an interrupt on REG_C read is also not an option since Windows wait for REG_C to become zero with interrupt disabled during boot. This patch uses mixed approach: accelerate timer + inject up to 1000 interrupts on REG_C read. Signed-off-by: Gleb Natapov Signed-off-by: Anthony Liguori (cherry picked from commit ba32edab7fdab0e74b54696942b4127d26861cf6) --- hw/mc146818rtc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index b8c7b0c1b..e4d55c7c7 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -30,6 +30,8 @@ //#define DEBUG_CMOS +#define RTC_REINJECT_ON_ACK_COUNT 1000 + #define RTC_SECONDS 0 #define RTC_SECONDS_ALARM 1 #define RTC_MINUTES 2 @@ -76,6 +78,7 @@ struct RTCState { int64_t next_periodic_time; /* second update */ int64_t next_second_time; + uint16_t irq_reinject_on_ack_count; uint32_t irq_coalesced; uint32_t period; QEMUTimer *coalesced_timer; @@ -180,6 +183,8 @@ static void rtc_periodic_timer(void *opaque) s->cmos_data[RTC_REG_C] |= 0xc0; #ifdef TARGET_I386 if(rtc_td_hack) { + if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT) + s->irq_reinject_on_ack_count = 0; apic_reset_irq_delivered(); rtc_irq_raise(s->irq); if (!apic_get_irq_delivered()) { @@ -458,6 +463,18 @@ static uint32_t cmos_ioport_read(void *opaque, uint32_t addr) case RTC_REG_C: ret = s->cmos_data[s->cmos_index]; qemu_irq_lower(s->irq); +#ifdef TARGET_I386 + if(s->irq_coalesced && + s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) { + s->irq_reinject_on_ack_count++; + apic_reset_irq_delivered(); + qemu_irq_raise(s->irq); + if (apic_get_irq_delivered()) + s->irq_coalesced--; + break; + } +#endif + s->cmos_data[RTC_REG_C] = 0x00; break; default: -- cgit v1.2.3 From 9df9eeeb18d93acf21e43710cf8aa2be8eff7a8a Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 9 Dec 2009 17:07:51 +0100 Subject: qdev: Rename USBDevice member devname to product_desc It's not a device name, it's the USB product description string. Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 0fe6d12e0bc752c29a93ac83a274e3650d457069) --- hw/bt-hid.c | 2 +- hw/usb-bus.c | 11 ++++++----- hw/usb-hid.c | 2 +- hw/usb.h | 2 +- usb-bsd.c | 4 ++-- usb-linux.c | 4 ++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hw/bt-hid.c b/hw/bt-hid.c index 020176eac..4a04bbd9b 100644 --- a/hw/bt-hid.c +++ b/hw/bt-hid.c @@ -552,7 +552,7 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net, BT_HID_MTU, bt_hid_new_interrupt_ch); s->usbdev = dev; - s->btdev.device.lmp_name = s->usbdev->devname; + s->btdev.device.lmp_name = s->usbdev->product_desc; usb_hid_datain_cb(s->usbdev, s, bt_hid_datain); s->btdev.device.handle_destroy = bt_hid_destroy; diff --git a/hw/usb-bus.c b/hw/usb-bus.c index 99d185e79..ba1b6e30e 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -43,7 +43,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base); int rc; - pstrcpy(dev->devname, sizeof(dev->devname), qdev->info->name); + pstrcpy(dev->product_desc, sizeof(dev->product_desc), qdev->info->name); dev->info = info; dev->auto_attach = 1; rc = dev->info->init(dev); @@ -131,7 +131,7 @@ static void do_attach(USBDevice *dev) if (dev->attached) { fprintf(stderr, "Warning: tried to attach usb device %s twice\n", - dev->devname); + dev->product_desc); return; } dev->attached++; @@ -166,7 +166,7 @@ int usb_device_detach(USBDevice *dev) if (!dev->attached) { fprintf(stderr, "Warning: tried to detach unattached usb device %s\n", - dev->devname); + dev->product_desc); return -1; } dev->attached--; @@ -228,7 +228,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent) monitor_printf(mon, "%*saddr %d.%d, speed %s, name %s%s\n", indent, "", bus->busnr, dev->addr, - usb_speed(dev->speed), dev->devname, + usb_speed(dev->speed), dev->product_desc, dev->attached ? ", attached" : ""); } @@ -249,7 +249,8 @@ void usb_info(Monitor *mon) if (!dev) continue; monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n", - bus->busnr, dev->addr, usb_speed(dev->speed), dev->devname); + bus->busnr, dev->addr, usb_speed(dev->speed), + dev->product_desc); } } } diff --git a/hw/usb-hid.c b/hw/usb-hid.c index f4a2a481e..6621f7227 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -701,7 +701,7 @@ static int usb_hid_handle_control(USBDevice *dev, int request, int value, break; case 2: /* product description */ - ret = set_usb_string(data, s->dev.devname); + ret = set_usb_string(data, s->dev.product_desc); break; case 3: /* vendor description */ diff --git a/hw/usb.h b/hw/usb.h index 351c466c7..39aba995f 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -132,7 +132,7 @@ struct USBDevice { int speed; uint8_t addr; - char devname[32]; + char product_desc[32]; int auto_attach; int attached; diff --git a/usb-bsd.c b/usb-bsd.c index a66364f0d..a9987d116 100644 --- a/usb-bsd.c +++ b/usb-bsd.c @@ -370,10 +370,10 @@ USBDevice *usb_host_device_open(const char *devname) dev->dev.speed = USB_SPEED_FULL - 1; if (strncmp(dev_info.udi_product, "product", 7) != 0) - pstrcpy(dev->dev.devname, sizeof(dev->dev.devname), + pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc), dev_info.udi_product); else - snprintf(dev->dev.devname, sizeof(dev->dev.devname), + snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc), "host:%s", devname); pstrcpy(dev->devpath, sizeof(dev->devpath), "/dev/"); diff --git a/usb-linux.c b/usb-linux.c index 285ac227a..67735d338 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -933,10 +933,10 @@ static int usb_host_open(USBHostDevice *dev, int bus_num, dev->dev.speed = USB_SPEED_HIGH; if (!prod_name || prod_name[0] == '\0') - snprintf(dev->dev.devname, sizeof(dev->dev.devname), + snprintf(dev->dev.product_desc, sizeof(dev->dev.product_desc), "host:%d.%d", bus_num, addr); else - pstrcpy(dev->dev.devname, sizeof(dev->dev.devname), + pstrcpy(dev->dev.product_desc, sizeof(dev->dev.product_desc), prod_name); /* USB devio uses 'write' flag to check for async completions */ -- cgit v1.2.3 From 5b6d0419d9a411d83a1078a146ee140482dcc02c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 9 Dec 2009 17:07:52 +0100 Subject: qdev: Separate USB product description from qdev name Using the qdev name for the product description makes for inconvenient qdev names. Put the product description in new USBDeviceInfo member product_desc. Make usb_qdev_init() use it. No user or guest visible change, since the value is still the same. Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 063846984ce7eb1c1ddce6dda39b662c64a80dc0) --- hw/usb-bt.c | 1 + hw/usb-bus.c | 2 +- hw/usb-hid.c | 3 +++ hw/usb-hub.c | 1 + hw/usb-msd.c | 1 + hw/usb-net.c | 1 + hw/usb-serial.c | 2 ++ hw/usb-wacom.c | 1 + hw/usb.h | 2 ++ usb-bsd.c | 1 + usb-linux.c | 1 + 11 files changed, 15 insertions(+), 1 deletion(-) diff --git a/hw/usb-bt.c b/hw/usb-bt.c index 18d7a98b4..07da1337e 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -645,6 +645,7 @@ USBDevice *usb_bt_init(HCIInfo *hci) } static struct USBDeviceInfo bt_info = { + .product_desc = "QEMU BT dongle", .qdev.name = "QEMU BT dongle", .qdev.size = sizeof(struct USBBtState), .init = usb_bt_initfn, diff --git a/hw/usb-bus.c b/hw/usb-bus.c index ba1b6e30e..8bbc80d6b 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -43,7 +43,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base); int rc; - pstrcpy(dev->product_desc, sizeof(dev->product_desc), qdev->info->name); + pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc); dev->info = info; dev->auto_attach = 1; rc = dev->info->init(dev); diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 6621f7227..33de302d6 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -880,6 +880,7 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) static struct USBDeviceInfo hid_info[] = { { + .product_desc = "QEMU USB Tablet", .qdev.name = "QEMU USB Tablet", .qdev.alias = "usb-tablet", .usbdevice_name = "tablet", @@ -891,6 +892,7 @@ static struct USBDeviceInfo hid_info[] = { .handle_data = usb_hid_handle_data, .handle_destroy = usb_hid_handle_destroy, },{ + .product_desc = "QEMU USB Mouse", .qdev.name = "QEMU USB Mouse", .qdev.alias = "usb-mouse", .usbdevice_name = "mouse", @@ -902,6 +904,7 @@ static struct USBDeviceInfo hid_info[] = { .handle_data = usb_hid_handle_data, .handle_destroy = usb_hid_handle_destroy, },{ + .product_desc = "QEMU USB Keyboard", .qdev.name = "QEMU USB Keyboard", .qdev.alias = "usb-kbd", .usbdevice_name = "keyboard", diff --git a/hw/usb-hub.c b/hw/usb-hub.c index e5a093877..32f2ab8c7 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -544,6 +544,7 @@ static int usb_hub_initfn(USBDevice *dev) } static struct USBDeviceInfo hub_info = { + .product_desc = "QEMU USB Hub", .qdev.name = "QEMU USB Hub", .qdev.size = sizeof(USBHubState), .init = usb_hub_initfn, diff --git a/hw/usb-msd.c b/hw/usb-msd.c index bb39b625a..b9f6588a7 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -600,6 +600,7 @@ static USBDevice *usb_msd_init(const char *filename) } static struct USBDeviceInfo msd_info = { + .product_desc = "QEMU USB MSD", .qdev.name = "QEMU USB MSD", .qdev.alias = "usb-storage", .qdev.size = sizeof(MSDState), diff --git a/hw/usb-net.c b/hw/usb-net.c index 2556e05dd..3dd05e370 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1487,6 +1487,7 @@ USBDevice *usb_net_init(NICInfo *nd) } static struct USBDeviceInfo net_info = { + .product_desc = "QEMU USB Network Interface", .qdev.name = "QEMU USB Network Interface", .qdev.size = sizeof(USBNetState), .init = usb_net_initfn, diff --git a/hw/usb-serial.c b/hw/usb-serial.c index 223d4c385..14e410ed9 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -605,6 +605,7 @@ static USBDevice *usb_braille_init(const char *unused) } static struct USBDeviceInfo serial_info = { + .product_desc = "QEMU USB Serial", .qdev.name = "QEMU USB Serial", .qdev.alias = "usb-serial", .qdev.size = sizeof(USBSerialState), @@ -625,6 +626,7 @@ static struct USBDeviceInfo serial_info = { }; static struct USBDeviceInfo braille_info = { + .product_desc = "QEMU USB Braille", .qdev.name = "QEMU USB Braille", .qdev.alias = "usb-braille", .qdev.size = sizeof(USBSerialState), diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c index ef6137637..b10864fe9 100644 --- a/hw/usb-wacom.c +++ b/hw/usb-wacom.c @@ -409,6 +409,7 @@ static int usb_wacom_initfn(USBDevice *dev) } static struct USBDeviceInfo wacom_info = { + .product_desc = "QEMU PenPartner Tablet", .qdev.name = "QEMU PenPartner Tablet", .qdev.alias = "wacom-tablet", .usbdevice_name = "wacom-tablet", diff --git a/hw/usb.h b/hw/usb.h index 39aba995f..068458850 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -185,6 +185,8 @@ struct USBDeviceInfo { */ int (*handle_data)(USBDevice *dev, USBPacket *p); + const char *product_desc; + /* handle legacy -usbdevice command line options */ const char *usbdevice_name; USBDevice *(*usbdevice_init)(const char *params); diff --git a/usb-bsd.c b/usb-bsd.c index a9987d116..e72d123f9 100644 --- a/usb-bsd.c +++ b/usb-bsd.c @@ -393,6 +393,7 @@ fail: } static struct USBDeviceInfo usb_host_dev_info = { + .product_desc = "USB Host Device", .qdev.name = "USB Host Device", .qdev.size = sizeof(USBHostDevice), .init = usb_host_initfn, diff --git a/usb-linux.c b/usb-linux.c index 67735d338..0004e969b 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -979,6 +979,7 @@ static int usb_host_initfn(USBDevice *dev) } static struct USBDeviceInfo usb_host_dev_info = { + .product_desc = "USB Host Device", .qdev.name = "USB Host Device", .qdev.alias = "usb-host", .qdev.size = sizeof(USBHostDevice), -- cgit v1.2.3 From 72fbd9f97c11a981d2b235212bce20582f1494a9 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 9 Dec 2009 17:07:53 +0100 Subject: qdev: Replace device names containing whitespace Device names with whitespace require quoting in the shell and in the monitor. Some of the offenders are also overly long. Some have a more convenient alias, some don't. The place for verbose device names is DeviceInfo member desc. The name should be short & sweet. Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit 556cd09885bec3f69ba78228fe4e46dc1dad145b) --- hw/bt-hid.c | 2 +- hw/cirrus_vga.c | 5 +++-- hw/grackle_pci.c | 4 ++-- hw/ide/cmd646.c | 4 ++-- hw/ide/piix.c | 8 ++++---- hw/unin_pci.c | 30 +++++++++++++++--------------- hw/usb-bt.c | 4 ++-- hw/usb-bus.c | 2 +- hw/usb-hid.c | 9 +++------ hw/usb-hub.c | 2 +- hw/usb-msd.c | 5 ++--- hw/usb-net.c | 4 ++-- hw/usb-ohci.c | 5 ++--- hw/usb-serial.c | 10 ++++------ hw/usb-uhci.c | 8 ++++---- hw/usb-wacom.c | 4 ++-- hw/vmware_vga.c | 4 ++-- usb-bsd.c | 4 ++-- usb-linux.c | 5 ++--- 19 files changed, 56 insertions(+), 63 deletions(-) diff --git a/hw/bt-hid.c b/hw/bt-hid.c index 4a04bbd9b..abdfd35e8 100644 --- a/hw/bt-hid.c +++ b/hw/bt-hid.c @@ -566,6 +566,6 @@ static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net, struct bt_device_s *bt_keyboard_init(struct bt_scatternet_s *net) { - USBDevice *dev = usb_create_simple(NULL /* FIXME */, "QEMU USB Keyboard"); + USBDevice *dev = usb_create_simple(NULL /* FIXME */, "usb-kbd"); return bt_hid_init(net, dev, class_keyboard); } diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 2d1dd4e11..24af81ceb 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -3217,11 +3217,12 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev) void pci_cirrus_vga_init(PCIBus *bus) { - pci_create_simple(bus, -1, "Cirrus VGA"); + pci_create_simple(bus, -1, "cirrus-vga"); } static PCIDeviceInfo cirrus_vga_info = { - .qdev.name = "Cirrus VGA", + .qdev.name = "cirrus-vga", + .qdev.desc = "Cirrus CLGD 54xx VGA", .qdev.size = sizeof(PCICirrusVGAState), .qdev.vmsd = &vmstate_pci_cirrus_vga, .init = pci_cirrus_vga_initfn, diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index 089d1fba0..ee4fed53e 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -178,7 +178,7 @@ static PCIDeviceInfo grackle_pci_host_info = { }; static PCIDeviceInfo dec_21154_pci_host_info = { - .qdev.name = "DEC 21154", + .qdev.name = "dec-21154", .qdev.size = sizeof(PCIDevice), .init = dec_21154_pci_host_init, }; @@ -188,7 +188,7 @@ static void grackle_register_devices(void) sysbus_register_dev("grackle", sizeof(GrackleState), pci_grackle_init_device); pci_qdev_register(&grackle_pci_host_info); - sysbus_register_dev("DEC 21154", sizeof(GrackleState), + sysbus_register_dev("dec-21154", sizeof(GrackleState), pci_dec_21154_init_device); pci_qdev_register(&dec_21154_pci_host_info); } diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 3b7c60608..e1e626e2a 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -245,7 +245,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, { PCIDevice *dev; - dev = pci_create(bus, -1, "CMD646 IDE"); + dev = pci_create(bus, -1, "cmd646-ide"); qdev_prop_set_uint32(&dev->qdev, "secondary", secondary_ide_enabled); qdev_init_nofail(&dev->qdev); @@ -254,7 +254,7 @@ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, static PCIDeviceInfo cmd646_ide_info[] = { { - .qdev.name = "CMD646 IDE", + .qdev.name = "cmd646-ide", .qdev.size = sizeof(PCIIDEState), .init = pci_cmd646_ide_initfn, .qdev.props = (Property[]) { diff --git a/hw/ide/piix.c b/hw/ide/piix.c index ec93f29b5..de3648023 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -161,7 +161,7 @@ void pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { PCIDevice *dev; - dev = pci_create_simple(bus, devfn, "PIIX3 IDE"); + dev = pci_create_simple(bus, devfn, "piix3-ide"); pci_ide_create_devs(dev, hd_table); } @@ -171,18 +171,18 @@ void pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) { PCIDevice *dev; - dev = pci_create_simple(bus, devfn, "PIIX4 IDE"); + dev = pci_create_simple(bus, devfn, "piix4-ide"); pci_ide_create_devs(dev, hd_table); } static PCIDeviceInfo piix_ide_info[] = { { - .qdev.name = "PIIX3 IDE", + .qdev.name = "piix3-ide", .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .init = pci_piix3_ide_initfn, },{ - .qdev.name = "PIIX4 IDE", + .qdev.name = "piix4-ide", .qdev.size = sizeof(PCIIDEState), .qdev.no_user = 1, .init = pci_piix4_ide_initfn, diff --git a/hw/unin_pci.c b/hw/unin_pci.c index 5b3f118fc..f07c96644 100644 --- a/hw/unin_pci.c +++ b/hw/unin_pci.c @@ -148,7 +148,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Use values found on a real PowerMac */ /* Uninorth main bus */ - dev = qdev_create(NULL, "Uni-north main"); + dev = qdev_create(NULL, "uni-north-main"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); @@ -157,7 +157,7 @@ PCIBus *pci_pmac_init(qemu_irq *pic) pic, 11 << 3, 4); #if 0 - pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north main"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-main"); #endif sysbus_mmio_map(s, 0, 0xf2800000); @@ -166,12 +166,12 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* DEC 21154 bridge */ #if 0 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ - pci_create_simple(d->host_state.bus, 12 << 3, "DEC 21154"); + pci_create_simple(d->host_state.bus, 12 << 3, "dec-21154"); #endif /* Uninorth AGP bus */ - pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north AGP"); - dev = qdev_create(NULL, "Uni-north AGP"); + pci_create_simple(d->host_state.bus, 11 << 3, "uni-north-AGP"); + dev = qdev_create(NULL, "uni-north-AGP"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf0800000); @@ -180,8 +180,8 @@ PCIBus *pci_pmac_init(qemu_irq *pic) /* Uninorth internal bus */ #if 0 /* XXX: not needed for now */ - pci_create_simple(d->host_state.bus, 14 << 3, "Uni-north internal"); - dev = qdev_create(NULL, "Uni-north internal"); + pci_create_simple(d->host_state.bus, 14 << 3, "uni-north-internal"); + dev = qdev_create(NULL, "uni-north-internal"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_mmio_map(s, 0, 0xf4800000); @@ -260,41 +260,41 @@ static int unin_internal_pci_host_init(PCIDevice *d) } static PCIDeviceInfo unin_main_pci_host_info = { - .qdev.name = "Uni-north main", + .qdev.name = "uni-north-main", .qdev.size = sizeof(PCIDevice), .init = unin_main_pci_host_init, }; static PCIDeviceInfo dec_21154_pci_host_info = { - .qdev.name = "DEC 21154", + .qdev.name = "dec-21154", .qdev.size = sizeof(PCIDevice), .init = dec_21154_pci_host_init, }; static PCIDeviceInfo unin_agp_pci_host_info = { - .qdev.name = "Uni-north AGP", + .qdev.name = "uni-north-AGP", .qdev.size = sizeof(PCIDevice), .init = unin_agp_pci_host_init, }; static PCIDeviceInfo unin_internal_pci_host_info = { - .qdev.name = "Uni-north internal", + .qdev.name = "uni-north-internal", .qdev.size = sizeof(PCIDevice), .init = unin_internal_pci_host_init, }; static void unin_register_devices(void) { - sysbus_register_dev("Uni-north main", sizeof(UNINState), + sysbus_register_dev("uni-north-main", sizeof(UNINState), pci_unin_main_init_device); pci_qdev_register(&unin_main_pci_host_info); - sysbus_register_dev("DEC 21154", sizeof(UNINState), + sysbus_register_dev("dec-21154", sizeof(UNINState), pci_dec_21154_init_device); pci_qdev_register(&dec_21154_pci_host_info); - sysbus_register_dev("Uni-north AGP", sizeof(UNINState), + sysbus_register_dev("uni-north-AGP", sizeof(UNINState), pci_unin_agp_init_device); pci_qdev_register(&unin_agp_pci_host_info); - sysbus_register_dev("Uni-north internal", sizeof(UNINState), + sysbus_register_dev("uni-north-internal", sizeof(UNINState), pci_unin_internal_init_device); pci_qdev_register(&unin_internal_pci_host_info); } diff --git a/hw/usb-bt.c b/hw/usb-bt.c index 07da1337e..56d1a6ce4 100644 --- a/hw/usb-bt.c +++ b/hw/usb-bt.c @@ -630,7 +630,7 @@ USBDevice *usb_bt_init(HCIInfo *hci) if (!hci) return NULL; - dev = usb_create_simple(NULL /* FIXME */, "QEMU BT dongle"); + dev = usb_create_simple(NULL /* FIXME */, "usb-bt-dongle"); s = DO_UPCAST(struct USBBtState, dev, dev); s->dev.opaque = s; @@ -646,7 +646,7 @@ USBDevice *usb_bt_init(HCIInfo *hci) static struct USBDeviceInfo bt_info = { .product_desc = "QEMU BT dongle", - .qdev.name = "QEMU BT dongle", + .qdev.name = "usb-bt-dongle", .qdev.size = sizeof(struct USBBtState), .init = usb_bt_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-bus.c b/hw/usb-bus.c index 8bbc80d6b..54027dfc4 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -153,7 +153,7 @@ int usb_device_attach(USBDevice *dev) if (bus->nfree == 1) { /* Create a new hub and chain it on. */ - hub = usb_create_simple(bus, "QEMU USB Hub"); + hub = usb_create_simple(bus, "usb-hub"); } do_attach(dev); return 0; diff --git a/hw/usb-hid.c b/hw/usb-hid.c index 33de302d6..6abb62993 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -881,8 +881,7 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) static struct USBDeviceInfo hid_info[] = { { .product_desc = "QEMU USB Tablet", - .qdev.name = "QEMU USB Tablet", - .qdev.alias = "usb-tablet", + .qdev.name = "usb-tablet", .usbdevice_name = "tablet", .qdev.size = sizeof(USBHIDState), .init = usb_tablet_initfn, @@ -893,8 +892,7 @@ static struct USBDeviceInfo hid_info[] = { .handle_destroy = usb_hid_handle_destroy, },{ .product_desc = "QEMU USB Mouse", - .qdev.name = "QEMU USB Mouse", - .qdev.alias = "usb-mouse", + .qdev.name = "usb-mouse", .usbdevice_name = "mouse", .qdev.size = sizeof(USBHIDState), .init = usb_mouse_initfn, @@ -905,8 +903,7 @@ static struct USBDeviceInfo hid_info[] = { .handle_destroy = usb_hid_handle_destroy, },{ .product_desc = "QEMU USB Keyboard", - .qdev.name = "QEMU USB Keyboard", - .qdev.alias = "usb-kbd", + .qdev.name = "usb-kbd", .usbdevice_name = "keyboard", .qdev.size = sizeof(USBHIDState), .init = usb_keyboard_initfn, diff --git a/hw/usb-hub.c b/hw/usb-hub.c index 32f2ab8c7..acf7f6072 100644 --- a/hw/usb-hub.c +++ b/hw/usb-hub.c @@ -545,7 +545,7 @@ static int usb_hub_initfn(USBDevice *dev) static struct USBDeviceInfo hub_info = { .product_desc = "QEMU USB Hub", - .qdev.name = "QEMU USB Hub", + .qdev.name = "usb-hub", .qdev.size = sizeof(USBHubState), .init = usb_hub_initfn, .handle_packet = usb_hub_handle_packet, diff --git a/hw/usb-msd.c b/hw/usb-msd.c index b9f6588a7..1fb62ad13 100644 --- a/hw/usb-msd.c +++ b/hw/usb-msd.c @@ -591,7 +591,7 @@ static USBDevice *usb_msd_init(const char *filename) } /* create guest device */ - dev = usb_create(NULL /* FIXME */, "QEMU USB MSD"); + dev = usb_create(NULL /* FIXME */, "usb-storage"); qdev_prop_set_drive(&dev->qdev, "drive", dinfo); if (qdev_init(&dev->qdev) < 0) return NULL; @@ -601,8 +601,7 @@ static USBDevice *usb_msd_init(const char *filename) static struct USBDeviceInfo msd_info = { .product_desc = "QEMU USB MSD", - .qdev.name = "QEMU USB MSD", - .qdev.alias = "usb-storage", + .qdev.name = "usb-storage", .qdev.size = sizeof(MSDState), .init = usb_msd_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-net.c b/hw/usb-net.c index 3dd05e370..122a0d849 100644 --- a/hw/usb-net.c +++ b/hw/usb-net.c @@ -1463,7 +1463,7 @@ USBDevice *usb_net_init(NICInfo *nd) USBDevice *dev; USBNetState *s; - dev = usb_create_simple(NULL /* FIXME */, "QEMU USB Network Interface"); + dev = usb_create_simple(NULL /* FIXME */, "usb-net"); s = DO_UPCAST(USBNetState, dev, dev); memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr)); @@ -1488,7 +1488,7 @@ USBDevice *usb_net_init(NICInfo *nd) static struct USBDeviceInfo net_info = { .product_desc = "QEMU USB Network Interface", - .qdev.name = "QEMU USB Network Interface", + .qdev.name = "usb-net", .qdev.size = sizeof(USBNetState), .init = usb_net_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 7ab3a9861..a8a014cb1 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1736,7 +1736,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) void usb_ohci_init_pci(struct PCIBus *bus, int devfn) { - pci_create_simple(bus, devfn, "OHCI USB PCI"); + pci_create_simple(bus, devfn, "pci-ohci"); } void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn, @@ -1762,8 +1762,7 @@ void usb_ohci_init_sm501(uint32_t mmio_base, uint32_t localmem_base, } static PCIDeviceInfo ohci_info = { - .qdev.name = "OHCI USB PCI", - .qdev.alias = "pci-ohci", + .qdev.name = "pci-ohci", .qdev.desc = "Apple USB Controller", .qdev.size = sizeof(OHCIPCIState), .init = usb_ohci_initfn_pci, diff --git a/hw/usb-serial.c b/hw/usb-serial.c index 14e410ed9..2775cf0f0 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -577,7 +577,7 @@ static USBDevice *usb_serial_init(const char *filename) if (!cdrv) return NULL; - dev = usb_create(NULL /* FIXME */, "QEMU USB Serial"); + dev = usb_create(NULL /* FIXME */, "usb-serial"); qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); if (vendorid) qdev_prop_set_uint16(&dev->qdev, "vendorid", vendorid); @@ -597,7 +597,7 @@ static USBDevice *usb_braille_init(const char *unused) if (!cdrv) return NULL; - dev = usb_create(NULL /* FIXME */, "QEMU USB Braille"); + dev = usb_create(NULL /* FIXME */, "usb-braille"); qdev_prop_set_chr(&dev->qdev, "chardev", cdrv); qdev_init(&dev->qdev); @@ -606,8 +606,7 @@ static USBDevice *usb_braille_init(const char *unused) static struct USBDeviceInfo serial_info = { .product_desc = "QEMU USB Serial", - .qdev.name = "QEMU USB Serial", - .qdev.alias = "usb-serial", + .qdev.name = "usb-serial", .qdev.size = sizeof(USBSerialState), .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, @@ -627,8 +626,7 @@ static struct USBDeviceInfo serial_info = { static struct USBDeviceInfo braille_info = { .product_desc = "QEMU USB Braille", - .qdev.name = "QEMU USB Braille", - .qdev.alias = "usb-braille", + .qdev.name = "usb-braille", .qdev.size = sizeof(USBSerialState), .init = usb_serial_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index ba26a4efc..dc52737ae 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -1111,12 +1111,12 @@ static int usb_uhci_piix4_initfn(PCIDevice *dev) static PCIDeviceInfo uhci_info[] = { { - .qdev.name = "PIIX3 USB-UHCI", + .qdev.name = "piix3-usb-uhci", .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_piix3_initfn, },{ - .qdev.name = "PIIX4 USB-UHCI", + .qdev.name = "piix4-usb-uhci", .qdev.size = sizeof(UHCIState), .qdev.vmsd = &vmstate_uhci, .init = usb_uhci_piix4_initfn, @@ -1133,10 +1133,10 @@ device_init(uhci_register); void usb_uhci_piix3_init(PCIBus *bus, int devfn) { - pci_create_simple(bus, devfn, "PIIX3 USB-UHCI"); + pci_create_simple(bus, devfn, "piix3-usb-uhci"); } void usb_uhci_piix4_init(PCIBus *bus, int devfn) { - pci_create_simple(bus, devfn, "PIIX4 USB-UHCI"); + pci_create_simple(bus, devfn, "piix4-usb-uhci"); } diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c index b10864fe9..fe052eb75 100644 --- a/hw/usb-wacom.c +++ b/hw/usb-wacom.c @@ -410,8 +410,8 @@ static int usb_wacom_initfn(USBDevice *dev) static struct USBDeviceInfo wacom_info = { .product_desc = "QEMU PenPartner Tablet", - .qdev.name = "QEMU PenPartner Tablet", - .qdev.alias = "wacom-tablet", + .qdev.name = "usb-wacom-tablet", + .qdev.desc = "QEMU PenPartner Tablet", .usbdevice_name = "wacom-tablet", .qdev.size = sizeof(USBWacomState), .init = usb_wacom_initfn, diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index a7e42c6e1..f3e3749e9 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -1196,11 +1196,11 @@ static int pci_vmsvga_initfn(PCIDevice *dev) void pci_vmsvga_init(PCIBus *bus) { - pci_create_simple(bus, -1, "QEMUware SVGA"); + pci_create_simple(bus, -1, "vmware-svga"); } static PCIDeviceInfo vmsvga_info = { - .qdev.name = "QEMUware SVGA", + .qdev.name = "vmware-svga", .qdev.size = sizeof(struct pci_vmsvga_state_s), .qdev.vmsd = &vmstate_vmware_vga, .init = pci_vmsvga_initfn, diff --git a/usb-bsd.c b/usb-bsd.c index e72d123f9..48567a3ba 100644 --- a/usb-bsd.c +++ b/usb-bsd.c @@ -361,7 +361,7 @@ USBDevice *usb_host_device_open(const char *devname) goto fail; } - d = usb_create(NULL /* FIXME */, "USB Host Device"); + d = usb_create(NULL /* FIXME */, "usb-host"); dev = DO_UPCAST(USBHostDevice, dev, d); if (dev_info.udi_speed == 1) @@ -394,7 +394,7 @@ fail: static struct USBDeviceInfo usb_host_dev_info = { .product_desc = "USB Host Device", - .qdev.name = "USB Host Device", + .qdev.name = "usb-host", .qdev.size = sizeof(USBHostDevice), .init = usb_host_initfn, .handle_packet = usb_generic_handle_packet, diff --git a/usb-linux.c b/usb-linux.c index 0004e969b..105ce88f3 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -980,8 +980,7 @@ static int usb_host_initfn(USBDevice *dev) static struct USBDeviceInfo usb_host_dev_info = { .product_desc = "USB Host Device", - .qdev.name = "USB Host Device", - .qdev.alias = "usb-host", + .qdev.name = "usb-host", .qdev.size = sizeof(USBHostDevice), .init = usb_host_initfn, .handle_packet = usb_host_handle_packet, @@ -1011,7 +1010,7 @@ USBDevice *usb_host_device_open(const char *devname) USBHostDevice *s; char *p; - dev = usb_create(NULL /* FIXME */, "USB Host Device"); + dev = usb_create(NULL /* FIXME */, "usb-host"); s = DO_UPCAST(USBHostDevice, dev, dev); if (strstr(devname, "auto:")) { -- cgit v1.2.3 From 08b2d3ba9ac77369a49df987c9ecd9ac2e171ca8 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Tue, 8 Dec 2009 13:33:54 +0100 Subject: Fix recently added QERR_ definitions Commits c7c338c4, 41471a23, 7a046f5f and a488be27 used lower_case_with_underscores for class values. Existing usage CamelCase. ChangeToThatForConsistency. Signed-off-by: Markus Armbruster Signed-off-by: Anthony Liguori (cherry picked from commit bd9d30640c3c2489175fd9ddd5459c69f94688f8) --- qerror.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qerror.h b/qerror.h index 09e32b9a3..9e220d6b4 100644 --- a/qerror.h +++ b/qerror.h @@ -59,16 +59,16 @@ QError *qobject_to_qerror(const QObject *obj); "{ 'class': 'DeviceNotRemovable', 'data': { 'device': %s } }" #define QERR_FD_NOT_FOUND \ - "{ 'class': 'fd_not_found', 'data': { 'name': %s } }" + "{ 'class': 'FdNotFound', 'data': { 'name': %s } }" #define QERR_FD_NOT_SUPPLIED \ - "{ 'class': 'fd_not_supplied', 'data': {} }" + "{ 'class': 'FdNotSupplied', 'data': {} }" #define QERR_INVALID_BLOCK_FORMAT \ "{ 'class': 'InvalidBlockFormat', 'data': { 'name': %s } }" #define QERR_INVALID_PARAMETER \ - "{ 'class': 'invalid_parameter', 'data': { 'name': %s } }" + "{ 'class': 'InvalidParameter', 'data': { 'name': %s } }" #define QERR_INVALID_PARAMETER_TYPE \ "{ 'class': 'InvalidParameterType', 'data': { 'name': %s,'expected': %s } }" @@ -95,7 +95,7 @@ QError *qobject_to_qerror(const QObject *obj); "{ 'class': 'UndefinedError', 'data': {} }" #define QERR_TOO_MANY_FILES \ - "{ 'class': 'fd_too_many_files', 'data': {} }" + "{ 'class': 'TooManyFiles', 'data': {} }" #define QERR_VNC_SERVER_FAILED \ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" -- cgit v1.2.3 From ebbc8a3d8e76d0402f8a08c10c0f32e24715d41d Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Tue, 8 Dec 2009 17:54:55 +0100 Subject: kvm: x86: Save/restore exception_index As KVM now makes use of exception_index to keep pending exceptions, we have to save&restore this field as well. NOTE: We have to nail the arch-independent exception_index down to a certain bit width for proper vmstate processing, namely to 32 bit. Signed-off-by: Jan Kiszka Signed-off-by: Anthony Liguori (cherry picked from commit 4d6e3ac5d411c461d0fb4b1cd2ace854963c9e30) --- cpu-defs.h | 2 +- target-i386/machine.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cpu-defs.h b/cpu-defs.h index 95068b530..51dc436b4 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -179,7 +179,7 @@ typedef struct CPUWatchpoint { \ /* Core interrupt code */ \ jmp_buf jmp_env; \ - int exception_index; \ + int32_t exception_index; \ \ CPUState *next_cpu; /* next CPU sharing TB cache */ \ int cpu_index; /* CPU index (informative) */ \ diff --git a/target-i386/machine.c b/target-i386/machine.c index cdc8898a6..ab4633e65 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -453,6 +453,7 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_UINT8_V(nmi_pending, CPUState, 11), VMSTATE_UINT8_V(has_error_code, CPUState, 11), VMSTATE_UINT32_V(sipi_vector, CPUState, 11), + VMSTATE_INT32_V(exception_index, CPUState, 11), /* MCE */ VMSTATE_UINT64_V(mcg_cap, CPUState, 10), VMSTATE_UINT64_V(mcg_status, CPUState, 10), -- cgit v1.2.3 From a63e5f1971c8b24142109929dab75a697a5dfb8c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:33 +0100 Subject: qdev: make compat stuff more generic This patch renames the compat properties into global properties and makes them more generic. The compatibility stuff is only one of multiple possible users now. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 458fb6792d834474c6b289738b6bf9601fad87ab) --- hw/boards.h | 2 +- hw/pc.c | 2 +- hw/qdev-properties.c | 22 ++++++++++++++-------- hw/qdev.c | 2 +- hw/qdev.h | 10 ++++++---- vl.c | 2 +- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/hw/boards.h b/hw/boards.h index d8893413d..7a0f20f63 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -20,7 +20,7 @@ typedef struct QEMUMachine { int use_scsi; int max_cpus; int is_default; - CompatProperty *compat_props; + GlobalProperty *compat_props; struct QEMUMachine *next; } QEMUMachine; diff --git a/hw/pc.c b/hw/pc.c index 8c1b7ea57..147a9a702 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -1298,7 +1298,7 @@ static QEMUMachine pc_machine_v0_10 = { .desc = "Standard PC, qemu 0.10", .init = pc_init_pci, .max_cpus = 255, - .compat_props = (CompatProperty[]) { + .compat_props = (GlobalProperty[]) { { .driver = "virtio-blk-pci", .property = "class", diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index bda669938..fe106bd6a 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -593,21 +593,27 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props) } } -static CompatProperty *compat_props; +static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props); -void qdev_prop_register_compat(CompatProperty *props) +void qdev_prop_register_global(GlobalProperty *prop) { - compat_props = props; + QTAILQ_INSERT_TAIL(&global_props, prop, next); } -void qdev_prop_set_compat(DeviceState *dev) +void qdev_prop_register_global_list(GlobalProperty *props) { - CompatProperty *prop; + int i; - if (!compat_props) { - return; + for (i = 0; props[i].driver != NULL; i++) { + qdev_prop_register_global(props+i); } - for (prop = compat_props; prop->driver != NULL; prop++) { +} + +void qdev_prop_set_globals(DeviceState *dev) +{ + GlobalProperty *prop; + + QTAILQ_FOREACH(prop, &global_props, next) { if (strcmp(dev->info->name, prop->driver) != 0) { continue; } diff --git a/hw/qdev.c b/hw/qdev.c index 13c9fe236..b6bd4aeab 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -103,7 +103,7 @@ DeviceState *qdev_create(BusState *bus, const char *name) dev->parent_bus = bus; qdev_prop_set_defaults(dev, dev->info->props); qdev_prop_set_defaults(dev, dev->parent_bus->info->props); - qdev_prop_set_compat(dev); + qdev_prop_set_globals(dev); QLIST_INSERT_HEAD(&bus->children, dev, sibling); if (qdev_hotplug) { assert(bus->allow_hotplug); diff --git a/hw/qdev.h b/hw/qdev.h index 8d53754d4..bbcdba185 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -92,11 +92,12 @@ struct PropertyInfo { int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len); }; -struct CompatProperty { +typedef struct GlobalProperty { const char *driver; const char *property; const char *value; -}; + QTAILQ_ENTRY(GlobalProperty) next; +} GlobalProperty; /*** Board API. This should go away once we have a machine config file. ***/ @@ -256,8 +257,9 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value); void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value); void qdev_prop_set_defaults(DeviceState *dev, Property *props); -void qdev_prop_register_compat(CompatProperty *props); -void qdev_prop_set_compat(DeviceState *dev); +void qdev_prop_register_global(GlobalProperty *prop); +void qdev_prop_register_global_list(GlobalProperty *props); +void qdev_prop_set_globals(DeviceState *dev); /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ extern struct BusInfo system_bus_info; diff --git a/vl.c b/vl.c index 09a0ec5cb..a242a11c4 100644 --- a/vl.c +++ b/vl.c @@ -5779,7 +5779,7 @@ int main(int argc, char **argv, char **envp) } if (machine->compat_props) { - qdev_prop_register_compat(machine->compat_props); + qdev_prop_register_global_list(machine->compat_props); } machine->init(ram_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model); -- cgit v1.2.3 From f49d2561cb1028f083a37119787366c382d9fa9f Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:34 +0100 Subject: qdev: add command line option to set global defaults for properties. This patch adds infrastructure and command line option for setting global defaults for device properties, i.e. you can for example use -global virtio-blk-pci.vectors=0 to turn off msi by default for all virtio block devices. The config file syntax is: [global] driver = "virtio-blk-pci" property = "vectors" value = "0" This can also be used to set properties for devices which are not created via -device but implicitly via machine init, i.e. -global isa-fdc,driveA= This patch uses the mechanism which configures properties for the compatibility machine types (pc-0.10 & friends). The command line takes precedence over the machine type values. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit d0fef6fbea36c62d29f3e3fa2214b7b52322983e) --- qemu-config.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qemu-config.h | 2 ++ qemu-options.hx | 3 +++ vl.c | 6 ++++++ 4 files changed, 67 insertions(+) diff --git a/qemu-config.c b/qemu-config.c index 92b5363ec..a23b1256e 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -2,6 +2,7 @@ #include "qemu-option.h" #include "qemu-config.h" #include "sysemu.h" +#include "hw/qdev.h" QemuOptsList qemu_drive_opts = { .name = "drive", @@ -205,6 +206,24 @@ QemuOptsList qemu_rtc_opts = { }, }; +QemuOptsList qemu_global_opts = { + .name = "global", + .head = QTAILQ_HEAD_INITIALIZER(qemu_global_opts.head), + .desc = { + { + .name = "driver", + .type = QEMU_OPT_STRING, + },{ + .name = "property", + .type = QEMU_OPT_STRING, + },{ + .name = "value", + .type = QEMU_OPT_STRING, + }, + { /* end if list */ } + }, +}; + static QemuOptsList *lists[] = { &qemu_drive_opts, &qemu_chardev_opts, @@ -212,6 +231,7 @@ static QemuOptsList *lists[] = { &qemu_netdev_opts, &qemu_net_opts, &qemu_rtc_opts, + &qemu_global_opts, NULL, }; @@ -260,6 +280,42 @@ int qemu_set_option(const char *str) return 0; } +int qemu_global_option(const char *str) +{ + char driver[64], property[64]; + QemuOpts *opts; + int rc, offset; + + rc = sscanf(str, "%63[^.].%63[^=]%n", driver, property, &offset); + if (rc < 2 || str[offset] != '=') { + qemu_error("can't parse: \"%s\"\n", str); + return -1; + } + + opts = qemu_opts_create(&qemu_global_opts, NULL, 0); + qemu_opt_set(opts, "driver", driver); + qemu_opt_set(opts, "property", property); + qemu_opt_set(opts, "value", str+offset+1); + return 0; +} + +static int qemu_add_one_global(QemuOpts *opts, void *opaque) +{ + GlobalProperty *g; + + g = qemu_mallocz(sizeof(*g)); + g->driver = qemu_opt_get(opts, "driver"); + g->property = qemu_opt_get(opts, "property"); + g->value = qemu_opt_get(opts, "value"); + qdev_prop_register_global(g); + return 0; +} + +void qemu_add_globals(void) +{ + qemu_opts_foreach(&qemu_global_opts, qemu_add_one_global, NULL, 0); +} + struct ConfigWriteData { QemuOptsList *list; FILE *fp; diff --git a/qemu-config.h b/qemu-config.h index b56485165..6246e76fc 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -9,6 +9,8 @@ extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_rtc_opts; int qemu_set_option(const char *str); +int qemu_global_option(const char *str); +void qemu_add_globals(void); void qemu_config_write(FILE *fp); int qemu_config_parse(FILE *fp); diff --git a/qemu-options.hx b/qemu-options.hx index 1b5781a10..b6f307599 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -109,6 +109,9 @@ DEF("set", HAS_ARG, QEMU_OPTION_set, "-set group.id.arg=value\n" " set parameter for item of type \n" " i.e. -set drive.$id.file=/path/to/image\n") +DEF("global", HAS_ARG, QEMU_OPTION_global, + "-global driver.property=value\n" + " set a global default for a driver property\n") STEXI @item -drive @var{option}[,@var{option}[,@var{option}[,...]]] diff --git a/vl.c b/vl.c index a242a11c4..f7acdd42c 100644 --- a/vl.c +++ b/vl.c @@ -4851,6 +4851,10 @@ int main(int argc, char **argv, char **envp) if (qemu_set_option(optarg) != 0) exit(1); break; + case QEMU_OPTION_global: + if (qemu_global_option(optarg) != 0) + exit(1); + break; case QEMU_OPTION_mtdblock: drive_add(optarg, MTD_ALIAS); break; @@ -5781,6 +5785,8 @@ int main(int argc, char **argv, char **envp) if (machine->compat_props) { qdev_prop_register_global_list(machine->compat_props); } + qemu_add_globals(); + machine->init(ram_size, boot_devices, kernel_filename, kernel_cmdline, initrd_filename, cpu_model); -- cgit v1.2.3 From 7058b807cd43b639d9ac1058959dc83f5ce54f4f Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:35 +0100 Subject: qdev: also match bus name for global properties i.e. -global PCI.= will set a default property for all PCI devices. Also works for the compat properties used by machine types. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 07a8de3566bd576dc33e55af830d63dcc2287617) --- hw/qdev-properties.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index fe106bd6a..fb07279ba 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -614,7 +614,8 @@ void qdev_prop_set_globals(DeviceState *dev) GlobalProperty *prop; QTAILQ_FOREACH(prop, &global_props, next) { - if (strcmp(dev->info->name, prop->driver) != 0) { + if (strcmp(dev->info->name, prop->driver) != 0 && + strcmp(dev->info->bus_info->name, prop->driver) != 0) { continue; } if (qdev_prop_parse(dev, prop->property, prop->value) != 0) { -- cgit v1.2.3 From d1d6963ebaf7b934e36d4ddd9c13f8afddb67268 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:36 +0100 Subject: chardev: make chardevs specified in config file work. The patch decuples the -chardev switch and the actual chardev initialization. Without this patch qemu ignores chardev entries coming via -readconfig. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 1a688d3bbc2a44bfefa3f6774a11b0385dafc029) --- vl.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/vl.c b/vl.c index f7acdd42c..aa678ad38 100644 --- a/vl.c +++ b/vl.c @@ -4586,6 +4586,16 @@ static int device_init_func(QemuOpts *opts, void *opaque) return 0; } +static int chardev_init_func(QemuOpts *opts, void *opaque) +{ + CharDriverState *chr; + + chr = qemu_chr_open_opts(opts, NULL); + if (!chr) + return -1; + return 0; +} + struct device_config { enum { DEV_USB, /* -usbdevice */ @@ -5180,9 +5190,6 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "parse error: %s\n", optarg); exit(1); } - if (qemu_chr_open_opts(opts, NULL) == NULL) { - exit(1); - } break; case QEMU_OPTION_serial: if (serial_device_index >= MAX_SERIAL_PORTS) { @@ -5501,6 +5508,9 @@ int main(int argc, char **argv, char **envp) } } + if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) + exit(1); + #ifndef _WIN32 if (daemonize) { pid_t pid; -- cgit v1.2.3 From 542d991b4c395f5e76e05cc257fba2b7999b1210 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:37 +0100 Subject: Revert "monitor: Command-line flag to enable control mode" This reverts commit adcb181afe5a951c521411c7a8e9d9b791aa6742. Conflicts: monitor.h Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 4e307fc883b39c89ffc093c79eb9c9735724d227) --- monitor.c | 18 ------------------ monitor.h | 1 - qemu-options.hx | 5 ++--- vl.c | 11 ++++------- 4 files changed, 6 insertions(+), 29 deletions(-) diff --git a/monitor.c b/monitor.c index a38a103e4..8a1be393a 100644 --- a/monitor.c +++ b/monitor.c @@ -4038,24 +4038,6 @@ static void monitor_event(void *opaque, int event) * End: */ -const char *monitor_cmdline_parse(const char *cmdline, int *flags) -{ - const char *dev; - - if (strstart(cmdline, "control,", &dev)) { - if (strstart(dev, "vc", NULL)) { - fprintf(stderr, "qemu: control mode is for low-level interaction "); - fprintf(stderr, "cannot be used with device 'vc'\n"); - exit(1); - } - *flags &= ~MONITOR_USE_READLINE; - *flags |= MONITOR_USE_CONTROL; - return dev; - } - - return cmdline; -} - void monitor_init(CharDriverState *chr, int flags) { static int is_first_init = 1; diff --git a/monitor.h b/monitor.h index 38cc2238a..6ed117a92 100644 --- a/monitor.h +++ b/monitor.h @@ -24,7 +24,6 @@ typedef enum MonitorEvent { } MonitorEvent; void monitor_protocol_event(MonitorEvent event, QObject *data); -const char *monitor_cmdline_parse(const char *cmdline, int *flags); void monitor_init(CharDriverState *chr, int flags); int monitor_suspend(Monitor *mon); diff --git a/qemu-options.hx b/qemu-options.hx index b6f307599..420b7d847 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1580,14 +1580,13 @@ Use @code{-parallel none} to disable all parallel ports. ETEXI DEF("monitor", HAS_ARG, QEMU_OPTION_monitor, \ - "-monitor [control,]dev redirect the monitor to char device 'dev'\n") + "-monitor dev redirect the monitor to char device 'dev'\n") STEXI -@item -monitor [@var{control},]@var{dev} +@item -monitor @var{dev} Redirect the monitor to host device @var{dev} (same devices as the serial port). The default device is @code{vc} in graphical mode and @code{stdio} in non graphical mode. -The option @var{control} enables the QEMU Monitor Protocol. ETEXI DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \ diff --git a/vl.c b/vl.c index aa678ad38..11eda45ea 100644 --- a/vl.c +++ b/vl.c @@ -4648,7 +4648,6 @@ int main(int argc, char **argv, char **envp) const char *r, *optarg; CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; const char *monitor_devices[MAX_MONITOR_DEVICES]; - int monitor_flags[MAX_MONITOR_DEVICES]; int monitor_device_index; const char *serial_devices[MAX_SERIAL_PORTS]; int serial_device_index; @@ -4751,10 +4750,8 @@ int main(int argc, char **argv, char **envp) #endif monitor_devices[0] = "vc:80Cx24C"; - monitor_flags[0] = MONITOR_IS_DEFAULT | MONITOR_USE_READLINE; for (i = 1; i < MAX_MONITOR_DEVICES; i++) { monitor_devices[i] = NULL; - monitor_flags[i] = MONITOR_USE_READLINE; } monitor_device_index = 0; @@ -5179,9 +5176,7 @@ int main(int argc, char **argv, char **envp) fprintf(stderr, "qemu: too many monitor devices\n"); exit(1); } - monitor_devices[monitor_device_index] = - monitor_cmdline_parse(optarg, - &monitor_flags[monitor_device_index]); + monitor_devices[monitor_device_index] = optarg; monitor_device_index++; break; case QEMU_OPTION_chardev: @@ -5891,7 +5886,9 @@ int main(int argc, char **argv, char **envp) for (i = 0; i < MAX_MONITOR_DEVICES; i++) { if (monitor_devices[i] && monitor_hds[i]) { - monitor_init(monitor_hds[i], monitor_flags[i]); + monitor_init(monitor_hds[i], + MONITOR_USE_READLINE | + ((i == 0) ? MONITOR_IS_DEFAULT : 0)); } } -- cgit v1.2.3 From f9800fe5a0a650d681b71e85645f8d08f6362f63 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:38 +0100 Subject: Revert "Set default console to virtio on S390x" This reverts commit 93d434b4aec0702b87ebf52449a3cdf2c3596825. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 014100bb73d8512fb3d62f5cb123bfb2d04f3089) --- vl.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/vl.c b/vl.c index 11eda45ea..172828afa 100644 --- a/vl.c +++ b/vl.c @@ -4720,20 +4720,6 @@ int main(int argc, char **argv, char **envp) cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; -#ifdef TARGET_S390X - for(i = 0; i < MAX_SERIAL_PORTS; i++) - serial_devices[i] = NULL; - serial_device_index = 0; - - for(i = 0; i < MAX_PARALLEL_PORTS; i++) - parallel_devices[i] = NULL; - parallel_device_index = 0; - - virtio_consoles[0] = "mon:stdio"; - for(i = 1; i < MAX_VIRTIO_CONSOLES; i++) - virtio_consoles[i] = NULL; - virtio_console_index = 0; -#else serial_devices[0] = "vc:80Cx24C"; for(i = 1; i < MAX_SERIAL_PORTS; i++) serial_devices[i] = NULL; @@ -4747,7 +4733,6 @@ int main(int argc, char **argv, char **envp) for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) virtio_consoles[i] = NULL; virtio_console_index = 0; -#endif monitor_devices[0] = "vc:80Cx24C"; for (i = 1; i < MAX_MONITOR_DEVICES; i++) { @@ -5664,17 +5649,6 @@ int main(int argc, char **argv, char **envp) break; } } - for (i = 0; i < MAX_VIRTIO_CONSOLES; i++) { - const char *devname = virtio_consoles[i]; - if (devname && !strcmp(devname,"mon:stdio")) { - monitor_devices[0] = NULL; - break; - } else if (devname && !strcmp(devname,"stdio")) { - monitor_devices[0] = NULL; - virtio_consoles[i] = "mon:stdio"; - break; - } - } } if (nb_numa_nodes > 0) { -- cgit v1.2.3 From 25d82d331113e8797199f960ce823089c1dbf829 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:39 +0100 Subject: chardev: move greeting into vc backend. Make the 'vc' chardev backend print a title line with the chardev name after initialization, using CharDriverState->label. This replaces the banner printing code in vl.c. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 51bfa4d3160fe1d5c2eca381020b8b6dd69c3c80) --- console.c | 8 ++++++++ vl.c | 24 ------------------------ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/console.c b/console.c index 82ddbe4d9..2aeb5b33c 100644 --- a/console.c +++ b/console.c @@ -1384,6 +1384,14 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpt s->t_attrib = s->t_attrib_default; text_console_resize(s); + if (chr->label) { + char msg[128]; + int len; + + len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); + console_puts(chr, (uint8_t*)msg, len); + } + qemu_chr_generic_open(chr); if (chr->init) chr->init(chr); diff --git a/vl.c b/vl.c index 172828afa..333780f38 100644 --- a/vl.c +++ b/vl.c @@ -5866,30 +5866,6 @@ int main(int argc, char **argv, char **envp) } } - for(i = 0; i < MAX_SERIAL_PORTS; i++) { - const char *devname = serial_devices[i]; - if (devname && strcmp(devname, "none")) { - if (strstart(devname, "vc", 0)) - qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i); - } - } - - for(i = 0; i < MAX_PARALLEL_PORTS; i++) { - const char *devname = parallel_devices[i]; - if (devname && strcmp(devname, "none")) { - if (strstart(devname, "vc", 0)) - qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i); - } - } - - for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { - const char *devname = virtio_consoles[i]; - if (virtcon_hds[i] && devname) { - if (strstart(devname, "vc", 0)) - qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i); - } - } - if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) { fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n", gdbstub_dev); -- cgit v1.2.3 From 6ac733bf09daf1ed07af632018944264cedeb3df Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:40 +0100 Subject: vc: colorize chardev title line with blue background. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 735ba5884943ad91be660b59092ab7592c4bde07) --- console.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/console.c b/console.c index 2aeb5b33c..8086bd6f2 100644 --- a/console.c +++ b/console.c @@ -1388,8 +1388,10 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds, QemuOpt char msg[128]; int len; + s->t_attrib.bgcol = COLOR_BLUE; len = snprintf(msg, sizeof(msg), "%s console\r\n", chr->label); console_puts(chr, (uint8_t*)msg, len); + s->t_attrib = s->t_attrib_default; } qemu_chr_generic_open(chr); -- cgit v1.2.3 From 96639424e262051f08c191f5933d02786d3f1d5c Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:41 +0100 Subject: default devices: core code & serial lines. Qemu creates a default serial line for you in case you didn't specify one on the command line. Right now this is tied to the '-serial ' command line switch, which in turn causes trouble if you are creating your serial line via '-device isa-serial,'. This patch adds a variable default_serial which says whenever a default serial line should be added. It is enabled by default. It is cleared when qemu finds '-serial' or '-device isa-serial' on the command line. Part of the patch is some infrastructure for the '-device $driver' checking (default_driver_check function) which will also be used by the other patches of this series. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 998bbd74b9d813b14a3a3b5009a5d5a48c7dce51) --- vl.c | 122 ++++++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 41 deletions(-) diff --git a/vl.c b/vl.c index 333780f38..ef9e48041 100644 --- a/vl.c +++ b/vl.c @@ -271,6 +271,30 @@ uint8_t qemu_uuid[16]; static QEMUBootSetHandler *boot_set_handler; static void *boot_set_opaque; +static int default_serial = 1; + +static struct { + const char *driver; + int *flag; +} default_list[] = { + { .driver = "isa-serial", .flag = &default_serial }, +}; + +static int default_driver_check(QemuOpts *opts, void *opaque) +{ + const char *driver = qemu_opt_get(opts, "driver"); + int i; + + if (!driver) + return 0; + for (i = 0; i < ARRAY_SIZE(default_list); i++) { + if (strcmp(default_list[i].driver, driver) != 0) + continue; + *(default_list[i].flag) = 0; + } + return 0; +} + /***********************************************************/ /* x86 ISA bus support */ @@ -4600,6 +4624,7 @@ struct device_config { enum { DEV_USB, /* -usbdevice */ DEV_BT, /* -bt */ + DEV_SERIAL, /* -serial */ } type; const char *cmdline; QTAILQ_ENTRY(device_config) next; @@ -4631,6 +4656,50 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline)) return 0; } +static void serial_monitor_mux(const char *monitor_devices[]) +{ + struct device_config *serial; + const char *devname; + + if (strcmp(monitor_devices[0],"stdio") != 0) + return; + QTAILQ_FOREACH(serial, &device_configs, next) { + if (serial->type != DEV_SERIAL) + continue; + devname = serial->cmdline; + if (devname && !strcmp(devname,"mon:stdio")) { + monitor_devices[0] = NULL; + break; + } else if (devname && !strcmp(devname,"stdio")) { + monitor_devices[0] = NULL; + serial->cmdline = "mon:stdio"; + break; + } + } +} + +static int serial_parse(const char *devname) +{ + static int index = 0; + char label[32]; + + if (strcmp(devname, "none") == 0) + return 0; + if (index == MAX_SERIAL_PORTS) { + fprintf(stderr, "qemu: too many serial ports\n"); + exit(1); + } + snprintf(label, sizeof(label), "serial%d", index); + serial_hds[index] = qemu_chr_open(label, devname, NULL); + if (!serial_hds[index]) { + fprintf(stderr, "qemu: could not open serial device '%s': %s\n", + devname, strerror(errno)); + return -1; + } + index++; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4649,8 +4718,6 @@ int main(int argc, char **argv, char **envp) CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; const char *monitor_devices[MAX_MONITOR_DEVICES]; int monitor_device_index; - const char *serial_devices[MAX_SERIAL_PORTS]; - int serial_device_index; const char *parallel_devices[MAX_PARALLEL_PORTS]; int parallel_device_index; const char *virtio_consoles[MAX_VIRTIO_CONSOLES]; @@ -4720,11 +4787,6 @@ int main(int argc, char **argv, char **envp) cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; - serial_devices[0] = "vc:80Cx24C"; - for(i = 1; i < MAX_SERIAL_PORTS; i++) - serial_devices[i] = NULL; - serial_device_index = 0; - parallel_devices[0] = "vc:80Cx24C"; for(i = 1; i < MAX_PARALLEL_PORTS; i++) parallel_devices[i] = NULL; @@ -5172,12 +5234,8 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_serial: - if (serial_device_index >= MAX_SERIAL_PORTS) { - fprintf(stderr, "qemu: too many serial ports\n"); - exit(1); - } - serial_devices[serial_device_index] = optarg; - serial_device_index++; + add_device_config(DEV_SERIAL, optarg); + default_serial = 0; break; case QEMU_OPTION_watchdog: if (watchdog) { @@ -5478,14 +5536,19 @@ int main(int argc, char **argv, char **envp) exit(1); } + qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0); + if (display_type == DT_NOGRAPHIC) { - if (serial_device_index == 0) - serial_devices[0] = "stdio"; + if (default_serial) + add_device_config(DEV_SERIAL, "stdio"); if (parallel_device_index == 0) parallel_devices[0] = "null"; if (strncmp(monitor_devices[0], "vc", 2) == 0) { monitor_devices[0] = "stdio"; } + } else { + if (default_serial) + add_device_config(DEV_SERIAL, "vc:80Cx24C"); } if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) @@ -5637,19 +5700,7 @@ int main(int argc, char **argv, char **envp) ram_load, NULL); /* Maintain compatibility with multiple stdio monitors */ - if (!strcmp(monitor_devices[0],"stdio")) { - for (i = 0; i < MAX_SERIAL_PORTS; i++) { - const char *devname = serial_devices[i]; - if (devname && !strcmp(devname,"mon:stdio")) { - monitor_devices[0] = NULL; - break; - } else if (devname && !strcmp(devname,"stdio")) { - monitor_devices[0] = NULL; - serial_devices[i] = "mon:stdio"; - break; - } - } - } + serial_monitor_mux(monitor_devices); if (nb_numa_nodes > 0) { int i; @@ -5711,19 +5762,8 @@ int main(int argc, char **argv, char **envp) } } - for(i = 0; i < MAX_SERIAL_PORTS; i++) { - const char *devname = serial_devices[i]; - if (devname && strcmp(devname, "none")) { - char label[32]; - snprintf(label, sizeof(label), "serial%d", i); - serial_hds[i] = qemu_chr_open(label, devname, NULL); - if (!serial_hds[i]) { - fprintf(stderr, "qemu: could not open serial device '%s': %s\n", - devname, strerror(errno)); - exit(1); - } - } - } + if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) + exit(1); for(i = 0; i < MAX_PARALLEL_PORTS; i++) { const char *devname = parallel_devices[i]; -- cgit v1.2.3 From 4986fd41115f7045431c9bb6de70ea86b9e15092 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:42 +0100 Subject: default devices: parallel port. Qemu creates a default parallel port for you in case you didn't specify one on the command line. Right now this is tied to the '-parallel ' command line switch, which in turn causes trouble if you are creating your parallel port via '-device isa-parallel,'. This patch adds a variable default_parallel which says whenever a default parallel port should be added. It is enabled by default. It is cleared when qemu finds '-parallel' or '-device isa-parallel' on the command line. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 6a5e8b0e310c483d8d14553a2b7b601d39ed8b75) --- vl.c | 64 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/vl.c b/vl.c index ef9e48041..b10cdf812 100644 --- a/vl.c +++ b/vl.c @@ -272,12 +272,14 @@ static QEMUBootSetHandler *boot_set_handler; static void *boot_set_opaque; static int default_serial = 1; +static int default_parallel = 1; static struct { const char *driver; int *flag; } default_list[] = { - { .driver = "isa-serial", .flag = &default_serial }, + { .driver = "isa-serial", .flag = &default_serial }, + { .driver = "isa-parallel", .flag = &default_parallel }, }; static int default_driver_check(QemuOpts *opts, void *opaque) @@ -4625,6 +4627,7 @@ struct device_config { DEV_USB, /* -usbdevice */ DEV_BT, /* -bt */ DEV_SERIAL, /* -serial */ + DEV_PARALLEL, /* -parallel */ } type; const char *cmdline; QTAILQ_ENTRY(device_config) next; @@ -4700,6 +4703,28 @@ static int serial_parse(const char *devname) return 0; } +static int parallel_parse(const char *devname) +{ + static int index = 0; + char label[32]; + + if (strcmp(devname, "none") == 0) + return 0; + if (index == MAX_PARALLEL_PORTS) { + fprintf(stderr, "qemu: too many parallel ports\n"); + exit(1); + } + snprintf(label, sizeof(label), "parallel%d", index); + parallel_hds[index] = qemu_chr_open(label, devname, NULL); + if (!parallel_hds[index]) { + fprintf(stderr, "qemu: could not open parallel device '%s': %s\n", + devname, strerror(errno)); + return -1; + } + index++; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4718,8 +4743,6 @@ int main(int argc, char **argv, char **envp) CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; const char *monitor_devices[MAX_MONITOR_DEVICES]; int monitor_device_index; - const char *parallel_devices[MAX_PARALLEL_PORTS]; - int parallel_device_index; const char *virtio_consoles[MAX_VIRTIO_CONSOLES]; int virtio_console_index; const char *loadvm = NULL; @@ -4787,11 +4810,6 @@ int main(int argc, char **argv, char **envp) cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; - parallel_devices[0] = "vc:80Cx24C"; - for(i = 1; i < MAX_PARALLEL_PORTS; i++) - parallel_devices[i] = NULL; - parallel_device_index = 0; - for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) virtio_consoles[i] = NULL; virtio_console_index = 0; @@ -5260,12 +5278,8 @@ int main(int argc, char **argv, char **envp) virtio_console_index++; break; case QEMU_OPTION_parallel: - if (parallel_device_index >= MAX_PARALLEL_PORTS) { - fprintf(stderr, "qemu: too many parallel ports\n"); - exit(1); - } - parallel_devices[parallel_device_index] = optarg; - parallel_device_index++; + add_device_config(DEV_PARALLEL, optarg); + default_parallel = 0; break; case QEMU_OPTION_loadvm: loadvm = optarg; @@ -5541,14 +5555,16 @@ int main(int argc, char **argv, char **envp) if (display_type == DT_NOGRAPHIC) { if (default_serial) add_device_config(DEV_SERIAL, "stdio"); - if (parallel_device_index == 0) - parallel_devices[0] = "null"; + if (default_parallel) + add_device_config(DEV_PARALLEL, "null"); if (strncmp(monitor_devices[0], "vc", 2) == 0) { monitor_devices[0] = "stdio"; } } else { if (default_serial) add_device_config(DEV_SERIAL, "vc:80Cx24C"); + if (default_parallel) + add_device_config(DEV_PARALLEL, "vc:80Cx24C"); } if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) @@ -5764,20 +5780,8 @@ int main(int argc, char **argv, char **envp) if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) exit(1); - - for(i = 0; i < MAX_PARALLEL_PORTS; i++) { - const char *devname = parallel_devices[i]; - if (devname && strcmp(devname, "none")) { - char label[32]; - snprintf(label, sizeof(label), "parallel%d", i); - parallel_hds[i] = qemu_chr_open(label, devname, NULL); - if (!parallel_hds[i]) { - fprintf(stderr, "qemu: could not open parallel device '%s': %s\n", - devname, strerror(errno)); - exit(1); - } - } - } + if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) + exit(1); for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { const char *devname = virtio_consoles[i]; -- cgit v1.2.3 From a20600b91733eba4e7350e2a9959c2f9a8f7f2e3 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:43 +0100 Subject: default devices: qemu monitor. This patch makes the monitor default device configuration work like the default serial and parallel port devices. It adds a variable default_monitor which says whenever a default monitor should be added. It is enabled by default. It is cleared when qemu finds '-monitor' on the command line. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit abdeed06b416eefb7eb1ec65cc1b87241cb3b6d2) --- vl.c | 94 ++++++++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/vl.c b/vl.c index b10cdf812..0d3f5e668 100644 --- a/vl.c +++ b/vl.c @@ -211,6 +211,7 @@ int no_quit = 0; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; +CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; #ifdef TARGET_I386 int win2k_install_hack = 0; int rtc_td_hack = 0; @@ -273,6 +274,7 @@ static void *boot_set_opaque; static int default_serial = 1; static int default_parallel = 1; +static int default_monitor = 1; static struct { const char *driver; @@ -4628,6 +4630,7 @@ struct device_config { DEV_BT, /* -bt */ DEV_SERIAL, /* -serial */ DEV_PARALLEL, /* -parallel */ + DEV_MONITOR, /* -monitor */ } type; const char *cmdline; QTAILQ_ENTRY(device_config) next; @@ -4659,22 +4662,27 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline)) return 0; } -static void serial_monitor_mux(const char *monitor_devices[]) +static void serial_monitor_mux(void) { - struct device_config *serial; + struct device_config *mon0, *serial; const char *devname; - if (strcmp(monitor_devices[0],"stdio") != 0) - return; + QTAILQ_FOREACH(mon0, &device_configs, next) { + if (mon0->type != DEV_MONITOR) + continue; + if (strcmp(mon0->cmdline,"stdio") != 0) + return; + break; + } QTAILQ_FOREACH(serial, &device_configs, next) { if (serial->type != DEV_SERIAL) continue; devname = serial->cmdline; if (devname && !strcmp(devname,"mon:stdio")) { - monitor_devices[0] = NULL; + QTAILQ_REMOVE(&device_configs, mon0, next); break; } else if (devname && !strcmp(devname,"stdio")) { - monitor_devices[0] = NULL; + QTAILQ_REMOVE(&device_configs, mon0, next); serial->cmdline = "mon:stdio"; break; } @@ -4725,6 +4733,32 @@ static int parallel_parse(const char *devname) return 0; } +static int monitor_parse(const char *devname) +{ + static int index = 0; + char label[32]; + + if (strcmp(devname, "none") == 0) + return 0; + if (index == MAX_MONITOR_DEVICES) { + fprintf(stderr, "qemu: too many monitor devices\n"); + exit(1); + } + if (index == 0) { + snprintf(label, sizeof(label), "monitor"); + } else { + snprintf(label, sizeof(label), "monitor%d", index); + } + monitor_hds[index] = qemu_chr_open(label, devname, NULL); + if (!monitor_hds[index]) { + fprintf(stderr, "qemu: could not open monitor device '%s'\n", + devname); + return -1; + } + index++; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4740,9 +4774,6 @@ int main(int argc, char **argv, char **envp) QemuOpts *hda_opts = NULL, *opts; int optind; const char *r, *optarg; - CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; - const char *monitor_devices[MAX_MONITOR_DEVICES]; - int monitor_device_index; const char *virtio_consoles[MAX_VIRTIO_CONSOLES]; int virtio_console_index; const char *loadvm = NULL; @@ -4814,12 +4845,6 @@ int main(int argc, char **argv, char **envp) virtio_consoles[i] = NULL; virtio_console_index = 0; - monitor_devices[0] = "vc:80Cx24C"; - for (i = 1; i < MAX_MONITOR_DEVICES; i++) { - monitor_devices[i] = NULL; - } - monitor_device_index = 0; - for (i = 0; i < MAX_NODES; i++) { node_mem[i] = 0; node_cpumask[i] = 0; @@ -5237,12 +5262,8 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_monitor: - if (monitor_device_index >= MAX_MONITOR_DEVICES) { - fprintf(stderr, "qemu: too many monitor devices\n"); - exit(1); - } - monitor_devices[monitor_device_index] = optarg; - monitor_device_index++; + add_device_config(DEV_MONITOR, optarg); + default_monitor = 0; break; case QEMU_OPTION_chardev: opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend"); @@ -5557,14 +5578,15 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_SERIAL, "stdio"); if (default_parallel) add_device_config(DEV_PARALLEL, "null"); - if (strncmp(monitor_devices[0], "vc", 2) == 0) { - monitor_devices[0] = "stdio"; - } + if (default_monitor) + add_device_config(DEV_MONITOR, "stdio"); } else { if (default_serial) add_device_config(DEV_SERIAL, "vc:80Cx24C"); if (default_parallel) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); + if (default_monitor) + add_device_config(DEV_MONITOR, "vc:80Cx24C"); } if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) @@ -5716,7 +5738,7 @@ int main(int argc, char **argv, char **envp) ram_load, NULL); /* Maintain compatibility with multiple stdio monitors */ - serial_monitor_mux(monitor_devices); + serial_monitor_mux(); if (nb_numa_nodes > 0) { int i; @@ -5760,24 +5782,8 @@ int main(int argc, char **argv, char **envp) } } - for (i = 0; i < MAX_MONITOR_DEVICES; i++) { - const char *devname = monitor_devices[i]; - if (devname && strcmp(devname, "none")) { - char label[32]; - if (i == 0) { - snprintf(label, sizeof(label), "monitor"); - } else { - snprintf(label, sizeof(label), "monitor%d", i); - } - monitor_hds[i] = qemu_chr_open(label, devname, NULL); - if (!monitor_hds[i]) { - fprintf(stderr, "qemu: could not open monitor device '%s'\n", - devname); - exit(1); - } - } - } - + if (foreach_device_config(DEV_MONITOR, monitor_parse) < 0) + exit(1); if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) exit(1); if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) @@ -5903,7 +5909,7 @@ int main(int argc, char **argv, char **envp) text_consoles_set_display(display_state); for (i = 0; i < MAX_MONITOR_DEVICES; i++) { - if (monitor_devices[i] && monitor_hds[i]) { + if (monitor_hds[i]) { monitor_init(monitor_hds[i], MONITOR_USE_READLINE | ((i == 0) ? MONITOR_IS_DEFAULT : 0)); -- cgit v1.2.3 From 7c6a56cc63a4b9cfc93a8cb82646396b7439dac5 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:44 +0100 Subject: zap serial_monitor_mux The logic in this code obviously predates the multiple monitor capability of qemu and looks increasingly silly these days. I think the intention of this piece of code is to get a reasonable default for the -nographic case: have monitor and serial line muxed on stdio. With the new default_serial and default_monitor variables we have now doing just that became much easier ;) Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit e1c09175bc00dd8dfb2ad1b26e1858dcdc109b59) --- vl.c | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/vl.c b/vl.c index 0d3f5e668..e3e035f45 100644 --- a/vl.c +++ b/vl.c @@ -4662,33 +4662,6 @@ static int foreach_device_config(int type, int (*func)(const char *cmdline)) return 0; } -static void serial_monitor_mux(void) -{ - struct device_config *mon0, *serial; - const char *devname; - - QTAILQ_FOREACH(mon0, &device_configs, next) { - if (mon0->type != DEV_MONITOR) - continue; - if (strcmp(mon0->cmdline,"stdio") != 0) - return; - break; - } - QTAILQ_FOREACH(serial, &device_configs, next) { - if (serial->type != DEV_SERIAL) - continue; - devname = serial->cmdline; - if (devname && !strcmp(devname,"mon:stdio")) { - QTAILQ_REMOVE(&device_configs, mon0, next); - break; - } else if (devname && !strcmp(devname,"stdio")) { - QTAILQ_REMOVE(&device_configs, mon0, next); - serial->cmdline = "mon:stdio"; - break; - } - } -} - static int serial_parse(const char *devname) { static int index = 0; @@ -5574,12 +5547,16 @@ int main(int argc, char **argv, char **envp) qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0); if (display_type == DT_NOGRAPHIC) { - if (default_serial) - add_device_config(DEV_SERIAL, "stdio"); if (default_parallel) add_device_config(DEV_PARALLEL, "null"); - if (default_monitor) - add_device_config(DEV_MONITOR, "stdio"); + if (default_serial && default_monitor) { + add_device_config(DEV_SERIAL, "mon:stdio"); + } else { + if (default_serial) + add_device_config(DEV_SERIAL, "stdio"); + if (default_monitor) + add_device_config(DEV_MONITOR, "stdio"); + } } else { if (default_serial) add_device_config(DEV_SERIAL, "vc:80Cx24C"); @@ -5737,9 +5714,6 @@ int main(int argc, char **argv, char **envp) register_savevm_live("ram", 0, 3, NULL, ram_save_live, NULL, ram_load, NULL); - /* Maintain compatibility with multiple stdio monitors */ - serial_monitor_mux(); - if (nb_numa_nodes > 0) { int i; -- cgit v1.2.3 From 84db615abc84bd5074e5a0189cb533f1853a4f22 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:45 +0100 Subject: default devices: vga adapter. Qemu creates a vga display for you in case you didn't specify one on the command line. Right now this is tied to the '-vga ' command line switch, which in turn causes trouble if you are creating your gfx card using '-device VGA,'. This patch adds a variable default_vga which says whenever a default serial line should be added. It is enabled by default. It is cleared when qemu finds '-vga' or '-device {VGA,Cirrus VGA,QEMUware SVGA}' on the command line. '-device VGA' still doesn't work though due to a initialization order issue (vga must init before calling i440fx_init_memory_mappings). Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 64465297cd4c701942988f36f7ce707fb21cc1d8) --- vl.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/vl.c b/vl.c index e3e035f45..444f41487 100644 --- a/vl.c +++ b/vl.c @@ -193,7 +193,7 @@ int autostart; static int rtc_utc = 1; static int rtc_date_offset = -1; /* -1 means no change */ QEMUClock *rtc_clock; -int vga_interface_type = VGA_CIRRUS; +int vga_interface_type = VGA_NONE; #ifdef TARGET_SPARC int graphic_width = 1024; int graphic_height = 768; @@ -275,6 +275,7 @@ static void *boot_set_opaque; static int default_serial = 1; static int default_parallel = 1; static int default_monitor = 1; +static int default_vga = 1; static struct { const char *driver; @@ -282,6 +283,9 @@ static struct { } default_list[] = { { .driver = "isa-serial", .flag = &default_serial }, { .driver = "isa-parallel", .flag = &default_parallel }, + { .driver = "VGA", .flag = &default_vga }, + { .driver = "Cirrus VGA", .flag = &default_vga }, + { .driver = "QEMUware SVGA", .flag = &default_vga }, }; static int default_driver_check(QemuOpts *opts, void *opaque) @@ -4373,6 +4377,7 @@ static void select_vgahw (const char *p) { const char *opts; + default_vga = 0; vga_interface_type = VGA_NONE; if (strstart(p, "std", &opts)) { vga_interface_type = VGA_STD; @@ -5565,6 +5570,8 @@ int main(int argc, char **argv, char **envp) if (default_monitor) add_device_config(DEV_MONITOR, "vc:80Cx24C"); } + if (default_vga) + vga_interface_type = VGA_CIRRUS; if (qemu_opts_foreach(&qemu_chardev_opts, chardev_init_func, NULL, 1) != 0) exit(1); -- cgit v1.2.3 From 64de0113f1ffed3b0bed8ec0deafa413b48dc8d2 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:46 +0100 Subject: default devices: add global cmd line option. Add global command line option to disable default devices. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit d8c208dd8a038d24ba4890156101bc679a8c8fef) --- qemu-options.hx | 5 +++++ vl.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx index 420b7d847..e05b2a0b8 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1881,6 +1881,11 @@ DEF("incoming", HAS_ARG, QEMU_OPTION_incoming, \ STEXI ETEXI +DEF("nodefaults", 0, QEMU_OPTION_nodefaults, \ + "-nodefaults don't create default devices.\n") +STEXI +ETEXI + #ifndef _WIN32 DEF("chroot", HAS_ARG, QEMU_OPTION_chroot, \ "-chroot dir Chroot to dir just before starting the VM.\n") diff --git a/vl.c b/vl.c index 444f41487..69b577fbb 100644 --- a/vl.c +++ b/vl.c @@ -5471,6 +5471,12 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_incoming: incoming = optarg; break; + case QEMU_OPTION_nodefaults: + default_serial = 0; + default_parallel = 0; + default_monitor = 0; + default_vga = 0; + break; #ifndef _WIN32 case QEMU_OPTION_chroot: chroot_dir = optarg; -- cgit v1.2.3 From 782e9e6554d2404689a156282622046538bccd17 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:47 +0100 Subject: default devices: network Add a default_net variable which specified whenever a default network should be created. It is cleared in case any -net option is specified and it is also added to the new -nodefaults switch. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit cb4522ccf67ba84d246291d9f75bd7f3df137d1a) --- net.c | 5 ++++- net.h | 1 + vl.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/net.c b/net.c index 13bdbb2ca..6ef93e615 100644 --- a/net.c +++ b/net.c @@ -39,6 +39,8 @@ static QTAILQ_HEAD(, VLANState) vlans; static QTAILQ_HEAD(, VLANClientState) non_vlan_clients; +int default_net = 1; + /***********************************************************/ /* network device redirectors */ @@ -1317,7 +1319,7 @@ static int net_init_netdev(QemuOpts *opts, void *dummy) int net_init_clients(void) { - if (QTAILQ_EMPTY(&qemu_net_opts.head)) { + if (default_net) { /* if no clients, we use a default config */ qemu_opts_set(&qemu_net_opts, NULL, "type", "nic"); #ifdef CONFIG_SLIRP @@ -1353,5 +1355,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg) return -1; } + default_net = 0; return 0; } diff --git a/net.h b/net.h index d583d590a..4971fcbbb 100644 --- a/net.h +++ b/net.h @@ -139,6 +139,7 @@ struct NICInfo { extern int nb_nics; extern NICInfo nd_table[MAX_NICS]; +extern int default_net; /* BT HCI info */ diff --git a/vl.c b/vl.c index 69b577fbb..482583626 100644 --- a/vl.c +++ b/vl.c @@ -5476,6 +5476,7 @@ int main(int argc, char **argv, char **envp) default_parallel = 0; default_monitor = 0; default_vga = 0; + default_net = 0; break; #ifndef _WIN32 case QEMU_OPTION_chroot: -- cgit v1.2.3 From f4f1df70f2e0d177080a4a3b8cc6cbd47d751a7e Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:48 +0100 Subject: default devices: drives Add a default_drive variable which specified whenever the default drives (cdrom, floppy, sd) should be created. It is cleared when the new -nodefaults switch is specified on the command line. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit aa40fc9c96474b0135d1b940611862f260aedba7) --- vl.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/vl.c b/vl.c index 482583626..f64f72ec5 100644 --- a/vl.c +++ b/vl.c @@ -276,6 +276,7 @@ static int default_serial = 1; static int default_parallel = 1; static int default_monitor = 1; static int default_vga = 1; +static int default_drive = 1; static struct { const char *driver; @@ -5477,6 +5478,7 @@ int main(int argc, char **argv, char **envp) default_monitor = 0; default_vga = 0; default_net = 0; + default_drive = 0; break; #ifndef _WIN32 case QEMU_OPTION_chroot: @@ -5709,14 +5711,16 @@ int main(int argc, char **argv, char **envp) blk_mig_init(); - /* we always create the cdrom drive, even if no disk is there */ - drive_add(NULL, CDROM_ALIAS); + if (default_drive) { + /* we always create the cdrom drive, even if no disk is there */ + drive_add(NULL, CDROM_ALIAS); - /* we always create at least one floppy */ - drive_add(NULL, FD_ALIAS, 0); + /* we always create at least one floppy */ + drive_add(NULL, FD_ALIAS, 0); - /* we always create one sd slot, even if no card is in it */ - drive_add(NULL, SD_ALIAS); + /* we always create one sd slot, even if no card is in it */ + drive_add(NULL, SD_ALIAS); + } /* open the virtual block devices */ if (snapshot) -- cgit v1.2.3 From 239a69680c825608edccf064568a0f1582084760 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:49 +0100 Subject: un-static qemu_chr_parse_compat() Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 33521634bf15996e020c51c47abaaa68e27bf356) --- qemu-char.c | 2 +- qemu-char.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/qemu-char.c b/qemu-char.c index da5c15c4f..c6008c395 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2231,7 +2231,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts) return NULL; } -static QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) +QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename) { char host[65], port[33], width[8], height[8]; int pos; diff --git a/qemu-char.h b/qemu-char.h index 9957db1f5..7fa8e5cc1 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -69,6 +69,7 @@ struct CharDriverState { QTAILQ_ENTRY(CharDriverState) next; }; +QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename); CharDriverState *qemu_chr_open_opts(QemuOpts *opts, void (*init)(struct CharDriverState *s)); CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s)); -- cgit v1.2.3 From ad960ddbceb0145abf2674404f2dd1ce57c21676 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:50 +0100 Subject: rework -monitor handling, switch to QemuOpts This patch reworks the -monitor handling: - It adds a new "mon" QemuOpts list for the monitor(s). - It adds a monitor_parse() function to parse the -monitor switch. - It adds a mon_init function to initialize the monitor(s) from the "mon" QemuOpts list. - It winds up everything and removes the old bits. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 88589343708f10f1ded0af100b2e11eec623bae2) --- qemu-config.c | 19 ++++++++++ qemu-config.h | 1 + vl.c | 119 +++++++++++++++++++++++++++++++++++++--------------------- 3 files changed, 96 insertions(+), 43 deletions(-) diff --git a/qemu-config.c b/qemu-config.c index a23b1256e..c3203c87f 100644 --- a/qemu-config.c +++ b/qemu-config.c @@ -224,6 +224,24 @@ QemuOptsList qemu_global_opts = { }, }; +QemuOptsList qemu_mon_opts = { + .name = "mon", + .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head), + .desc = { + { + .name = "mode", + .type = QEMU_OPT_STRING, + },{ + .name = "chardev", + .type = QEMU_OPT_STRING, + },{ + .name = "default", + .type = QEMU_OPT_BOOL, + }, + { /* end if list */ } + }, +}; + static QemuOptsList *lists[] = { &qemu_drive_opts, &qemu_chardev_opts, @@ -232,6 +250,7 @@ static QemuOptsList *lists[] = { &qemu_net_opts, &qemu_rtc_opts, &qemu_global_opts, + &qemu_mon_opts, NULL, }; diff --git a/qemu-config.h b/qemu-config.h index 6246e76fc..34dfadc5f 100644 --- a/qemu-config.h +++ b/qemu-config.h @@ -7,6 +7,7 @@ extern QemuOptsList qemu_device_opts; extern QemuOptsList qemu_netdev_opts; extern QemuOptsList qemu_net_opts; extern QemuOptsList qemu_rtc_opts; +extern QemuOptsList qemu_mon_opts; int qemu_set_option(const char *str); int qemu_global_option(const char *str); diff --git a/vl.c b/vl.c index f64f72ec5..bb9ffd31d 100644 --- a/vl.c +++ b/vl.c @@ -172,9 +172,6 @@ int main(int argc, char **argv) #define DEFAULT_RAM_SIZE 128 -/* Maximum number of monitor devices */ -#define MAX_MONITOR_DEVICES 10 - static const char *data_dir; const char *bios_name = NULL; /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available @@ -211,7 +208,6 @@ int no_quit = 0; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; -CharDriverState *monitor_hds[MAX_MONITOR_DEVICES]; #ifdef TARGET_I386 int win2k_install_hack = 0; int rtc_td_hack = 0; @@ -4630,13 +4626,83 @@ static int chardev_init_func(QemuOpts *opts, void *opaque) return 0; } +static int mon_init_func(QemuOpts *opts, void *opaque) +{ + CharDriverState *chr; + const char *chardev; + const char *mode; + int flags; + + mode = qemu_opt_get(opts, "mode"); + if (mode == NULL) { + mode = "readline"; + } + if (strcmp(mode, "readline") == 0) { + flags = MONITOR_USE_READLINE; + } else if (strcmp(mode, "control") == 0) { + flags = MONITOR_USE_CONTROL; + } else { + fprintf(stderr, "unknown monitor mode \"%s\"\n", mode); + exit(1); + } + + if (qemu_opt_get_bool(opts, "default", 0)) + flags |= MONITOR_IS_DEFAULT; + + chardev = qemu_opt_get(opts, "chardev"); + chr = qemu_chr_find(chardev); + if (chr == NULL) { + fprintf(stderr, "chardev \"%s\" not found\n", chardev); + exit(1); + } + + monitor_init(chr, flags); + return 0; +} + +static void monitor_parse(const char *optarg) +{ + static int monitor_device_index = 0; + QemuOpts *opts; + const char *p; + char label[32]; + int def = 0; + + if (strstart(optarg, "chardev:", &p)) { + snprintf(label, sizeof(label), "%s", p); + } else { + if (monitor_device_index) { + snprintf(label, sizeof(label), "monitor%d", + monitor_device_index); + } else { + snprintf(label, sizeof(label), "monitor"); + def = 1; + } + opts = qemu_chr_parse_compat(label, optarg); + if (!opts) { + fprintf(stderr, "parse error: %s\n", optarg); + exit(1); + } + } + + opts = qemu_opts_create(&qemu_mon_opts, label, 1); + if (!opts) { + fprintf(stderr, "duplicate chardev: %s\n", label); + exit(1); + } + qemu_opt_set(opts, "mode", "readline"); + qemu_opt_set(opts, "chardev", label); + if (def) + qemu_opt_set(opts, "default", "on"); + monitor_device_index++; +} + struct device_config { enum { DEV_USB, /* -usbdevice */ DEV_BT, /* -bt */ DEV_SERIAL, /* -serial */ DEV_PARALLEL, /* -parallel */ - DEV_MONITOR, /* -monitor */ } type; const char *cmdline; QTAILQ_ENTRY(device_config) next; @@ -4712,32 +4778,6 @@ static int parallel_parse(const char *devname) return 0; } -static int monitor_parse(const char *devname) -{ - static int index = 0; - char label[32]; - - if (strcmp(devname, "none") == 0) - return 0; - if (index == MAX_MONITOR_DEVICES) { - fprintf(stderr, "qemu: too many monitor devices\n"); - exit(1); - } - if (index == 0) { - snprintf(label, sizeof(label), "monitor"); - } else { - snprintf(label, sizeof(label), "monitor%d", index); - } - monitor_hds[index] = qemu_chr_open(label, devname, NULL); - if (!monitor_hds[index]) { - fprintf(stderr, "qemu: could not open monitor device '%s'\n", - devname); - return -1; - } - index++; - return 0; -} - int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -5241,7 +5281,7 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_monitor: - add_device_config(DEV_MONITOR, optarg); + monitor_parse(optarg); default_monitor = 0; break; case QEMU_OPTION_chardev: @@ -5569,7 +5609,7 @@ int main(int argc, char **argv, char **envp) if (default_serial) add_device_config(DEV_SERIAL, "stdio"); if (default_monitor) - add_device_config(DEV_MONITOR, "stdio"); + monitor_parse("stdio"); } } else { if (default_serial) @@ -5577,7 +5617,7 @@ int main(int argc, char **argv, char **envp) if (default_parallel) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); if (default_monitor) - add_device_config(DEV_MONITOR, "vc:80Cx24C"); + monitor_parse("vc:80Cx24C"); } if (default_vga) vga_interface_type = VGA_CIRRUS; @@ -5774,8 +5814,6 @@ int main(int argc, char **argv, char **envp) } } - if (foreach_device_config(DEV_MONITOR, monitor_parse) < 0) - exit(1); if (foreach_device_config(DEV_SERIAL, serial_parse) < 0) exit(1); if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) @@ -5900,13 +5938,8 @@ int main(int argc, char **argv, char **envp) text_consoles_set_display(display_state); - for (i = 0; i < MAX_MONITOR_DEVICES; i++) { - if (monitor_hds[i]) { - monitor_init(monitor_hds[i], - MONITOR_USE_READLINE | - ((i == 0) ? MONITOR_IS_DEFAULT : 0)); - } - } + if (qemu_opts_foreach(&qemu_mon_opts, mon_init_func, NULL, 1) != 0) + exit(1); if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) { fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n", -- cgit v1.2.3 From fc05630f1f6faa50d51834f3e15c6cd86cfdf1e0 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:51 +0100 Subject: add new -mon switch Add -mon switch which maps pretty straight forward into the QemuOpts internal representation: -mon chardev=[,mode=[control|readline]][,[no]default] Via config file: [mon] chardev = "" mode = "readline" default = "on" Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 22a0e04b9bb5a02e13b3e5cf5ea8abfac5f34120) --- qemu-options.hx | 7 +++++++ vl.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx index e05b2a0b8..7234447e5 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1589,6 +1589,13 @@ The default device is @code{vc} in graphical mode and @code{stdio} in non graphical mode. ETEXI +DEF("mon", HAS_ARG, QEMU_OPTION_mon, \ + "-mon chardev=[name][,mode=readline|control][,default]\n") +STEXI +@item -mon chardev=[name][,mode=readline|control][,default] +Setup monitor on chardev @var{name}. +ETEXI + DEF("pidfile", HAS_ARG, QEMU_OPTION_pidfile, \ "-pidfile file write PID to 'file'\n") STEXI diff --git a/vl.c b/vl.c index bb9ffd31d..d90975fed 100644 --- a/vl.c +++ b/vl.c @@ -5284,6 +5284,14 @@ int main(int argc, char **argv, char **envp) monitor_parse(optarg); default_monitor = 0; break; + case QEMU_OPTION_mon: + opts = qemu_opts_parse(&qemu_mon_opts, optarg, "chardev"); + if (!opts) { + fprintf(stderr, "parse error: %s\n", optarg); + exit(1); + } + default_monitor = 0; + break; case QEMU_OPTION_chardev: opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend"); if (!opts) { -- cgit v1.2.3 From f2604b35dc2bade22aadc27e71fdb22e96e2d69b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:52 +0100 Subject: add -qmp convinience switch Acts like -monitor but switched into qmp mode. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 6ca5582d4f06d8ff0c646b8fe3cfe721dc573597) --- qemu-options.hx | 2 ++ vl.c | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index 7234447e5..b8cc3750c 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1588,6 +1588,8 @@ serial port). The default device is @code{vc} in graphical mode and @code{stdio} in non graphical mode. ETEXI +DEF("qmp", HAS_ARG, QEMU_OPTION_qmp, \ + "-qmp dev like -monitor but opens in 'control' mode.\n") DEF("mon", HAS_ARG, QEMU_OPTION_mon, \ "-mon chardev=[name][,mode=readline|control][,default]\n") diff --git a/vl.c b/vl.c index d90975fed..ab77c35e1 100644 --- a/vl.c +++ b/vl.c @@ -4660,7 +4660,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque) return 0; } -static void monitor_parse(const char *optarg) +static void monitor_parse(const char *optarg, const char *mode) { static int monitor_device_index = 0; QemuOpts *opts; @@ -4690,7 +4690,7 @@ static void monitor_parse(const char *optarg) fprintf(stderr, "duplicate chardev: %s\n", label); exit(1); } - qemu_opt_set(opts, "mode", "readline"); + qemu_opt_set(opts, "mode", mode); qemu_opt_set(opts, "chardev", label); if (def) qemu_opt_set(opts, "default", "on"); @@ -5281,7 +5281,11 @@ int main(int argc, char **argv, char **envp) break; } case QEMU_OPTION_monitor: - monitor_parse(optarg); + monitor_parse(optarg, "readline"); + default_monitor = 0; + break; + case QEMU_OPTION_qmp: + monitor_parse(optarg, "control"); default_monitor = 0; break; case QEMU_OPTION_mon: @@ -5617,7 +5621,7 @@ int main(int argc, char **argv, char **envp) if (default_serial) add_device_config(DEV_SERIAL, "stdio"); if (default_monitor) - monitor_parse("stdio"); + monitor_parse("stdio", "readline"); } } else { if (default_serial) @@ -5625,7 +5629,7 @@ int main(int argc, char **argv, char **envp) if (default_parallel) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); if (default_monitor) - monitor_parse("vc:80Cx24C"); + monitor_parse("vc:80Cx24C", "readline"); } if (default_vga) vga_interface_type = VGA_CIRRUS; -- cgit v1.2.3 From a231a8272ce373cfcdb7e9ce5df009e94a66c007 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:53 +0100 Subject: default devices: virtio consoles. This patch adds a variable default_virtcon which says whenever a default virtio console should be added. It is disabled by default, followup patch will enable it for s390. It is cleared when qemu finds '-virtiocon', '-device virtio-console-s390' or '-device virtio-console-pci' on the command line. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit aee1b935c53cc747528138a85fcce8163d272598) --- vl.c | 65 +++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/vl.c b/vl.c index ab77c35e1..b4138be0e 100644 --- a/vl.c +++ b/vl.c @@ -270,6 +270,7 @@ static void *boot_set_opaque; static int default_serial = 1; static int default_parallel = 1; +static int default_virtcon = 0; static int default_monitor = 1; static int default_vga = 1; static int default_drive = 1; @@ -280,6 +281,8 @@ static struct { } default_list[] = { { .driver = "isa-serial", .flag = &default_serial }, { .driver = "isa-parallel", .flag = &default_parallel }, + { .driver = "virtio-console-pci", .flag = &default_virtcon }, + { .driver = "virtio-console-s390", .flag = &default_virtcon }, { .driver = "VGA", .flag = &default_vga }, { .driver = "Cirrus VGA", .flag = &default_vga }, { .driver = "QEMUware SVGA", .flag = &default_vga }, @@ -4699,10 +4702,11 @@ static void monitor_parse(const char *optarg, const char *mode) struct device_config { enum { - DEV_USB, /* -usbdevice */ - DEV_BT, /* -bt */ - DEV_SERIAL, /* -serial */ - DEV_PARALLEL, /* -parallel */ + DEV_USB, /* -usbdevice */ + DEV_BT, /* -bt */ + DEV_SERIAL, /* -serial */ + DEV_PARALLEL, /* -parallel */ + DEV_VIRTCON, /* -virtioconsole */ } type; const char *cmdline; QTAILQ_ENTRY(device_config) next; @@ -4778,6 +4782,28 @@ static int parallel_parse(const char *devname) return 0; } +static int virtcon_parse(const char *devname) +{ + static int index = 0; + char label[32]; + + if (strcmp(devname, "none") == 0) + return 0; + if (index == MAX_VIRTIO_CONSOLES) { + fprintf(stderr, "qemu: too many virtio consoles\n"); + exit(1); + } + snprintf(label, sizeof(label), "virtcon%d", index); + virtcon_hds[index] = qemu_chr_open(label, devname, NULL); + if (!virtcon_hds[index]) { + fprintf(stderr, "qemu: could not open virtio console '%s': %s\n", + devname, strerror(errno)); + return -1; + } + index++; + return 0; +} + int main(int argc, char **argv, char **envp) { const char *gdbstub_dev = NULL; @@ -4793,8 +4819,6 @@ int main(int argc, char **argv, char **envp) QemuOpts *hda_opts = NULL, *opts; int optind; const char *r, *optarg; - const char *virtio_consoles[MAX_VIRTIO_CONSOLES]; - int virtio_console_index; const char *loadvm = NULL; QEMUMachine *machine; const char *cpu_model; @@ -4860,10 +4884,6 @@ int main(int argc, char **argv, char **envp) cyls = heads = secs = 0; translation = BIOS_ATA_TRANSLATION_AUTO; - for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) - virtio_consoles[i] = NULL; - virtio_console_index = 0; - for (i = 0; i < MAX_NODES; i++) { node_mem[i] = 0; node_cpumask[i] = 0; @@ -5322,12 +5342,8 @@ int main(int argc, char **argv, char **envp) } break; case QEMU_OPTION_virtiocon: - if (virtio_console_index >= MAX_VIRTIO_CONSOLES) { - fprintf(stderr, "qemu: too many virtio consoles\n"); - exit(1); - } - virtio_consoles[virtio_console_index] = optarg; - virtio_console_index++; + add_device_config(DEV_VIRTCON, optarg); + default_virtcon = 0; break; case QEMU_OPTION_parallel: add_device_config(DEV_PARALLEL, optarg); @@ -5527,6 +5543,7 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_nodefaults: default_serial = 0; default_parallel = 0; + default_virtcon = 0; default_monitor = 0; default_vga = 0; default_net = 0; @@ -5830,20 +5847,8 @@ int main(int argc, char **argv, char **envp) exit(1); if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) exit(1); - - for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) { - const char *devname = virtio_consoles[i]; - if (devname && strcmp(devname, "none")) { - char label[32]; - snprintf(label, sizeof(label), "virtcon%d", i); - virtcon_hds[i] = qemu_chr_open(label, devname, NULL); - if (!virtcon_hds[i]) { - fprintf(stderr, "qemu: could not open virtio console '%s': %s\n", - devname, strerror(errno)); - exit(1); - } - } - } + if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0) + exit(1); module_call_init(MODULE_INIT_DEVICE); -- cgit v1.2.3 From 828b2ff6769ff8e8d294e0c7b77472f985476a9f Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Tue, 8 Dec 2009 13:11:54 +0100 Subject: Set default console to virtio on S390x All "normal" system emulation targets in qemu I'm aware of display output on either VGA or serial output. Our S390x virtio machine doesn't have such kind of legacy hardware. So instead we need to default to a virtio console. Add flags to QEMUMachine to indicate which kind of default devices make sense for the machine in question. Use it for S390x: enable virtcon, disable serial, parallel and vga. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 986c5f78543bdbd696664447ecdd08cf6d935370) --- hw/boards.h | 4 ++++ hw/s390-virtio.c | 4 ++++ vl.c | 19 ++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/hw/boards.h b/hw/boards.h index 7a0f20f63..8fe0fbc8f 100644 --- a/hw/boards.h +++ b/hw/boards.h @@ -19,6 +19,10 @@ typedef struct QEMUMachine { QEMUMachineInitFunc *init; int use_scsi; int max_cpus; + int no_serial:1, + no_parallel:1, + use_virtcon:1, + no_vga:1; int is_default; GlobalProperty *compat_props; struct QEMUMachine *next; diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index cc21ee6da..51c032adc 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -243,6 +243,10 @@ static QEMUMachine s390_machine = { .alias = "s390", .desc = "VirtIO based S390 machine", .init = s390_init, + .no_serial = 1, + .no_parallel = 1, + .use_virtcon = 1. + .no_vga = 1, .max_cpus = 255, .is_default = 1, }; diff --git a/vl.c b/vl.c index b4138be0e..d02893173 100644 --- a/vl.c +++ b/vl.c @@ -270,7 +270,7 @@ static void *boot_set_opaque; static int default_serial = 1; static int default_parallel = 1; -static int default_virtcon = 0; +static int default_virtcon = 1; static int default_monitor = 1; static int default_vga = 1; static int default_drive = 1; @@ -5629,14 +5629,31 @@ int main(int argc, char **argv, char **envp) qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0); + if (machine->no_serial) { + default_serial = 0; + } + if (machine->no_parallel) { + default_parallel = 0; + } + if (!machine->use_virtcon) { + default_virtcon = 0; + } + if (machine->no_vga) { + default_vga = 0; + } + if (display_type == DT_NOGRAPHIC) { if (default_parallel) add_device_config(DEV_PARALLEL, "null"); if (default_serial && default_monitor) { add_device_config(DEV_SERIAL, "mon:stdio"); + } else if (default_virtcon && default_monitor) { + add_device_config(DEV_VIRTCON, "mon:stdio"); } else { if (default_serial) add_device_config(DEV_SERIAL, "stdio"); + if (default_virtcon) + add_device_config(DEV_VIRTCON, "stdio"); if (default_monitor) monitor_parse("stdio", "readline"); } -- cgit v1.2.3 From 992f3cb78ecf4987ada77b0caffa1640faead8cc Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 10 Dec 2009 11:11:05 +0100 Subject: pci: don't abort() when trying to hotplug with acpi off. The PCI bus on x86 requires ACPI for hotplug support, thus disbling ACPI also disables hotplug for the PCI bus. This patch makes qemu check whenever the PCI bus in question can handle hotplug before trying to add devices. This is needed because qdev will abort() on any attempt to hotplug devices into a non-hotpluggable bus. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 53e0d8affe8514b070db2d265af13a534cb8eda4) --- hw/pci-hotplug.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 081d6d1ac..7e5c51dfe 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -40,7 +40,18 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, const char *opts_str) { QemuOpts *opts; - int ret; + PCIBus *bus; + int ret, devfn; + + bus = pci_get_bus_devfn(&devfn, devaddr); + if (!bus) { + monitor_printf(mon, "Invalid PCI device address %s\n", devaddr); + return NULL; + } + if (!((BusState*)bus)->allow_hotplug) { + monitor_printf(mon, "PCI bus doesn't support hotplug\n"); + return NULL; + } opts = qemu_opts_parse(&qemu_net_opts, opts_str ? opts_str : "", NULL); if (!opts) { @@ -179,6 +190,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, monitor_printf(mon, "Invalid PCI device address %s\n", devaddr); return NULL; } + if (!((BusState*)bus)->allow_hotplug) { + monitor_printf(mon, "PCI bus doesn't support hotplug\n"); + return NULL; + } switch (type) { case IF_SCSI: -- cgit v1.2.3 From ea2138cf90fd4c2a6fefabff23b4c8681411a3f0 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 10 Dec 2009 11:11:06 +0100 Subject: pci: don't hw_error() when no slot is available. Current PCI code will simply hw_error() and thus abort in case no free PCI slot is available or the requested PCI slot is already in use by another device. For the hotplug case this behavior is not acceptable. This patch makes qemu pass up the error properly, so the calling code can decide whenever it wants to exit with an error (on startup) or whenever it wants to continue (hotplug). Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 09e3acc6cfabfd85a9dacc04471df5f05019c779) --- hw/pci.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 4f662b769..404eead58 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -580,11 +580,13 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, if (!bus->devices[devfn]) goto found; } - hw_error("PCI: no devfn available for %s, all in use\n", name); + qemu_error("PCI: no devfn available for %s, all in use\n", name); + return NULL; found: ; } else if (bus->devices[devfn]) { - hw_error("PCI: devfn %d not available for %s, in use by %s\n", devfn, + qemu_error("PCI: devfn %d not available for %s, in use by %s\n", devfn, name, bus->devices[devfn]->name); + return NULL; } pci_dev->bus = bus; pci_dev->devfn = devfn; @@ -625,6 +627,9 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, config_read, config_write, PCI_HEADER_TYPE_NORMAL); + if (pci_dev == NULL) { + hw_error("PCI: can't register device\n"); + } return pci_dev; } static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr) @@ -1376,6 +1381,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn, info->config_read, info->config_write, info->header_type); + if (pci_dev == NULL) + return -1; rc = info->init(pci_dev); if (rc != 0) return rc; -- cgit v1.2.3 From 6e792a557e5c710c9ccb3507bf5aa4e457a49318 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 10 Dec 2009 11:11:07 +0100 Subject: scsi: fix drive hotplug. This patch fills the DriveInfo->unit after hotplugging a scsi disk. It makes a difference when auto-assigning a scsi id, where unit was left filled with '-1' instead of the actual scsi id. With this patch applied the the drive naming logic in drive_init() works as good as it did in previous releases. Which means it works fine with a single scsi bus. Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 11f4d7f483d9ca3a8979abd605cf1468b3e96aa2) --- hw/pci-hotplug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 7e5c51dfe..9e8e6ed42 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -93,6 +93,7 @@ static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo) */ dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit); + dinfo->unit = scsidev->id; if (printinfo) qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id); -- cgit v1.2.3 From e2deb622c29e15603d5f192c9f5378d2568d0749 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 10 Dec 2009 11:11:08 +0100 Subject: QemuOpts: allow larger option values. Use case: loooooooooooooooooong file names for -drive file=... Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit d318ff9900f080dfa802bbbea81f1a68dcd02013) --- qemu-option.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qemu-option.c b/qemu-option.c index b00910900..24392fcb4 100644 --- a/qemu-option.c +++ b/qemu-option.c @@ -705,7 +705,7 @@ int qemu_opts_print(QemuOpts *opts, void *dummy) int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname) { - char option[128], value[128]; + char option[128], value[1024]; const char *p,*pe,*pc; for (p = params; *p != '\0'; p++) { @@ -751,7 +751,7 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, const char *firstname) { - char value[128], *id = NULL; + char value[1024], *id = NULL; const char *p; QemuOpts *opts; -- cgit v1.2.3 From d707483ce33847aa101a208478d6fe01b56b6ecf Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 11 Dec 2009 11:25:07 +0100 Subject: vnc: fix capslock tracking logic. The capslock tracking logic added by commit 6b1325029d80455b9da7cd7bd84a88cb915b867c doesn't work correctly for vnc clients without EXT_KEY_EVENT support. The reason is that qemu converts keysyms for letters to lowercase for the keysym2scancode lookup. It then also passes the lowercase value down to do_key_event(), but the capslock tracking code needs it with the correct case to work properly. This patch adds a new variable for the lowercase keysym so we'll keep the unmodified value for do_key_event(). The keysym2scancode is not needed with EXT_KEY_EVENT capable clients like any app based on the gtk-vnc widget, so I missed that case in testing ... Signed-off-by: Gerd Hoffmann Signed-off-by: Anthony Liguori (cherry picked from commit 4a93fe17081c7ae7f4d5607b266ca384d328986c) --- vnc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/vnc.c b/vnc.c index 32c467880..39c0d9860 100644 --- a/vnc.c +++ b/vnc.c @@ -1506,11 +1506,13 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym) static void key_event(VncState *vs, int down, uint32_t sym) { int keycode; + int lsym = sym; - if (sym >= 'A' && sym <= 'Z' && is_graphic_console()) - sym = sym - 'A' + 'a'; + if (lsym >= 'A' && lsym <= 'Z' && is_graphic_console()) { + lsym = lsym - 'A' + 'a'; + } - keycode = keysym2scancode(vs->vd->kbd_layout, sym & 0xFFFF); + keycode = keysym2scancode(vs->vd->kbd_layout, lsym & 0xFFFF); do_key_event(vs, down, keycode, sym); } -- cgit v1.2.3 From 2d95575edbc82d9144cabca2420829f384e7629b Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:51 -0200 Subject: Introduce qemu-objects.h header file An easy way to include all QEMU objects. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 2471dd00ef212af4b7e1262d5339f0db17e55661) --- qemu-objects.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 qemu-objects.h diff --git a/qemu-objects.h b/qemu-objects.h new file mode 100644 index 000000000..e1d1e0ca7 --- /dev/null +++ b/qemu-objects.h @@ -0,0 +1,24 @@ +/* + * Include all QEMU objects. + * + * Copyright (C) 2009 Red Hat Inc. + * + * Authors: + * Luiz Capitulino + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ +#ifndef QEMU_OBJECTS_H +#define QEMU_OBJECTS_H + +#include "qobject.h" +#include "qint.h" +#include "qfloat.h" +#include "qbool.h" +#include "qstring.h" +#include "qdict.h" +#include "qlist.h" +#include "qjson.h" + +#endif /* QEMU_OBJECTS_H */ -- cgit v1.2.3 From 61a606dade093fbc550f2073a18e6c9c1ed08d4a Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:52 -0200 Subject: Makefile: move QObject objs to their own entry Other subsystems will need to link against them. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 2a01000f7df5faeeb06742b8f7afabf9e8a9d2b6) --- Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 85ad68846..ea90c235f 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,12 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS)) recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES) +####################################################################### +# QObject +qobject-obj-y = qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o +qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o +qobject-obj-y += qerror.o + ####################################################################### # block-obj-y is code used by both qemu system emulation and qemu-img @@ -120,6 +126,7 @@ net-obj-y += $(addprefix net/, $(net-nested-y)) obj-y = $(block-obj-y) obj-y += $(net-obj-y) +obj-y += $(qobject-obj-y) obj-y += readline.o console.o obj-y += tcg-runtime.o host-utils.o @@ -152,8 +159,6 @@ obj-y += buffered_file.o migration.o migration-tcp.o qemu-sockets.o obj-y += qemu-char.o aio.o savevm.o obj-y += msmouse.o ps2.o obj-y += qdev.o qdev-properties.o -obj-y += qint.o qstring.o qdict.o qlist.o qfloat.o qbool.o json-lexer.o -obj-y += json-streamer.o json-parser.o qjson.o qerror.o obj-y += qemu-config.o block-migration.o obj-$(CONFIG_BRLAPI) += baum.o -- cgit v1.2.3 From db830f26cbe996d1f9ea74c18ce558eedbf9bcab Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:53 -0200 Subject: QDict: Introduce qdict_get_qbool() This is a helper function that does type checking before retrieving a QBool from the dictionary. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit cd4dde36ae8e7bd8e02839533c5708011bf994cf) --- Makefile | 2 +- qdict.c | 15 +++++++++++++++ qdict.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ea90c235f..b4356ae52 100644 --- a/Makefile +++ b/Makefile @@ -246,7 +246,7 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx check-qint: check-qint.o qint.o qemu-malloc.o check-qstring: check-qstring.o qstring.o qemu-malloc.o -check-qdict: check-qdict.o qdict.o qint.o qstring.o qemu-malloc.o +check-qdict: check-qdict.o qdict.o qint.o qstring.o qbool.o qemu-malloc.o check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o check-qfloat: check-qfloat.o qfloat.o qemu-malloc.o check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o qemu-malloc.o diff --git a/qdict.c b/qdict.c index 0e04cb1fe..45e08bec9 100644 --- a/qdict.c +++ b/qdict.c @@ -12,6 +12,7 @@ #include "qint.h" #include "qdict.h" +#include "qbool.h" #include "qstring.h" #include "qobject.h" #include "qemu-queue.h" @@ -188,6 +189,20 @@ int64_t qdict_get_int(const QDict *qdict, const char *key) return qint_get_int(qobject_to_qint(obj)); } +/** + * qdict_get_bool(): Get a bool mapped by 'key' + * + * This function assumes that 'key' exists and it stores a + * QBool object. + * + * Return bool mapped by 'key'. + */ +int qdict_get_bool(const QDict *qdict, const char *key) +{ + QObject *obj = qdict_get_obj(qdict, key, QTYPE_QBOOL); + return qbool_get_int(qobject_to_qbool(obj)); +} + /** * qdict_get_str(): Get a pointer to the stored string mapped * by 'key' diff --git a/qdict.h b/qdict.h index 14b26330f..1473c047f 100644 --- a/qdict.h +++ b/qdict.h @@ -37,6 +37,7 @@ void qdict_iter(const QDict *qdict, /* High level helpers */ int64_t qdict_get_int(const QDict *qdict, const char *key); +int qdict_get_bool(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t err_value); -- cgit v1.2.3 From f1f84ba22399b3a47d09d20ce498aef3df1da05f Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:54 -0200 Subject: QDict: Introduce qdict_get_qlist() A helper function to get a QList from a QDict. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit f2e1750803240ec8b78ae126af0d54f7896ee11d) --- Makefile | 2 +- qdict.c | 13 +++++++++++++ qdict.h | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b4356ae52..f1b01310f 100644 --- a/Makefile +++ b/Makefile @@ -246,7 +246,7 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx check-qint: check-qint.o qint.o qemu-malloc.o check-qstring: check-qstring.o qstring.o qemu-malloc.o -check-qdict: check-qdict.o qdict.o qint.o qstring.o qbool.o qemu-malloc.o +check-qdict: check-qdict.o qdict.o qint.o qstring.o qbool.o qemu-malloc.o qlist.o check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o check-qfloat: check-qfloat.o qfloat.o qemu-malloc.o check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o qemu-malloc.o diff --git a/qdict.c b/qdict.c index 45e08bec9..ef73265f4 100644 --- a/qdict.c +++ b/qdict.c @@ -203,6 +203,19 @@ int qdict_get_bool(const QDict *qdict, const char *key) return qbool_get_int(qobject_to_qbool(obj)); } +/** + * qdict_get_qlist(): Get the QList mapped by 'key' + * + * This function assumes that 'key' exists and it stores a + * QList object. + * + * Return QList mapped by 'key'. + */ +QList *qdict_get_qlist(const QDict *qdict, const char *key) +{ + return qobject_to_qlist(qdict_get_obj(qdict, key, QTYPE_QLIST)); +} + /** * qdict_get_str(): Get a pointer to the stored string mapped * by 'key' diff --git a/qdict.h b/qdict.h index 1473c047f..5fef1ea4e 100644 --- a/qdict.h +++ b/qdict.h @@ -2,6 +2,7 @@ #define QDICT_H #include "qobject.h" +#include "qlist.h" #include "qemu-queue.h" #include @@ -38,6 +39,7 @@ void qdict_iter(const QDict *qdict, /* High level helpers */ int64_t qdict_get_int(const QDict *qdict, const char *key); int qdict_get_bool(const QDict *qdict, const char *key); +QList *qdict_get_qlist(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t err_value); -- cgit v1.2.3 From 7589acc9e8e2a5b7d54f40b91e004d6c62f8fcb8 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:01 -0200 Subject: monitor: Convert do_info_name() to QObject Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit e05486cba662ccceef6be4b3ce38961876aa8f6e) --- monitor.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index 18c461215..eb641e3d0 100644 --- a/monitor.c +++ b/monitor.c @@ -514,10 +514,33 @@ static void do_info_version(Monitor *mon, QObject **ret_data) QEMU_VERSION, QEMU_PKGVERSION); } -static void do_info_name(Monitor *mon) +static void do_info_name_print(Monitor *mon, const QObject *data) { - if (qemu_name) - monitor_printf(mon, "%s\n", qemu_name); + QDict *qdict; + + qdict = qobject_to_qdict(data); + if (qdict_size(qdict) == 0) { + return; + } + + monitor_printf(mon, "%s\n", qdict_get_str(qdict, "name")); +} + +/** + * do_info_name(): Show VM name + * + * Return a QDict with the following information: + * + * - "name": VM's name (optional) + * + * Example: + * + * { "name": "qemu-name" } + */ +static void do_info_name(Monitor *mon, QObject **ret_data) +{ + *ret_data = qemu_name ? qobject_from_jsonf("{'name': %s }", qemu_name) : + qobject_from_jsonf("{}"); } static QObject *get_cmd_dict(const char *name) @@ -2472,7 +2495,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM name", - .mhandler.info = do_info_name, + .user_print = do_info_name_print, + .mhandler.info_new = do_info_name, }, { .name = "uuid", -- cgit v1.2.3 From b0a84d0525ac84acabe69ebee552eac1a416724c Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:55 -0200 Subject: monitor: Fix do_info_balloon() output Monitor commands should always return values in bytes and info commands should always return a QDict. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 7f1796713ed2f338bd9abc094aacf10f67aed1e5) --- monitor.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index 8a1be393a..d942d33ed 100644 --- a/monitor.c +++ b/monitor.c @@ -1919,12 +1919,24 @@ static void do_balloon(Monitor *mon, const QDict *qdict, QObject **ret_data) static void monitor_print_balloon(Monitor *mon, const QObject *data) { - monitor_printf(mon, "balloon: actual=%d\n", - (int)qint_get_int(qobject_to_qint(data))); + QDict *qdict; + + qdict = qobject_to_qdict(data); + + monitor_printf(mon, "balloon: actual=%" PRId64 "\n", + qdict_get_int(qdict, "balloon") >> 20); } /** * do_info_balloon(): Balloon information + * + * Return a QDict with the following information: + * + * - "balloon": current balloon value in bytes + * + * Example: + * + * { "balloon": 1073741824 } */ static void do_info_balloon(Monitor *mon, QObject **ret_data) { @@ -1936,7 +1948,8 @@ static void do_info_balloon(Monitor *mon, QObject **ret_data) else if (actual == 0) qemu_error_new(QERR_DEVICE_NOT_ACTIVE, "balloon"); else - *ret_data = QOBJECT(qint_from_int((int)(actual >> 20))); + *ret_data = qobject_from_jsonf("{ 'balloon': %" PRId64 "}", + (int64_t) actual); } static qemu_acl *find_acl(Monitor *mon, const char *name) -- cgit v1.2.3 From 6e785bee32f9225e9e4dd5fffd7192f8b3f83f08 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:58 -0200 Subject: monitor: do_info_version(): Use QDict All 'info' commands should use QDict, this commit also kills monitor_print_qobject() as do_info_version() doesn't use it anymore (and no handler will). Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 45e914cfe03f9fcf946bdc124f752d8f288eff05) --- monitor.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/monitor.c b/monitor.c index 31a2afaa1..33ed3c53b 100644 --- a/monitor.c +++ b/monitor.c @@ -257,24 +257,6 @@ static inline int monitor_has_error(const Monitor *mon) return mon->error != NULL; } -static void monitor_print_qobject(Monitor *mon, const QObject *data) -{ - switch (qobject_type(data)) { - case QTYPE_QSTRING: - monitor_printf(mon, "%s",qstring_get_str(qobject_to_qstring(data))); - break; - case QTYPE_QINT: - monitor_printf(mon, "%" PRId64,qint_get_int(qobject_to_qint(data))); - break; - default: - monitor_printf(mon, "ERROR: unsupported type: %d", - qobject_type(data)); - break; - } - - monitor_puts(mon, "\n"); -} - static void monitor_json_emitter(Monitor *mon, const QObject *data) { QString *json; @@ -504,12 +486,32 @@ help: help_cmd(mon, "info"); } +static void do_info_version_print(Monitor *mon, const QObject *data) +{ + QDict *qdict; + + qdict = qobject_to_qdict(data); + + monitor_printf(mon, "%s%s\n", qdict_get_str(qdict, "qemu"), + qdict_get_str(qdict, "package")); +} + /** * do_info_version(): Show QEMU version + * + * Return a QDict with the following information: + * + * - "qemu": QEMU's version + * - "package": package's version + * + * Example: + * + * { "qemu": "0.11.50", "package": "" } */ static void do_info_version(Monitor *mon, QObject **ret_data) { - *ret_data = QOBJECT(qstring_from_str(QEMU_VERSION QEMU_PKGVERSION)); + *ret_data = qobject_from_jsonf("{ 'qemu': %s, 'package': %s }", + QEMU_VERSION, QEMU_PKGVERSION); } static void do_info_name(Monitor *mon) @@ -2223,7 +2225,7 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the version of QEMU", - .user_print = monitor_print_qobject, + .user_print = do_info_version_print, .mhandler.info_new = do_info_version, }, { -- cgit v1.2.3 From 5f9fe0f8d0b38d0af6b2b3a3bc9974e5a9a28213 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:02 -0200 Subject: monitor: Convert do_info_hpet() to QObject Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 14f0720df929181eed5424b3f436d84ce05541c3) --- monitor.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index eb641e3d0..7f091a3fe 100644 --- a/monitor.c +++ b/monitor.c @@ -597,10 +597,27 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) } #if defined(TARGET_I386) -static void do_info_hpet(Monitor *mon) +static void do_info_hpet_print(Monitor *mon, const QObject *data) { monitor_printf(mon, "HPET is %s by QEMU\n", - (no_hpet) ? "disabled" : "enabled"); + qdict_get_bool(qobject_to_qdict(data), "enabled") ? + "enabled" : "disabled"); +} + +/** + * do_info_hpet(): Show HPET state + * + * Return a QDict with the following information: + * + * - "enabled": true if hpet if enabled, false otherwise + * + * Example: + * + * { "enabled": true } + */ +static void do_info_hpet(Monitor *mon, QObject **ret_data) +{ + *ret_data = qobject_from_jsonf("{ 'enabled': %i }", !no_hpet); } #endif @@ -2401,7 +2418,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show state of HPET", - .mhandler.info = do_info_hpet, + .user_print = do_info_hpet_print, + .mhandler.info_new = do_info_hpet, }, #endif { -- cgit v1.2.3 From 5daa7bb7a4fa88142d38862860bfdbd253deceb3 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:56 -0200 Subject: monitor: Fix do_info_commands() output Should return a QDict and should not print the user protocol bits (eg. "c|cont"). Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 1a728677d4e2f0434caf352c0e88100652fd6711) --- monitor.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index d942d33ed..339f50eaf 100644 --- a/monitor.c +++ b/monitor.c @@ -518,10 +518,34 @@ static void do_info_name(Monitor *mon) monitor_printf(mon, "%s\n", qemu_name); } +static QObject *get_cmd_dict(const char *name) +{ + const char *p; + + /* Remove '|' from some commands */ + p = strchr(name, '|'); + if (p) { + p++; + } else { + p = name; + } + + return qobject_from_jsonf("{ 'name': %s }", p); +} + /** * do_info_commands(): List QMP available commands * - * Return a QList of QStrings. + * Each command is represented by a QDict, the returned QObject is a QList + * of all commands. + * + * The QDict contains: + * + * - "name": command's name + * + * Example: + * + * { [ { "name": "query-balloon" }, { "name": "system_powerdown" } ] } */ static void do_info_commands(Monitor *mon, QObject **ret_data) { @@ -532,7 +556,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) for (cmd = mon_cmds; cmd->name != NULL; cmd++) { if (monitor_handler_ported(cmd) && !compare_cmd(cmd->name, "info")) { - qlist_append(cmd_list, qstring_from_str(cmd->name)); + qlist_append_obj(cmd_list, get_cmd_dict(cmd->name)); } } @@ -540,7 +564,7 @@ static void do_info_commands(Monitor *mon, QObject **ret_data) if (monitor_handler_ported(cmd)) { char buf[128]; snprintf(buf, sizeof(buf), "query-%s", cmd->name); - qlist_append(cmd_list, qstring_from_str(buf)); + qlist_append_obj(cmd_list, get_cmd_dict(buf)); } } -- cgit v1.2.3 From e637fd2386aba3e57345130d2fc3262f789e56c9 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:59 -0200 Subject: monitor: Convert do_info_status() to QObject Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit c0e8520ed5efef2891e2e930a1bb21c1b040410f) --- monitor.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/monitor.c b/monitor.c index 33ed3c53b..3d37548d6 100644 --- a/monitor.c +++ b/monitor.c @@ -1933,16 +1933,41 @@ static void do_inject_nmi(Monitor *mon, const QDict *qdict) } #endif -static void do_info_status(Monitor *mon) +static void do_info_status_print(Monitor *mon, const QObject *data) { - if (vm_running) { - if (singlestep) { - monitor_printf(mon, "VM status: running (single step mode)\n"); - } else { - monitor_printf(mon, "VM status: running\n"); + QDict *qdict; + + qdict = qobject_to_qdict(data); + + monitor_printf(mon, "VM status: "); + if (qdict_get_bool(qdict, "running")) { + monitor_printf(mon, "running"); + if (qdict_get_bool(qdict, "singlestep")) { + monitor_printf(mon, " (single step mode)"); } - } else - monitor_printf(mon, "VM status: paused\n"); + } else { + monitor_printf(mon, "paused"); + } + + monitor_printf(mon, "\n"); +} + +/** + * do_info_status(): VM status + * + * Return a QDict with the following information: + * + * - "running": true if the VM is running, or false if it is paused + * - "singlestep": true if the VM is in single step mode, false otherwise + * + * Example: + * + * { "running": true, "singlestep": false } + */ +static void do_info_status(Monitor *mon, QObject **ret_data) +{ + *ret_data = qobject_from_jsonf("{ 'running': %i, 'singlestep': %i }", + vm_running, singlestep); } /** @@ -2393,7 +2418,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM status (running|paused)", - .mhandler.info = do_info_status, + .user_print = do_info_status_print, + .mhandler.info_new = do_info_status, }, { .name = "pcmcia", -- cgit v1.2.3 From ee70ef8771a69e11c0814ab332c48efdf19ad0a2 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:03 -0200 Subject: monitor: Convert do_info_uuid() to QObject snprintf() is used because the UUID_FMT is too complex for qobject_from_jsonf(). Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 9603ceba2edd1dc7e3823da76d84706d3d1c3d78) --- monitor.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index 7f091a3fe..daa45fcaa 100644 --- a/monitor.c +++ b/monitor.c @@ -621,13 +621,32 @@ static void do_info_hpet(Monitor *mon, QObject **ret_data) } #endif -static void do_info_uuid(Monitor *mon) +static void do_info_uuid_print(Monitor *mon, const QObject *data) { - monitor_printf(mon, UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], + monitor_printf(mon, "%s\n", qdict_get_str(qobject_to_qdict(data), "UUID")); +} + +/** + * do_info_uuid(): Show VM UUID + * + * Return a QDict with the following information: + * + * - "UUID": Universally Unique Identifier + * + * Example: + * + * { "UUID": "550e8400-e29b-41d4-a716-446655440000" } + */ +static void do_info_uuid(Monitor *mon, QObject **ret_data) +{ + char uuid[64]; + + snprintf(uuid, sizeof(uuid), UUID_FMT, qemu_uuid[0], qemu_uuid[1], qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14], qemu_uuid[15]); + *ret_data = qobject_from_jsonf("{ 'UUID': %s }", uuid); } /* get the current CPU defined by the user */ @@ -2521,7 +2540,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the current VM UUID", - .mhandler.info = do_info_uuid, + .user_print = do_info_uuid_print, + .mhandler.info_new = do_info_uuid, }, #if defined(TARGET_PPC) { -- cgit v1.2.3 From f883e4f7b8f37b53fc54660d20fd36fbe3383f46 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:15:57 -0200 Subject: monitor: do_info_cpus(): Use QBool While there update the documentation as well. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 55483ad657dcb62cde09bce3b38a5fc28d08f999) --- monitor.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/monitor.c b/monitor.c index 339f50eaf..31a2afaa1 100644 --- a/monitor.c +++ b/monitor.c @@ -635,8 +635,9 @@ static void print_cpu_iter(QObject *obj, void *opaque) assert(qobject_type(obj) == QTYPE_QDICT); cpu = qobject_to_qdict(obj); - if (strcmp(qdict_get_str(cpu, "current"), "yes") == 0) + if (qdict_get_bool(cpu, "current")) { active = '*'; + } monitor_printf(mon, "%c CPU #%d: ", active, (int)qdict_get_int(cpu, "CPU")); @@ -656,8 +657,9 @@ static void print_cpu_iter(QObject *obj, void *opaque) (target_long) qdict_get_int(cpu, "PC")); #endif - if (strcmp(qdict_get_str(cpu, "halted"), "yes") == 0) + if (qdict_get_bool(cpu, "halted")) { monitor_printf(mon, " (halted)"); + } monitor_printf(mon, "\n"); } @@ -674,12 +676,21 @@ static void monitor_print_cpus(Monitor *mon, const QObject *data) /** * do_info_cpus(): Show CPU information * - * Return a QList with a QDict for each CPU. + * Return a QList. Each CPU is represented by a QDict, which contains: * - * For example: + * - "cpu": CPU index + * - "current": true if this is the current CPU, false otherwise + * - "halted": true if the cpu is halted, false otherwise + * - Current program counter. The key's name depends on the architecture: + * "pc": i386/x86)64 + * "nip": PPC + * "pc" and "npc": sparc + * "PC": mips * - * [ { "CPU": 0, "current": "yes", "pc": 0x..., "halted": "no" }, - * { "CPU": 1, "current": "no", "pc": 0x..., "halted": "yes" } ] + * Example: + * + * [ { "CPU": 0, "current": true, "halted": false, "pc": 3227107138 }, + * { "CPU": 1, "current": false, "halted": true, "pc": 7108165 } ] */ static void do_info_cpus(Monitor *mon, QObject **ret_data) { @@ -692,14 +703,17 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data) mon_get_cpu(); for(env = first_cpu; env != NULL; env = env->next_cpu) { - const char *answer; - QDict *cpu = qdict_new(); + QDict *cpu; + QObject *obj; cpu_synchronize_state(env); - qdict_put(cpu, "CPU", qint_from_int(env->cpu_index)); - answer = (env == mon->mon_cpu) ? "yes" : "no"; - qdict_put(cpu, "current", qstring_from_str(answer)); + obj = qobject_from_jsonf("{ 'CPU': %d, 'current': %i, 'halted': %i }", + env->cpu_index, env == mon->mon_cpu, + env->halted); + assert(obj != NULL); + + cpu = qobject_to_qdict(obj); #if defined(TARGET_I386) qdict_put(cpu, "pc", qint_from_int(env->eip + env->segs[R_CS].base)); @@ -711,8 +725,6 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data) #elif defined(TARGET_MIPS) qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC)); #endif - answer = env->halted ? "yes" : "no"; - qdict_put(cpu, "halted", qstring_from_str(answer)); qlist_append(cpu_list, cpu); } -- cgit v1.2.3 From 94f539bdac57daea5f5d853cfee86bd683cf81cf Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:00 -0200 Subject: monitor: Convert do_info_kvm() to QObject Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 2af5ba712b3e03cf644320f7386bf1dfd2c2b6a8) --- monitor.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index 3d37548d6..18c461215 100644 --- a/monitor.c +++ b/monitor.c @@ -1806,16 +1806,40 @@ static void tlb_info(Monitor *mon) #endif -static void do_info_kvm(Monitor *mon) +static void do_info_kvm_print(Monitor *mon, const QObject *data) { -#ifdef CONFIG_KVM + QDict *qdict; + + qdict = qobject_to_qdict(data); + monitor_printf(mon, "kvm support: "); - if (kvm_enabled()) - monitor_printf(mon, "enabled\n"); - else - monitor_printf(mon, "disabled\n"); + if (qdict_get_bool(qdict, "present")) { + monitor_printf(mon, "%s\n", qdict_get_bool(qdict, "enabled") ? + "enabled" : "disabled"); + } else { + monitor_printf(mon, "not compiled\n"); + } +} + +/** + * do_info_kvm(): Show KVM information + * + * Return a QDict with the following information: + * + * - "enabled": true if KVM support is enabled, false otherwise + * - "present": true if QEMU has KVM support, false otherwise + * + * Example: + * + * { "enabled": true, "present": true } + */ +static void do_info_kvm(Monitor *mon, QObject **ret_data) +{ +#ifdef CONFIG_KVM + *ret_data = qobject_from_jsonf("{ 'enabled': %i, 'present': true }", + kvm_enabled()); #else - monitor_printf(mon, "kvm support: not compiled\n"); + *ret_data = qobject_from_jsonf("{ 'enabled': false, 'present': false }"); #endif } @@ -2369,7 +2393,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show KVM information", - .mhandler.info = do_info_kvm, + .user_print = do_info_kvm_print, + .mhandler.info_new = do_info_kvm, }, { .name = "numa", -- cgit v1.2.3 From d2d51eeff012ba83097f47a511cb21b14da0a170 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:05 -0200 Subject: migration: Convert do_info_migrate() to QObject Return a QDict, which may contain up to more two QDicts, depending on the type of migration we're performing. IMPORTANT: as a QInt stores a int64_t integer, RAM values are going to be stored as int64_t and not as uint64_t as they are today. If this is a problem QInt will have to be changed. This commit should not change user output. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit c86a668390d16d6b3249acd50bfa61ad825c7a80) --- migration.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------- migration.h | 4 ++- monitor.c | 3 +- 3 files changed, 107 insertions(+), 17 deletions(-) diff --git a/migration.c b/migration.c index d6a3e2615..fda61e642 100644 --- a/migration.c +++ b/migration.c @@ -19,6 +19,7 @@ #include "block.h" #include "qemu_socket.h" #include "block-migration.h" +#include "qemu-objects.h" //#define DEBUG_MIGRATION @@ -163,37 +164,123 @@ void do_migrate_set_downtime(Monitor *mon, const QDict *qdict) max_downtime = (uint64_t)d; } -void do_info_migrate(Monitor *mon) +static void migrate_print_status(Monitor *mon, const char *name, + const QDict *status_dict) { + QDict *qdict; + + qdict = qobject_to_qdict(qdict_get(status_dict, name)); + + monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name, + qdict_get_int(qdict, "transferred") >> 10); + monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name, + qdict_get_int(qdict, "remaining") >> 10); + monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name, + qdict_get_int(qdict, "total") >> 10); +} + +void do_info_migrate_print(Monitor *mon, const QObject *data) +{ + QDict *qdict; + + qdict = qobject_to_qdict(data); + + monitor_printf(mon, "Migration status: %s\n", + qdict_get_str(qdict, "status")); + + if (qdict_haskey(qdict, "ram")) { + migrate_print_status(mon, "ram", qdict); + } + + if (qdict_haskey(qdict, "disk")) { + migrate_print_status(mon, "disk", qdict); + } +} + +static void migrate_put_status(QDict *qdict, const char *name, + uint64_t trans, uint64_t rem, uint64_t total) +{ + QObject *obj; + + obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", " + "'remaining': %" PRId64 ", " + "'total': %" PRId64 " }", trans, rem, total); + assert(obj != NULL); + + qdict_put_obj(qdict, name, obj); +} + +/** + * do_info_migrate(): Migration status + * + * Return a QDict. If migration is active there will be another + * QDict with RAM migration status and if block migration is active + * another one with block migration status. + * + * The main QDict contains the following: + * + * - "status": migration status + * - "ram": only present if "status" is "active", it is a QDict with the + * following RAM information (in bytes): + * - "transferred": amount transferred + * - "remaining": amount remaining + * - "total": total + * - "disk": only present if "status" is "active" and it is a block migration, + * it is a QDict with the following disk information (in bytes): + * - "transferred": amount transferred + * - "remaining": amount remaining + * - "total": total + * + * Examples: + * + * 1. Migration is "completed": + * + * { "status": "completed" } + * + * 2. Migration is "active" and it is not a block migration: + * + * { "status": "active", + * "ram": { "transferred": 123, "remaining": 123, "total": 246 } } + * + * 3. Migration is "active" and it is a block migration: + * + * { "status": "active", + * "ram": { "total": 1057024, "remaining": 1053304, "transferred": 3720 }, + * "disk": { "total": 20971520, "remaining": 20880384, "transferred": 91136 }} + */ +void do_info_migrate(Monitor *mon, QObject **ret_data) +{ + QDict *qdict; MigrationState *s = current_migration; if (s) { - monitor_printf(mon, "Migration status: "); switch (s->get_status(s)) { case MIG_STATE_ACTIVE: - monitor_printf(mon, "active\n"); - monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n", ram_bytes_transferred() >> 10); - monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n", ram_bytes_remaining() >> 10); - monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n", ram_bytes_total() >> 10); + qdict = qdict_new(); + qdict_put(qdict, "status", qstring_from_str("active")); + + migrate_put_status(qdict, "ram", ram_bytes_transferred(), + ram_bytes_remaining(), ram_bytes_total()); + if (blk_mig_active()) { - monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n", - blk_mig_bytes_transferred() >> 10); - monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n", - blk_mig_bytes_remaining() >> 10); - monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n", - blk_mig_bytes_total() >> 10); + migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(), + blk_mig_bytes_remaining(), + blk_mig_bytes_total()); } + + *ret_data = QOBJECT(qdict); break; case MIG_STATE_COMPLETED: - monitor_printf(mon, "completed\n"); + *ret_data = qobject_from_jsonf("{ 'status': 'completed' }"); break; case MIG_STATE_ERROR: - monitor_printf(mon, "failed\n"); + *ret_data = qobject_from_jsonf("{ 'status': 'failed' }"); break; case MIG_STATE_CANCELLED: - monitor_printf(mon, "cancelled\n"); + *ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }"); break; } + assert(*ret_data != NULL); } } diff --git a/migration.h b/migration.h index 3f2b3df2b..3ac208bf5 100644 --- a/migration.h +++ b/migration.h @@ -62,7 +62,9 @@ uint64_t migrate_max_downtime(void); void do_migrate_set_downtime(Monitor *mon, const QDict *qdict); -void do_info_migrate(Monitor *mon); +void do_info_migrate_print(Monitor *mon, const QObject *data); + +void do_info_migrate(Monitor *mon, QObject **ret_data); int exec_start_incoming_migration(const char *host_port); diff --git a/monitor.c b/monitor.c index aa97f89b3..0cb534a60 100644 --- a/monitor.c +++ b/monitor.c @@ -2567,7 +2567,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show migration status", - .mhandler.info = do_info_migrate, + .user_print = do_info_migrate_print, + .mhandler.info_new = do_info_migrate, }, { .name = "balloon", -- cgit v1.2.3 From 4305793badb13a97c55ca8262e7b1a099ee0a0cf Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:06 -0200 Subject: block: Convert bdrv_info() to QObject Each block device information is stored in a QDict and the returned QObject is a QList of all devices. This commit should not change user output. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit d15e546567d75fca36d852c39e30adaab02121a7) --- Makefile | 6 +-- block.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- block.h | 4 +- monitor.c | 3 +- 4 files changed, 111 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index f1b01310f..a662d96a8 100644 --- a/Makefile +++ b/Makefile @@ -235,11 +235,11 @@ libqemu_common.a: $(obj-y) qemu-img.o: qemu-img-cmds.h -qemu-img$(EXESUF): qemu-img.o qemu-tool.o $(block-obj-y) +qemu-img$(EXESUF): qemu-img.o qemu-tool.o $(block-obj-y) $(qobject-obj-y) -qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o $(block-obj-y) +qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o $(block-obj-y) $(qobject-obj-y) -qemu-io$(EXESUF): qemu-io.o qemu-tool.o cmd.o $(block-obj-y) +qemu-io$(EXESUF): qemu-io.o qemu-tool.o cmd.o $(block-obj-y) $(qobject-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") diff --git a/block.c b/block.c index 853f0256a..d7eccb78a 100644 --- a/block.c +++ b/block.c @@ -26,6 +26,7 @@ #include "monitor.h" #include "block_int.h" #include "module.h" +#include "qemu-objects.h" #ifdef CONFIG_BSD #include @@ -1139,43 +1140,125 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum); } -void bdrv_info(Monitor *mon) +static void bdrv_print_dict(QObject *obj, void *opaque) { + QDict *bs_dict; + Monitor *mon = opaque; + + bs_dict = qobject_to_qdict(obj); + + monitor_printf(mon, "%s: type=%s removable=%d", + qdict_get_str(bs_dict, "device"), + qdict_get_str(bs_dict, "type"), + qdict_get_bool(bs_dict, "removable")); + + if (qdict_get_bool(bs_dict, "removable")) { + monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked")); + } + + if (qdict_haskey(bs_dict, "inserted")) { + QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted")); + + monitor_printf(mon, " file="); + monitor_print_filename(mon, qdict_get_str(qdict, "file")); + if (qdict_haskey(qdict, "backing_file")) { + monitor_printf(mon, " backing_file="); + monitor_print_filename(mon, qdict_get_str(qdict, "backing_file")); + } + monitor_printf(mon, " ro=%d drv=%s encrypted=%d", + qdict_get_bool(qdict, "ro"), + qdict_get_str(qdict, "drv"), + qdict_get_bool(qdict, "encrypted")); + } else { + monitor_printf(mon, " [not inserted]"); + } + + monitor_printf(mon, "\n"); +} + +void bdrv_info_print(Monitor *mon, const QObject *data) +{ + qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon); +} + +/** + * bdrv_info(): Block devices information + * + * Each block device information is stored in a QDict and the + * returned QObject is a QList of all devices. + * + * The QDict contains the following: + * + * - "device": device name + * - "type": device type + * - "removable": true if the device is removable, false otherwise + * - "locked": true if the device is locked, false otherwise + * - "inserted": only present if the device is inserted, it is a QDict + * containing the following: + * - "file": device file name + * - "ro": true if read-only, false otherwise + * - "drv": driver format name + * - "backing_file": backing file name if one is used + * - "encrypted": true if encrypted, false otherwise + * + * Example: + * + * [ { "device": "ide0-hd0", "type": "hd", "removable": false, "locked": false, + * "inserted": { "file": "/tmp/foobar", "ro": false, "drv": "qcow2" } }, + * { "device": "floppy0", "type": "floppy", "removable": true, + * "locked": false } ] + */ +void bdrv_info(Monitor *mon, QObject **ret_data) +{ + QList *bs_list; BlockDriverState *bs; + bs_list = qlist_new(); + for (bs = bdrv_first; bs != NULL; bs = bs->next) { - monitor_printf(mon, "%s:", bs->device_name); - monitor_printf(mon, " type="); + QObject *bs_obj; + const char *type = "unknown"; + switch(bs->type) { case BDRV_TYPE_HD: - monitor_printf(mon, "hd"); + type = "hd"; break; case BDRV_TYPE_CDROM: - monitor_printf(mon, "cdrom"); + type = "cdrom"; break; case BDRV_TYPE_FLOPPY: - monitor_printf(mon, "floppy"); + type = "floppy"; break; } - monitor_printf(mon, " removable=%d", bs->removable); - if (bs->removable) { - monitor_printf(mon, " locked=%d", bs->locked); - } + + bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': %s, " + "'removable': %i, 'locked': %i }", + bs->device_name, type, bs->removable, + bs->locked); + assert(bs_obj != NULL); + if (bs->drv) { - monitor_printf(mon, " file="); - monitor_print_filename(mon, bs->filename); + QObject *obj; + QDict *bs_dict = qobject_to_qdict(bs_obj); + + obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, " + "'encrypted': %i }", + bs->filename, bs->read_only, + bs->drv->format_name, + bdrv_is_encrypted(bs)); + assert(obj != NULL); if (bs->backing_file[0] != '\0') { - monitor_printf(mon, " backing_file="); - monitor_print_filename(mon, bs->backing_file); + QDict *qdict = qobject_to_qdict(obj); + qdict_put(qdict, "backing_file", + qstring_from_str(bs->backing_file)); } - monitor_printf(mon, " ro=%d", bs->read_only); - monitor_printf(mon, " drv=%s", bs->drv->format_name); - monitor_printf(mon, " encrypted=%d", bdrv_is_encrypted(bs)); - } else { - monitor_printf(mon, " [not inserted]"); + + qdict_put_obj(bs_dict, "inserted", obj); } - monitor_printf(mon, "\n"); + qlist_append_obj(bs_list, bs_obj); } + + *ret_data = QOBJECT(bs_list); } /* The "info blockstats" command. */ diff --git a/block.h b/block.h index 4a8b6283e..3282dd2cd 100644 --- a/block.h +++ b/block.h @@ -4,6 +4,7 @@ #include "qemu-aio.h" #include "qemu-common.h" #include "qemu-option.h" +#include "qobject.h" /* block.c */ typedef struct BlockDriver BlockDriver; @@ -45,7 +46,8 @@ typedef struct QEMUSnapshotInfo { #define BDRV_SECTOR_SIZE (1 << BDRV_SECTOR_BITS) #define BDRV_SECTOR_MASK ~(BDRV_SECTOR_SIZE - 1); -void bdrv_info(Monitor *mon); +void bdrv_info_print(Monitor *mon, const QObject *data); +void bdrv_info(Monitor *mon, QObject **ret_data); void bdrv_info_stats(Monitor *mon); void bdrv_init(void); diff --git a/monitor.c b/monitor.c index 0cb534a60..17fccfd5c 100644 --- a/monitor.c +++ b/monitor.c @@ -2363,7 +2363,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the block devices", - .mhandler.info = bdrv_info, + .user_print = bdrv_info_print, + .mhandler.info_new = bdrv_info, }, { .name = "blockstats", -- cgit v1.2.3 From 0108d4e3233cd3aa289f354eb8b78dfe5bb16b09 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:07 -0200 Subject: block: Convert bdrv_info_stats() to QObject Each device statistic information is stored in a QDict and the returned QObject is a QList of all devices. This commit should not change user output. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 218a536a7a7c6d3679d5eca0103f32fd11fbfaf0) --- block.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- block.h | 3 ++- monitor.c | 3 ++- 3 files changed, 76 insertions(+), 14 deletions(-) diff --git a/block.c b/block.c index d7eccb78a..3f3496ec9 100644 --- a/block.c +++ b/block.c @@ -1261,22 +1261,82 @@ void bdrv_info(Monitor *mon, QObject **ret_data) *ret_data = QOBJECT(bs_list); } -/* The "info blockstats" command. */ -void bdrv_info_stats(Monitor *mon) +static void bdrv_stats_iter(QObject *data, void *opaque) { + QDict *qdict; + Monitor *mon = opaque; + + qdict = qobject_to_qdict(data); + monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); + + qdict = qobject_to_qdict(qdict_get(qdict, "stats")); + monitor_printf(mon, " rd_bytes=%" PRId64 + " wr_bytes=%" PRId64 + " rd_operations=%" PRId64 + " wr_operations=%" PRId64 + "\n", + qdict_get_int(qdict, "rd_bytes"), + qdict_get_int(qdict, "wr_bytes"), + qdict_get_int(qdict, "rd_operations"), + qdict_get_int(qdict, "wr_operations")); +} + +void bdrv_stats_print(Monitor *mon, const QObject *data) +{ + qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon); +} + +/** + * bdrv_info_stats(): show block device statistics + * + * Each device statistic information is stored in a QDict and + * the returned QObject is a QList of all devices. + * + * The QDict contains the following: + * + * - "device": device name + * - "stats": A QDict with the statistics information, it contains: + * - "rd_bytes": bytes read + * - "wr_bytes": bytes written + * - "rd_operations": read operations + * - "wr_operations": write operations + * + * Example: + * + * [ { "device": "ide0-hd0", + * "stats": { "rd_bytes": 512, + * "wr_bytes": 0, + * "rd_operations": 1, + * "wr_operations": 0 } }, + * { "device": "ide1-cd0", + * "stats": { "rd_bytes": 0, + * "wr_bytes": 0, + * "rd_operations": 0, + * "wr_operations": 0 } } ] + */ +void bdrv_info_stats(Monitor *mon, QObject **ret_data) +{ + QObject *obj; + QList *devices; BlockDriverState *bs; + devices = qlist_new(); + for (bs = bdrv_first; bs != NULL; bs = bs->next) { - monitor_printf(mon, "%s:" - " rd_bytes=%" PRIu64 - " wr_bytes=%" PRIu64 - " rd_operations=%" PRIu64 - " wr_operations=%" PRIu64 - "\n", - bs->device_name, - bs->rd_bytes, bs->wr_bytes, - bs->rd_ops, bs->wr_ops); - } + obj = qobject_from_jsonf("{ 'device': %s, 'stats': {" + "'rd_bytes': %" PRId64 "," + "'wr_bytes': %" PRId64 "," + "'rd_operations': %" PRId64 "," + "'wr_operations': %" PRId64 + "} }", + bs->device_name, + bs->rd_bytes, bs->wr_bytes, + bs->rd_ops, bs->wr_ops); + assert(obj != NULL); + qlist_append_obj(devices, obj); + } + + *ret_data = QOBJECT(devices); } const char *bdrv_get_encrypted_filename(BlockDriverState *bs) diff --git a/block.h b/block.h index 3282dd2cd..fa51ddf15 100644 --- a/block.h +++ b/block.h @@ -48,7 +48,8 @@ typedef struct QEMUSnapshotInfo { void bdrv_info_print(Monitor *mon, const QObject *data); void bdrv_info(Monitor *mon, QObject **ret_data); -void bdrv_info_stats(Monitor *mon); +void bdrv_stats_print(Monitor *mon, const QObject *data); +void bdrv_info_stats(Monitor *mon, QObject **ret_data); void bdrv_init(void); void bdrv_init_with_whitelist(void); diff --git a/monitor.c b/monitor.c index 17fccfd5c..349ba971c 100644 --- a/monitor.c +++ b/monitor.c @@ -2371,7 +2371,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show block device statistics", - .mhandler.info = bdrv_info_stats, + .user_print = bdrv_stats_print, + .mhandler.info_new = bdrv_info_stats, }, { .name = "registers", -- cgit v1.2.3 From bdae662c9436d0d7cc6c6ae4e28f891d2f16e208 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:08 -0200 Subject: char: Convert qemu_chr_info() to QObject Each device is represented by a QDict. The returned QObject is a QList of all devices. This commit should not change user output. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 588b38320134edee4a569f60ed88c9848961d6ee) --- monitor.c | 3 ++- qemu-char.c | 43 +++++++++++++++++++++++++++++++++++++++++-- qemu-char.h | 4 +++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index 349ba971c..897280ab5 100644 --- a/monitor.c +++ b/monitor.c @@ -2356,7 +2356,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the character devices", - .mhandler.info = qemu_chr_info, + .user_print = qemu_chr_info_print, + .mhandler.info_new = qemu_chr_info, }, { .name = "block", diff --git a/qemu-char.c b/qemu-char.c index c6008c395..b13f8d4cf 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -32,6 +32,7 @@ #include "hw/usb.h" #include "hw/baum.h" #include "hw/msmouse.h" +#include "qemu-objects.h" #include #include @@ -2469,13 +2470,51 @@ void qemu_chr_close(CharDriverState *chr) qemu_free(chr); } -void qemu_chr_info(Monitor *mon) +static void qemu_chr_qlist_iter(QObject *obj, void *opaque) { + QDict *chr_dict; + Monitor *mon = opaque; + + chr_dict = qobject_to_qdict(obj); + monitor_printf(mon, "%s: filename=%s\n", qdict_get_str(chr_dict, "label"), + qdict_get_str(chr_dict, "filename")); +} + +void qemu_chr_info_print(Monitor *mon, const QObject *ret_data) +{ + qlist_iter(qobject_to_qlist(ret_data), qemu_chr_qlist_iter, mon); +} + +/** + * qemu_chr_info(): Character devices information + * + * Each device is represented by a QDict. The returned QObject is a QList + * of all devices. + * + * The QDict contains the following: + * + * - "label": device's label + * - "filename": device's file + * + * Example: + * + * [ { "label": "monitor", "filename", "stdio" }, + * { "label": "serial0", "filename": "vc" } ] + */ +void qemu_chr_info(Monitor *mon, QObject **ret_data) +{ + QList *chr_list; CharDriverState *chr; + chr_list = qlist_new(); + QTAILQ_FOREACH(chr, &chardevs, next) { - monitor_printf(mon, "%s: filename=%s\n", chr->label, chr->filename); + QObject *obj = qobject_from_jsonf("{ 'label': %s, 'filename': %s }", + chr->label, chr->filename); + qlist_append_obj(chr_list, obj); } + + *ret_data = QOBJECT(chr_list); } CharDriverState *qemu_chr_find(const char *name) diff --git a/qemu-char.h b/qemu-char.h index 7fa8e5cc1..bcc07664d 100644 --- a/qemu-char.h +++ b/qemu-char.h @@ -5,6 +5,7 @@ #include "qemu-queue.h" #include "qemu-option.h" #include "qemu-config.h" +#include "qobject.h" /* character device */ @@ -88,7 +89,8 @@ int qemu_chr_can_read(CharDriverState *s); void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len); int qemu_chr_get_msgfd(CharDriverState *s); void qemu_chr_accept_input(CharDriverState *s); -void qemu_chr_info(Monitor *mon); +void qemu_chr_info_print(Monitor *mon, const QObject *ret_data); +void qemu_chr_info(Monitor *mon, QObject **ret_data); CharDriverState *qemu_chr_find(const char *name); extern int term_escape_char; -- cgit v1.2.3 From 3be42b28c14e2826eebbced68ad3ceb92507401d Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:04 -0200 Subject: monitor: Convert do_info_mice() to QObject Each mouse is represented by a QDict, the returned QObject is a QList of all mice. This commit should not change user output. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit e78c48ec4e192ef1b1a210bdf5a8d253d7826c25) --- console.h | 3 ++- monitor.c | 3 ++- vl.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/console.h b/console.h index 9615f5636..c7172f6d3 100644 --- a/console.h +++ b/console.h @@ -44,7 +44,8 @@ struct MouseTransformInfo { int a[7]; }; -void do_info_mice(Monitor *mon); +void do_info_mice_print(Monitor *mon, const QObject *data); +void do_info_mice(Monitor *mon, QObject **ret_data); void do_mouse_set(Monitor *mon, const QDict *qdict); /* keysym is a unicode code except for special keys (see QEMU_KEY_xxx diff --git a/monitor.c b/monitor.c index daa45fcaa..aa97f89b3 100644 --- a/monitor.c +++ b/monitor.c @@ -2518,7 +2518,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show which guest mouse is receiving events", - .mhandler.info = do_info_mice, + .user_print = do_info_mice_print, + .mhandler.info_new = do_info_mice, }, { .name = "vnc", diff --git a/vl.c b/vl.c index d02893173..c0d98f56d 100644 --- a/vl.c +++ b/vl.c @@ -156,6 +156,7 @@ int main(int argc, char **argv) #include "balloon.h" #include "qemu-option.h" #include "qemu-config.h" +#include "qemu-objects.h" #include "disas.h" @@ -490,25 +491,72 @@ int kbd_mouse_is_absolute(void) return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute; } -void do_info_mice(Monitor *mon) +static void info_mice_iter(QObject *data, void *opaque) +{ + QDict *mouse; + Monitor *mon = opaque; + + mouse = qobject_to_qdict(data); + monitor_printf(mon, "%c Mouse #%" PRId64 ": %s\n", + (qdict_get_bool(mouse, "current") ? '*' : ' '), + qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name")); +} + +void do_info_mice_print(Monitor *mon, const QObject *data) +{ + QList *mice_list; + + mice_list = qobject_to_qlist(data); + if (qlist_empty(mice_list)) { + monitor_printf(mon, "No mouse devices connected\n"); + return; + } + + qlist_iter(mice_list, info_mice_iter, mon); +} + +/** + * do_info_mice(): Show VM mice information + * + * Each mouse is represented by a QDict, the returned QObject is a QList of + * all mice. + * + * The mouse QDict contains the following: + * + * - "name": mouse's name + * - "index": mouse's index + * - "current": true if this mouse is receiving events, false otherwise + * + * Example: + * + * [ { "name": "QEMU Microsoft Mouse", "index": 0, "current": false }, + * { "name": "QEMU PS/2 Mouse", "index": 1, "current": true } ] + */ +void do_info_mice(Monitor *mon, QObject **ret_data) { QEMUPutMouseEntry *cursor; + QList *mice_list; int index = 0; + mice_list = qlist_new(); + if (!qemu_put_mouse_event_head) { - monitor_printf(mon, "No mouse devices connected\n"); - return; + goto out; } - monitor_printf(mon, "Mouse devices available:\n"); cursor = qemu_put_mouse_event_head; while (cursor != NULL) { - monitor_printf(mon, "%c Mouse #%d: %s\n", - (cursor == qemu_put_mouse_event_current ? '*' : ' '), - index, cursor->qemu_put_mouse_event_name); + QObject *obj; + obj = qobject_from_jsonf("{ 'name': %s, 'index': %d, 'current': %i }", + cursor->qemu_put_mouse_event_name, + index, cursor == qemu_put_mouse_event_current); + qlist_append_obj(mice_list, obj); index++; cursor = cursor->next; } + +out: + *ret_data = QOBJECT(mice_list); } void do_mouse_set(Monitor *mon, const QDict *qdict) -- cgit v1.2.3 From 1c1d7bda2cd507aec72057a1c16094541add9dd6 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:09 -0200 Subject: PCI: Convert pci_device_hot_add() to QObject Return a QDict with information about the just added device. This commit should not change user output. Please, note that this patch does not do error handling conversion. In error conditions the handler still calls monitor_printf(). Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit 7a344f7ac7bb651d0556a933ed8060d3a9e5d949) --- hw/pci-hotplug.c | 40 ++++++++++++++++++++++++++++++++++++---- qemu-monitor.hx | 3 ++- sysemu.h | 3 ++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 9e8e6ed42..f10c868ee 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -33,6 +33,7 @@ #include "scsi.h" #include "virtio-blk.h" #include "qemu-config.h" +#include "qemu-objects.h" #if defined(TARGET_I386) static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, @@ -228,7 +229,36 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, return dev; } -void pci_device_hot_add(Monitor *mon, const QDict *qdict) +void pci_device_hot_add_print(Monitor *mon, const QObject *data) +{ + QDict *qdict; + + assert(qobject_type(data) == QTYPE_QDICT); + qdict = qobject_to_qdict(data); + + monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n", + (int) qdict_get_int(qdict, "domain"), + (int) qdict_get_int(qdict, "bus"), + (int) qdict_get_int(qdict, "slot"), + (int) qdict_get_int(qdict, "function")); + +} + +/** + * pci_device_hot_add(): Hot add a PCI device + * + * Return a QDict with the following device information: + * + * - "domain": domain number + * - "bus": bus number + * - "slot": slot number + * - "function": function number + * + * Example: + * + * { "domain": 0, "bus": 0, "slot": 5, "function": 0 } + */ +void pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data) { PCIDevice *dev = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); @@ -255,9 +285,11 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict) monitor_printf(mon, "invalid type: %s\n", type); if (dev) { - monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n", - 0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); + *ret_data = + qobject_from_jsonf("{ 'domain': 0, 'bus': %d, 'slot': %d, " + "'function': %d }", pci_bus_num(dev->bus), + PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + assert(*ret_data != NULL); } else monitor_printf(mon, "failed to add %s\n", opts); } diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 0657b2d16..c788c7378 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -810,7 +810,8 @@ ETEXI .args_type = "pci_addr:s,type:s,opts:s?", .params = "auto|[[:]:] nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", .help = "hot-add PCI device", - .mhandler.cmd = pci_device_hot_add, + .user_print = pci_device_hot_add_print, + .mhandler.cmd_new = pci_device_hot_add, }, #endif diff --git a/sysemu.h b/sysemu.h index efed771d0..9d80bb202 100644 --- a/sysemu.h +++ b/sysemu.h @@ -212,7 +212,8 @@ extern DriveInfo *drive_init(QemuOpts *arg, void *machine, int *fatal_error); DriveInfo *add_init_drive(const char *opts); /* pci-hotplug */ -void pci_device_hot_add(Monitor *mon, const QDict *qdict); +void pci_device_hot_add_print(Monitor *mon, const QObject *data); +void pci_device_hot_add(Monitor *mon, const QDict *qdict, QObject **ret_data); void drive_hot_add(Monitor *mon, const QDict *qdict); void pci_device_hot_remove(Monitor *mon, const char *pci_addr); void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict, -- cgit v1.2.3 From 5118f7b47cdb388f7411713d56865a0e610d0abd Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Thu, 10 Dec 2009 17:16:10 -0200 Subject: VNC: Convert do_info_vnc() to QObject Return a QDict with server information. Connected clients are returned as a QList of QDicts. The new functions (vnc_qdict_remote_addr(), vnc_qdict_local_addr() and put_addr_qdict()) are used to insert 'host' and 'service' information in the returned QDict. This patch is big, but I don't see how to split it. Signed-off-by: Luiz Capitulino Signed-off-by: Anthony Liguori (cherry picked from commit d96fd29cca420d1ff3d34cde233cf41a3818c550) --- console.h | 3 +- monitor.c | 3 +- vnc.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 166 insertions(+), 33 deletions(-) diff --git a/console.h b/console.h index c7172f6d3..dfc8ae41d 100644 --- a/console.h +++ b/console.h @@ -323,7 +323,8 @@ void vnc_display_init(DisplayState *ds); void vnc_display_close(DisplayState *ds); int vnc_display_open(DisplayState *ds, const char *display); int vnc_display_password(DisplayState *ds, const char *password); -void do_info_vnc(Monitor *mon); +void do_info_vnc_print(Monitor *mon, const QObject *data); +void do_info_vnc(Monitor *mon, QObject **ret_data); char *vnc_display_local_addr(DisplayState *ds); /* curses.c */ diff --git a/monitor.c b/monitor.c index 897280ab5..d97d529cc 100644 --- a/monitor.c +++ b/monitor.c @@ -2529,7 +2529,8 @@ static const mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the vnc server status", - .mhandler.info = do_info_vnc, + .user_print = do_info_vnc_print, + .mhandler.info_new = do_info_vnc, }, { .name = "name", diff --git a/vnc.c b/vnc.c index 39c0d9860..c54c6e070 100644 --- a/vnc.c +++ b/vnc.c @@ -29,6 +29,7 @@ #include "qemu_socket.h" #include "qemu-timer.h" #include "acl.h" +#include "qemu-objects.h" #define VNC_REFRESH_INTERVAL_BASE 30 #define VNC_REFRESH_INTERVAL_INC 50 @@ -99,6 +100,54 @@ char *vnc_socket_remote_addr(const char *format, int fd) { return addr_to_string(format, &sa, salen); } +static int put_addr_qdict(QDict *qdict, struct sockaddr_storage *sa, + socklen_t salen) +{ + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + int err; + + if ((err = getnameinfo((struct sockaddr *)sa, salen, + host, sizeof(host), + serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { + VNC_DEBUG("Cannot resolve address %d: %s\n", + err, gai_strerror(err)); + return -1; + } + + qdict_put(qdict, "host", qstring_from_str(host)); + qdict_put(qdict, "service", qstring_from_str(serv)); + + return 0; +} + +static int vnc_qdict_local_addr(QDict *qdict, int fd) +{ + struct sockaddr_storage sa; + socklen_t salen; + + salen = sizeof(sa); + if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) { + return -1; + } + + return put_addr_qdict(qdict, &sa, salen); +} + +static int vnc_qdict_remote_addr(QDict *qdict, int fd) +{ + struct sockaddr_storage sa; + socklen_t salen; + + salen = sizeof(sa); + if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) { + return -1; + } + + return put_addr_qdict(qdict, &sa, salen); +} + static const char *vnc_auth_name(VncDisplay *vd) { switch (vd->auth) { case VNC_AUTH_INVALID: @@ -150,58 +199,140 @@ static const char *vnc_auth_name(VncDisplay *vd) { return "unknown"; } -static void do_info_vnc_client(Monitor *mon, VncState *client) +static QDict *do_info_vnc_client(Monitor *mon, VncState *client) { - char *clientAddr = - vnc_socket_remote_addr(" address: %s:%s\n", - client->csock); - if (!clientAddr) - return; + QDict *qdict; - monitor_printf(mon, "Client:\n"); - monitor_printf(mon, "%s", clientAddr); - free(clientAddr); + qdict = qdict_new(); + if (vnc_qdict_remote_addr(qdict, client->csock) < 0) { + QDECREF(qdict); + return NULL; + } #ifdef CONFIG_VNC_TLS if (client->tls.session && - client->tls.dname) - monitor_printf(mon, " x509 dname: %s\n", client->tls.dname); - else - monitor_printf(mon, " x509 dname: none\n"); + client->tls.dname) { + qdict_put(qdict, "x509_dname", qstring_from_str(client->tls.dname)); + } #endif #ifdef CONFIG_VNC_SASL if (client->sasl.conn && - client->sasl.username) - monitor_printf(mon, " username: %s\n", client->sasl.username); - else - monitor_printf(mon, " username: none\n"); + client->sasl.username) { + qdict_put(qdict, "username", qstring_from_str(client->sasl.username)); + } #endif + + return qdict; } -void do_info_vnc(Monitor *mon) +static void info_vnc_iter(QObject *obj, void *opaque) { - if (vnc_display == NULL || vnc_display->display == NULL) { + QDict *client; + Monitor *mon = opaque; + + client = qobject_to_qdict(obj); + monitor_printf(mon, "Client:\n"); + monitor_printf(mon, " address: %s:%s\n", + qdict_get_str(client, "host"), + qdict_get_str(client, "service")); + +#ifdef CONFIG_VNC_TLS + monitor_printf(mon, " x509_dname: %s\n", + qdict_haskey(client, "x509_dname") ? + qdict_get_str(client, "x509_dname") : "none"); +#endif +#ifdef CONFIG_VNC_SASL + monitor_printf(mon, " username: %s\n", + qdict_haskey(client, "username") ? + qdict_get_str(client, "username") : "none"); +#endif +} + +void do_info_vnc_print(Monitor *mon, const QObject *data) +{ + QDict *server; + QList *clients; + + server = qobject_to_qdict(data); + if (strcmp(qdict_get_str(server, "status"), "disabled") == 0) { monitor_printf(mon, "Server: disabled\n"); - } else { - char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n", - vnc_display->lsock); + return; + } - if (!serverAddr) - return; + monitor_printf(mon, "Server:\n"); + monitor_printf(mon, " address: %s:%s\n", + qdict_get_str(server, "host"), + qdict_get_str(server, "service")); + monitor_printf(mon, " auth: %s\n", + qdict_haskey(server, "auth") ? qdict_get_str(server, "auth") : "none"); + + clients = qdict_get_qlist(server, "clients"); + if (qlist_empty(clients)) { + monitor_printf(mon, "Client: none\n"); + } else { + qlist_iter(clients, info_vnc_iter, mon); + } +} - monitor_printf(mon, "Server:\n"); - monitor_printf(mon, "%s", serverAddr); - free(serverAddr); - monitor_printf(mon, " auth: %s\n", vnc_auth_name(vnc_display)); +/** + * do_info_vnc(): Show VNC server information + * + * Return a QDict with server information. Connected clients are returned + * as a QList of QDicts. + * + * The main QDict contains the following: + * + * - "status": "disabled" or "enabled" + * - "host": server's IP address + * - "service": server's port number + * - "auth": authentication method (optional) + * - "clients": a QList of all connected clients + * + * Clients are described by a QDict, with the following information: + * + * - "host": client's IP address + * - "service": client's port number + * - "x509_dname": TLS dname (optional) + * - "username": SASL username (optional) + * + * Example: + * + * { "status": "enabled", "host": "0.0.0.0", "service": "50402", "auth": "vnc", + * "clients": [ { "host": "127.0.0.1", "service": "50401" } ] } + */ +void do_info_vnc(Monitor *mon, QObject **ret_data) +{ + if (vnc_display == NULL || vnc_display->display == NULL) { + *ret_data = qobject_from_jsonf("{ 'status': 'disabled' }"); + } else { + QDict *qdict; + QList *clist; + clist = qlist_new(); if (vnc_display->clients) { VncState *client = vnc_display->clients; while (client) { - do_info_vnc_client(mon, client); + qdict = do_info_vnc_client(mon, client); + if (qdict) + qlist_append(clist, qdict); client = client->next; } - } else { - monitor_printf(mon, "Client: none\n"); + } + + *ret_data = qobject_from_jsonf("{ 'status': 'enabled', 'clients': %p }", + QOBJECT(clist)); + assert(*ret_data != NULL); + + qdict = qobject_to_qdict(*ret_data); + + if (vnc_display->auth != VNC_AUTH_NONE) { + qdict_put(qdict, "auth", + qstring_from_str(vnc_auth_name(vnc_display))); + } + + if (vnc_qdict_local_addr(qdict, vnc_display->lsock) < 0) { + qobject_decref(*ret_data); + *ret_data = NULL; } } } -- cgit v1.2.3 From 0014803d23acaccc15b31180f06784f5d6edfd3a Mon Sep 17 00:00:00 2001 From: Glauber Costa Date: Thu, 22 Oct 2009 10:26:56 -0200 Subject: v2: properly save kvm system time msr registers Currently, the msrs involved in setting up pvclock are not saved over migration and/or save/restore. This patch puts their value in special fields in our CPUState, and deal with them using vmstate. kvm also has to account for it, by including them in the msr list for the ioctls. This is a backport from qemu-kvm.git [v2: sucessfully build without kerneldir ] Signed-off-by: Glauber Costa Signed-off-by: Marcelo Tosatti Signed-off-by: Anthony Liguori (cherry picked from commit 1a03675db146dfc760b3b48b3448075189f142cc) --- target-i386/cpu.h | 2 ++ target-i386/kvm.c | 15 +++++++++++++++ target-i386/machine.c | 3 +++ 3 files changed, 20 insertions(+) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 9c3e905f6..9ef1be482 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -651,6 +651,8 @@ typedef struct CPUX86State { target_ulong fmask; target_ulong kernelgsbase; #endif + uint64_t system_time_msr; + uint64_t wall_clock_msr; uint64_t tsc; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 88b504c34..53955b405 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -35,6 +35,9 @@ do { } while (0) #endif +#define MSR_KVM_WALL_CLOCK 0x11 +#define MSR_KVM_SYSTEM_TIME 0x12 + #ifdef KVM_CAP_EXT_CPUID static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) @@ -494,6 +497,9 @@ static int kvm_put_msrs(CPUState *env) kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask); kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar); #endif + kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, env->system_time_msr); + kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr); + msr_data.info.nmsrs = n; return kvm_vcpu_ioctl(env, KVM_SET_MSRS, &msr_data); @@ -634,6 +640,9 @@ static int kvm_get_msrs(CPUState *env) msrs[n++].index = MSR_FMASK; msrs[n++].index = MSR_LSTAR; #endif + msrs[n++].index = MSR_KVM_SYSTEM_TIME; + msrs[n++].index = MSR_KVM_WALL_CLOCK; + msr_data.info.nmsrs = n; ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data); if (ret < 0) @@ -670,6 +679,12 @@ static int kvm_get_msrs(CPUState *env) case MSR_IA32_TSC: env->tsc = msrs[i].data; break; + case MSR_KVM_SYSTEM_TIME: + env->system_time_msr = msrs[i].data; + break; + case MSR_KVM_WALL_CLOCK: + env->wall_clock_msr = msrs[i].data; + break; } } diff --git a/target-i386/machine.c b/target-i386/machine.c index ab4633e65..2fb8faba9 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -461,6 +461,9 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_UINT64_ARRAY_V(mce_banks, CPUState, MCE_BANKS_DEF *4, 10), /* rdtscp */ VMSTATE_UINT64_V(tsc_aux, CPUState, 11), + /* KVM pvclock msr */ + VMSTATE_UINT64_V(system_time_msr, CPUState, 11), + VMSTATE_UINT64_V(wall_clock_msr, CPUState, 11), VMSTATE_END_OF_LIST() /* The above list is not sorted /wrt version numbers, watch out! */ } -- cgit v1.2.3 From a68fc29ceb7ed18baffbe9cb47c4ab7f80131593 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Sat, 12 Dec 2009 08:29:25 -0600 Subject: Update Changelog and VERSION for 0.12.0-rc2 Signed-off-by: Anthony Liguori --- Changelog | 36 ++++++++++++++++++++++++++++++++++++ VERSION | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index 2a3e37d2b..79cd934a4 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,39 @@ +version 0.12.0-rc2: + + - v2: properly save kvm system time msr registers (Glauber Costa) + - convert more monitor commands to qmp (Luiz Capitulino) + - vnc: fix capslock tracking logic. (Gerd Hoffmann) + - QemuOpts: allow larger option values. (Gerd Hoffmann) + - scsi: fix drive hotplug. (Gerd Hoffmann) + - pci: don't hw_error() when no slot is available. (Gerd Hoffmann) + - pci: don't abort() when trying to hotplug with acpi off. (Gerd Hoffmann) + - allow default devices to be implemented in config file (Gerd Hoffman) + - vc: colorize chardev title line with blue background. (Gerd Hoffmann) + - chardev: make chardevs specified in config file work. (Gerd Hoffmann) + - qdev: also match bus name for global properties (Gerd Hoffmann) + - qdev: add command line option to set global defaults for properties. (Gerd Hoffmann) + - kvm: x86: Save/restore exception_index (Jan Kiszka) + - qdev: Replace device names containing whitespace (Markus Armbruster) + - fix rtc-td-hack on host without high-res timers (Gleb Natapov) + - virtio: verify features on load (Michael S. Tsirkin) + - vmware_vga: add rom file so that it boots. (Dave Airlie) + - Do not abort on qemu_malloc(0) in production builds (Anthony Liguori) + - Fix ARM userspace strex implementation. (Paul Brook) + - qemu: delete rule target on error (Michael S. Tsirkin) + - QMP: add human-readable description to error response (Markus Armbruster) + - convert more monitor commands to QError (Markus Armbruster) + - monitor: Fix double-prompt after "change vnc passwd BLA" (Markus Armbruster) + - monitor: do_cont(): Don't ask for passwords (Luiz Capitulino) + - monitor: Introduce 'block_passwd' command (Luiz Capitulino) + - pci: interrupt disable bit support (Michael S. Tsirkin) + - pci: interrupt status bit implementation (Michael S. Tsirkin) + - pci: prepare irq code for interrupt state (Michael S. Tsirkin) + - msix: function mask support (Michael S. Tsirkin) + - msix: macro rename for function mask support (Michael S. Tsirkin) + - cpuid: Fix multicore setup on Intel (Andre Przywara) + - kvm: x86: Fix initial kvm_has_msr_star (Jan Kiszka) + - Update OpenBIOS images to r640 (Aurelien Jarno) + version 0.10.2: - fix savevm/loadvm (Anthony Liguori) diff --git a/VERSION b/VERSION index 568d15238..c25276499 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.91 +0.11.92 -- cgit v1.2.3 From 03a23e5c6ea4ce318a430b23f7dffbfebcd57ee2 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 13 Dec 2009 16:44:33 +0200 Subject: s390: fix build on 32 bit host MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building on 32 bit host we get: hw/s390-virtio.c: In function ‘s390_init’: hw/s390-virtio.c:184: error: integer constant is too large for ‘unsigned long’ type 64 bit values must be ULL. Signed-off-by: Michael S. Tsirkin Acked-by: Alexander Graf Signed-off-by: Aurelien Jarno --- hw/s390-virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index 51c032adc..e71dbe61a 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -181,7 +181,7 @@ static void s390_init(ram_addr_t ram_size, cpu_synchronize_state(env); env->psw.addr = KERN_IMAGE_START; - env->psw.mask = 0x0000000180000000UL; + env->psw.mask = 0x0000000180000000ULL; } if (initrd_filename) { -- cgit v1.2.3 From 251241dc90e66189dd78bdc68c34a2d6474b0230 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 13 Dec 2009 16:45:47 +0200 Subject: s390: typo fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s390 code has an obvious typo, which results in: hw/s390-virtio.c: At top level: hw/s390-virtio.c:249: error: request for member ‘no_vga’ in something not a structure or union Signed-off-by: Michael S. Tsirkin Acked-by: Alexander Graf Signed-off-by: Aurelien Jarno --- hw/s390-virtio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c index e71dbe61a..b56788652 100644 --- a/hw/s390-virtio.c +++ b/hw/s390-virtio.c @@ -245,7 +245,7 @@ static QEMUMachine s390_machine = { .init = s390_init, .no_serial = 1, .no_parallel = 1, - .use_virtcon = 1. + .use_virtcon = 1, .no_vga = 1, .max_cpus = 255, .is_default = 1, -- cgit v1.2.3 From 910628f39676ee65211727245809eec7ca4d75f5 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Mon, 7 Dec 2009 12:05:38 +0100 Subject: target-i386: Update CPUID feature set for TCG The CPUID features QEMU presented to the guest were not up-to-date with QEMU's emulated feature set. Add the missing bits of recent (and not so recent) additions to QEMU's emulation engine. For stability reasons only the user mode usable bits are exposed for now, features like Monitor or CR8LEG are left out. Signed-off-by: Andre Przywara Signed-off-by: Aurelien Jarno (cherry picked from commit f1e00a9cf326acc1f2386a72525af8859852e1df) --- target-i386/helper.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/target-i386/helper.c b/target-i386/helper.c index 08e6d6c39..730e396a6 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -131,10 +131,11 @@ static x86_def_t x86_defs[] = { CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | /* this feature is needed for Solaris and isn't fully implemented */ CPUID_PSE36, - .ext_features = CPUID_EXT_SSE3, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT, .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - .ext3_features = CPUID_EXT3_SVM, + .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000000A, .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, @@ -151,18 +152,19 @@ static x86_def_t x86_defs[] = { .features = PPRO_FEATURES | CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36, - /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */ - .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 | + CPUID_EXT_POPCNT, /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */ .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT | CPUID_EXT2_FFXSR, - /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, - CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A, + /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC, + CPUID_EXT3_CR8LEG, CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH, CPUID_EXT3_OSVW, CPUID_EXT3_IBS */ - .ext3_features = CPUID_EXT3_SVM, + .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | + CPUID_EXT3_ABM | CPUID_EXT3_SSE4A, .xlevel = 0x8000001A, .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor" }, @@ -183,7 +185,7 @@ static x86_def_t x86_defs[] = { CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */ .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3, .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, - /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */ + .ext3_features = CPUID_EXT3_LAHF_LM, .xlevel = 0x80000008, .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz", }, @@ -221,7 +223,7 @@ static x86_def_t x86_defs[] = { .model = 3, .stepping = 3, .features = PPRO_FEATURES, - .ext_features = CPUID_EXT_SSE3, + .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT, .xlevel = 0, .model_id = "QEMU Virtual CPU version " QEMU_VERSION, }, @@ -1783,11 +1785,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } if (kvm_enabled()) { - /* Nested SVM not yet supported in KVM */ + /* Nested SVM not yet supported in upstream QEMU */ *ecx &= ~CPUID_EXT3_SVM; - } else { - /* AMD 3DNow! is not supported in QEMU */ - *edx &= ~(CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT); } break; case 0x80000002: -- cgit v1.2.3