[Qemu-devel] [PATCH v2 3/4] xilinx_spi: initial version
device model for xilinx XPS SPI controller (v2.0) Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com --- changed from v1: converted spi api to modified txrx style Makefile.target |1 + hw/xilinx_spi.c | 482 +++ 2 files changed, 483 insertions(+), 0 deletions(-) create mode 100644 hw/xilinx_spi.c diff --git a/Makefile.target b/Makefile.target index 6c568b4..be28bfe 100644 --- a/Makefile.target +++ b/Makefile.target @@ -321,6 +321,7 @@ obj-microblaze-y = petalogix_s3adsp1800_mmu.o obj-microblaze-y += petalogix_ml605_mmu.o obj-microblaze-y += microblaze_boot.o obj-microblaze-y += m25p80.o +obj-microblaze-y += xilinx_spi.o obj-microblaze-y += microblaze_pic_cpu.o obj-microblaze-y += xilinx_intc.o diff --git a/hw/xilinx_spi.c b/hw/xilinx_spi.c new file mode 100644 index 000..5e40015 --- /dev/null +++ b/hw/xilinx_spi.c @@ -0,0 +1,482 @@ +/* + * QEMU model of the Xilinx SPI Controller + * + * Copyright (C) 2010 Edgar E. Iglesias. + * Copyright (C) 2012 Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com + * Copyright (C) 2012 PetaLogix + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include sysbus.h +#include sysemu.h +#include ptimer.h +#include qemu-log.h + +#include spi.h + +#ifdef XILINX_SPI_ERR_DEBUG +#define DB_PRINT(...) do { \ +fprintf(stderr, : %s: , __func__); \ +fprintf(stderr, ## __VA_ARGS__); \ +} while (0); +#else +#define DB_PRINT(...) +#endif + +#define R_DGIER (0x1c / 4) +#define R_DGIER_IE (1 31) + +#define R_IPISR (0x20 / 4) +#define IRQ_DRR_NOT_EMPTY(1 (31 - 23)) +#define IRQ_DRR_OVERRUN (1 (31 - 26)) +#define IRQ_DRR_FULL (1 (31 - 27)) +#define IRQ_TX_FF_HALF_EMPTY (1 6) +#define IRQ_DTR_UNDERRUN (1 3) +#define IRQ_DTR_EMPTY(1 (31 - 29)) + +#define R_IPIER (0x28 / 4) +#define R_SRR (0x40 / 4) +#define R_SPICR (0x60 / 4) +#define R_SPICR_TXFF_RST (1 5) +#define R_SPICR_RXFF_RST (1 6) +#define R_SPICR_MTI (1 8) + +#define R_SPISR (0x64 / 4) +#define SR_TX_FULL(1 3) +#define SR_TX_EMPTY (1 2) +#define SR_RX_FULL(1 1) +#define SR_RX_EMPTY (1 0) + + +#define R_SPIDTR(0x68 / 4) +#define R_SPIDRR(0x6C / 4) +#define R_SPISSR(0x70 / 4) +#define R_TX_FF_OCY (0x74 / 4) +#define R_RX_FF_OCY (0x78 / 4) +#define R_MAX (0x7C / 4) + +struct XilinxSPI { +SysBusDevice busdev; +MemoryRegion mmio; +qemu_irq irq; +int irqline; + +QEMUBH *bh; +ptimer_state *ptimer; + +SPIBus *spi; + +uint32_t c_fifo_exist; + +uint8_t rx_fifo[256]; +unsigned int rx_fifo_pos; +unsigned int rx_fifo_len; + +uint8_t tx_fifo[256]; +unsigned int tx_fifo_pos; +unsigned int tx_fifo_len; + +/* Slave select. */ +uint8_t num_cs; +int cmd_ongoing; + +uint32_t regs[R_MAX]; +}; + +static void txfifo_reset(struct XilinxSPI *s) +{ +s-tx_fifo_pos = 0; +s-tx_fifo_len = 0; + +s-regs[R_SPISR] = ~SR_TX_FULL; +s-regs[R_SPISR] |= SR_TX_EMPTY; +s-regs[R_SPISR] = ~SR_TX_FULL; +s-regs[R_IPISR] |= IRQ_DTR_EMPTY; +} + +static void rxfifo_reset(struct XilinxSPI *s) +{ +s-rx_fifo_pos = 0; +s-rx_fifo_len = 0; + +s-regs[R_SPISR] |= SR_RX_EMPTY; +s-regs[R_SPISR] = ~SR_RX_FULL; +s-regs[R_IPISR] = ~IRQ_DRR_NOT_EMPTY; +s-regs[R_IPISR] = ~IRQ_DRR_OVERRUN; +} + +static void xlx_spi_reset(struct XilinxSPI *s) +{ +memset(s-regs, 0, sizeof s-regs); + +rxfifo_reset(s); +txfifo_reset(s); + +s-regs[R_SPISSR] = 1; +spi_set_cs(s-spi, 0); +} + +static void xlx_spi_update_irq(struct XilinxSPI *s) +{ +uint32_t pending; +pending = s-regs[R_IPISR] s-regs[R_IPIER]; + +pending = pending (s-regs[R_DGIER] R_DGIER_IE); +pending = !!pending; + +/* This call lies right in the data paths so dont call the + irq chain unless things really changed. */ +if
Re: [Qemu-devel] [PATCHv3] piix: fix up/down races
- Original Message - From: Michael S. Tsirkin m...@redhat.com To: Alex Williamson alex.william...@redhat.com Cc: qemu-devel@nongnu.org, Anthony Liguori aligu...@us.ibm.com, Gerd Hoffmann kra...@redhat.com, Isaku Yamahata yamah...@valinux.co.jp, Aurelien Jarno aurel...@aurel32.net, Paolo Bonzini pbonz...@redhat.com, g...@redhat.com, imamm...@redhat.com Sent: Monday, April 2, 2012 9:20:32 PM Subject: Re: [PATCHv3] piix: fix up/down races On Mon, Apr 02, 2012 at 12:59:54PM -0600, Alex Williamson wrote: On Mon, 2012-04-02 at 13:03 +0300, Michael S. Tsirkin wrote: piix acpi interface suffers from the following 2 issues: 1. - delete device a - quickly add device b in another slot if we do this before guest reads the down register, the down event is discarded and device will never be deleted. 2. - delete device a - quickly reset before guest can respond interrupt is reset and guest will never eject the device. To fix this, we implement three changes: 1. Do not clear up/down registers on each hotplug event. this ensures we don't lose events. 2. Make existing up/down registers write 1 to clear; bios will now write back to these the value it read. 3. on reset, remove all devices which have DOWN bit set For compatibility with old guests, we also clear the DOWN bit on write to EJ0 for a device. This patch also extends the documentation for the ACPI interface, to make the semantics explicit. Compatibility notes: migrating guests across qemu versions can cause bios from one qemu realease running on another qemu release. The following documents the behaviour in this case: A. new bios running on old qemu A bios implementing the change mentioned above will if running on an old qemu introduce a race: the registers were writeable there, so if a register changes between read and write, we'll clobber the new bits losing events. As that version tends to lose events anyway, and as the better than complicating the interface. If someone cares enough, the fix can go on the stable branch. Seems like it'd be easy to have seabios probe this on boot, ex. write value to 0xae00, read 0xae00 to see if value is reflected. If it is, old qemu, modify dsdt to avoid writes. This won't help at all: the issue is when we migrate to old qemu after boot. B. old bios running on new qemu Down bits will get cleared on eject because of 3 above. Up bits only get cleared on reset. This will cause unnecessary notifications and bus rescans, but they are harmless. Doesn't windows poll these bits. No. How can we say that introducing a bus rescan every poll interval is harmless? It's not done every poll interval - all this does is cause extra rescans when system interrupt is asserted. it will do rescan only when PIIX4_PCI_HOTPLUG_STATUS in gpe.sts is set. Signed-off-by: Michael S. Tsirkin m...@redhat.com --- Changes from v2: - Use existing register instead of adding a new one, and update documentation Changes from v1: - tweaked a comment about clearing down register on reset - documentation update docs/specs/acpi_pci_hotplug.txt | 55 +++- hw/acpi_piix4.c | 58 --- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.txt index f0f74a7..e4a9556 100644 --- a/docs/specs/acpi_pci_hotplug.txt +++ b/docs/specs/acpi_pci_hotplug.txt @@ -7,31 +7,70 @@ describes the interface between QEMU and the ACPI BIOS. ACPI GPE block (IO ports 0xafe0-0xafe3, byte access): - -Generic ACPI GPE block. Bit 1 (GPE.1) used to notify PCI hotplug/eject +Generic ACPI GPE block. Bit 1 (GPE.1) is used to notify PCI hotplug/hotunplug event to ACPI BIOS, via SCI interrupt. -PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access): +Semantics: this event occurs each time a bit in either Pending PCI slot +injection notification or Pending PCI slot removal notification registers +changes status from 0 to 1. Or if your bios doesn't clear it, 1 to 1. + +Pending PCI slot injection notification (IO port 0xae00-0xae03, 4-byte access): --- -Slot injection notification pending. One bit per slot. +Slot injection notification is pending. One bit per slot. +When written by Guest, this register implements write one to clear behaviour. So we're writing the mask of the bits (slots) to be cleared? Can multiple slots be cleared in one write? Read by ACPI BIOS GPE.1 handler to notify OS of injection events.
[Qemu-devel] [PATCH v2 0/2] SDHCI for Xilinx Zynq
These two patched add a device model for the standard SD host controller interface (1) and instantiates it as a device to the Xilinx Zynq platform (2). Peter A. G. Crosthwaite (2): SDHCI: inital version xilinx_zynq: added sdhci controller Makefile.target |1 + hw/sdhci.c | 736 ++ hw/xilinx_zynq.c | 13 +- 3 files changed, 749 insertions(+), 1 deletions(-) create mode 100644 hw/sdhci.c -- 1.7.3.2
[Qemu-devel] [PATCH v2 1/2] SDHCI: inital version
Device model for standard SD Host Controller Interface (SDHCI). Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com --- changed from v1: Made undefined op behaviour consisistent. fixed compile warning. Makefile.target |1 + hw/sdhci.c | 736 +++ 2 files changed, 737 insertions(+), 0 deletions(-) create mode 100644 hw/sdhci.c diff --git a/Makefile.target b/Makefile.target index 9b0cf74..c118dc6 100644 --- a/Makefile.target +++ b/Makefile.target @@ -363,6 +363,7 @@ obj-arm-y += versatile_pci.o obj-arm-y += cadence_uart.o obj-arm-y += cadence_ttc.o obj-arm-y += cadence_gem.o +obj-arm-y += sdhci.o obj-arm-y += xilinx_zynq.o zynq_slcr.o obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o diff --git a/hw/sdhci.c b/hw/sdhci.c new file mode 100644 index 000..b387013 --- /dev/null +++ b/hw/sdhci.c @@ -0,0 +1,736 @@ +/* + * Copyright 2011 Google Inc. + * Copyright (C) 2012 Peter A.G. Crosthwaite peter.crosthwa...@petalogix.com + * Copyright (C) 2012 PetaLogix Pty Ltd. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + * + * + * SDHCI (SD Host Controler Interface) emulation + */ + +#include blockdev.h +#include sysbus.h +#include sd.h + +#ifdef SDHCI_ERR_DEBUG +#define DB_PRINT(...) do { \ +fprintf(stderr, : %s: , __func__); \ +fprintf(stderr, ## __VA_ARGS__); \ +} while (0); +#else +#define DB_PRINT(...) +#endif + + +/* Controller registers */ + +#define SDHCI_DMA_ADDRESS 0x00 + +#define SDHCI_BLOCK_SIZE0x04 + +#define SDHCI_BLOCK_COUNT 0x06 + +#define SDHCI_ARGUMENT 0x08 + +#define SDHCI_TRANSFER_MODE 0x0C +#define SDHCI_TRNS_DMA 0x01 +#define SDHCI_TRNS_BLK_CNT_EN 0x02 +#define SDHCI_TRNS_ACMD12 0x04 +#define SDHCI_TRNS_READ0x10 +#define SDHCI_TRNS_MULTI 0x20 + +#define SDHCI_COMMAND 0x0E +#define SDHCI_CMD_RESP_MASK0x03 +#define SDHCI_CMD_CRC 0x08 +#define SDHCI_CMD_INDEX0x10 +#define SDHCI_CMD_DATA 0x20 + +#define SDHCI_CMD_RESP_NONE0x00 +#define SDHCI_CMD_RESP_LONG0x01 +#define SDHCI_CMD_RESP_SHORT 0x02 +#define SDHCI_CMD_RESP_SHORT_BUSY 0x03 + +#define SDHCI_RESPONSE 0x10 + +#define SDHCI_BUFFER0x20 + +#define SDHCI_PRESENT_STATE 0x24 +#define SDHCI_CMD_INHIBIT 0x0001 +#define SDHCI_DATA_INHIBIT 0x0002 +#define SDHCI_DOING_WRITE 0x0100 +#define SDHCI_DOING_READ 0x0200 +#define SDHCI_SPACE_AVAILABLE 0x0400 +#define SDHCI_DATA_AVAILABLE 0x0800 +#define SDHCI_CARD_PRESENT 0x0001 +#define SDHCI_WRITE_PROTECT0x0008 + +#define SDHCI_HOST_CONTROL 0x28 +#define SDHCI_CTRL_LED 0x01 +#define SDHCI_CTRL_4BITBUS 0x02 +#define SDHCI_CTRL_HISPD 0x04 +#define SDHCI_CTRL_DMA_MASK0x18 +#define SDHCI_CTRL_SDMA 0x00 +#define SDHCI_CTRL_ADMA1 0x08 +#define SDHCI_CTRL_ADMA32 0x10 +#define SDHCI_CTRL_ADMA64 0x18 +#define SDHCI_CTRL_8BITBUS0x20 + +#define SDHCI_POWER_CONTROL 0x29 +#define SDHCI_POWER_ON 0x01 +#define SDHCI_POWER_1800x0A +#define SDHCI_POWER_3000x0C +#define SDHCI_POWER_3300x0E + +#define SDHCI_BLOCK_GAP_CONTROL 0x2A + +#define SDHCI_WAKE_UP_CONTROL 0x2B +#define SDHCI_WAKE_ON_INT 0x01 +#define SDHCI_WAKE_ON_INSERT 0x02 +#define SDHCI_WAKE_ON_REMOVE 0x04 + +#define SDHCI_CLOCK_CONTROL 0x2C +#define SDHCI_DIVIDER_SHIFT8 +#define SDHCI_DIVIDER_HI_SHIFT 6 +#define SDHCI_DIV_MASK 0xFF +#define SDHCI_DIV_MASK_LEN 8 +#define SDHCI_DIV_HI_MASK 0x300 +#define SDHCI_CLOCK_CARD_EN0x0004 +#define SDHCI_CLOCK_INT_STABLE 0x0002 +#define SDHCI_CLOCK_INT_EN 0x0001 + +#define SDHCI_TIMEOUT_CONTROL 0x2E + +#define SDHCI_SOFTWARE_RESET0x2F +#define SDHCI_RESET_ALL0x01 +#define SDHCI_RESET_CMD0x02 +#define SDHCI_RESET_DATA 0x04 + +#define SDHCI_INT_STATUS0x30 +#define SDHCI_INT_ENABLE0x34 +#define SDHCI_SIGNAL_ENABLE 0x38 +#define SDHCI_INT_RESPONSE 0x0001 +#define SDHCI_INT_DATA_END 0x0002 +#define SDHCI_INT_DMA_END
[Qemu-devel] [PATCH v2 2/2] xilinx_zynq: added sdhci controller
Signed-off-by: Peter A. G. Crosthwaite peter.crosthwa...@petalogix.com --- hw/xilinx_zynq.c | 13 - 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/hw/xilinx_zynq.c b/hw/xilinx_zynq.c index 31d9e81..e92ebe0 100644 --- a/hw/xilinx_zynq.c +++ b/hw/xilinx_zynq.c @@ -161,6 +161,18 @@ static void zynq_init(ram_addr_t ram_size, const char *boot_device, sysbus_create_varargs(cadence_ttc, 0xF8002000, pic[69-IRQ_OFFSET], pic[70-IRQ_OFFSET], pic[71-IRQ_OFFSET], NULL); +dev = qdev_create(NULL, sysbus_sdhci); +dinfo = drive_get(IF_SD, 0, 0); +if (dinfo) { +if (qdev_prop_set_drive(dev, block, dinfo ? dinfo-bdrv : NULL)) { +fprintf(stderr, ZYNQ: ERROR: bad sd data file specified\n); +} +} +qdev_init_nofail(dev); +busdev = sysbus_from_qdev(dev); +sysbus_mmio_map(busdev, 0, 0xE010); +sysbus_connect_irq(busdev, 0, pic[56-IRQ_OFFSET]); + for (n = 0; n nb_nics; n++) { nd = nd_table[n]; if (n == 0) { @@ -190,7 +202,6 @@ static QEMUMachine zynq_machine = { .init = zynq_init, .use_scsi = 1, .max_cpus = 2, -.no_sdcard = 1 }; static void zynq_machine_init(void) -- 1.7.3.2
Re: [Qemu-devel] [PATCH 3/4] Switch from array based resource allocation to list
Hi Kevin, Thank you for the patches! I've created a diff of final version of your changes over mine, to make it clear what has changed. Rather than including the complete diff, I've just left relevant parts and added comments. --- a/src/pciinit.c +++ b/src/pciinit.c@@ -12,8 +12,9 @@ @@ -34,25 +35,44 @@ struct pci_region_entry { struct pci_device *dev; int bar; -u32 base; u32 size; -int is64bit; +int is64; enum pci_region_type type; -struct pci_bus *this_bus; +struct pci_bus *child_bus; Structure members naming was one of difficult things when I was writing the code. The child_bus might be a bit confusing as people may thing that it describes a child bus in the bus topology,in fact this element describes the bus this pci_region_entry is representing. ... + +static int pci_size_to_index(u32 size, enum pci_region_type type) +{ +int index = __fls(size); +int shift = (type == PCI_REGION_TYPE_IO) ? +PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT; + +if (index shift) +index = shift; +index -= shift; +return index; +} + +static u32 pci_index_to_size(int index, enum pci_region_type type) +{ +int shift = (type == PCI_REGION_TYPE_IO) ? +PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT; + +return 0x1 (index + shift); +} The only purpose to have these functions is to define the minimum size of pci BAR. They are used only once. What if we add size adjustment to pci_region_create_entry, or just create a function like pci_adjust_size(u32 size, enum pci_region_type type, int bridge)? . -list_add_head(bus-r[type].list, entry); entry-parent_bus = bus; - +// Insert into list in sorted order. +struct pci_region_entry **pprev; +for (pprev = bus-r[type].list; *pprev; pprev = (*pprev)-next) { +struct pci_region_entry *pos = *pprev; +if (pos-size size) +break; +} +entry-next = *pprev; +*pprev = entry; + .. static void pci_bios_map_devices(struct pci_bus *busses) { -struct pci_region_entry *entry, *next; - +// Map regions on each device. int bus; for (bus = 0; bus=MaxPCIBus; bus++) { int type; for (type = 0; type PCI_REGION_TYPE_COUNT; type++) { -u32 size; -for (size = busses[bus].r[type].max; size 0; size = 1) { -list_foreach_entry_safe(busses[bus].r[type].list, - next, entry) { -if (size == entry-size) { -entry-base = busses[bus].r[type].base; -busses[bus].r[type].base += size; -pci_region_map_one_entry(entry); -list_del(entry); -free(entry); -} -} +struct pci_region_entry *entry = busses[bus].r[type].list; +while (entry) { +pci_region_map_one_entry(entry); +struct pci_region_entry *next = entry-next; +free(entry); +entry = next; } } } Right, instead of sorting entries by size in pci_bios_map_devices, the entries are sorted when they are created. This makes the implementation simpler. Note: In case of 64bit BARs we have to migrate entries, so just sorting on create won't be enough, we should also add sorting when entries are migrated. This will add some more complexity, while in case of old implementation complexity will remain the same. I expect it shouldn't be that complicated, so any of these approaches are fine for me.
Re: [Qemu-devel] [PATCH, RESEND] kvm: Fix dirty tracking with large kernel page size
On 2012-04-02 06:04, David Gibson wrote: From: Ben Herrenschmidt b...@kernel.crashing.org If the kernel page size is larger than TARGET_PAGE_SIZE, which happens for example on ppc64 with kernels compiled for 64K pages, the dirty tracking doesn't work. Cc: Avi Kivity a...@redhat.com Cc: Marcelo Tosatti mtosa...@redhat.com Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org Signed-off-by: David Gibson da...@gibson.dropbear.id.au --- kvm-all.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) I've sent this a number of times now, the last couple without comment. It fixes a real bug, please apply. diff --git a/kvm-all.c b/kvm-all.c index ba2cee1..7e44429 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -354,6 +354,7 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section, unsigned long page_number, c; target_phys_addr_t addr, addr1; unsigned int len = ((section-size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) / HOST_LONG_BITS; +unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE; /* * bitmap-traveling is faster than memory-traveling (for addr...) @@ -365,10 +366,11 @@ static int kvm_get_dirty_pages_log_range(MemoryRegionSection *section, do { j = ffsl(c) - 1; c = ~(1ul j); -page_number = i * HOST_LONG_BITS + j; +page_number = (i * HOST_LONG_BITS + j) * hpratio; addr1 = page_number * TARGET_PAGE_SIZE; addr = section-offset_within_region + addr1; -memory_region_set_dirty(section-mr, addr, TARGET_PAGE_SIZE); +memory_region_set_dirty(section-mr, addr, +TARGET_PAGE_SIZE * hpratio); } while (c != 0); } } Ack for this, but - as proposed earlier - please add an assert(TARGET_PAGE_SIZE = getpagesize()) + comment to kvm_init(). Also, what's about coalesced MMIO? I see that the ring definition depends on [TARGET_]PAGE_SIZE. What page size does the power kernel use for it, and does it make a relevant difference for space? Jan signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] Better support for dma_addr_t variables
On 3 April 2012 01:51, David Gibson d...@au1.ibm.com wrote: On Mon, Apr 02, 2012 at 09:49:12AM +0200, Andreas Färber wrote: Yes, the issue here is under what license the file is. It's a new file, so in lack of a license statement is it under GPLv2 because QEMU as a whole currently is? Thus a header explicitly saying that it's under GPLv2+ (or BSD or MIT/X11 or ...) would be appreciated to avoid further complications. Compare our GPLv2+ relicensing page: http://wiki.qemu.org/Relicensing It's 4 trivial lines. Well under the copyrightability threshold even by the paranoid estimates of IBM Legal. (a) other legal departments may be more paranoid still (b) how about when somebody else adds more code to the header later (c) if a file has a clear license statement then it's immediately obvious what the situation is. Why be ambigious when you can be clear? -- PMM
Re: [Qemu-devel] qdev property listing broken
Il 03/04/2012 00:27, Peter Maydell ha scritto: On 2 April 2012 23:03, Paolo Bonzini pbonz...@redhat.com wrote: Il 02/04/2012 22:07, Peter Maydell ha scritto: On 2 April 2012 20:40, Paolo Bonzini pbonz...@redhat.com wrote: diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index a310cc7..923519c 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -157,7 +157,7 @@ int qdev_device_help(QemuOpts *opts) * for removal. This conditional should be removed along with * it. */ -if (!prop-info-parse) { +if (!prop-info-get) { continue; /* no way to set it, don't show */ } This looks really weird: there's no get method so we conclude no way to *set* it ?? Is the comment wrong? See the comment above. You mean /* * TODO Properties without a parser are just for dirty hacks. * qdev_prop_ptr is the only such PropertyInfo. It's marked * for removal. This conditional should be removed along with * it. */ ? That also looks odd now because we're no longer testing whether the property has a parser... (plus doesn't qdev_prop_vlan also have no parser ?) Oops... parse is set, print is get. It was too late... Paolo
[Qemu-devel] [RFC][PATCH v2 0/4] uq/master: Basic MSI support for in-kernel irqchip mode
This is v2 of the RFC, fixing a memory leak in kvm_flush_dynamic_msi_routes and adding support for the proposed KVM_SIGNAL_MSI IOCTL. This series depends on kvm: set gsi_bits and max_gsi correctly (http://thread.gmane.org/gmane.comp.emulators.kvm.devel/88906). Jan Kiszka (4): kvm: Refactor KVMState::max_gsi to gsi_count kvm: Introduce basic MSI support for in-kernel irqchips KVM: x86: Wire up MSI support for in-kernel irqchip kvm: Add support for direct MSI injections hw/apic.c |3 + hw/kvm/apic.c | 33 +- hw/pc.c |5 -- kvm-all.c | 195 +++-- kvm.h |1 + 5 files changed, 225 insertions(+), 12 deletions(-) -- 1.7.3.4
[Qemu-devel] [RFC][PATCH v2 1/4] kvm: Refactor KVMState::max_gsi to gsi_count
From: Jan Kiszka jan.kis...@siemens.com Instead of the bitmap size, store the maximum of GSIs the kernel support. Move the GSI limit assertion to the API function kvm_irqchip_add_route and make it stricter. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |8 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index b8e9dc6..eb0b4c0 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -86,7 +86,7 @@ struct KVMState struct kvm_irq_routing *irq_routes; int nr_allocated_irq_routes; uint32_t *used_gsi_bitmap; -unsigned int max_gsi; +unsigned int gsi_count; #endif }; @@ -857,8 +857,6 @@ int kvm_irqchip_set_irq(KVMState *s, int irq, int level) #ifdef KVM_CAP_IRQ_ROUTING static void set_gsi(KVMState *s, unsigned int gsi) { -assert(gsi s-max_gsi); - s-used_gsi_bitmap[gsi / 32] |= 1U (gsi % 32); } @@ -873,7 +871,7 @@ static void kvm_init_irq_routing(KVMState *s) /* Round up so we can search ints using ffs */ gsi_bits = ALIGN(gsi_count, 32); s-used_gsi_bitmap = g_malloc0(gsi_bits / 8); -s-max_gsi = gsi_bits; +s-gsi_count = gsi_count; /* Mark any over-allocated bits as already in use */ for (i = gsi_count; i gsi_bits; i++) { @@ -918,6 +916,8 @@ void kvm_irqchip_add_route(KVMState *s, int irq, int irqchip, int pin) { struct kvm_irq_routing_entry e; +assert(pin s-gsi_count); + e.gsi = irq; e.type = KVM_IRQ_ROUTING_IRQCHIP; e.flags = 0; -- 1.7.3.4
[Qemu-devel] [RFC][PATCH v2 2/4] kvm: Introduce basic MSI support for in-kernel irqchips
From: Jan Kiszka jan.kis...@siemens.com This patch basically adds kvm_irqchip_send_msi, a service for sending arbitrary MSI messages to KVM's in-kernel irqchip models. As the current KVI API requires us to establish a static route from a pseudo GSI to the target MSI message and inject the MSI via toggling that GSI, we need to play some tricks to make this unfortunately interface transparent. We create those routes on demand and keep them in a hash table. Succeeding messages can then search for an existing route in the table first and reuse it whenever possible. If we should run out of limited GSIs, we simply flush the table and rebuild it as messages are sent. This approach is rather simple and could be optimized further. However, future kernels will contain a more efficient MSI injection interface that will obsolete the GSI-based dynamic injection. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c | 171 - kvm.h |1 + 2 files changed, 171 insertions(+), 1 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index eb0b4c0..5256511 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -48,6 +48,8 @@ do { } while (0) #endif +#define KVM_MSI_HASHTAB_SIZE256 + typedef struct KVMSlot { target_phys_addr_t start_addr; @@ -59,6 +61,11 @@ typedef struct KVMSlot typedef struct kvm_dirty_log KVMDirtyLog; +typedef struct KVMMSIRoute { +struct kvm_irq_routing_entry kroute; +QTAILQ_ENTRY(KVMMSIRoute) entry; +} KVMMSIRoute; + struct KVMState { KVMSlot slots[32]; @@ -87,6 +94,7 @@ struct KVMState int nr_allocated_irq_routes; uint32_t *used_gsi_bitmap; unsigned int gsi_count; +QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; #endif }; @@ -860,9 +868,14 @@ static void set_gsi(KVMState *s, unsigned int gsi) s-used_gsi_bitmap[gsi / 32] |= 1U (gsi % 32); } +static void clear_gsi(KVMState *s, unsigned int gsi) +{ +s-used_gsi_bitmap[gsi / 32] = ~(1U (gsi % 32)); +} + static void kvm_init_irq_routing(KVMState *s) { -int gsi_count; +int gsi_count, i; gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING); if (gsi_count 0) { @@ -882,6 +895,10 @@ static void kvm_init_irq_routing(KVMState *s) s-irq_routes = g_malloc0(sizeof(*s-irq_routes)); s-nr_allocated_irq_routes = 0; +for (i = 0; i KVM_MSI_HASHTAB_SIZE; i++) { +QTAILQ_INIT(s-msi_hashtab[i]); +} + kvm_arch_init_irq_routing(s); } @@ -912,6 +929,54 @@ static void kvm_add_routing_entry(KVMState *s, set_gsi(s, entry-gsi); } +static void kvm_remove_routing_entry(KVMState *s, + struct kvm_irq_routing_entry *entry) +{ +struct kvm_irq_routing_entry *e; +int gsi = entry-gsi; +int i; + +for (i = 0; i s-irq_routes-nr; ++i) { +e = s-irq_routes-entries[i]; +if (e-type == entry-type e-gsi == gsi) { +switch (e-type) { +case KVM_IRQ_ROUTING_IRQCHIP: +if (e-u.irqchip.irqchip == entry-u.irqchip.irqchip +e-u.irqchip.pin == entry-u.irqchip.pin) { +goto found; +} +break; +case KVM_IRQ_ROUTING_MSI: +if (e-u.msi.address_lo == entry-u.msi.address_lo +e-u.msi.address_hi == entry-u.msi.address_hi +e-u.msi.data == entry-u.msi.data) { +goto found; +} +break; +default: +break; +} +} +} +/* route not found */ +return; + +found: +s-irq_routes-nr--; +*e = s-irq_routes-entries[s-irq_routes-nr]; + +/* If there are no other users of this GSI, release it. */ +for (i = 0; i s-irq_routes-nr; i++) { +e = s-irq_routes-entries[i]; +if (e-gsi == gsi) { +break; +} +} +if (i == s-irq_routes-nr) { +clear_gsi(s, gsi); +} +} + void kvm_irqchip_add_route(KVMState *s, int irq, int irqchip, int pin) { struct kvm_irq_routing_entry e; @@ -932,11 +997,115 @@ int kvm_irqchip_commit_routes(KVMState *s) return kvm_vm_ioctl(s, KVM_SET_GSI_ROUTING, s-irq_routes); } +static unsigned int kvm_hash_msi(uint32_t data) +{ +/* This is optimized for IA32 MSI layout. However, no other arch shall + * repeat the mistake of not providing a direct MSI injection API. */ +return data 0xff; +} + +static void kvm_flush_dynamic_msi_routes(KVMState *s) +{ +KVMMSIRoute *route, *next; +unsigned int hash; + +for (hash = 0; hash KVM_MSI_HASHTAB_SIZE; hash++) { +QTAILQ_FOREACH_SAFE(route, s-msi_hashtab[hash], entry, next) { +kvm_remove_routing_entry(s, route-kroute); +QTAILQ_REMOVE(s-msi_hashtab[hash], route, entry); +g_free(route); +} +} +} + +static int kvm_get_pseudo_gsi(KVMState *s) +{ +
[Qemu-devel] [RFC][PATCH v2 4/4] kvm: Add support for direct MSI injections
From: Jan Kiszka jan.kis...@siemens.com If the kernel supports KVM_SIGNAL_MSI, we can avoid the route-based MSI injection mechanism. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c | 22 +++--- 1 files changed, 19 insertions(+), 3 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 5256511..6225bab 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -95,6 +95,7 @@ struct KVMState uint32_t *used_gsi_bitmap; unsigned int gsi_count; QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE]; +bool direct_msi; #endif }; @@ -895,8 +896,10 @@ static void kvm_init_irq_routing(KVMState *s) s-irq_routes = g_malloc0(sizeof(*s-irq_routes)); s-nr_allocated_irq_routes = 0; -for (i = 0; i KVM_MSI_HASHTAB_SIZE; i++) { -QTAILQ_INIT(s-msi_hashtab[i]); +if (!s-direct_msi) { +for (i = 0; i KVM_MSI_HASHTAB_SIZE; i++) { +QTAILQ_INIT(s-msi_hashtab[i]); +} } kvm_arch_init_irq_routing(s); @@ -1035,7 +1038,7 @@ again: return bit - 1 + i * 32; } -if (retry) { +if (!s-direct_msi retry) { retry = false; kvm_flush_dynamic_msi_routes(s); goto again; @@ -1062,8 +1065,19 @@ static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, uint64_t addr, int kvm_irqchip_send_msi(KVMState *s, uint64_t addr, uint32_t data) { +struct kvm_msi msi; KVMMSIRoute *route; +if (s-direct_msi) { +msi.address_lo = (uint32_t)addr; +msi.address_hi = addr 32; +msi.data = data; +msi.flags = 0; +memset(msi.pad, 0, sizeof(msi.pad)); + +return kvm_vm_ioctl(s, KVM_SIGNAL_MSI, msi); +} + route = kvm_lookup_msi_route(s, addr, data); if (!route) { int gsi, ret; @@ -1231,6 +1245,8 @@ int kvm_init(void) s-pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); #endif +s-direct_msi = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) 0); + ret = kvm_arch_init(s); if (ret 0) { goto err; -- 1.7.3.4
Re: [Qemu-devel] [PATCH 00/12 v11] introducing a new, dedicated guest memory dump mechanism
On 2012-04-02 05:19, Wen Congyang wrote: At 03/28/2012 08:44 PM, Luiz Capitulino Wrote: On Wed, 28 Mar 2012 13:17:43 +0800 Wen Congyang we...@cn.fujitsu.com wrote: Hi, Luiz, Anthony, Jan do you have any comments about this patchset? As far as QMP is concerned: Acked-by: Luiz Capitulino lcapitul...@redhat.com I fix a overflow bug and resend patch 12/12 This can go through me tree, but I'd like an ACK from Jan and/or Anthony. Hi, Jan, Anthony when do you have tiem to review this patchset? High on my to-do list. I hope to have a look and a try the next days. Sorry for the long delay. Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [RFC][PATCH v2 3/4] KVM: x86: Wire up MSI support for in-kernel irqchip
From: Jan Kiszka jan.kis...@siemens.com Catch writes to the MSI MMIO region in the KVM APIC and forward them to the kernel. Provide the kernel support GSI routing, this allows to enable MSI support also for in-kernel irqchip mode. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/apic.c |3 +++ hw/kvm/apic.c | 33 +++-- hw/pc.c |5 - 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/hw/apic.c b/hw/apic.c index 4eeaf88..5fbf01c 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -19,6 +19,7 @@ #include apic_internal.h #include apic.h #include ioapic.h +#include msi.h #include host-utils.h #include trace.h #include pc.h @@ -862,6 +863,8 @@ static void apic_init(APICCommonState *s) s-timer = qemu_new_timer_ns(vm_clock, apic_timer, s); local_apics[s-idx] = s; + +msi_supported = true; } static void apic_class_init(ObjectClass *klass, void *data) diff --git a/hw/kvm/apic.c b/hw/kvm/apic.c index ffe7a52..7d83b1a 100644 --- a/hw/kvm/apic.c +++ b/hw/kvm/apic.c @@ -10,6 +10,7 @@ * See the COPYING file in the top-level directory. */ #include hw/apic_internal.h +#include hw/msi.h #include kvm.h static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic, @@ -145,10 +146,38 @@ static void kvm_apic_external_nmi(APICCommonState *s) run_on_cpu(s-cpu_env, do_inject_external_nmi, s); } +static uint64_t kvm_apic_mem_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ +return -1U; +} + +static void kvm_apic_mem_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ +int ret; + +ret = kvm_irqchip_send_msi(kvm_state, addr, data); +if (ret 0) { +fprintf(stderr, KVM: injection failed, MSI lost (%s)\n, +strerror(-ret)); +} +} + +static const MemoryRegionOps kvm_apic_io_ops = { +.read = kvm_apic_mem_read, +.write = kvm_apic_mem_write, +.endianness = DEVICE_NATIVE_ENDIAN, +}; + static void kvm_apic_init(APICCommonState *s) { -memory_region_init_reservation(s-io_memory, kvm-apic-msi, - MSI_SPACE_SIZE); +memory_region_init_io(s-io_memory, kvm_apic_io_ops, s, kvm-apic-msi, + MSI_SPACE_SIZE); + +if (kvm_has_gsi_routing()) { +msi_supported = true; +} } static void kvm_apic_class_init(ObjectClass *klass, void *data) diff --git a/hw/pc.c b/hw/pc.c index 83a1b5b..fab620a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -907,11 +907,6 @@ static DeviceState *apic_init(void *env, uint8_t apic_id) apic_mapped = 1; } -/* KVM does not support MSI yet. */ -if (!kvm_irqchip_in_kernel()) { -msi_supported = true; -} - return dev; } -- 1.7.3.4
Re: [Qemu-devel] [PATCH] Memory: unify ioport registration
On 04/02/2012 05:37 PM, Julien Grall wrote: Replace register_ioport* by portio_list_*. All ioports registered by the previous functions don't call memory callback. Signed-off-by: Julien Grall julien.gr...@citrix.com --- hw/acpi_piix4.c | 22 +++--- hw/cirrus_vga.c | 31 ++- hw/pc.c | 39 +-- hw/serial.c | 13 +++-- Please split into separate patches. @@ -27,6 +27,7 @@ #include sysemu.h #include range.h #include ioport.h +#include exec-memory.h Remove please. //#define DEBUG @@ -325,10 +326,23 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) } +static const MemoryRegionPortio piix4_portio_list[] = { +{ 0x00, 64, 1, .read = smb_ioport_readb, }, /* s-smb_io_base */ +{ 0x00, 64, 1, .write = smb_ioport_writeb, }, /* s-smb_io_base */ +PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio acpi_portio_list[] = { +{ 0x00, 4, 4, .write = acpi_dbg_writel, }, /* ACPI_DBG_IO_ADDR */ +PORTIO_END_OF_LIST(), +}; + static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev); uint8_t *pci_conf; +PortioList *piix4_port_list = g_new(PortioList, 1); +PortioList *acpi_port_list = g_new(PortioList, 1); Make these fields in PIIX4PMState to avoid the allocation. pci_conf = s-dev.config; pci_conf[0x06] = 0x80; @@ -341,7 +355,8 @@ static int piix4_pm_initfn(PCIDevice *dev) /* APM */ apm_init(s-apm, apm_ctrl_changed, s); -register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, s); +portio_list_init(acpi_port_list, acpi_portio_list, s, piix4-acpi); +portio_list_add(acpi_port_list, get_system_io(), ACPI_DBG_IO_ADDR); Use pci_address_space_io() instead. if (s-kvm_enabled) { /* Mark SMM as already inited to prevent SMM from running. KVM does not @@ -354,8 +369,9 @@ static int piix4_pm_initfn(PCIDevice *dev) pci_conf[0x90] = s-smb_io_base | 1; pci_conf[0x91] = s-smb_io_base 8; pci_conf[0xd2] = 0x09; -register_ioport_write(s-smb_io_base, 64, 1, smb_ioport_writeb, s-smb); -register_ioport_read(s-smb_io_base, 64, 1, smb_ioport_readb, s-smb); + +portio_list_init(piix4_port_list, piix4_portio_list, s, piix4-acpi); +portio_list_add(piix4_port_list, get_system_io(), s-smb_io_base); pci_address_space_io() acpi_pm_tmr_init(s-ar, pm_tmr_timer); acpi_gpe_init(s-ar, GPE_LEN); diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index afedaa4..aae82d5 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -32,6 +32,7 @@ #include console.h #include vga_int.h #include loader.h +#include exec-memory.h Remove. /* * TODO: @@ -2781,11 +2782,26 @@ static const MemoryRegionOps cirrus_linear_io_ops = { }, }; +static const MemoryRegionPortio cirrus_portio_list[] = { +{ 0x04, 2, 1, .write = cirrus_vga_ioport_write, +.read = cirrus_vga_ioport_read, }, /* 0x3b4 */ +{ 0x0a, 1, 1, .write = cirrus_vga_ioport_write, +.read = cirrus_vga_ioport_read, }, /* 0x3ba */ +{ 0x10, 16, 1, .write = cirrus_vga_ioport_write, +.read = cirrus_vga_ioport_read, }, /* 0x3c0 */ +{ 0x24, 2, 1, .write = cirrus_vga_ioport_write, +.read = cirrus_vga_ioport_read, }, /* 0x3d4 */ +{ 0x2a, 1, 1, .write = cirrus_vga_ioport_write, +.read = cirrus_vga_ioport_read, }, /* 0x3da */ +PORTIO_END_OF_LIST (), +}; + static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, MemoryRegion *system_memory) { int i; static int inited; +PortioList *cirrus_port_list = g_new(PortioList, 1); Into CirrusVGAState. if (!inited) { inited = 1; @@ -2814,19 +2830,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, s-bustype = CIRRUS_BUSTYPE_ISA; } -register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s); - -register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s); - -register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s); - -register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s); +portio_list_init(cirrus_port_list, cirrus_portio_list, s, cirrus-io); +portio_list_add(cirrus_port_list, get_system_io(), 0x3b0); Please pass either pci_address_space_io() or isa_io_address_space() (you'll have to write the latter) to
Re: [Qemu-devel] [RFC PATCH v1 2/4] m25p80: initial verion
On Fri, Mar 30, 2012 at 04:37:11PM +1000, Peter A. G. Crosthwaite wrote: +static void flash_sync_page(struct flash *s, int page) +{ +if (s-bdrv) { +int bdrv_sector; +int offset; + +bdrv_sector = (page * s-pagesize) / 512; +offset = bdrv_sector * 512; +bdrv_write(s-bdrv, bdrv_sector, + s-storage + offset, (s-pagesize + 511) / 512); Devices should not use synchronous block I/O interfaces. sd, flash, and a couple others still do for historical reasons but new devices should not. The vcpu, QEMU monitor, and VNC are all blocked while I/O takes place. This can be avoided by using bdrv_aio_writev() instead. Can you change this code to use bdrv_aio_writev() or is this flash device specified to complete operations within certain time constraints? (The problem is that the image file could be on a slow harddisk or other media that don't meet those timing requirements.) +static int m25p80_init(SPISlave *ss) +{ +DriveInfo *dinfo; +struct flash *s = FROM_SPI_SLAVE(struct flash, ss); +/* FIXME: This should be handled centrally! */ +static int mtdblock_idx; +dinfo = drive_get(IF_MTD, 0, mtdblock_idx++); + +DB_PRINT(inited m25p80 device model - dinfo = %p\n, dinfo); +/* TODO: parameterize */ +s-size = 8 * 1024 * 1024; +s-pagesize = 256; +s-sectorsize = 4 * 1024; +s-dirty_page = -1; +s-storage = g_malloc0(s-size); Please use qemu_blockalign(s-bdrv, s-size) to allocate I/O buffers. It honors memory alignment requirements (necessary for O_DIRECT files). Stefan
Re: [Qemu-devel] [PATCH v2] sheepdog: implement SD_OP_FLUSH_VDI operation
On Tue, Apr 03, 2012 at 01:15:40PM +0800, Liu Yuan wrote: +static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs) +{ +BDRVSheepdogState *s = bs-opaque; +SheepdogObjReq hdr = { 0 }; +SheepdogObjRsp *rsp = (SheepdogObjRsp *)hdr; +SheepdogInode *inode = s-inode; +int ret; +unsigned int wlen = 0, rlen = 0; + +if (!s-cache_enabled) +return 0; + +hdr.opcode = SD_OP_FLUSH_VDI; +hdr.oid = vid_to_vdi_oid(inode-vdi_id); + +ret = do_req(s-fd, (SheepdogReq *)hdr, NULL, wlen, rlen); +if (ret) { +error_report(failed to send a request to the sheep); +return -1; +} + +if (rsp-result != SD_RES_SUCCESS) { +error_report(%s, sd_strerror(rsp-result)); +return -1; +} + +return 0; +} .bdrv_co_flush_to_disk() is a coroutine_fn so that it can yield while waiting for socket I/O. Using do_req() defeats its purpose and will pause both the guest and QEMU's own monitor/VNC/etc while waiting for the sheepdog server to communicate with us. You should use coroutine send/recv functions - they yield if the socket returns EAGAIN/EWOULDBLOCK. Also please return negative errno values instead of -1 (which is -EPERM). Stefan
Re: [Qemu-devel] Intermittent e1000 failure on qemu-kvm 1.0
On Mon, Apr 02, 2012 at 04:37:23PM +0100, Chris Webb wrote: We initially saw a problem after an upgrade from 0.15.x to 1.0. Perhaps git-bisect(1) can help you track down the change that introduced this between 0.15 and 1.0. Once I've got a guest with broken networking, the network stays down even if I do things like 'ip link set eth0 down; sleep 5; ip link set eth0 up'. Killing and restarting the same VM, it runs fine next time. It sounds like this is not the issue, but are you sure the bridge has forwarding delay set to 0 or Spanning Tree Protocol disabled? With STP enabled no traffic will be forwarded by the bridge for a configured timeout, and depending on the timing of your VM bootup you could see weird things. You can check with brctl showstp br0. Stefan
Re: [Qemu-devel] Intermittent e1000 failure on qemu-kvm 1.0
Stefan Hajnoczi stefa...@gmail.com writes: On Mon, Apr 02, 2012 at 04:37:23PM +0100, Chris Webb wrote: We initially saw a problem after an upgrade from 0.15.x to 1.0. Perhaps git-bisect(1) can help you track down the change that introduced this between 0.15 and 1.0. Hi. I attempted this, but the bug is so intermittent and there are so many unrelated red-herring breakages along the branchy path between the two that I had to abandon the effort after a week I'm afraid. It's phenomenally time consuming, unlike any other bug I've tried to bisect. It sounds like this is not the issue, but are you sure the bridge has forwarding delay set to 0 or Spanning Tree Protocol disabled? With STP enabled no traffic will be forwarded by the bridge for a configured timeout, and depending on the timing of your VM bootup you could see weird things. You can check with brctl showstp br0. No STP enabled, but the networking is permanently broken on these guests in any case, not just slow to get started. Usually they've been sat there for half an hour or more by the time I get back to the stopped reboot loop, and I left one broken over a weekend without it fixing itself. The network is statically configured, so if it were down temporarily and came back, pings would then start working fine. Cheers, Chris.
Re: [Qemu-devel] Intermittent e1000 failure on qemu-kvm 1.0
On Tue, Apr 3, 2012 at 9:13 AM, Chris Webb ch...@arachsys.com wrote: Stefan Hajnoczi stefa...@gmail.com writes: On Mon, Apr 02, 2012 at 04:37:23PM +0100, Chris Webb wrote: It sounds like this is not the issue, but are you sure the bridge has forwarding delay set to 0 or Spanning Tree Protocol disabled? With STP enabled no traffic will be forwarded by the bridge for a configured timeout, and depending on the timing of your VM bootup you could see weird things. You can check with brctl showstp br0. No STP enabled, but the networking is permanently broken on these guests in any case, not just slow to get started. Usually they've been sat there for half an hour or more by the time I get back to the stopped reboot loop, and I left one broken over a weekend without it fixing itself. The network is statically configured, so if it were down temporarily and came back, pings would then start working fine. In a case like this it might be most effective to catch a VM in the bad state and then go in with gdb to see what is broken. The basic approach would be putting breakpoints on the e1000 device model's transmit/receive paths to see if the guest is giving us packets and whether the tap device is transmitting/receiving. If guest and host appear to be working then QEMU's e1000 model must be in a bad state and it's a question of looking at the tx/rx rings and other hardware emulation state to figure out what went wrong. Have you tried unloading the e1000 kernel module inside the guest and then modprobing it again? Does this fix the issue? Stefan
[Qemu-devel] [PATCH v3] sheepdog: implement SD_OP_FLUSH_VDI operation
From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- v2 - v3: address Stefan Hajnoczi comments. Thanks ! - use qemu_co_send/recv to send/revc msg v1 - v2: address Michael Tokarev comments. Thanks ! - use per-device flag - use bs-fd instead of 'connect_to_sdog()' block/sheepdog.c | 133 -- 1 files changed, 119 insertions(+), 14 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 00276f6f..b2bb522 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -32,9 +32,11 @@ #define SD_OP_RELEASE_VDI0x13 #define SD_OP_GET_VDI_INFO 0x14 #define SD_OP_READ_VDIS 0x15 +#define SD_OP_FLUSH_VDI 0x16 #define SD_FLAG_CMD_WRITE0x01 #define SD_FLAG_CMD_COW 0x02 +#define SD_FLAG_CMD_CACHE0x04 #define SD_RES_SUCCESS 0x00 /* Success */ #define SD_RES_UNKNOWN 0x01 /* Unknown error */ @@ -293,6 +295,7 @@ typedef struct BDRVSheepdogState { char name[SD_MAX_VDI_LEN]; int is_snapshot; +uint8_t cache_enabled; char *addr; char *port; @@ -516,6 +519,23 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, return ret; } +static int send_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen) +{ +int ret; + +ret = qemu_co_send(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to send a req, %s, strerror(errno)); +} + +ret = qemu_co_send(sockfd, data, *wlen); +if (ret *wlen) { +error_report(failed to send a req, %s, strerror(errno)); +} + +return ret; +} static int do_req(int sockfd, SheepdogReq *hdr, void *data, unsigned int *wlen, unsigned int *rlen) { @@ -550,6 +570,40 @@ out: return ret; } +static int do_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen, unsigned int *rlen) +{ +int ret; + +socket_set_block(sockfd); +ret = send_co_req(sockfd, hdr, data, wlen); +if (ret 0) { +goto out; +} + +ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to get a rsp, %s, strerror(errno)); +goto out; +} + +if (*rlen hdr-data_length) { +*rlen = hdr-data_length; +} + +if (*rlen) { +ret = qemu_co_recv(sockfd, data, *rlen); +if (ret *rlen) { +error_report(failed to get the data, %s, strerror(errno)); +goto out; +} +} +ret = 0; +out: +socket_set_nonblock(sockfd); +return ret; +} + static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type); @@ -900,6 +954,10 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, hdr.flags = SD_FLAG_CMD_WRITE | flags; } +if (s-cache_enabled) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.cow_oid = old_oid; hdr.copies = s-inode.nr_copies; @@ -942,7 +1000,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, static int read_write_object(int fd, char *buf, uint64_t oid, int copies, unsigned int datalen, uint64_t offset, - int write, int create) + int write, int create, uint8_t cache) { SheepdogObjReq hdr; SheepdogObjRsp *rsp = (SheepdogObjRsp *)hdr; @@ -965,6 +1023,11 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, rlen = datalen; hdr.opcode = SD_OP_READ_OBJ; } + +if (cache) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.data_length = datalen; hdr.offset = offset; @@ -986,15 +1049,18 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, } static int read_object(int fd, char *buf, uint64_t oid, int copies, - unsigned int datalen, uint64_t offset) + unsigned int datalen, uint64_t offset, uint8_t cache) { -return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0); +return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0, + cache); } static int write_object(int fd, char *buf, uint64_t oid, int copies, -unsigned int datalen, uint64_t offset, int create) +unsigned int datalen, uint64_t offset,
Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object
On 04/03/2012 01:02 AM, Paolo Bonzini wrote: Il 02/04/2012 22:56, Igor Mitsyanko ha scritto: 2) At first I made SD card child of SD host controller, but it most certainly wrong, it should be a link. This is a bit thorny, because BlockDriverState exposes a slot and its medium, not just the medium (you can have an empty BDS, and that is not NULL). I think there's no point in preserving BlockDriverState along with SDState when we eject image from slot. Just drive_add()-drive_init() it when user inserts image and drive_put_ref() when user ejects image. I think the right place for the SD card would be a child of the block device, but as block devices are not qdevified, for now it can be left as a child of the host controller. QOM tree is intended for user, right? As a user I would prefer to use qom-set /my-board/slot0.image /home/dodo/my_sd.img rather then qom-set /my-board/cortex-a20/sdhc0/card.image /home/dod/my_sd.img. Anyway, sdhc/childcard is the best decision for now I think.. The patch looks good, except that I would prefer to have wrappers for SD_GET_CLASS(foo)-method(args) in sd.h. It would also make the patch much smaller. OK, thanks. -- Mitsyanko Igor ASWG, Moscow RD center, Samsung Electronics email: i.mitsya...@samsung.com
Re: [Qemu-devel] [PATCH 1/3] configure: Fix typo 'lib_qga' - 'libs_qga'
On Mon, Apr 02, 2012 at 02:49:38PM +0200, Lluís Vilanova wrote: Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu --- configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure b/configure index bea4a2c..c7be13d 100755 --- a/configure +++ b/configure @@ -526,7 +526,7 @@ EOF bindir=\${prefix} sysconfdir=\${prefix} confsuffix= - libs_qga=-lws2_32 -lwinmm -lpowrprof $lib_qga + libs_qga=-lws2_32 -lwinmm -lpowrprof $libs_qga fi werror= An equivalent patch is already in the trivial-patches tree: http://patchwork.ozlabs.org/patch/148919/ Thanks, Stefan
Re: [Qemu-devel] [PATCH 2/3] configure: Link QEMU against 'liburcu-bp'
On Mon, Apr 02, 2012 at 02:49:44PM +0200, Lluís Vilanova wrote: This library is needed when using 'ust/tracepoint.h'. Signed-off-by: Harsh Prateek Bora ha...@linux.vnet.ibm.com Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu --- configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Thanks, applied to the trivial patches tree: https://github.com/stefanha/qemu/commits/trivial-patches I also sent an email to lttng-devel asking if pkg-config --libs ust should include this, you are CCed. If the library details will change it would be best for us to use pkg-config. Stefan
[Qemu-devel] [PATCH 02/10] coroutine: rename unlock_bh_queue to co_runnable_queue
It stands for runnable Coroutines. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 26ad76b..10e8dbb 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -29,17 +29,17 @@ #include main-loop.h #include trace.h -static QTAILQ_HEAD(, Coroutine) unlock_bh_queue = -QTAILQ_HEAD_INITIALIZER(unlock_bh_queue); -static QEMUBH* unlock_bh; +static QTAILQ_HEAD(, Coroutine) co_runnable_queue = +QTAILQ_HEAD_INITIALIZER(co_runnable_queue); +static QEMUBH* co_runnable_bh; static void qemu_co_queue_next_bh(void *opaque) { Coroutine *next; trace_qemu_co_queue_next_bh(); -while ((next = QTAILQ_FIRST(unlock_bh_queue))) { -QTAILQ_REMOVE(unlock_bh_queue, next, co_queue_next); +while ((next = QTAILQ_FIRST(co_runnable_queue))) { +QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); qemu_coroutine_enter(next, NULL); } } @@ -48,8 +48,8 @@ void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); -if (!unlock_bh) { -unlock_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); +if (!co_runnable_bh) { +co_runnable_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); } } @@ -76,9 +76,9 @@ bool qemu_co_queue_next(CoQueue *queue) next = QTAILQ_FIRST(queue-entries); if (next) { QTAILQ_REMOVE(queue-entries, next, co_queue_next); -QTAILQ_INSERT_TAIL(unlock_bh_queue, next, co_queue_next); +QTAILQ_INSERT_TAIL(co_runnable_queue, next, co_queue_next); trace_qemu_co_queue_next(next); -qemu_bh_schedule(unlock_bh); +qemu_bh_schedule(co_runnable_bh); } return (next != NULL); -- 1.7.4.4
Re: [Qemu-devel] [PATCH] Better support for dma_addr_t variables
Am 03.04.2012 02:51, schrieb David Gibson: On Mon, Apr 02, 2012 at 09:49:12AM +0200, Andreas Färber wrote: Am 31.03.2012 10:50, schrieb David Gibson: On Fri, Mar 30, 2012 at 11:34:25AM +0200, Andreas Färber wrote: Am 30.03.2012 11:32, schrieb Andreas Färber: Am 27.03.2012 04:43, schrieb David Gibson: diff --git a/hw/qdev-dma.h b/hw/qdev-dma.h new file mode 100644 index 000..e407771 --- /dev/null +++ b/hw/qdev-dma.h @@ -0,0 +1,4 @@ +#include qdev-addr.h + +#define DEFINE_PROP_DMAADDR(_n, _s, _f, _d) \ +DEFINE_PROP_TADDR(_n, _s, _f, _d) Is a new header just for this really needed? It's not being used in this patch, so its necessity is hard to judge. ;) Additionally it's missing a license notice. Just like qdev-addr.h. And qdev.h for that matter. You seriously want a license notice for two lines of trivial macro? Yes, the issue here is under what license the file is. It's a new file, so in lack of a license statement is it under GPLv2 because QEMU as a whole currently is? Thus a header explicitly saying that it's under GPLv2+ (or BSD or MIT/X11 or ...) would be appreciated to avoid further complications. Compare our GPLv2+ relicensing page: http://wiki.qemu.org/Relicensing It's 4 trivial lines. Well under the copyrightability threshold even by the paranoid estimates of IBM Legal. Tell that to your IBM colleague. We had an argument about 1 line of trivial code replacement (not even new code) that kept us from relicensing target-unicore32/helper.c just recently. This is not me who's being paranoid about lines of code, really. I've even heard that header files may not even be the subject of licenses at all in some legislations. I'm just picky and sometimes spot the odd sock from afar. ;) Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [Qemu-trivial] [PATCH trivial] make: fix clean rule by removing build file in qom/
On Mon, Apr 02, 2012 at 04:10:39PM +0100, Anthony PERARD wrote: Make clean does not clean the 'qom' directory, leaving *.o and *.d files. This patch fixes this. Signed-off-by: Anthony PERARD anthony.per...@citrix.com --- Makefile |1 + 1 files changed, 1 insertions(+), 0 deletions(-) Thanks, applied to the trivial patches tree: https://github.com/stefanha/qemu/commits/trivial-patches tg: (a3b6181..) fix/make-clean (depends on: master) What's this? I'm curious. First I thought it was a signature joke that I didn't get but I guess it's for some kind of commit tracking system? Stefan
[Qemu-devel] [PATCH] versatilepb: add i2c support
Signed-off-by: Oskar Andero oskar.and...@gmail.com --- hw/versatilepb.c | 80 ++ 1 files changed, 80 insertions(+), 0 deletions(-) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 25afb1e..014621a 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -16,9 +16,18 @@ #include boards.h #include blockdev.h #include exec-memory.h +#include bitbang_i2c.h /* Primary interrupt controller. */ +typedef struct { +SysBusDevice busdev; +MemoryRegion iomem; +bitbang_i2c_interface *bitbang; +int out; +int in; +} vpb_i2c_state; + typedef struct vpb_sic_state { SysBusDevice busdev; @@ -153,6 +162,64 @@ static int vpb_sic_init(SysBusDevice *dev) return 0; } +static uint64_t vpb_i2c_read(void *opaque, target_phys_addr_t offset, + unsigned size) +{ +vpb_i2c_state *s = (vpb_i2c_state *)opaque; + +if (offset == 0) { +return (s-out 1) | (s-in 1); +} else { +hw_error(%s: Bad offset 0x%x\n, __func__, (int)offset); +return -1; +} +} + +static void vpb_i2c_write(void *opaque, target_phys_addr_t offset, + uint64_t value, unsigned size) +{ +vpb_i2c_state *s = (vpb_i2c_state *)opaque; + +switch (offset) { +case 0: +s-out |= value 3; +break; +case 4: +s-out = ~value; +break; +default: +hw_error(%s: Bad offset 0x%x\n, __func__, (int)offset); +} +bitbang_i2c_set(s-bitbang, BITBANG_I2C_SCL, (s-out 1) != 0); +s-in = bitbang_i2c_set(s-bitbang, BITBANG_I2C_SDA, (s-out 2) != 0); +} + +static const MemoryRegionOps vpb_i2c_ops = { +.read = vpb_i2c_read, +.write = vpb_i2c_write, +.endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int vpb_i2c_init(SysBusDevice *dev) +{ +vpb_i2c_state *s = FROM_SYSBUS(vpb_i2c_state, dev); +i2c_bus *bus; + +bus = i2c_init_bus(dev-qdev, i2c); +s-bitbang = bitbang_i2c_init(bus); +memory_region_init_io(s-iomem, vpb_i2c_ops, s, + vpb-i2c, 0x1000); +sysbus_init_mmio(dev, s-iomem); +return 0; +} + +static void vpb_i2c_class_init(ObjectClass *klass, void *data) +{ +SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + +k-init = vpb_i2c_init; +} + /* Board init. */ /* The AB and PB boards both use the same core, just with different @@ -177,6 +244,7 @@ static void versatile_init(ram_addr_t ram_size, SysBusDevice *busdev; DeviceState *pl041; PCIBus *pci_bus; +i2c_bus *i2c; NICInfo *nd; int n; int done_smc = 0; @@ -268,6 +336,10 @@ static void versatile_init(ram_addr_t ram_size, /* Add PL031 Real Time Clock. */ sysbus_create_simple(pl031, 0x101e8000, pic[10]); +dev = sysbus_create_simple(vpb_i2c, 0x10002000, NULL); +i2c = (i2c_bus *)qdev_get_child_bus(dev, i2c); +i2c_create_slave(i2c, ds1338, 0x68); + /* Add PL041 AACI Interface to the LM4549 codec */ pl041 = qdev_create(NULL, pl041); qdev_prop_set_uint32(pl041, nc_fifo_depth, 512); @@ -380,9 +452,17 @@ static TypeInfo vpb_sic_info = { .class_init= vpb_sic_class_init, }; +static TypeInfo vpb_i2c_info = { +.name = vpb_i2c, +.parent= TYPE_SYS_BUS_DEVICE, +.instance_size = sizeof(vpb_i2c_state), +.class_init= vpb_i2c_class_init, +}; + static void versatilepb_register_types(void) { type_register_static(vpb_sic_info); +type_register_static(vpb_i2c_info); } type_init(versatilepb_register_types) -- 1.7.3.4
Re: [Qemu-devel] [PATCH v3] sheepdog: implement SD_OP_FLUSH_VDI operation
Am 03.04.2012 10:35, schrieb Liu Yuan: From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- v2 - v3: address Stefan Hajnoczi comments. Thanks ! - use qemu_co_send/recv to send/revc msg v1 - v2: address Michael Tokarev comments. Thanks ! - use per-device flag - use bs-fd instead of 'connect_to_sdog()' This version looks okay to me now. Waiting for Kazutaka's Acked-by. +static int send_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen) +{ +int ret; + +ret = qemu_co_send(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to send a req, %s, strerror(errno)); +} + +ret = qemu_co_send(sockfd, data, *wlen); +if (ret *wlen) { +error_report(failed to send a req, %s, strerror(errno)); +} + +return ret; +} If sending the header fails, why do we still send the data? In fact, if sending the data succeeds then (which is unlikely, but who knows), we'll even return success. This only copies the logic of the existing send_req(), so if it needs to be fixed, another patch on top that fixes both instances would be okay. Kevin
[Qemu-devel] [PATCH 10/10] coroutine: add qemu_coroutine_run() wrapper
Wrapper for qemu_coroutine_create()+qemu_coroutine_enter() Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- block.c | 28 +++- hw/9pfs/virtio-9p.c |4 +--- nbd.c |2 +- qemu-coroutine.h| 12 qemu-io.c |4 +--- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/block.c b/block.c index b88ee90..adf2010 100644 --- a/block.c +++ b/block.c @@ -1451,7 +1451,6 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, .iov_base = (void *)buf, .iov_len = nb_sectors * BDRV_SECTOR_SIZE, }; -Coroutine *co; RwCo rwco = { .bs = bs, .sector_num = sector_num, @@ -1467,8 +1466,7 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, /* Fast-path if already in coroutine context */ bdrv_rw_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_rw_co_entry); -qemu_coroutine_enter(co, rwco); +qemu_coroutine_run(bdrv_rw_co_entry, rwco); while (rwco.ret == NOT_DONE) { qemu_aio_wait(); } @@ -2414,7 +2412,6 @@ static void coroutine_fn bdrv_is_allocated_co_entry(void *opaque) int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { -Coroutine *co; BdrvCoIsAllocatedData data = { .bs = bs, .sector_num = sector_num, @@ -2423,8 +2420,7 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, .done = false, }; -co = qemu_coroutine_create(bdrv_is_allocated_co_entry); -qemu_coroutine_enter(co, data); +qemu_coroutine_run(bdrv_is_allocated_co_entry, data); while (!data.done) { qemu_aio_wait(); } @@ -3348,7 +3344,6 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, void *opaque, bool is_write) { -Coroutine *co; BlockDriverAIOCBCoroutine *acb; acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); @@ -3357,8 +3352,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, acb-req.qiov = qiov; acb-is_write = is_write; -co = qemu_coroutine_create(bdrv_co_do_rw); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_co_do_rw, acb); return acb-common; } @@ -3378,12 +3372,10 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, { trace_bdrv_aio_flush(bs, opaque); -Coroutine *co; BlockDriverAIOCBCoroutine *acb; acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); -co = qemu_coroutine_create(bdrv_aio_flush_co_entry); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_aio_flush_co_entry, acb); return acb-common; } @@ -3402,7 +3394,6 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { -Coroutine *co; BlockDriverAIOCBCoroutine *acb; trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque); @@ -3410,8 +3401,7 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); acb-req.sector = sector_num; acb-req.nb_sectors = nb_sectors; -co = qemu_coroutine_create(bdrv_aio_discard_co_entry); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_aio_discard_co_entry, acb); return acb-common; } @@ -3586,7 +3576,6 @@ void bdrv_invalidate_cache_all(void) int bdrv_flush(BlockDriverState *bs) { -Coroutine *co; RwCo rwco = { .bs = bs, .ret = NOT_DONE, @@ -3596,8 +3585,7 @@ int bdrv_flush(BlockDriverState *bs) /* Fast-path if already in coroutine context */ bdrv_flush_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_flush_co_entry); -qemu_coroutine_enter(co, rwco); +qemu_coroutine_run(bdrv_flush_co_entry, rwco); while (rwco.ret == NOT_DONE) { qemu_aio_wait(); } @@ -3645,7 +3633,6 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -Coroutine *co; RwCo rwco = { .bs = bs, .sector_num = sector_num, @@ -3657,8 +3644,7 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) /* Fast-path if already in coroutine context */ bdrv_discard_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_discard_co_entry); -qemu_coroutine_enter(co, rwco); +qemu_coroutine_run(bdrv_discard_co_entry, rwco); while (rwco.ret == NOT_DONE) { qemu_aio_wait(); } diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index c633fb9..e2f384e
Re: [Qemu-devel] [PATCH] versatilepb: add i2c support
Am 02.04.2012 22:17, schrieb Oskar Andero: Signed-off-by: Oskar Andero oskar.and...@gmail.com --- hw/versatilepb.c | 80 ++ 1 files changed, 80 insertions(+), 0 deletions(-) diff --git a/hw/versatilepb.c b/hw/versatilepb.c index 25afb1e..014621a 100644 --- a/hw/versatilepb.c +++ b/hw/versatilepb.c @@ -16,9 +16,18 @@ #include boards.h #include blockdev.h #include exec-memory.h +#include bitbang_i2c.h /* Primary interrupt controller. */ +typedef struct { +SysBusDevice busdev; +MemoryRegion iomem; +bitbang_i2c_interface *bitbang; +int out; +int in; +} vpb_i2c_state; Please use Camel Case for new types, e.g., VPBI2CState. + typedef struct vpb_sic_state { SysBusDevice busdev; [...] @@ -380,9 +452,17 @@ static TypeInfo vpb_sic_info = { .class_init= vpb_sic_class_init, }; +static TypeInfo vpb_i2c_info = { static const, please, since you don't modify it. +.name = vpb_i2c, +.parent= TYPE_SYS_BUS_DEVICE, +.instance_size = sizeof(vpb_i2c_state), +.class_init= vpb_i2c_class_init, +}; + static void versatilepb_register_types(void) { type_register_static(vpb_sic_info); +type_register_static(vpb_i2c_info); } type_init(versatilepb_register_types) Otherwise looks okay technically; don't know about I2C personally. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH 04/10] coroutine: init co_runnable_bh during boot
use __attribute__((constructor)) to do the initialization. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 90141cd..7c29bc4 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -44,13 +44,14 @@ static void qemu_co_process_runnable(void *opaque) } } +static void __attribute__((constructor)) co_runnable_bh_init(void) +{ +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); +} + void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); - -if (!co_runnable_bh) { -co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); -} } void coroutine_fn qemu_co_queue_wait(CoQueue *queue) -- 1.7.4.4
[Qemu-devel] [PATCH 07/10] coroutine: split qemu-coroutine-lock.c
queues are not just internal things for locks, split them. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- Makefile.objs |2 +- qemu-coroutine-lock.c | 49 +-- qemu-coroutine-queue.c | 76 trace-events |4 ++- 4 files changed, 81 insertions(+), 50 deletions(-) create mode 100644 qemu-coroutine-queue.c diff --git a/Makefile.objs b/Makefile.objs index 226b01d..1f0cc31 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -27,7 +27,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o ### # coroutines coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o -coroutine-obj-y += qemu-coroutine-sleep.o +coroutine-obj-y += qemu-coroutine-sleep.o qemu-coroutine-queue.o ifeq ($(CONFIG_UCONTEXT_COROUTINE),y) coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o else diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 159d66d..2bfbd41 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -1,5 +1,5 @@ /* - * coroutine queues and locks + * coroutine locks * * Copyright (c) 2011 Kevin Wolf kw...@redhat.com * @@ -28,53 +28,6 @@ #include qemu-queue.h #include trace.h -void qemu_co_queue_init(CoQueue *queue) -{ -QTAILQ_INIT(queue-entries); -} - -void coroutine_fn qemu_co_queue_wait(CoQueue *queue) -{ -Coroutine *self = qemu_coroutine_self(); -QTAILQ_INSERT_TAIL(queue-entries, self, co_queue_next); -qemu_coroutine_yield(); -assert(qemu_in_coroutine()); -} - -void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue) -{ -Coroutine *self = qemu_coroutine_self(); -QTAILQ_INSERT_HEAD(queue-entries, self, co_queue_next); -qemu_coroutine_yield(); -assert(qemu_in_coroutine()); -} - -bool qemu_co_queue_next(CoQueue *queue) -{ -Coroutine *next; - -next = QTAILQ_FIRST(queue-entries); -if (next) { -QTAILQ_REMOVE(queue-entries, next, co_queue_next); -trace_qemu_co_queue_next(next); -qemu_co_runnable_schedule(next); -} - -return (next != NULL); -} - -void qemu_co_queue_restart_all(CoQueue *queue) -{ -while (qemu_co_queue_next(queue)) { -/* Do nothing */ -} -} - -bool qemu_co_queue_empty(CoQueue *queue) -{ -return (QTAILQ_FIRST(queue-entries) == NULL); -} - void qemu_co_mutex_init(CoMutex *mutex) { memset(mutex, 0, sizeof(*mutex)); diff --git a/qemu-coroutine-queue.c b/qemu-coroutine-queue.c new file mode 100644 index 000..b90818d --- /dev/null +++ b/qemu-coroutine-queue.c @@ -0,0 +1,76 @@ +/* + * coroutine queues + * + * Copyright (c) 2011 Kevin Wolf kw...@redhat.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include qemu-common.h +#include qemu-coroutine.h +#include qemu-coroutine-int.h +#include qemu-queue.h +#include trace.h + +void qemu_co_queue_init(CoQueue *queue) +{ +QTAILQ_INIT(queue-entries); +} + +void coroutine_fn qemu_co_queue_wait(CoQueue *queue) +{ +Coroutine *self = qemu_coroutine_self(); +QTAILQ_INSERT_TAIL(queue-entries, self, co_queue_next); +qemu_coroutine_yield(); +assert(qemu_in_coroutine()); +} + +void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue) +{ +Coroutine *self = qemu_coroutine_self(); +QTAILQ_INSERT_HEAD(queue-entries, self, co_queue_next); +qemu_coroutine_yield(); +assert(qemu_in_coroutine()); +} + +bool qemu_co_queue_next(CoQueue *queue) +{ +Coroutine *next; + +next = QTAILQ_FIRST(queue-entries); +if (next) { +QTAILQ_REMOVE(queue-entries, next, co_queue_next); +trace_qemu_co_queue_next(next); +qemu_co_runnable_schedule(next); +} + +return (next != NULL); +} + +void qemu_co_queue_restart_all(CoQueue *queue) +{ +while (qemu_co_queue_next(queue)) { +/* Do nothing */ +} +} + +bool
Re: [Qemu-devel] [PATCH 3/3] configure: Link qga against UST tracing related libraries
On Mon, Apr 02, 2012 at 02:49:49PM +0200, Lluís Vilanova wrote: Signed-off-by: Harsh Prateek Bora ha...@linux.vnet.ibm.com Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu --- configure |1 + 1 files changed, 1 insertions(+), 0 deletions(-) Thanks, applied to the trivial patches tree: https://github.com/stefanha/qemu/commits/trivial-patches It would be nice to clean up libs_qga in the future so that common library lists can be reused instead of duplicating them in both LIBS and libs_qga. Anyway, thanks for this fix. Stefan
Re: [Qemu-devel] [PATCH v3] sheepdog: implement SD_OP_FLUSH_VDI operation
At Tue, 3 Apr 2012 16:35:00 +0800, Liu Yuan wrote: +static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs) +{ +BDRVSheepdogState *s = bs-opaque; +SheepdogObjReq hdr = { 0 }; +SheepdogObjRsp *rsp = (SheepdogObjRsp *)hdr; +SheepdogInode *inode = s-inode; +int ret; +unsigned int wlen = 0, rlen = 0; + +if (!s-cache_enabled) { +return 0; +} + +hdr.opcode = SD_OP_FLUSH_VDI; +hdr.oid = vid_to_vdi_oid(inode-vdi_id); + +ret = do_co_req(s-fd, (SheepdogReq *)hdr, NULL, wlen, rlen); This will mix the flush request with I/O requests on s-fd. We can read s-fd only in aio_read_response() and write only in add_aio_request(), so please create another connection for flush operations. Thanks, Kazutaka
Re: [Qemu-devel] [PATCH] Memory: unify ioport registration
Am 02.04.2012 16:37, schrieb Julien Grall: Replace register_ioport* by portio_list_*. [snip] Are these changes guaranteed to not change the addresses in some way? We've had really subtle bugs with offsets added / not added in the past. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH] Memory: unify ioport registration
On 04/03/2012 08:51 AM, Avi Kivity wrote: On 04/02/2012 05:37 PM, Julien Grall wrote: if (!inited) { inited = 1; @@ -2814,19 +2830,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, s-bustype = CIRRUS_BUSTYPE_ISA; } -register_ioport_write(0x3c0, 16, 1, cirrus_vga_ioport_write, s); - -register_ioport_write(0x3b4, 2, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3d4, 2, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3ba, 1, 1, cirrus_vga_ioport_write, s); -register_ioport_write(0x3da, 1, 1, cirrus_vga_ioport_write, s); - -register_ioport_read(0x3c0, 16, 1, cirrus_vga_ioport_read, s); - -register_ioport_read(0x3b4, 2, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3d4, 2, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s); -register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s); +portio_list_init(cirrus_port_list, cirrus_portio_list, s, cirrus-io); +portio_list_add(cirrus_port_list, get_system_io(), 0x3b0); Please pass either pci_address_space_io() or isa_io_address_space() (you'll have to write the latter) to cirrus_init_common() from its callers. We really want to avoid get_system_io(). isa_io_address_space doesn't exist. I will create it, but which memory region we need to return ? get_system_io () ?
[Qemu-devel] [PATCH 08/10] coroutine: process the coroutines woken by child when child yield
If the child wake up someone, process them. It would the child complete its works if woken coroutine release the locks that the child needs. It may help for the cache, if the child wake up some someone, they are probably accessing the same data. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine.c | 29 +++-- 1 files changed, 23 insertions(+), 6 deletions(-) diff --git a/qemu-coroutine.c b/qemu-coroutine.c index c67d557..ce6b3af 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -22,17 +22,25 @@ static QTAILQ_HEAD(, Coroutine) co_runnable_queue = QTAILQ_HEAD_INITIALIZER(co_runnable_queue); static QEMUBH* co_runnable_bh; -static void qemu_co_process_runnable(void *opaque) +static void coroutine_enter(Coroutine *self, Coroutine *co, void *opaque); +static void process_runnable(Coroutine *self) { Coroutine *next; -trace_qemu_co_process_runnable(); while ((next = QTAILQ_FIRST(co_runnable_queue))) { QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); -qemu_coroutine_enter(next, NULL); +coroutine_enter(self, next, NULL); } } +static void qemu_co_process_runnable(void *opaque) +{ +Coroutine *self = qemu_coroutine_self(); + +trace_qemu_co_process_runnable(); +process_runnable(self); +} + void qemu_co_runnable_schedule(Coroutine *co) { QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); @@ -69,10 +77,8 @@ static void coroutine_swap(Coroutine *from, Coroutine *to) } } -void qemu_coroutine_enter(Coroutine *co, void *opaque) +static void coroutine_enter(Coroutine *self, Coroutine *co, void *opaque) { -Coroutine *self = qemu_coroutine_self(); - trace_qemu_coroutine_enter(self, co, opaque); if (co-caller) { @@ -85,6 +91,17 @@ void qemu_coroutine_enter(Coroutine *co, void *opaque) coroutine_swap(self, co); } +void qemu_coroutine_enter(Coroutine *co, void *opaque) +{ +Coroutine *self = qemu_coroutine_self(); +typeof(co_runnable_queue) snap = co_runnable_queue; + +QTAILQ_INIT(co_runnable_queue); +coroutine_enter(self, co, opaque); +process_runnable(self); +co_runnable_queue = snap; +} + void coroutine_fn qemu_coroutine_yield(void) { Coroutine *self = qemu_coroutine_self(); -- 1.7.4.4
Re: [Qemu-devel] [patch V5 0/5] i.MX31 support
Peter, Am 03.04.2012 03:55, schrieb Peter Chubb: This is the fifth round of patches for preliminary Freescale i.MX31 support. If you resend this, it would be nice to shorten the subjects, so that the interesting part is not hidden in the back. First one's fine, then for example: i.MX31: Clock Control Module i.MX31: Timers i.MX31: AVIC i.MX31: KZM-ARM11-01 evaluation board Freescale is mentioned further down in most commit messages (in varying spellings fwiw - freescale.com has it as Freescale). Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
[Qemu-devel] [PATCH 09/10] coroutine: schedule timeout coroutine instead process it directly
Avoid a timer callback spends too much time. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-sleep.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c index fd65274..df9254a 100644 --- a/qemu-coroutine-sleep.c +++ b/qemu-coroutine-sleep.c @@ -24,7 +24,7 @@ static void co_sleep_cb(void *opaque) CoSleepCB *sleep_cb = opaque; qemu_free_timer(sleep_cb-ts); -qemu_coroutine_enter(sleep_cb-co, NULL); +qemu_co_runnable_schedule(sleep_cb-co); } void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns) -- 1.7.4.4
[Qemu-devel] [PATCH 01/10] coroutine: use qemu_coroutine_switch() directly
When qemu_coroutine_switch() in the qemu_coroutine_yield() returns, It must be someone calls qemu_coroutine_enter() for it, so the @to is active, the tests in coroutine_swap() are unneeded, so we use qemu_coroutine_switch() directly in qemu_coroutine_yield(). Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-coroutine.c b/qemu-coroutine.c index 600be26..c01252e 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -71,5 +71,5 @@ void coroutine_fn qemu_coroutine_yield(void) } self-caller = NULL; -coroutine_swap(self, to); +qemu_coroutine_switch(self, to, COROUTINE_YIELD); } -- 1.7.4.4
Re: [Qemu-devel] [PATCH 6/6] hw/sd.c: convert to QOM object
Il 03/04/2012 10:35, Igor Mitsyanko ha scritto: I think there's no point in preserving BlockDriverState along with SDState when we eject image from slot. Just drive_add()-drive_init() it when user inserts image and drive_put_ref() when user ejects image. Note that the BlockDriverState currently cannot be changed without deleting whatever device holds it (qdev properties can only be set at construction time). As a user I would prefer to use qom-set /my-board/slot0.image /home/dodo/my_sd.img rather then qom-set /my-board/cortex-a20/sdhc0/card.image /home/dod/my_sd.img. You can use partial paths: qom-set sdhc0/card /home/dod/my_sd.img More precisely, that would be something like # Add a block device pointing to the file blockdev-add my_sd file=/home/dod/my_sd.img # Point the drive property to it qom-set sdhc0/card drive=my_sd The alternative would be something like this: # Add a block device pointing to the file blockdev-add my_sd file=/home/dod/my_sd.img # Make it visible as an SD card # my_sd = parent path # card = property name # sd = class name qom-add my_sd card sd # Point the host controller to the newly-created card qom-set sdhc0 card=my_sd/card Anyway, sdhc/childcard is the best decision for now I think.. Yes, agreed. Paolo
[Qemu-devel] [PATCH 06/10] coroutine: move runnale coroutine code to qemu-coroutine.c
runnable coroutine queue is the core mangement of the coroutine. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c | 27 --- qemu-coroutine.c | 27 +++ qemu-coroutine.h |7 +++ trace-events |2 +- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 6f47685..159d66d 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -26,35 +26,8 @@ #include qemu-coroutine.h #include qemu-coroutine-int.h #include qemu-queue.h -#include main-loop.h #include trace.h -static QTAILQ_HEAD(, Coroutine) co_runnable_queue = -QTAILQ_HEAD_INITIALIZER(co_runnable_queue); -static QEMUBH* co_runnable_bh; - -static void qemu_co_process_runnable(void *opaque) -{ -Coroutine *next; - -trace_qemu_co_process_runnable(); -while ((next = QTAILQ_FIRST(co_runnable_queue))) { -QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); -qemu_coroutine_enter(next, NULL); -} -} - -static void qemu_co_runnable_schedule(Coroutine *co) -{ -QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); -qemu_bh_schedule(co_runnable_bh); -} - -static void __attribute__((constructor)) co_runnable_bh_init(void) -{ -co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); -} - void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); diff --git a/qemu-coroutine.c b/qemu-coroutine.c index c01252e..c67d557 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -16,6 +16,33 @@ #include qemu-common.h #include qemu-coroutine.h #include qemu-coroutine-int.h +#include main-loop.h + +static QTAILQ_HEAD(, Coroutine) co_runnable_queue = +QTAILQ_HEAD_INITIALIZER(co_runnable_queue); +static QEMUBH* co_runnable_bh; + +static void qemu_co_process_runnable(void *opaque) +{ +Coroutine *next; + +trace_qemu_co_process_runnable(); +while ((next = QTAILQ_FIRST(co_runnable_queue))) { +QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); +qemu_coroutine_enter(next, NULL); +} +} + +void qemu_co_runnable_schedule(Coroutine *co) +{ +QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); +qemu_bh_schedule(co_runnable_bh); +} + +static void __attribute__((constructor)) co_runnable_bh_init(void) +{ +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); +} Coroutine *qemu_coroutine_create(CoroutineEntry *entry) { diff --git a/qemu-coroutine.h b/qemu-coroutine.h index 34c15d4..82a7e5c 100644 --- a/qemu-coroutine.h +++ b/qemu-coroutine.h @@ -82,6 +82,13 @@ void qemu_coroutine_enter(Coroutine *coroutine, void *opaque); void coroutine_fn qemu_coroutine_yield(void); /** + * Add a coroutine to runnable to runnable queue + * + * The coroutine will be processed later. + */ +void qemu_co_runnable_schedule(Coroutine *co); + +/** * Get the currently executing coroutine */ Coroutine *coroutine_fn qemu_coroutine_self(void); diff --git a/trace-events b/trace-events index a1737c2..39b9c84 100644 --- a/trace-events +++ b/trace-events @@ -556,12 +556,12 @@ qemu_put_ram_ptr(void* addr) %p xen_platform_log(char *s) xen platform: %s # qemu-coroutine.c +qemu_co_process_runnable(void) qemu_coroutine_enter(void *from, void *to, void *opaque) from %p to %p opaque %p qemu_coroutine_yield(void *from, void *to) from %p to %p qemu_coroutine_terminate(void *co) self %p # qemu-coroutine-lock.c -qemu_co_process_runnable(void) qemu_co_queue_next(void *next) next %p qemu_co_mutex_lock_entry(void *mutex, void *self) mutex %p self %p qemu_co_mutex_lock_return(void *mutex, void *self) mutex %p self %p -- 1.7.4.4
[Qemu-devel] [PATCH 03/10] coroutine: rename qemu_co_queue_next_bh() to qemu_co_process_runnable()
Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |6 +++--- trace-events |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 10e8dbb..90141cd 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -33,11 +33,11 @@ static QTAILQ_HEAD(, Coroutine) co_runnable_queue = QTAILQ_HEAD_INITIALIZER(co_runnable_queue); static QEMUBH* co_runnable_bh; -static void qemu_co_queue_next_bh(void *opaque) +static void qemu_co_process_runnable(void *opaque) { Coroutine *next; -trace_qemu_co_queue_next_bh(); +trace_qemu_co_process_runnable(); while ((next = QTAILQ_FIRST(co_runnable_queue))) { QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); qemu_coroutine_enter(next, NULL); @@ -49,7 +49,7 @@ void qemu_co_queue_init(CoQueue *queue) QTAILQ_INIT(queue-entries); if (!co_runnable_bh) { -co_runnable_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); } } diff --git a/trace-events b/trace-events index 70f059d..a1737c2 100644 --- a/trace-events +++ b/trace-events @@ -561,7 +561,7 @@ qemu_coroutine_yield(void *from, void *to) from %p to %p qemu_coroutine_terminate(void *co) self %p # qemu-coroutine-lock.c -qemu_co_queue_next_bh(void) +qemu_co_process_runnable(void) qemu_co_queue_next(void *next) next %p qemu_co_mutex_lock_entry(void *mutex, void *self) mutex %p self %p qemu_co_mutex_lock_return(void *mutex, void *self) mutex %p self %p -- 1.7.4.4
[Qemu-devel] [PATCH v4] sheepdog: implement SD_OP_FLUSH_VDI operation
From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- v3 - v4: address Kazutaka's comments. Thanks ! - use a dedicated fd for flush operation v2 - v3: address Stefan Hajnoczi comments. Thanks ! - use qemu_co_send/recv to send/revc msg v1 - v2: address Michael Tokarev comments. Thanks ! - use per-device flag - use bs-fd instead of 'connect_to_sdog()' block/sheepdog.c | 142 - 1 files changed, 128 insertions(+), 14 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 00276f6f..62dfa48 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -32,9 +32,11 @@ #define SD_OP_RELEASE_VDI0x13 #define SD_OP_GET_VDI_INFO 0x14 #define SD_OP_READ_VDIS 0x15 +#define SD_OP_FLUSH_VDI 0x16 #define SD_FLAG_CMD_WRITE0x01 #define SD_FLAG_CMD_COW 0x02 +#define SD_FLAG_CMD_CACHE0x04 #define SD_RES_SUCCESS 0x00 /* Success */ #define SD_RES_UNKNOWN 0x01 /* Unknown error */ @@ -293,10 +295,12 @@ typedef struct BDRVSheepdogState { char name[SD_MAX_VDI_LEN]; int is_snapshot; +uint8_t cache_enabled; char *addr; char *port; int fd; +int flush_fd; CoMutex lock; Coroutine *co_send; @@ -516,6 +520,23 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, return ret; } +static int send_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen) +{ +int ret; + +ret = qemu_co_send(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to send a req, %s, strerror(errno)); +} + +ret = qemu_co_send(sockfd, data, *wlen); +if (ret *wlen) { +error_report(failed to send a req, %s, strerror(errno)); +} + +return ret; +} static int do_req(int sockfd, SheepdogReq *hdr, void *data, unsigned int *wlen, unsigned int *rlen) { @@ -550,6 +571,40 @@ out: return ret; } +static int do_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen, unsigned int *rlen) +{ +int ret; + +socket_set_block(sockfd); +ret = send_co_req(sockfd, hdr, data, wlen); +if (ret 0) { +goto out; +} + +ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to get a rsp, %s, strerror(errno)); +goto out; +} + +if (*rlen hdr-data_length) { +*rlen = hdr-data_length; +} + +if (*rlen) { +ret = qemu_co_recv(sockfd, data, *rlen); +if (ret *rlen) { +error_report(failed to get the data, %s, strerror(errno)); +goto out; +} +} +ret = 0; +out: +socket_set_nonblock(sockfd); +return ret; +} + static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type); @@ -900,6 +955,10 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, hdr.flags = SD_FLAG_CMD_WRITE | flags; } +if (s-cache_enabled) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.cow_oid = old_oid; hdr.copies = s-inode.nr_copies; @@ -942,7 +1001,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, static int read_write_object(int fd, char *buf, uint64_t oid, int copies, unsigned int datalen, uint64_t offset, - int write, int create) + int write, int create, uint8_t cache) { SheepdogObjReq hdr; SheepdogObjRsp *rsp = (SheepdogObjRsp *)hdr; @@ -965,6 +1024,11 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, rlen = datalen; hdr.opcode = SD_OP_READ_OBJ; } + +if (cache) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.data_length = datalen; hdr.offset = offset; @@ -986,15 +1050,18 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, } static int read_object(int fd, char *buf, uint64_t oid, int copies, - unsigned int datalen, uint64_t offset) + unsigned int datalen, uint64_t offset, uint8_t cache) { -return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0); +return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0, + cache); } static int write_object(int fd,
[Qemu-devel] [PATCH 05/10] coroutine: add qemu_co_runnable_schedule()
split qemu_co_queue_next() as two parts: the first part is dequeuing next from the wait queue. the second part is schedule it to the runnable queue(qemu_co_runnable_schedule()) Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 7c29bc4..6f47685 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -44,6 +44,12 @@ static void qemu_co_process_runnable(void *opaque) } } +static void qemu_co_runnable_schedule(Coroutine *co) +{ +QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); +qemu_bh_schedule(co_runnable_bh); +} + static void __attribute__((constructor)) co_runnable_bh_init(void) { co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); @@ -77,9 +83,8 @@ bool qemu_co_queue_next(CoQueue *queue) next = QTAILQ_FIRST(queue-entries); if (next) { QTAILQ_REMOVE(queue-entries, next, co_queue_next); -QTAILQ_INSERT_TAIL(co_runnable_queue, next, co_queue_next); trace_qemu_co_queue_next(next); -qemu_bh_schedule(co_runnable_bh); +qemu_co_runnable_schedule(next); } return (next != NULL); -- 1.7.4.4
Re: [Qemu-devel] [Xen-devel] [XEN][RFC PATCH 14/15] xl-parsing: Parse the new option device_models
On Mon, 2 Apr 2012, Ian Jackson wrote: Julien Grall writes ([Xen-devel] [XEN][RFC PATCH 14/15] xl-parsing: Parse the new option device_models): For the support of multiple ioreq server, we add a new option device_models. It's an array of device model, for each device model, we need to specify which pci, IO range (MMIO, PIO) will be allow. I don't think this is really a suitable interface. The PCI space in the guest is controlled by the device models(s) and the user should surely specify which devices should be provided by which dms, in terms of devices not in terms of PCI space. Julien added a name parameter to select the device, maybe we need something clearer? Specifying the PCI address is important, because we have to make sure the PCI addresses of the devices remain the same in a given VM across multiple boots. Thus we could make it optional from the user POV, but in that case we need a clear, well defined and stable algorithm in xl to figure out a PCI address from a given config file.
[Qemu-devel] RE. [PATCH] sheepdog: fix send req helpers
From: Liu Yuan tailai...@taobao.com Yes, I think so. Here is the patch. Subject: [PATCH] sheepdog: fix send req helpers From: Liu Yuan tailai...@taobao.com We should return if reading of the header fails. Cc: Kevin Wolf kw...@redhat.com Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Signed-off-by: Liu Yuan tailai...@taobao.com --- block/sheepdog.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 62dfa48..73308b2 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -510,6 +510,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, ret = qemu_send_full(sockfd, hdr, sizeof(*hdr), 0); if (ret sizeof(*hdr)) { error_report(failed to send a req, %s, strerror(errno)); +return ret; } ret = qemu_send_full(sockfd, data, *wlen, 0); @@ -528,6 +529,7 @@ static int send_co_req(int sockfd, SheepdogReq *hdr, void *data, ret = qemu_co_send(sockfd, hdr, sizeof(*hdr)); if (ret sizeof(*hdr)) { error_report(failed to send a req, %s, strerror(errno)); +return ret; } ret = qemu_co_send(sockfd, data, *wlen); -- 1.7.8.2
Re: [Qemu-devel] [PATCHv3] piix: fix up/down races
On Tue, Apr 03, 2012 at 02:40:41AM -0400, Igor Mammedov wrote: + */ +s-pci0_status.down = ~(1U slot); Should we clear up here too? Is it possible to create pci dev for not yet freed pci slot? It's not possible ATM. If not then we should not care, otherwise we should fix that. @@ -567,8 +595,6 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, return 0; } -s-pci0_status.up = 0; -s-pci0_status.down = 0; if (state == PCI_HOTPLUG_ENABLED) { enable_device(s, slot); } else { So if we have an old bios and do an add, followed by a remove, guest ACPI finds both up and down set for the slot and we rely on the ordering of the AML checking up before down to keep the duct tape and bailing wire from exploding? In fact UP triggers a rescan - there is no injection event in ACPI. So it seems you can check the events in any order. Hmm, can't say I'm excited about this hack either. Thanks, Alex
Re: [Qemu-devel] [Qemu-trivial] [PATCH trivial] make: fix clean rule by removing build file in qom/
On Tue, Apr 3, 2012 at 09:56, Stefan Hajnoczi stefa...@gmail.com wrote: tg: (a3b6181..) fix/make-clean (depends on: master) What's this? I'm curious. First I thought it was a signature joke that I didn't get but I guess it's for some kind of commit tracking system? No, it is not. To prepare a patch (or patch set), I use a tool called topgit. http://repo.or.cz/w/topgit.git It creates one git branch per patch, and you can add as many dependence branch as you want. When you want to rebase a patch, topgit will merge with the depends. -- Anthony PERARD
[Qemu-devel] [PATCH v4 UPDATE] sheepdog: implement SD_OP_FLUSH_VDI operation
From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- UPDATE: use flush_fd instead of s-fd. block/sheepdog.c | 142 - 1 files changed, 128 insertions(+), 14 deletions(-) diff --git a/block/sheepdog.c b/block/sheepdog.c index 00276f6f..da3afbf 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -32,9 +32,11 @@ #define SD_OP_RELEASE_VDI0x13 #define SD_OP_GET_VDI_INFO 0x14 #define SD_OP_READ_VDIS 0x15 +#define SD_OP_FLUSH_VDI 0x16 #define SD_FLAG_CMD_WRITE0x01 #define SD_FLAG_CMD_COW 0x02 +#define SD_FLAG_CMD_CACHE0x04 #define SD_RES_SUCCESS 0x00 /* Success */ #define SD_RES_UNKNOWN 0x01 /* Unknown error */ @@ -293,10 +295,12 @@ typedef struct BDRVSheepdogState { char name[SD_MAX_VDI_LEN]; int is_snapshot; +uint8_t cache_enabled; char *addr; char *port; int fd; +int flush_fd; CoMutex lock; Coroutine *co_send; @@ -516,6 +520,23 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data, return ret; } +static int send_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen) +{ +int ret; + +ret = qemu_co_send(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to send a req, %s, strerror(errno)); +} + +ret = qemu_co_send(sockfd, data, *wlen); +if (ret *wlen) { +error_report(failed to send a req, %s, strerror(errno)); +} + +return ret; +} static int do_req(int sockfd, SheepdogReq *hdr, void *data, unsigned int *wlen, unsigned int *rlen) { @@ -550,6 +571,40 @@ out: return ret; } +static int do_co_req(int sockfd, SheepdogReq *hdr, void *data, + unsigned int *wlen, unsigned int *rlen) +{ +int ret; + +socket_set_block(sockfd); +ret = send_co_req(sockfd, hdr, data, wlen); +if (ret 0) { +goto out; +} + +ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr)); +if (ret sizeof(*hdr)) { +error_report(failed to get a rsp, %s, strerror(errno)); +goto out; +} + +if (*rlen hdr-data_length) { +*rlen = hdr-data_length; +} + +if (*rlen) { +ret = qemu_co_recv(sockfd, data, *rlen); +if (ret *rlen) { +error_report(failed to get the data, %s, strerror(errno)); +goto out; +} +} +ret = 0; +out: +socket_set_nonblock(sockfd); +return ret; +} + static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type); @@ -900,6 +955,10 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, hdr.flags = SD_FLAG_CMD_WRITE | flags; } +if (s-cache_enabled) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.cow_oid = old_oid; hdr.copies = s-inode.nr_copies; @@ -942,7 +1001,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, static int read_write_object(int fd, char *buf, uint64_t oid, int copies, unsigned int datalen, uint64_t offset, - int write, int create) + int write, int create, uint8_t cache) { SheepdogObjReq hdr; SheepdogObjRsp *rsp = (SheepdogObjRsp *)hdr; @@ -965,6 +1024,11 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, rlen = datalen; hdr.opcode = SD_OP_READ_OBJ; } + +if (cache) { +hdr.flags |= SD_FLAG_CMD_CACHE; +} + hdr.oid = oid; hdr.data_length = datalen; hdr.offset = offset; @@ -986,15 +1050,18 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies, } static int read_object(int fd, char *buf, uint64_t oid, int copies, - unsigned int datalen, uint64_t offset) + unsigned int datalen, uint64_t offset, uint8_t cache) { -return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0); +return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0, + cache); } static int write_object(int fd, char *buf, uint64_t oid, int copies, -unsigned int datalen, uint64_t offset, int create) +unsigned int datalen, uint64_t offset, int create, +uint8_t cache) { -return read_write_object(fd, buf, oid,
Re: [Qemu-devel] [PATCH] Memory: unify ioport registration
On 04/03/2012 12:38 PM, Julien Grall wrote: Please pass either pci_address_space_io() or isa_io_address_space() (you'll have to write the latter) to cirrus_init_common() from its callers. We really want to avoid get_system_io(). isa_io_address_space doesn't exist. I will create it, but which memory region we need to return ? get_system_io () ? Yes. The point it that we can later remove that get_system_io() in one place, instead of many. Please add isa_io_address_space() in a separate patch. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [Qemu-trivial] [PATCH trivial] make: fix clean rule by removing build file in qom/
On Tue, Apr 03, 2012 at 11:06:45AM +0100, Anthony PERARD wrote: On Tue, Apr 3, 2012 at 09:56, Stefan Hajnoczi stefa...@gmail.com wrote: tg: (a3b6181..) fix/make-clean (depends on: master) What's this? I'm curious. First I thought it was a signature joke that I didn't get but I guess it's for some kind of commit tracking system? No, it is not. To prepare a patch (or patch set), I use a tool called topgit. http://repo.or.cz/w/topgit.git It creates one git branch per patch, and you can add as many dependence branch as you want. When you want to rebase a patch, topgit will merge with the depends. Thanks for sharing! Stefan
Re: [Qemu-devel] [PATCH] Memory: unify ioport registration
On 04/03/2012 12:34 PM, Andreas Färber wrote: Am 02.04.2012 16:37, schrieb Julien Grall: Replace register_ioport* by portio_list_*. [snip] Are these changes guaranteed to not change the addresses in some way? Yes (modulo those subtle bugs). We've had really subtle bugs with offsets added / not added in the past. Those were bugs in the implementation of the portio functions and the memory core, not the conversions IIRC. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH v4 UPDATE] sheepdog: implement SD_OP_FLUSH_VDI operation
At Tue, 3 Apr 2012 18:08:10 +0800, Liu Yuan wrote: From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- UPDATE: use flush_fd instead of s-fd. block/sheepdog.c | 142 - 1 files changed, 128 insertions(+), 14 deletions(-) Thanks, looks good to me. Acked-by: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp
Re: [Qemu-devel] [PATCH v4 UPDATE] sheepdog: implement SD_OP_FLUSH_VDI operation
Am 03.04.2012 12:32, schrieb MORITA Kazutaka: At Tue, 3 Apr 2012 18:08:10 +0800, Liu Yuan wrote: From: Liu Yuan tailai...@taobao.com Flush operation is supposed to flush the write-back cache of sheepdog cluster. By issuing flush operation, we can assure the Guest of data reaching the sheepdog cluster storage. Cc: Kevin Wolf kw...@redhat.com Cc: Michael Tokarev m...@tls.msk.ru Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Cc: Stefan Hajnoczi stefa...@gmail.com Signed-off-by: Liu Yuan tailai...@taobao.com --- UPDATE: use flush_fd instead of s-fd. block/sheepdog.c | 142 - 1 files changed, 128 insertions(+), 14 deletions(-) Thanks, looks good to me. Acked-by: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Thanks, applied to the block branch. Kevin
[Qemu-devel] [PATCH 5/8] main-loop: make qemu_event_handle static
From: Frediano Ziglio fredd...@gmail.com Signed-off-by: Frediano Ziglio fredd...@gmail.com Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- main-loop.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/main-loop.c b/main-loop.c index db23de0..fc738d1 100644 --- a/main-loop.c +++ b/main-loop.c @@ -164,7 +164,7 @@ static int qemu_signal_init(void) #else /* _WIN32 */ -HANDLE qemu_event_handle = NULL; +static HANDLE qemu_event_handle = NULL; static void dummy_event_handler(void *opaque) { -- 1.7.9.1
[Qemu-devel] [PULL 0/8] Trivial patches for 27 March to 3 April 2012
I'm will be gone from tomorrow until Monday so it's time to flush the trivial-patches queue. The following changes since commit f05f6b4adb4db3affb0cdd17383b0a7e905e66e1: qdev: put all devices under /machine (2012-04-02 15:04:15 -0500) are available in the git repository at: git://github.com/stefanha/qemu.git trivial-patches for you to fetch changes up to 53fbf7b5391c76cc474d469bfed6a69a1243f4de: make: fix clean rule by removing build file in qom/ (2012-04-03 09:55:26 +0100) Anthony PERARD (1): make: fix clean rule by removing build file in qom/ Frediano Ziglio (1): main-loop: make qemu_event_handle static Jan Kiszka (1): w32: Undefine error constants before their redefinition Lluís Vilanova (2): configure: Link QEMU against 'liburcu-bp' configure: Link qga against UST tracing related libraries Stefan Hajnoczi (1): configure: fix mingw32 libs_qga typo Stefan Weil (2): qtest: Add missing GCC_FMT_ATTR block/curl: Replace usleep by g_usleep Makefile |1 + block/curl.c |2 +- configure |5 +++-- main-loop.c |2 +- qemu_socket.h |2 ++ qtest.c |3 ++- 6 files changed, 10 insertions(+), 5 deletions(-) -- 1.7.9.1
[Qemu-devel] [PATCH 7/8] configure: Link qga against UST tracing related libraries
From: Lluís Vilanova vilan...@ac.upc.edu Signed-off-by: Harsh Prateek Bora ha...@linux.vnet.ibm.com Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- configure |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 319355b..520bd93 100755 --- a/configure +++ b/configure @@ -2673,6 +2673,7 @@ int main(void) { return 0; } EOF if compile_prog ; then LIBS=-lust -lurcu-bp $LIBS +libs_qga=-lust -lurcu-bp $libs_qga else echo echo Error: Trace backend 'ust' missing libust header files -- 1.7.9.1
Re: [Qemu-devel] RE. [PATCH] sheepdog: fix send req helpers
At Tue, 3 Apr 2012 18:04:21 +0800, Liu Yuan wrote: From: Liu Yuan tailai...@taobao.com Yes, I think so. Here is the patch. Subject: [PATCH] sheepdog: fix send req helpers From: Liu Yuan tailai...@taobao.com We should return if reading of the header fails. Cc: Kevin Wolf kw...@redhat.com Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Signed-off-by: Liu Yuan tailai...@taobao.com --- block/sheepdog.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) Acked-by: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp
[Qemu-devel] [PATCH 1/8] configure: fix mingw32 libs_qga typo
It's typical to prepend or append parameters to an argument string so that other places in ./configure can add parameters without clobbering the string. In the mingw32 libs_qga case there is a typo $lib_qga instead of $libs_qga. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com Reviewed-by: Andreas Färber afaer...@suse.de --- configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure b/configure index 4b3adc9..c0a542b 100755 --- a/configure +++ b/configure @@ -526,7 +526,7 @@ EOF bindir=\${prefix} sysconfdir=\${prefix} confsuffix= - libs_qga=-lws2_32 -lwinmm -lpowrprof $lib_qga + libs_qga=-lws2_32 -lwinmm -lpowrprof $libs_qga fi werror= -- 1.7.9.1
[Qemu-devel] [PATCH 6/8] configure: Link QEMU against 'liburcu-bp'
From: Lluís Vilanova vilan...@ac.upc.edu This library is needed when using 'ust/tracepoint.h'. Signed-off-by: Harsh Prateek Bora ha...@linux.vnet.ibm.com Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- configure |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure b/configure index c0a542b..319355b 100755 --- a/configure +++ b/configure @@ -2672,7 +2672,7 @@ if test $trace_backend = ust; then int main(void) { return 0; } EOF if compile_prog ; then -LIBS=-lust $LIBS +LIBS=-lust -lurcu-bp $LIBS else echo echo Error: Trace backend 'ust' missing libust header files -- 1.7.9.1
Re: [Qemu-devel] [PATCH 0/6] fix w32 sockets
Il 20/03/2012 10:49, Paolo Bonzini ha scritto: The w32 main loop has been mostly broken by the introduction of the glib main loop. glib's g_poll does not use sockets on w32, so we need a separate approach. Patch 1 is a simple cleanup that is needed later in the series. Patch 2 and patch 3 completely separate the way the main loop waits on POSIX and w32 systems, and drop glib source handling from the w32 main loop. Patch 4 fixes a longstanding bug in how sockets are handled, also simplifying the code in the process. On top of this simplification, patch 5 starts using g_poll in the w32 main loop and patch 6 adds back glib source handling. I didn't test this in the conditions explained in bug 916720, but I tested both a TCP monitor and an stdio monitor and both work (under Wine that is). Stefan, can you please take care of shepherding the patches in (pinging etc.)? Paolo Bonzini (6): slirp: use socket_set_nonblock main loop: use msec-based timeout in glib_select_fill main-loop: disable fd_set-based glib integration under w32 main-loop: interrupt wait when data arrives on a socket main-loop: replace WaitForMultipleObjects with g_poll main-loop: integrate glib sources for w32 Patch 1 is now in separately through the slirp tree, so the other 5 can now be applied. Blue, can you commit them? Paolo
[Qemu-devel] [PATCH 4/8] block/curl: Replace usleep by g_usleep
From: Stefan Weil s...@weilnetz.de The function usleep is not available for all supported platforms: at least some versions of MinGW don't support it. usleep was also declared obsolete by POSIX.1-2001. The function g_usleep is part of glib2.0, so it is available for all supported platforms. Using nanosleep would also be possible but needs more code. Signed-off-by: Stefan Weil s...@weilnetz.de Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- block/curl.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/block/curl.c b/block/curl.c index e9102e3..a909eca 100644 --- a/block/curl.c +++ b/block/curl.c @@ -282,7 +282,7 @@ static CURLState *curl_init_state(BDRVCURLState *s) break; } if (!state) { -usleep(100); +g_usleep(100); curl_multi_do(s); } } while(!state); -- 1.7.9.1
[Qemu-devel] [PATCH 3/8] qtest: Add missing GCC_FMT_ATTR
From: Stefan Weil s...@weilnetz.de gcc reports an error when the code is compiled with -Wmissing-format-attribute. Signed-off-by: Stefan Weil s...@weilnetz.de Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- qtest.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/qtest.c b/qtest.c index daeabb7..18afcd9 100644 --- a/qtest.c +++ b/qtest.c @@ -156,7 +156,8 @@ static void qtest_send_prefix(CharDriverState *chr) tv.tv_sec, tv.tv_usec); } -static void qtest_send(CharDriverState *chr, const char *fmt, ...) +static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, + const char *fmt, ...) { va_list ap; char buffer[1024]; -- 1.7.9.1
[Qemu-devel] [PATCH 00/25] qdev properties final installment: push, push!
This is the final installment of the qdev property cleanup. It includes the following parts: * various bits of state are moved from DeviceState to Object: state (aka realized), reset, static properties, and the simple type property * bus properties are replaced with superclass properties The series has many parts; they are logically separate, but because of dependencies it would take too much time to submit them one by one. In fact, to avoid conflicts, and because his patchset does not apply anymore, I took the liberty to include here Michael Roth's patches for uint*_t and int*_t visitors. Patches 1 to 5 are small preparatory changes in QOM. Patches 6 and 7 are bonus bugfixes. Patches 8 to 13 refactor bus properties. Patches 14 to 18 are Michael's patches + two cleanups. Patches 19 to 22 push static properties from qdev to Object. As you can see from the diffstat below, this has to touch a lot of files. Patches 23 to 25 implement the realized property and reimplement qdev's object lifecycle in terms of realize/unrealize. Michael Roth (3): qapi: add Visitor interfaces for uint*_t and int*_t qdev: use int32_t container for devfn property qdev: switch property accessors to fixed-width visitor interfaces Paolo Bonzini (22): qom: add object_class_get_parent qom: add object_child_foreach qom: add class_base_init qom: make Object a type qom: push type up to Object qdev: fix -device foo,? qdev: use object_property_print in info qtree qdev: remove qdev_prop_set_defaults qdev: move bus properties to a separate global qdev: do not propagate properties to subclasses qdev: pick global properties from superclasses qdev: factor setting of global properties qdev: replace bus properties with superclass properties qdev: remove PropertyInfo range checking qdev: remove qdev_prop_exists qom: push state up to Object qdev: generalize properties to Objects qdev: move bulk of qdev-properties.c to qom/object.c qom: push static properties to Object qom: add realized property qdev: implement qdev_init on top of realize qdev: split part of device_finalize to device_unrealize hw/9pfs/virtio-9p-device.c|2 +- hw/a15mpcore.c|3 +- hw/a9mpcore.c |2 +- hw/ac97.c |2 +- hw/acpi_piix4.c |2 +- hw/apic_common.c |2 +- hw/applesmc.c |2 +- hw/arm11mpcore.c |6 +- hw/arm_l2x0.c |2 +- hw/arm_mptimer.c |2 +- hw/arm_sysctl.c |2 +- hw/arm_timer.c|3 +- hw/armv7m.c |3 +- hw/armv7m_nvic.c |2 +- hw/cadence_gem.c |2 +- hw/ccid-card-emulated.c |2 +- hw/ccid-card-passthru.c |2 +- hw/cs4231.c |2 +- hw/cs4231a.c |2 +- hw/debugcon.c |3 +- hw/ds1225y.c |2 +- hw/e1000.c|2 +- hw/eccmemctl.c|2 +- hw/eepro100.c |2 +- hw/escc.c |2 +- hw/esp.c |2 +- hw/etraxfs_eth.c |3 +- hw/etraxfs_pic.c |3 +- hw/exynos4210_combiner.c |2 +- hw/exynos4210_gic.c |3 +- hw/exynos4210_uart.c |2 +- hw/fdc.c |6 +- hw/fw_cfg.c |2 +- hw/g364fb.c |2 +- hw/grlib_apbuart.c|3 +- hw/grlib_gptimer.c|2 +- hw/grlib_irqmp.c |2 +- hw/gus.c |2 +- hw/hda-audio.c|4 +- hw/hpet.c |2 +- hw/i2c.c | 10 +- hw/i82374.c |2 +- hw/i82378.c |2 +- hw/i8254.c|2 +- hw/i8259_common.c |2 +- hw/ide/ahci.c |2 +- hw/ide/cmd646.c |3 +- hw/ide/isa.c |2 +- hw/ide/qdev.c | 16 +- hw/integratorcp.c |3 +- hw/intel-hda.c| 12 +- hw/ioh3420.c |2 +- hw/ivshmem.c |2 +- hw/kvm/i8254.c|2 +- hw/kvm/ioapic.c |2 +- hw/lan9118.c |2 +- hw/lance.c|2 +- hw/lm32_sys.c |2 +- hw/lm32_timer.c |2 +- hw/m48t59.c |4 +- hw/marvell_88w8618_audio.c|2 +- hw/mc146818rtc.c |9 +- hw/milkymist-minimac2.c |2 +- hw/milkymist-softusb.c|2 +- hw/milkymist-sysctl.c |2 +- hw/milkymist-vgafb.c |2 +- hw/mipsnet.c |2 +- hw/musicpal.c |2 +- hw/nand.c |2 +- hw/ne2000-isa.c
[Qemu-devel] [PATCH 04/25] qom: make Object a type
Right now the base Object class has a special NULL type. Change this so that we will be able to add class_init and class_base_init callbacks. To do this, remove some special casing of ObjectClass that is not really necessary. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/qemu/object.h |2 +- qom/object.c | 59 + 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/include/qemu/object.h b/include/qemu/object.h index ccaea7d..22f646d 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -33,7 +33,7 @@ typedef struct TypeInfo TypeInfo; typedef struct InterfaceClass InterfaceClass; typedef struct InterfaceInfo InterfaceInfo; -#define TYPE_OBJECT NULL +#define TYPE_OBJECT object /** * SECTION:object.h diff --git a/qom/object.c b/qom/object.c index 6ff1c19..585619d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -210,7 +210,7 @@ static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface) static void type_initialize(TypeImpl *ti) { -size_t class_size = sizeof(ObjectClass); +TypeImpl *parent; int i; if (ti-class) { @@ -221,30 +221,24 @@ static void type_initialize(TypeImpl *ti) ti-instance_size = type_object_get_size(ti); ti-class = g_malloc0(ti-class_size); -ti-class-type = ti; - -if (type_has_parent(ti)) { -TypeImpl *parent = type_get_parent(ti); +parent = type_get_parent(ti); +if (parent) { type_initialize(parent); -class_size = parent-class_size; g_assert(parent-class_size = ti-class_size); +memcpy(ti-class, parent-class, parent-class_size); +} -memcpy((void *)ti-class + sizeof(ObjectClass), - (void *)parent-class + sizeof(ObjectClass), - parent-class_size - sizeof(ObjectClass)); +ti-class-type = ti; -while (parent) { -if (parent-class_base_init) { -parent-class_base_init(ti-class, ti-class_data); -} -parent = type_get_parent(parent); +while (parent) { +if (parent-class_base_init) { +parent-class_base_init(ti-class, ti-class_data); } +parent = type_get_parent(parent); } -memset((void *)ti-class + class_size, 0, ti-class_size - class_size); - for (i = 0; i ti-num_interfaces; i++) { type_class_interface_init(ti, ti-interfaces[i]); } @@ -467,19 +461,6 @@ Object *object_dynamic_cast(Object *obj, const char *typename) } -static void register_types(void) -{ -static TypeInfo interface_info = { -.name = TYPE_INTERFACE, -.instance_size = sizeof(Interface), -.abstract = true, -}; - -type_interface = type_register_static(interface_info); -} - -type_init(register_types) - Object *object_dynamic_cast_assert(Object *obj, const char *typename) { Object *inst; @@ -1233,3 +1214,23 @@ void object_property_add_str(Object *obj, const char *name, property_release_str, prop, errp); } + +static void register_types(void) +{ +static TypeInfo interface_info = { +.name = TYPE_INTERFACE, +.instance_size = sizeof(Interface), +.abstract = true, +}; + +static TypeInfo object_info = { +.name = TYPE_OBJECT, +.instance_size = sizeof(Object), +.abstract = true, +}; + +type_interface = type_register_static(interface_info); +type_register_static(object_info); +} + +type_init(register_types) -- 1.7.9.3
[Qemu-devel] [PATCH 06/25] qdev: fix -device foo,?
Since most property types do not have a parse property now, this was broken. Fix it by looking at the setter instead. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-monitor.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 4783366..0acfc82 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -157,7 +157,7 @@ int qdev_device_help(QemuOpts *opts) * for removal. This conditional should be removed along with * it. */ -if (!prop-info-parse) { +if (!prop-info-set) { continue; /* no way to set it, don't show */ } error_printf(%s.%s=%s\n, driver, prop-name, @@ -165,7 +165,7 @@ int qdev_device_help(QemuOpts *opts) } if (info-bus_info) { for (prop = info-bus_info-props; prop prop-name; prop++) { -if (!prop-info-parse) { +if (!prop-info-set) { continue; /* no way to set it, don't show */ } error_printf(%s.%s=%s\n, driver, prop-name, -- 1.7.9.3
[Qemu-devel] [PATCH 02/25] qom: add object_child_foreach
A utility function that will be used to implement hierarchical realization. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/qemu/object.h | 14 +- qom/object.c | 17 + 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/qemu/object.h b/include/qemu/object.h index f814521..470efe3 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -918,6 +918,19 @@ void object_property_add_str(Object *obj, const char *name, struct Error **errp); /** + * object_child_foreach: + * @obj: the object whose children will be navigated + * @fn: the iterator function to be called + * @opaque: an opaque value that will be passed to the iterator + * + * Call @fn passing each child of @obj and @opaque to it, until @fn returns + * non-zero. Return the last value returned by @fn, or 0 if there is no + * child. + */ +int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), + void *opaque); + +/** * container_get: * @path: path to the container * @@ -928,5 +941,4 @@ void object_property_add_str(Object *obj, const char *name, */ Object *container_get(const char *path); - #endif diff --git a/qom/object.c b/qom/object.c index 3e9fed7..4975d93 100644 --- a/qom/object.c +++ b/qom/object.c @@ -597,6 +597,23 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, data); } +int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), + void *opaque) +{ +ObjectProperty *prop; +int ret = 0; + +QTAILQ_FOREACH(prop, obj-properties, node) { +if (strstart(prop-type, child, NULL)) { +ret = fn(prop-opaque, opaque); +if (ret != 0) { +break; +} +} +} +return ret; +} + static void object_class_get_list_tramp(ObjectClass *klass, void *opaque) { GSList **list = opaque; -- 1.7.9.3
[Qemu-devel] [PATCH 19/25] qom: push state up to Object
qdev properties use the state member (an embryo of the realized property) in order to disable setting them after a device has been initialized. So, in order to push qdev properties up to Object we need to push this bit there too. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-addr.c|3 ++- hw/qdev-properties.c | 24 hw/qdev.c | 11 +-- hw/qdev.h |6 -- include/qemu/object.h | 14 ++ qom/object.c |6 ++ 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c index b711b6b..a3796bd 100644 --- a/hw/qdev-addr.c +++ b/hw/qdev-addr.c @@ -1,3 +1,4 @@ +#include qemu/object.h #include qdev.h #include qdev-addr.h #include targphys.h @@ -39,7 +40,7 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque, Error *local_err = NULL; int64_t value; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index ffd601a..282cf68 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -53,7 +53,7 @@ static void set_bit(Object *obj, Visitor *v, void *opaque, Error *local_err = NULL; bool value; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -93,7 +93,7 @@ static void set_uint8(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; uint8_t *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -160,7 +160,7 @@ static void set_uint16(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; uint16_t *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -193,7 +193,7 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; uint32_t *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -218,7 +218,7 @@ static void set_int32(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; int32_t *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -291,7 +291,7 @@ static void set_uint64(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; uint64_t *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -379,7 +379,7 @@ static void set_string(Object *obj, Visitor *v, void *opaque, Error *local_err = NULL; char *str; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -457,7 +457,7 @@ static void set_pointer(Object *obj, Visitor *v, Property *prop, char *str; int ret; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -626,7 +626,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque, int64_t id; VLANState *vlan; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -696,7 +696,7 @@ static void set_mac(Object *obj, Visitor *v, void *opaque, int i, pos; char *str, *p; -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -764,7 +764,7 @@ static void set_enum(Object *obj, Visitor *v, void *opaque, Property *prop = opaque; int *ptr = qdev_get_prop_ptr(dev, prop); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } @@ -795,7 +795,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque, Error *local_err = NULL; char *str = (char *); -if (dev-state != DEV_STATE_CREATED) { +if (object_is_realized(obj)) { error_set(errp, QERR_PERMISSION_DENIED); return; } diff --git a/hw/qdev.c b/hw/qdev.c index 9e7a4b7..12752e9 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -124,7 +124,7 @@ int qdev_init(DeviceState *dev) DeviceClass *dc =
[Qemu-devel] [PATCH 17/25] qdev: remove PropertyInfo range checking
Range checking in PropertyInfo is now used only for pci_devfn properties. Move it there, and remove all code that implements it in the various property types. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-properties.c | 102 -- hw/qdev.h|2 - 2 files changed, 24 insertions(+), 80 deletions(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 85d8a11..ace81cf 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -91,34 +91,20 @@ static void set_uint8(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -uint8_t value, *ptr = qdev_get_prop_ptr(dev, prop); -Error *local_err = NULL; +uint8_t *ptr = qdev_get_prop_ptr(dev, prop); if (dev-state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } -visit_type_uint8(v, value, name, local_err); -if (local_err) { -error_propagate(errp, local_err); -return; -} -if (value = prop-info-min value = prop-info-max) { -*ptr = value; -} else { -error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, - dev-id?:, name, (int64_t)value, prop-info-min, - prop-info-max); -} +visit_type_uint8(v, ptr, name, errp); } PropertyInfo qdev_prop_uint8 = { .name = uint8, .get = get_uint8, .set = set_uint8, -.min = 0, -.max = 255, }; /* --- 8bit hex value --- */ @@ -153,8 +139,6 @@ PropertyInfo qdev_prop_hex8 = { .print = print_hex8, .get = get_uint8, .set = set_uint8, -.min = 0, -.max = 255, }; /* --- 16bit integer --- */ @@ -174,34 +158,20 @@ static void set_uint16(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -uint16_t value, *ptr = qdev_get_prop_ptr(dev, prop); -Error *local_err = NULL; +uint16_t *ptr = qdev_get_prop_ptr(dev, prop); if (dev-state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } -visit_type_uint16(v, value, name, local_err); -if (local_err) { -error_propagate(errp, local_err); -return; -} -if (value = prop-info-min value = prop-info-max) { -*ptr = value; -} else { -error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, - dev-id?:, name, (int64_t)value, prop-info-min, - prop-info-max); -} +visit_type_uint16(v, ptr, name, errp); } PropertyInfo qdev_prop_uint16 = { .name = uint16, .get = get_uint16, .set = set_uint16, -.min = 0, -.max = 65535, }; /* --- 32bit integer --- */ @@ -211,10 +181,9 @@ static void get_uint32(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -uint32_t value, *ptr = qdev_get_prop_ptr(dev, prop); +uint32_t *ptr = qdev_get_prop_ptr(dev, prop); -value = *ptr; -visit_type_uint32(v, value, name, errp); +visit_type_uint32(v, ptr, name, errp); } static void set_uint32(Object *obj, Visitor *v, void *opaque, @@ -222,26 +191,14 @@ static void set_uint32(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -uint32_t value, *ptr = qdev_get_prop_ptr(dev, prop); -Error *local_err = NULL; +uint32_t *ptr = qdev_get_prop_ptr(dev, prop); if (dev-state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED); return; } -visit_type_uint32(v, value, name, local_err); -if (local_err) { -error_propagate(errp, local_err); -return; -} -if (value = prop-info-min value = prop-info-max) { -*ptr = value; -} else { -error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, - dev-id?:, name, (int64_t)value, prop-info-min, - prop-info-max); -} +visit_type_uint32(v, ptr, name, errp); } static void get_int32(Object *obj, Visitor *v, void *opaque, @@ -249,10 +206,9 @@ static void get_int32(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); +int32_t *ptr = qdev_get_prop_ptr(dev, prop); -value = *ptr; -visit_type_int32(v, value, name, errp); +visit_type_int32(v, ptr, name, errp); } static void set_int32(Object *obj, Visitor *v, void *opaque, @@ -260,42 +216,26 @@ static void set_int32(Object *obj, Visitor *v, void *opaque, { DeviceState *dev = DEVICE(obj); Property *prop = opaque; -int32_t value, *ptr = qdev_get_prop_ptr(dev, prop); -Error *local_err = NULL; +int32_t *ptr = qdev_get_prop_ptr(dev, prop); if (dev-state != DEV_STATE_CREATED) { error_set(errp, QERR_PERMISSION_DENIED);
Re: [Qemu-devel] [PATCH] block: bdrv_append() fixes
Am 27.03.2012 22:30, schrieb Jeff Cody: A few fixups for bdrv_append(): The new bs (bs_new) passed into bdrv_append() should be anonymous. Rather than call bdrv_make_anon() to enforce this, use an assert to catch when a caller is passing in a bs_new that is not anonymous. Also, the new top layer should have its backing_format reflect the original top's format. And last, after the swap of bs contents, the device_name will have been copied down. This needs to be cleared to reflect the anonymity of the bs that was pushed down. Signed-off-by: Jeff Cody jc...@redhat.com Thanks, applied to the block branch. Kevin
[Qemu-devel] [PATCH 14/25] qapi: add Visitor interfaces for uint*_t and int*_t
From: Michael Roth mdr...@linux.vnet.ibm.com This adds visitor interfaces for fixed-width integers types. Implementing these in visitors is optional, otherwise we fall back to visit_type_int() (int64_t) with some additional bounds checking to avoid integer overflows for cases where the value fetched exceeds the bounds of our target C type. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/mc146818rtc.c |7 --- qapi/qapi-visit-core.c | 139 qapi/qapi-visit-core.h | 16 ++ 3 files changed, 155 insertions(+), 7 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 9c64e0a..3777f85 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -599,13 +599,6 @@ static const MemoryRegionOps cmos_ops = { .old_portio = cmos_portio }; -// FIXME add int32 visitor -static void visit_type_int32(Visitor *v, int *value, const char *name, Error **errp) -{ -int64_t val = *value; -visit_type_int(v, val, name, errp); -} - static void rtc_get_date(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index a4e088c..9a29674 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -97,6 +97,145 @@ void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp) } } +void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_uint8) { +v-type_uint8(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value UINT8_MAX) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : null, + uint8_t); +return; +} +*obj = value; +} +} +} + +void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_uint16) { +v-type_uint16(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value UINT16_MAX) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : null, + uint16_t); +return; +} +*obj = value; +} +} +} + +void visit_type_uint32(Visitor *v, uint32_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_uint32) { +v-type_uint32(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value UINT32_MAX) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : null, + uint32_t); +return; +} +*obj = value; +} +} +} + +void visit_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_uint64) { +v-type_uint64(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +*obj = value; +} +} +} + +void visit_type_int8(Visitor *v, int8_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_int8) { +v-type_int8(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value INT8_MIN || value INT8_MAX) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : null, + int8_t); +return; +} +*obj = value; +} +} +} + +void visit_type_int16(Visitor *v, int16_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_int16) { +v-type_int16(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value INT16_MIN || value INT16_MAX) { +error_set(errp, QERR_INVALID_PARAMETER_VALUE, name ? name : null, + int16_t); +return; +} +*obj = value; +} +} +} + +void visit_type_int32(Visitor *v, int32_t *obj, const char *name, Error **errp) +{ +int64_t value; +if (!error_is_set(errp)) { +if (v-type_int32) { +v-type_int32(v, obj, name, errp); +} else { +value = *obj; +v-type_int(v, value, name, errp); +if (value INT32_MIN || value INT32_MAX) { +
[Qemu-devel] [PATCH 18/25] qdev: remove qdev_prop_exists
Can be replaced everywhere with object_property_find. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-properties.c |5 - hw/qdev.c |2 +- hw/qdev.h |1 - hw/scsi-bus.c |2 +- include/qemu/object.h |9 + qom/object.c |2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index ace81cf..ffd601a 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -882,11 +882,6 @@ static Property *qdev_prop_find(DeviceState *dev, const char *name) return NULL; } -int qdev_prop_exists(DeviceState *dev, const char *name) -{ -return qdev_prop_find(dev, name) ? true : false; -} - void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev, Property *prop, const char *value) { diff --git a/hw/qdev.c b/hw/qdev.c index aeebb86..9e7a4b7 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -295,7 +295,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd) if (nd-netdev) qdev_prop_set_netdev(dev, netdev, nd-netdev); if (nd-nvectors != DEV_NVECTORS_UNSPECIFIED -qdev_prop_exists(dev, vectors)) { +object_property_find(OBJECT(dev), vectors)) { qdev_prop_set_uint32(dev, vectors, nd-nvectors); } nd-instantiated = 1; diff --git a/hw/qdev.h b/hw/qdev.h index dfff93a..a159b94 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -287,7 +287,6 @@ extern PropertyInfo qdev_prop_pci_devfn; /* Set properties between creation and init. */ void *qdev_get_prop_ptr(DeviceState *dev, Property *prop); -int qdev_prop_exists(DeviceState *dev, const char *name); int qdev_prop_parse(DeviceState *dev, const char *name, const char *value); void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value); void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value); diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 10f9c63..2777566 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -206,7 +206,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, if (bootindex = 0) { qdev_prop_set_int32(dev, bootindex, bootindex); } -if (qdev_prop_exists(dev, removable)) { +if (object_property_find(OBJECT(dev), removable)) { qdev_prop_set_bit(dev, removable, removable); } if (qdev_prop_set_drive(dev, drive, bdrv) 0) { diff --git a/include/qemu/object.h b/include/qemu/object.h index 22f646d..80f2bf3 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -637,6 +637,15 @@ void object_property_add(Object *obj, const char *name, const char *type, void object_property_del(Object *obj, const char *name, struct Error **errp); +/** + * object_property_find: + * @obj: the object + * @name: the name of the property + * + * Look up a property for an object and return its #ObjectProperty if found. + */ +ObjectProperty *object_property_find(Object *obj, const char *name); + void object_unparent(Object *obj); /** diff --git a/qom/object.c b/qom/object.c index ff36946..488047c 100644 --- a/qom/object.c +++ b/qom/object.c @@ -656,7 +656,7 @@ void object_property_add(Object *obj, const char *name, const char *type, QTAILQ_INSERT_TAIL(obj-properties, prop, node); } -static ObjectProperty *object_property_find(Object *obj, const char *name) +ObjectProperty *object_property_find(Object *obj, const char *name) { ObjectProperty *prop; -- 1.7.9.3
Re: [Qemu-devel] [PATCH 09/10] coroutine: schedule timeout coroutine instead process it directly
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: Avoid a timer callback spends too much time. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-sleep.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c index fd65274..df9254a 100644 --- a/qemu-coroutine-sleep.c +++ b/qemu-coroutine-sleep.c @@ -24,7 +24,7 @@ static void co_sleep_cb(void *opaque) CoSleepCB *sleep_cb = opaque; qemu_free_timer(sleep_cb-ts); -qemu_coroutine_enter(sleep_cb-co, NULL); +qemu_co_runnable_schedule(sleep_cb-co); } void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns) Why is this important? Also, why should it be different for timers, fd_handlers (used for example by NBD) and bottom halves (used for AIO callbacks)? Paolo
Re: [Qemu-devel] [PATCH 01/10] coroutine: use qemu_coroutine_switch() directly
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: When qemu_coroutine_switch() in the qemu_coroutine_yield() returns, It must be someone calls qemu_coroutine_enter() for it, so the @to is active, the tests in coroutine_swap() are unneeded, so we use qemu_coroutine_switch() directly in qemu_coroutine_yield(). The patches are very different. Some of them are just cleanups which I like (patches 2 to 7, more or less). The others seem to be a (micro?) optimization whose usecase and result you didn't document because there was no cover letter. This patch is an example, is one or two ifs so expensive that it matters? Paolo Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qemu-coroutine.c b/qemu-coroutine.c index 600be26..c01252e 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -71,5 +71,5 @@ void coroutine_fn qemu_coroutine_yield(void) } self-caller = NULL; -coroutine_swap(self, to); +qemu_coroutine_switch(self, to, COROUTINE_YIELD); }
Re: [Qemu-devel] [PATCH 02/10] coroutine: rename unlock_bh_queue to co_runnable_queue
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: It stands for runnable Coroutines. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c | 18 +- 1 files changed, 9 insertions(+), 9 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 26ad76b..10e8dbb 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -29,17 +29,17 @@ #include main-loop.h #include trace.h -static QTAILQ_HEAD(, Coroutine) unlock_bh_queue = -QTAILQ_HEAD_INITIALIZER(unlock_bh_queue); -static QEMUBH* unlock_bh; +static QTAILQ_HEAD(, Coroutine) co_runnable_queue = +QTAILQ_HEAD_INITIALIZER(co_runnable_queue); +static QEMUBH* co_runnable_bh; static void qemu_co_queue_next_bh(void *opaque) { Coroutine *next; trace_qemu_co_queue_next_bh(); -while ((next = QTAILQ_FIRST(unlock_bh_queue))) { -QTAILQ_REMOVE(unlock_bh_queue, next, co_queue_next); +while ((next = QTAILQ_FIRST(co_runnable_queue))) { +QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); qemu_coroutine_enter(next, NULL); } } @@ -48,8 +48,8 @@ void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); -if (!unlock_bh) { -unlock_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); +if (!co_runnable_bh) { +co_runnable_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); } } @@ -76,9 +76,9 @@ bool qemu_co_queue_next(CoQueue *queue) next = QTAILQ_FIRST(queue-entries); if (next) { QTAILQ_REMOVE(queue-entries, next, co_queue_next); -QTAILQ_INSERT_TAIL(unlock_bh_queue, next, co_queue_next); +QTAILQ_INSERT_TAIL(co_runnable_queue, next, co_queue_next); trace_qemu_co_queue_next(next); -qemu_bh_schedule(unlock_bh); +qemu_bh_schedule(co_runnable_bh); } return (next != NULL); Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] RE. [PATCH] sheepdog: fix send req helpers
Am 03.04.2012 13:13, schrieb MORITA Kazutaka: At Tue, 3 Apr 2012 18:04:21 +0800, Liu Yuan wrote: From: Liu Yuan tailai...@taobao.com Yes, I think so. Here is the patch. Subject: [PATCH] sheepdog: fix send req helpers From: Liu Yuan tailai...@taobao.com We should return if reading of the header fails. Cc: Kevin Wolf kw...@redhat.com Cc: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Signed-off-by: Liu Yuan tailai...@taobao.com --- block/sheepdog.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) Acked-by: MORITA Kazutaka morita.kazut...@lab.ntt.co.jp Thanks, applied this one as well. Kevin
Re: [Qemu-devel] [PATCH 03/10] coroutine: rename qemu_co_queue_next_bh() to qemu_co_process_runnable()
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |6 +++--- trace-events |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 10e8dbb..90141cd 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -33,11 +33,11 @@ static QTAILQ_HEAD(, Coroutine) co_runnable_queue = QTAILQ_HEAD_INITIALIZER(co_runnable_queue); static QEMUBH* co_runnable_bh; -static void qemu_co_queue_next_bh(void *opaque) +static void qemu_co_process_runnable(void *opaque) { Coroutine *next; -trace_qemu_co_queue_next_bh(); +trace_qemu_co_process_runnable(); while ((next = QTAILQ_FIRST(co_runnable_queue))) { QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); qemu_coroutine_enter(next, NULL); @@ -49,7 +49,7 @@ void qemu_co_queue_init(CoQueue *queue) QTAILQ_INIT(queue-entries); if (!co_runnable_bh) { -co_runnable_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL); +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); } } diff --git a/trace-events b/trace-events index 70f059d..a1737c2 100644 --- a/trace-events +++ b/trace-events @@ -561,7 +561,7 @@ qemu_coroutine_yield(void *from, void *to) from %p to %p qemu_coroutine_terminate(void *co) self %p # qemu-coroutine-lock.c -qemu_co_queue_next_bh(void) +qemu_co_process_runnable(void) qemu_co_queue_next(void *next) next %p qemu_co_mutex_lock_entry(void *mutex, void *self) mutex %p self %p qemu_co_mutex_lock_return(void *mutex, void *self) mutex %p self %p Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] [PATCH 05/10] coroutine: add qemu_co_runnable_schedule()
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: split qemu_co_queue_next() as two parts: the first part is dequeuing next from the wait queue. the second part is schedule it to the runnable queue(qemu_co_runnable_schedule()) Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 7c29bc4..6f47685 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -44,6 +44,12 @@ static void qemu_co_process_runnable(void *opaque) } } +static void qemu_co_runnable_schedule(Coroutine *co) +{ +QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); +qemu_bh_schedule(co_runnable_bh); +} + static void __attribute__((constructor)) co_runnable_bh_init(void) { co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); @@ -77,9 +83,8 @@ bool qemu_co_queue_next(CoQueue *queue) next = QTAILQ_FIRST(queue-entries); if (next) { QTAILQ_REMOVE(queue-entries, next, co_queue_next); -QTAILQ_INSERT_TAIL(co_runnable_queue, next, co_queue_next); trace_qemu_co_queue_next(next); -qemu_bh_schedule(co_runnable_bh); +qemu_co_runnable_schedule(next); } return (next != NULL); Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] [PATCH 04/10] coroutine: init co_runnable_bh during boot
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: use __attribute__((constructor)) to do the initialization. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 90141cd..7c29bc4 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -44,13 +44,14 @@ static void qemu_co_process_runnable(void *opaque) } } +static void __attribute__((constructor)) co_runnable_bh_init(void) +{ +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); +} + void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); - -if (!co_runnable_bh) { -co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); -} } void coroutine_fn qemu_co_queue_wait(CoQueue *queue) Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] [PATCH 06/10] coroutine: move runnale coroutine code to qemu-coroutine.c
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: runnable coroutine queue is the core mangement of the coroutine. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c | 27 --- qemu-coroutine.c | 27 +++ qemu-coroutine.h |7 +++ trace-events |2 +- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 6f47685..159d66d 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -26,35 +26,8 @@ #include qemu-coroutine.h #include qemu-coroutine-int.h #include qemu-queue.h -#include main-loop.h #include trace.h -static QTAILQ_HEAD(, Coroutine) co_runnable_queue = -QTAILQ_HEAD_INITIALIZER(co_runnable_queue); -static QEMUBH* co_runnable_bh; - -static void qemu_co_process_runnable(void *opaque) -{ -Coroutine *next; - -trace_qemu_co_process_runnable(); -while ((next = QTAILQ_FIRST(co_runnable_queue))) { -QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); -qemu_coroutine_enter(next, NULL); -} -} - -static void qemu_co_runnable_schedule(Coroutine *co) -{ -QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); -qemu_bh_schedule(co_runnable_bh); -} - -static void __attribute__((constructor)) co_runnable_bh_init(void) -{ -co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); -} - void qemu_co_queue_init(CoQueue *queue) { QTAILQ_INIT(queue-entries); diff --git a/qemu-coroutine.c b/qemu-coroutine.c index c01252e..c67d557 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -16,6 +16,33 @@ #include qemu-common.h #include qemu-coroutine.h #include qemu-coroutine-int.h +#include main-loop.h + +static QTAILQ_HEAD(, Coroutine) co_runnable_queue = +QTAILQ_HEAD_INITIALIZER(co_runnable_queue); +static QEMUBH* co_runnable_bh; + +static void qemu_co_process_runnable(void *opaque) +{ +Coroutine *next; + +trace_qemu_co_process_runnable(); +while ((next = QTAILQ_FIRST(co_runnable_queue))) { +QTAILQ_REMOVE(co_runnable_queue, next, co_queue_next); +qemu_coroutine_enter(next, NULL); +} +} + +void qemu_co_runnable_schedule(Coroutine *co) +{ +QTAILQ_INSERT_TAIL(co_runnable_queue, co, co_queue_next); +qemu_bh_schedule(co_runnable_bh); +} + +static void __attribute__((constructor)) co_runnable_bh_init(void) +{ +co_runnable_bh = qemu_bh_new(qemu_co_process_runnable, NULL); +} Coroutine *qemu_coroutine_create(CoroutineEntry *entry) { diff --git a/qemu-coroutine.h b/qemu-coroutine.h index 34c15d4..82a7e5c 100644 --- a/qemu-coroutine.h +++ b/qemu-coroutine.h @@ -82,6 +82,13 @@ void qemu_coroutine_enter(Coroutine *coroutine, void *opaque); void coroutine_fn qemu_coroutine_yield(void); /** + * Add a coroutine to runnable to runnable queue + * + * The coroutine will be processed later. + */ +void qemu_co_runnable_schedule(Coroutine *co); + +/** * Get the currently executing coroutine */ Coroutine *coroutine_fn qemu_coroutine_self(void); diff --git a/trace-events b/trace-events index a1737c2..39b9c84 100644 --- a/trace-events +++ b/trace-events @@ -556,12 +556,12 @@ qemu_put_ram_ptr(void* addr) %p xen_platform_log(char *s) xen platform: %s # qemu-coroutine.c +qemu_co_process_runnable(void) qemu_coroutine_enter(void *from, void *to, void *opaque) from %p to %p opaque %p qemu_coroutine_yield(void *from, void *to) from %p to %p qemu_coroutine_terminate(void *co) self %p # qemu-coroutine-lock.c -qemu_co_process_runnable(void) qemu_co_queue_next(void *next) next %p qemu_co_mutex_lock_entry(void *mutex, void *self) mutex %p self %p qemu_co_mutex_lock_return(void *mutex, void *self) mutex %p self %p I think the point here was to have qemu-coroutine.c not depend on the QEMU main loop, so this is not ok. Paolo
Re: [Qemu-devel] [PATCH 07/10] coroutine: split qemu-coroutine-lock.c
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: queues are not just internal things for locks, split them. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- Makefile.objs |2 +- qemu-coroutine-lock.c | 49 +-- qemu-coroutine-queue.c | 76 trace-events |4 ++- 4 files changed, 81 insertions(+), 50 deletions(-) create mode 100644 qemu-coroutine-queue.c diff --git a/Makefile.objs b/Makefile.objs index 226b01d..1f0cc31 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -27,7 +27,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o ### # coroutines coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o -coroutine-obj-y += qemu-coroutine-sleep.o +coroutine-obj-y += qemu-coroutine-sleep.o qemu-coroutine-queue.o ifeq ($(CONFIG_UCONTEXT_COROUTINE),y) coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o else diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 159d66d..2bfbd41 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -1,5 +1,5 @@ /* - * coroutine queues and locks + * coroutine locks * * Copyright (c) 2011 Kevin Wolf kw...@redhat.com * @@ -28,53 +28,6 @@ #include qemu-queue.h #include trace.h -void qemu_co_queue_init(CoQueue *queue) -{ -QTAILQ_INIT(queue-entries); -} - -void coroutine_fn qemu_co_queue_wait(CoQueue *queue) -{ -Coroutine *self = qemu_coroutine_self(); -QTAILQ_INSERT_TAIL(queue-entries, self, co_queue_next); -qemu_coroutine_yield(); -assert(qemu_in_coroutine()); -} - -void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue) -{ -Coroutine *self = qemu_coroutine_self(); -QTAILQ_INSERT_HEAD(queue-entries, self, co_queue_next); -qemu_coroutine_yield(); -assert(qemu_in_coroutine()); -} - -bool qemu_co_queue_next(CoQueue *queue) -{ -Coroutine *next; - -next = QTAILQ_FIRST(queue-entries); -if (next) { -QTAILQ_REMOVE(queue-entries, next, co_queue_next); -trace_qemu_co_queue_next(next); -qemu_co_runnable_schedule(next); -} - -return (next != NULL); -} - -void qemu_co_queue_restart_all(CoQueue *queue) -{ -while (qemu_co_queue_next(queue)) { -/* Do nothing */ -} -} - -bool qemu_co_queue_empty(CoQueue *queue) -{ -return (QTAILQ_FIRST(queue-entries) == NULL); -} - void qemu_co_mutex_init(CoMutex *mutex) { memset(mutex, 0, sizeof(*mutex)); diff --git a/qemu-coroutine-queue.c b/qemu-coroutine-queue.c new file mode 100644 index 000..b90818d --- /dev/null +++ b/qemu-coroutine-queue.c @@ -0,0 +1,76 @@ +/* + * coroutine queues + * + * Copyright (c) 2011 Kevin Wolf kw...@redhat.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include qemu-common.h +#include qemu-coroutine.h +#include qemu-coroutine-int.h +#include qemu-queue.h +#include trace.h + +void qemu_co_queue_init(CoQueue *queue) +{ +QTAILQ_INIT(queue-entries); +} + +void coroutine_fn qemu_co_queue_wait(CoQueue *queue) +{ +Coroutine *self = qemu_coroutine_self(); +QTAILQ_INSERT_TAIL(queue-entries, self, co_queue_next); +qemu_coroutine_yield(); +assert(qemu_in_coroutine()); +} + +void coroutine_fn qemu_co_queue_wait_insert_head(CoQueue *queue) +{ +Coroutine *self = qemu_coroutine_self(); +QTAILQ_INSERT_HEAD(queue-entries, self, co_queue_next); +qemu_coroutine_yield(); +assert(qemu_in_coroutine()); +} + +bool qemu_co_queue_next(CoQueue *queue) +{ +Coroutine *next; + +next = QTAILQ_FIRST(queue-entries); +if (next) { +QTAILQ_REMOVE(queue-entries, next, co_queue_next); +trace_qemu_co_queue_next(next); +
Re: [Qemu-devel] [PATCH 10/10] coroutine: add qemu_coroutine_run() wrapper
Il 03/04/2012 10:38, Lai Jiangshan ha scritto: Wrapper for qemu_coroutine_create()+qemu_coroutine_enter() Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- block.c | 28 +++- hw/9pfs/virtio-9p.c |4 +--- nbd.c |2 +- qemu-coroutine.h| 12 qemu-io.c |4 +--- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/block.c b/block.c index b88ee90..adf2010 100644 --- a/block.c +++ b/block.c @@ -1451,7 +1451,6 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, .iov_base = (void *)buf, .iov_len = nb_sectors * BDRV_SECTOR_SIZE, }; -Coroutine *co; RwCo rwco = { .bs = bs, .sector_num = sector_num, @@ -1467,8 +1466,7 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, /* Fast-path if already in coroutine context */ bdrv_rw_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_rw_co_entry); -qemu_coroutine_enter(co, rwco); +qemu_coroutine_run(bdrv_rw_co_entry, rwco); while (rwco.ret == NOT_DONE) { qemu_aio_wait(); } @@ -2414,7 +2412,6 @@ static void coroutine_fn bdrv_is_allocated_co_entry(void *opaque) int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { -Coroutine *co; BdrvCoIsAllocatedData data = { .bs = bs, .sector_num = sector_num, @@ -2423,8 +2420,7 @@ int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, .done = false, }; -co = qemu_coroutine_create(bdrv_is_allocated_co_entry); -qemu_coroutine_enter(co, data); +qemu_coroutine_run(bdrv_is_allocated_co_entry, data); while (!data.done) { qemu_aio_wait(); } @@ -3348,7 +3344,6 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, void *opaque, bool is_write) { -Coroutine *co; BlockDriverAIOCBCoroutine *acb; acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); @@ -3357,8 +3352,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs, acb-req.qiov = qiov; acb-is_write = is_write; -co = qemu_coroutine_create(bdrv_co_do_rw); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_co_do_rw, acb); return acb-common; } @@ -3378,12 +3372,10 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs, { trace_bdrv_aio_flush(bs, opaque); -Coroutine *co; BlockDriverAIOCBCoroutine *acb; acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); -co = qemu_coroutine_create(bdrv_aio_flush_co_entry); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_aio_flush_co_entry, acb); return acb-common; } @@ -3402,7 +3394,6 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { -Coroutine *co; BlockDriverAIOCBCoroutine *acb; trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque); @@ -3410,8 +3401,7 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs, acb = qemu_aio_get(bdrv_em_co_aio_pool, bs, cb, opaque); acb-req.sector = sector_num; acb-req.nb_sectors = nb_sectors; -co = qemu_coroutine_create(bdrv_aio_discard_co_entry); -qemu_coroutine_enter(co, acb); +qemu_coroutine_run(bdrv_aio_discard_co_entry, acb); return acb-common; } @@ -3586,7 +3576,6 @@ void bdrv_invalidate_cache_all(void) int bdrv_flush(BlockDriverState *bs) { -Coroutine *co; RwCo rwco = { .bs = bs, .ret = NOT_DONE, @@ -3596,8 +3585,7 @@ int bdrv_flush(BlockDriverState *bs) /* Fast-path if already in coroutine context */ bdrv_flush_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_flush_co_entry); -qemu_coroutine_enter(co, rwco); +qemu_coroutine_run(bdrv_flush_co_entry, rwco); while (rwco.ret == NOT_DONE) { qemu_aio_wait(); } @@ -3645,7 +3633,6 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -Coroutine *co; RwCo rwco = { .bs = bs, .sector_num = sector_num, @@ -3657,8 +3644,7 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) /* Fast-path if already in coroutine context */ bdrv_discard_co_entry(rwco); } else { -co = qemu_coroutine_create(bdrv_discard_co_entry); -qemu_coroutine_enter(co, rwco); +
[Qemu-devel] [PATCH 03/25] qom: add class_base_init
The class_base_init TypeInfo callback was present in one of the early QOM versions but removed (on my request...) before committing. We will need it soon, add it. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/qemu/object.h | 10 -- qom/object.c |9 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/qemu/object.h b/include/qemu/object.h index 470efe3..ccaea7d 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -291,10 +291,15 @@ struct Object * has occurred to allow a class to set its default virtual method pointers. * This is also the function to use to override virtual methods from a parent * class. + * @class_base_init: This function is called for all base classes after all + * parent class initialization has occurred, but before the class itself + * is initialized. This is the function to use to undo the effects of + * memcpy from the parent class to the descendents. * @class_finalize: This function is called during class destruction and is * meant to release and dynamic parameters allocated by @class_init. - * @class_data: Data to pass to the @class_init and @class_finalize functions. - * This can be useful when building dynamic classes. + * @class_data: Data to pass to the @class_init, @class_base_init and + * @class_finalize functions. This can be useful when building dynamic + * classes. * @interfaces: The list of interfaces associated with this type. This * should point to a static array that's terminated with a zero filled * element. @@ -312,6 +317,7 @@ struct TypeInfo size_t class_size; void (*class_init)(ObjectClass *klass, void *data); +void (*class_base_init)(ObjectClass *klass, void *data); void (*class_finalize)(ObjectClass *klass, void *data); void *class_data; diff --git a/qom/object.c b/qom/object.c index 4975d93..6ff1c19 100644 --- a/qom/object.c +++ b/qom/object.c @@ -45,6 +45,7 @@ struct TypeImpl size_t instance_size; void (*class_init)(ObjectClass *klass, void *data); +void (*class_base_init)(ObjectClass *klass, void *data); void (*class_finalize)(ObjectClass *klass, void *data); void *class_data; @@ -112,6 +113,7 @@ TypeImpl *type_register(const TypeInfo *info) ti-instance_size = info-instance_size; ti-class_init = info-class_init; +ti-class_base_init = info-class_base_init; ti-class_finalize = info-class_finalize; ti-class_data = info-class_data; @@ -232,6 +234,13 @@ static void type_initialize(TypeImpl *ti) memcpy((void *)ti-class + sizeof(ObjectClass), (void *)parent-class + sizeof(ObjectClass), parent-class_size - sizeof(ObjectClass)); + +while (parent) { +if (parent-class_base_init) { +parent-class_base_init(ti-class, ti-class_data); +} +parent = type_get_parent(parent); +} } memset((void *)ti-class + class_size, 0, ti-class_size - class_size); -- 1.7.9.3
Re: [Qemu-devel] [PATCH 03/10] coroutine: rename qemu_co_queue_next_bh() to qemu_co_process_runnable()
Am 03.04.2012 10:38, schrieb Lai Jiangshan: Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- qemu-coroutine-lock.c |6 +++--- trace-events |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c index 10e8dbb..90141cd 100644 --- a/qemu-coroutine-lock.c +++ b/qemu-coroutine-lock.c @@ -33,11 +33,11 @@ static QTAILQ_HEAD(, Coroutine) co_runnable_queue = QTAILQ_HEAD_INITIALIZER(co_runnable_queue); static QEMUBH* co_runnable_bh; -static void qemu_co_queue_next_bh(void *opaque) +static void qemu_co_process_runnable(void *opaque) Please keep the _bh suffix there, so that it's obvious that this is used as a bottom half. Kevin
Re: [Qemu-devel] [PATCH 07/10] coroutine: split qemu-coroutine-lock.c
Am 03.04.2012 10:38, schrieb Lai Jiangshan: queues are not just internal things for locks, split them. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- Makefile.objs |2 +- qemu-coroutine-lock.c | 49 +-- qemu-coroutine-queue.c | 76 trace-events |4 ++- 4 files changed, 81 insertions(+), 50 deletions(-) What's the point? qemu-coroutine-lock.c is already a small file (171 lines) and all functions in it are doing related things (they synchronise coroutines). Splitting a small cohesive file into two tiny halves isn't an improvement, IMO. Kevin
[Qemu-devel] [PATCH 8/8] make: fix clean rule by removing build file in qom/
From: Anthony PERARD anthony.per...@citrix.com Make clean does not clean the 'qom' directory, leaving *.o and *.d files. This patch fixes this. Signed-off-by: Anthony PERARD anthony.per...@citrix.com Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- Makefile |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Makefile b/Makefile index 35c7a2a..a78f53d 100644 --- a/Makefile +++ b/Makefile @@ -217,6 +217,7 @@ clean: rm -f *.o *.d *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~ rm -Rf .libs rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d + rm -f qom/*.o qom/*.d rm -f qemu-img-cmds.h rm -f trace/*.o trace/*.d rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp -- 1.7.9.1
[Qemu-devel] [PATCH] Fix race resulting in loosing event bit in GPE.1.sts
After receiving hotplug gpe event, guest masks event in GPE.1.en register, executes associated AML handler and then resets event bit in GPE.1.sts. If another pci device was hot-plugged after AML handler has been executed and before event bit is reset in GPE.1.sts, then guest will loose GPE event and it will not see all hotplugged devices. Could be reproduced with: ./QMP/qmp device_add --driver=e1000 sleep 0.X ./QMP/qmp device_add --driver=e1000 Signed-off-by: Igor Mammedov imamm...@redhat.com --- hw/acpi.c | 23 ++- hw/acpi.h |1 + hw/acpi_piix4.c |7 +++ 3 files changed, 30 insertions(+), 1 deletions(-) diff --git a/hw/acpi.c b/hw/acpi.c index 5d521e5..be6efab 100644 --- a/hw/acpi.c +++ b/hw/acpi.c @@ -412,6 +412,7 @@ void acpi_gpe_init(ACPIREGS *ar, uint8_t len) ar-gpe.len = len; ar-gpe.sts = g_malloc0(len / 2); ar-gpe.en = g_malloc0(len / 2); +ar-gpe.pending_sts = g_malloc0(len / 2); } void acpi_gpe_blk(ACPIREGS *ar, uint32_t blk) @@ -423,6 +424,7 @@ void acpi_gpe_reset(ACPIREGS *ar) { memset(ar-gpe.sts, 0, ar-gpe.len / 2); memset(ar-gpe.en, 0, ar-gpe.len / 2); +memset(ar-gpe.pending_sts, 0, ar-gpe.len / 2); } static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr) @@ -440,15 +442,34 @@ static uint8_t *acpi_gpe_ioport_get_ptr(ACPIREGS *ar, uint32_t addr) return cur; } +static uint8_t *acpi_gpe_get_pend_sts_ptr(ACPIREGS *ar, uint32_t addr) +{ +uint8_t *cur = NULL; + +if (addr ar-gpe.len / 2) { +cur = ar-gpe.pending_sts + addr; +} else { +abort(); +} + +return cur; + +} + void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val) { -uint8_t *cur; +uint8_t *cur, *psts; addr -= ar-gpe.blk; cur = acpi_gpe_ioport_get_ptr(ar, addr); if (addr ar-gpe.len / 2) { /* GPE_STS */ *cur = (*cur) ~val; +psts = acpi_gpe_get_pend_sts_ptr(ar, addr); +if (*cur != *psts) { +*cur |= *psts; +*psts = 0; +} } else if (addr ar-gpe.len) { /* GPE_EN */ *cur = val; diff --git a/hw/acpi.h b/hw/acpi.h index fe8cdb4..6a6953d 100644 --- a/hw/acpi.h +++ b/hw/acpi.h @@ -104,6 +104,7 @@ struct ACPIGPE { uint8_t *sts; uint8_t *en; +uint8_t *pending_sts; }; struct ACPIREGS { diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 797ed24..ce50d85 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -66,6 +66,9 @@ typedef struct PIIX4PMState { int kvm_enabled; Notifier machine_ready; +/* for hotplug */ +uint16_t pending_gpe_events; + /* for pci hotplug */ struct pci_status pci0_status; uint32_t pci0_hotplug_enable; @@ -575,6 +578,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, disable_device(s, slot); } +if (~s-ar.gpe.en[0] PIIX4_PCI_HOTPLUG_STATUS) { +s-ar.gpe.pending_sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; +} + pm_update_sci(s); return 0; -- 1.7.7.6
[Qemu-devel] [PATCH 01/25] qom: add object_class_get_parent
This simple bit of functionality was missing and we'll need it soon, so add it. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- include/qemu/object.h | 14 ++ qom/object.c | 13 + 2 files changed, 27 insertions(+) diff --git a/include/qemu/object.h b/include/qemu/object.h index a675937..f814521 100644 --- a/include/qemu/object.h +++ b/include/qemu/object.h @@ -548,6 +548,14 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass, const char *typename); /** + * object_class_get_parent: + * @klass: The class to obtain the parent for. + * + * Returns: The parent for @klass. + */ +ObjectClass *object_class_get_parent(ObjectClass *klass); + +/** * object_class_get_name: * @klass: The class to obtain the QOM typename for. * @@ -555,6 +563,12 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass, */ const char *object_class_get_name(ObjectClass *klass); +/** + * object_class_by_name: + * @typename: The QOM typename to obtain the class for. + * + * Returns: The class for @typename. + */ ObjectClass *object_class_by_name(const char *typename); void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), diff --git a/qom/object.c b/qom/object.c index e721fc2..3e9fed7 100644 --- a/qom/object.c +++ b/qom/object.c @@ -545,6 +545,19 @@ ObjectClass *object_class_by_name(const char *typename) return type-class; } +ObjectClass *object_class_get_parent(ObjectClass *class) +{ +TypeImpl *type = type_get_parent(class-type); + +if (!type) { +return NULL; +} + +type_initialize(type); + +return type-class; +} + typedef struct OCFData { void (*fn)(ObjectClass *klass, void *opaque); -- 1.7.9.3
Re: [Qemu-devel] [PATCH v3] Replace bdrv_* to bdrv_aio_* functions in DMA mode in fdc.c.
I think what you say up is right, I will correct them, thank you very much! +bdrv_aio_readv(cur_drv-bs, fd_sector(cur_drv), +fdctrl-qiov, fdc_sector_num, fdctrl_read_DMA_cb, opaque_cb); +return dma_len; Should be return 0 since we haven't completed I/O yet. Stefan I think the return value is not used not, so no matter what is returned it not necessary. if set the dma_len = 0, when call void DMA_set_return(int nret) function will return the real value; :)
Re: [Qemu-devel] [PATCH] coroutine-gthread.c: Avoid threading APIs deprecated in GLib 2.31
Ping^2 ? On 14 March 2012 14:50, Peter Maydell peter.mayd...@linaro.org wrote: Ping? On 3 March 2012 14:52, Peter Maydell peter.mayd...@linaro.org wrote: The GLib threading APIs were revamped in GLib 2.31 and a number of the old interfaces were deprecated, which means they provoke compilation warnings (errors if -Werror) now. Add support for the new interfaces while retaining the old ones so we can still compile on older versions of GLib too. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- In particular, this fixes compilation failure on ARM hosts running Ubuntu Precise. Seems kinda ugly to me, suggestions for improvement welcomed. coroutine-gthread.c | 96 ++- 1 files changed, 87 insertions(+), 9 deletions(-) diff --git a/coroutine-gthread.c b/coroutine-gthread.c index 662801b..30c24c9 100644 --- a/coroutine-gthread.c +++ b/coroutine-gthread.c @@ -26,13 +26,93 @@ typedef struct { Coroutine base; GThread *thread; bool runnable; + bool free_on_thread_exit; CoroutineAction action; } CoroutineGThread; -static GCond *coroutine_cond; static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT; + +/* GLib 2.31 and beyond deprecated various parts of the thread API, + * but the new interfaces are not available in older GLib versions + * so we have to cope with both. + */ +#if GLIB_CHECK_VERSION(2, 31, 0) +/* Default zero-initialisation is sufficient for 2.31+ GCond */ +static GCond the_coroutine_cond; +static GCond *coroutine_cond = the_coroutine_cond; +static inline void init_coroutine_cond(void) +{ +} + +/* Awkwardly, the GPrivate API doesn't provide a way to update the + * GDestroyNotify handler for the coroutine key dynamically. So instead + * we track whether or not the CoroutineGThread should be freed on + * thread exit / coroutine key update using the free_on_thread_exit + * field. + */ +static void coroutine_destroy_notify(gpointer data) +{ + CoroutineGThread *co = data; + if (co co-free_on_thread_exit) { + g_free(co); + } +} + +static GPrivate coroutine_key = G_PRIVATE_INIT(coroutine_destroy_notify); + +static inline CoroutineGThread *get_coroutine_key(void) +{ + return g_private_get(coroutine_key); +} + +static inline void set_coroutine_key(CoroutineGThread *co, + bool free_on_thread_exit) +{ + /* Unlike g_static_private_set() this does not call the GDestroyNotify + * if the previous value of the key was NULL. Fortunately we only need + * the GDestroyNotify in the non-NULL key case. + */ + co-free_on_thread_exit = free_on_thread_exit; + g_private_replace(coroutine_key, co); +} + +static inline GThread *create_thread(GThreadFunc func, gpointer data) +{ + return g_thread_new(coroutine, func, data); +} + +#else + +/* Handle older GLib versions */ +static GCond *coroutine_cond; +static inline void init_coroutine_cond(void) +{ + coroutine_cond = g_cond_new(); +} + static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT; +static inline CoroutineGThread *get_coroutine_key(void) +{ + return g_static_private_get(coroutine_key); +} + +static inline void set_coroutine_key(CoroutineGThread *co, + bool free_on_thread_exit) +{ + g_static_private_set(coroutine_key, co, + free_on_thread_exit ? (GDestroyNotify)g_free : NULL); +} + +static inline GThread *create_thread(GThreadFunc func, gpointer data) +{ + return g_thread_create_full(func, data, 0, TRUE, TRUE, + G_THREAD_PRIORITY_NORMAL, NULL); +} + +#endif + + static void __attribute__((constructor)) coroutine_init(void) { if (!g_thread_supported()) { @@ -44,7 +124,7 @@ static void __attribute__((constructor)) coroutine_init(void) #endif } - coroutine_cond = g_cond_new(); + init_coroutine_cond(); } static void coroutine_wait_runnable_locked(CoroutineGThread *co) @@ -65,7 +145,7 @@ static gpointer coroutine_thread(gpointer opaque) { CoroutineGThread *co = opaque; - g_static_private_set(coroutine_key, co, NULL); + set_coroutine_key(co, false); coroutine_wait_runnable(co); co-base.entry(co-base.entry_arg); qemu_coroutine_switch(co-base, co-base.caller, COROUTINE_TERMINATE); @@ -77,8 +157,7 @@ Coroutine *qemu_coroutine_new(void) CoroutineGThread *co; co = g_malloc0(sizeof(*co)); - co-thread = g_thread_create_full(coroutine_thread, co, 0, TRUE, TRUE, - G_THREAD_PRIORITY_NORMAL, NULL); + co-thread = create_thread(coroutine_thread, co); if (!co-thread) { g_free(co); return NULL; @@ -117,12 +196,11 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *qemu_coroutine_self(void) { - CoroutineGThread *co =
Re: [Qemu-devel] [PATCH v2] Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c.
On 2012年04月02日 20:07, Stefan Hajnoczi wrote: On Sat, Mar 31, 2012 at 09:15:10PM +0800, Li Zhi Hui wrote: Replace bdrv_* to bdrv_aio_* functions in pio mode in fdc.c. Signed-off-by: Li Zhi Huizhihu...@linux.vnet.ibm.com --- hw/fdc.c | 123 +- 1 files changed, 89 insertions(+), 34 deletions(-) How can I test this patch? Stefan sorry, I don't find a good way to test it directly. but I have read the datasheet of floppy, I modify it according to the datasheet.
Re: [Qemu-devel] [PATCH] gdbstub: Synchronize CPU state unconditionally in gdb_set_cpu_pc
Ping? -- PMM On 12 March 2012 16:24, Peter Maydell peter.mayd...@linaro.org wrote: Synchronize the CPU state via cpu_sychronize_state() unconditionally in gdb_set_cpu_pc() rather than only in some of the target ifdef ladder cases. We can divide the CPUs into three categories: * non-KVM targets: no change of behaviour since we will use the kvm-stub.c no-op function. * i386 and s390: no change of behaviour since they were already calling this function * PPC (in KVM mode): this fixes an error: failing to synchronise was accidental and probably a bug. This also paves the way for other targets (specifically ARM) which can add KVM support in future without having to add another target specific change to this bit of code. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- Alex: could you test the KVM PPC case, please, since that's the only one where we actually change behaviour here? gdbstub.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index ef95ac2..776dcc5 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -1904,8 +1904,8 @@ static void gdb_breakpoint_remove_all(void) static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) { -#if defined(TARGET_I386) cpu_synchronize_state(s-c_cpu); +#if defined(TARGET_I386) s-c_cpu-eip = pc; #elif defined (TARGET_PPC) s-c_cpu-nip = pc; @@ -1930,7 +1930,6 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) #elif defined (TARGET_ALPHA) s-c_cpu-pc = pc; #elif defined (TARGET_S390X) - cpu_synchronize_state(s-c_cpu); s-c_cpu-psw.addr = pc; #elif defined (TARGET_LM32) s-c_cpu-pc = pc; -- 1.7.1
[Qemu-devel] [PATCH 12/25] qdev: factor setting of global properties
Now that global properties do not depend on buses anymore, set them directly in the device instance_init function. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-monitor.c |1 - hw/qdev.c |2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 07ac525..3d95940 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -448,7 +448,6 @@ DeviceState *qdev_device_add(QemuOpts *opts) /* create device, set properties */ qdev = DEVICE(object_new(driver)); qdev_set_parent_bus(qdev, bus); -qdev_prop_set_globals(qdev); id = qemu_opts_id(opts); if (id) { diff --git a/hw/qdev.c b/hw/qdev.c index d2b0134..adef566 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -129,7 +129,6 @@ DeviceState *qdev_try_create(BusState *bus, const char *type) } qdev_set_parent_bus(dev, bus); -qdev_prop_set_globals(dev); return dev; } @@ -644,6 +643,7 @@ static void device_initfn(Object *obj) qdev_property_add_legacy(dev, prop, NULL); qdev_property_add_static(dev, prop, NULL); } +qdev_prop_set_globals(dev); } /* Unlink device from bus and free the structure. */ -- 1.7.9.3
[Qemu-devel] [PATCH 09/25] qdev: move bus properties to a separate global
Simple code movement in order to simplify future refactoring. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/i2c.c | 10 ++ hw/ide/qdev.c | 10 ++ hw/intel-hda.c| 10 ++ hw/pci.c | 22 -- hw/scsi-bus.c | 14 -- hw/spapr_vio.c| 10 ++ hw/usb/bus.c | 11 +++ hw/usb/dev-smartcard-reader.c | 10 ++ hw/virtio-serial-bus.c| 12 +++- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/hw/i2c.c b/hw/i2c.c index 23dfccb..cb10b1d 100644 --- a/hw/i2c.c +++ b/hw/i2c.c @@ -17,13 +17,15 @@ struct i2c_bus uint8_t saved_address; }; +static Property i2c_props[] = { +DEFINE_PROP_UINT8(address, struct I2CSlave, address, 0), +DEFINE_PROP_END_OF_LIST(), +}; + static struct BusInfo i2c_bus_info = { .name = I2C, .size = sizeof(i2c_bus), -.props = (Property[]) { -DEFINE_PROP_UINT8(address, struct I2CSlave, address, 0), -DEFINE_PROP_END_OF_LIST(), -} +.props = i2c_props, }; static void i2c_bus_pre_save(void *opaque) diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c index f6a4896..4d372f8 100644 --- a/hw/ide/qdev.c +++ b/hw/ide/qdev.c @@ -27,14 +27,16 @@ static char *idebus_get_fw_dev_path(DeviceState *dev); +static Property ide_props[] = { +DEFINE_PROP_UINT32(unit, IDEDevice, unit, -1), +DEFINE_PROP_END_OF_LIST(), +}; + static struct BusInfo ide_bus_info = { .name = IDE, .size = sizeof(IDEBus), .get_fw_dev_path = idebus_get_fw_dev_path, -.props = (Property[]) { -DEFINE_PROP_UINT32(unit, IDEDevice, unit, -1), -DEFINE_PROP_END_OF_LIST(), -}, +.props = ide_props, }; void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id) diff --git a/hw/intel-hda.c b/hw/intel-hda.c index bb11af2..0994f6b 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -29,13 +29,15 @@ /* - */ /* hda bus */ +static Property hda_props[] = { +DEFINE_PROP_UINT32(cad, HDACodecDevice, cad, -1), +DEFINE_PROP_END_OF_LIST() +}; + static struct BusInfo hda_codec_bus_info = { .name = HDA, .size = sizeof(HDACodecBus), -.props = (Property[]) { -DEFINE_PROP_UINT32(cad, HDACodecDevice, cad, -1), -DEFINE_PROP_END_OF_LIST() -} +.props = hda_props, }; void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, diff --git a/hw/pci.c b/hw/pci.c index ed8ec99..fff4c4a 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -44,6 +44,17 @@ static char *pcibus_get_dev_path(DeviceState *dev); static char *pcibus_get_fw_dev_path(DeviceState *dev); static int pcibus_reset(BusState *qbus); +static Property pci_props[] = { +DEFINE_PROP_PCI_DEVFN(addr, PCIDevice, devfn, -1), +DEFINE_PROP_STRING(romfile, PCIDevice, romfile), +DEFINE_PROP_UINT32(rombar, PCIDevice, rom_bar, 1), +DEFINE_PROP_BIT(multifunction, PCIDevice, cap_present, +QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), +DEFINE_PROP_BIT(command_serr_enable, PCIDevice, cap_present, +QEMU_PCI_CAP_SERR_BITNR, true), +DEFINE_PROP_END_OF_LIST() +}; + struct BusInfo pci_bus_info = { .name = PCI, .size = sizeof(PCIBus), @@ -51,16 +62,7 @@ struct BusInfo pci_bus_info = { .get_dev_path = pcibus_get_dev_path, .get_fw_dev_path = pcibus_get_fw_dev_path, .reset = pcibus_reset, -.props = (Property[]) { -DEFINE_PROP_PCI_DEVFN(addr, PCIDevice, devfn, -1), -DEFINE_PROP_STRING(romfile, PCIDevice, romfile), -DEFINE_PROP_UINT32(rombar, PCIDevice, rom_bar, 1), -DEFINE_PROP_BIT(multifunction, PCIDevice, cap_present, -QEMU_PCI_CAP_MULTIFUNCTION_BITNR, false), -DEFINE_PROP_BIT(command_serr_enable, PCIDevice, cap_present, -QEMU_PCI_CAP_SERR_BITNR, true), -DEFINE_PROP_END_OF_LIST() -} +.props = pci_props, }; static void pci_update_mappings(PCIDevice *d); diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 8e76c5d..0352c59 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -12,17 +12,19 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev); static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf); static void scsi_req_dequeue(SCSIRequest *req); +static Property scsi_props[] = { +DEFINE_PROP_UINT32(channel, SCSIDevice, channel, 0), +DEFINE_PROP_UINT32(scsi-id, SCSIDevice, id, -1), +DEFINE_PROP_UINT32(lun, SCSIDevice, lun, -1), +DEFINE_PROP_END_OF_LIST(), +}; + static struct BusInfo scsi_bus_info = { .name = SCSI, .size = sizeof(SCSIBus), .get_dev_path = scsibus_get_dev_path, .get_fw_dev_path =
[Qemu-devel] [PATCH 05/25] qom: push type up to Object
Now that Object is a type, add an instance_init function and push the type property from qdev to there. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev.c|6 -- qom/object.c | 11 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/qdev.c b/hw/qdev.c index 0d3c0fc..bb6c1aa 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -510,11 +510,6 @@ char* qdev_get_fw_dev_path(DeviceState *dev) return strdup(path); } -static char *qdev_get_type(Object *obj, Error **errp) -{ -return g_strdup(object_get_typename(obj)); -} - /** * Legacy property handling */ @@ -630,7 +625,6 @@ static void device_initfn(Object *obj) qdev_property_add_static(dev, prop, NULL); } -object_property_add_str(OBJECT(dev), type, qdev_get_type, NULL, NULL); qdev_prop_set_defaults(dev, qdev_get_props(dev)); } diff --git a/qom/object.c b/qom/object.c index 585619d..f3ffaa6 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1215,6 +1215,16 @@ void object_property_add_str(Object *obj, const char *name, prop, errp); } +static char *qdev_get_type(Object *obj, Error **errp) +{ +return g_strdup(object_get_typename(obj)); +} + +static void object_instance_init(Object *obj) +{ +object_property_add_str(obj, type, qdev_get_type, NULL, NULL); +} + static void register_types(void) { static TypeInfo interface_info = { @@ -1226,6 +1236,7 @@ static void register_types(void) static TypeInfo object_info = { .name = TYPE_OBJECT, .instance_size = sizeof(Object), +.instance_init = object_instance_init, .abstract = true, }; -- 1.7.9.3
[Qemu-devel] [PATCH 20/25] qdev: generalize properties to Objects
The property machinery uses DeviceState arguments in a few places. Replace this with Object so that we can push properties up. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/qdev-addr.c | 19 +++--- hw/qdev-properties.c | 173 +- hw/qdev.c|8 +-- hw/qdev.h| 10 +-- 4 files changed, 90 insertions(+), 120 deletions(-) diff --git a/hw/qdev-addr.c b/hw/qdev-addr.c index a3796bd..99ca116 100644 --- a/hw/qdev-addr.c +++ b/hw/qdev-addr.c @@ -5,26 +5,25 @@ /* --- target physical address --- */ -static int parse_taddr(DeviceState *dev, Property *prop, const char *str) +static int parse_taddr(Object *obj, Property *prop, const char *str) { -target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); +target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop); *ptr = strtoull(str, NULL, 16); return 0; } -static int print_taddr(DeviceState *dev, Property *prop, char *dest, size_t len) +static int print_taddr(Object *obj, Property *prop, char *dest, size_t len) { -target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); +target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop); return snprintf(dest, len, 0x TARGET_FMT_plx, *ptr); } static void get_taddr(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { -DeviceState *dev = DEVICE(obj); Property *prop = opaque; -target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); +target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop); int64_t value; value = *ptr; @@ -34,9 +33,8 @@ static void get_taddr(Object *obj, Visitor *v, void *opaque, static void set_taddr(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { -DeviceState *dev = DEVICE(obj); Property *prop = opaque; -target_phys_addr_t *ptr = qdev_get_prop_ptr(dev, prop); +target_phys_addr_t *ptr = object_get_prop_ptr(obj, prop); Error *local_err = NULL; int64_t value; @@ -53,9 +51,8 @@ static void set_taddr(Object *obj, Visitor *v, void *opaque, if ((uint64_t)value = (uint64_t) ~(target_phys_addr_t)0) { *ptr = value; } else { -error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, - dev-id?:, name, value, (uint64_t) 0, - (uint64_t) ~(target_phys_addr_t)0); +error_set(errp, QERR_INVALID_PARAMETER_VALUE, + name, target_phys_addr_t); } } diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c index 282cf68..59b9615 100644 --- a/hw/qdev-properties.c +++ b/hw/qdev-properties.c @@ -3,23 +3,23 @@ #include qerror.h #include blockdev.h -void *qdev_get_prop_ptr(DeviceState *dev, Property *prop) +void *object_get_prop_ptr(Object *obj, Property *prop) { -void *ptr = dev; +void *ptr = obj; ptr += prop-offset; return ptr; } -static uint32_t qdev_get_prop_mask(Property *prop) +static uint32_t get_prop_mask(Property *prop) { assert(prop-info == qdev_prop_bit); return 0x1 prop-bitnr; } -static void bit_prop_set(DeviceState *dev, Property *props, bool val) +static void bit_prop_set(Object *obj, Property *props, bool val) { -uint32_t *p = qdev_get_prop_ptr(dev, props); -uint32_t mask = qdev_get_prop_mask(props); +uint32_t *p = object_get_prop_ptr(obj, props); +uint32_t mask = get_prop_mask(props); if (val) *p |= mask; else @@ -28,19 +28,18 @@ static void bit_prop_set(DeviceState *dev, Property *props, bool val) /* Bit */ -static int print_bit(DeviceState *dev, Property *prop, char *dest, size_t len) +static int print_bit(Object *obj, Property *prop, char *dest, size_t len) { -uint32_t *p = qdev_get_prop_ptr(dev, prop); -return snprintf(dest, len, (*p qdev_get_prop_mask(prop)) ? on : off); +uint32_t *p = object_get_prop_ptr(obj, prop); +return snprintf(dest, len, (*p get_prop_mask(prop)) ? on : off); } static void get_bit(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { -DeviceState *dev = DEVICE(obj); Property *prop = opaque; -uint32_t *p = qdev_get_prop_ptr(dev, prop); -bool value = (*p qdev_get_prop_mask(prop)) != 0; +uint32_t *p = object_get_prop_ptr(obj, prop); +bool value = (*p get_prop_mask(prop)) != 0; visit_type_bool(v, value, name, errp); } @@ -48,7 +47,6 @@ static void get_bit(Object *obj, Visitor *v, void *opaque, static void set_bit(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { -DeviceState *dev = DEVICE(obj); Property *prop = opaque; Error *local_err = NULL; bool value; @@ -63,7 +61,7 @@ static void set_bit(Object *obj, Visitor *v, void *opaque, error_propagate(errp, local_err); return; } -bit_prop_set(dev, prop, value); +bit_prop_set(obj, prop, value); } PropertyInfo
Re: [Qemu-devel] [PATCH 23/25] qom: add realized property
Paolo, Am 03.04.2012 13:15, schrieb Paolo Bonzini: Since we had to move the state field from DeviceState to Object, we cannot delay the implementation of the realized property. The property is a trigger for two actions that propagate through the composition tree. Realize is called when the property becomes true, and propagates in pre-order; realize can fail if the values of the properties are not valid. Unrealize is called when the property becomes false, and propagates in post-order; unrealize cannot fail. Unrealize is also called by object_deinit, as a separate step before finalization. Realize/unrealize is separate from reset. Reset propagation is a thorny issue of its own. We expect classes that care to implement a reset method and call it from realize or realize_children, depending on whether pre-order or post-order is more appropriate. This patch adds four methods (realize, realize_children, unrealize, unrealize_children) to ObjectClass, together with a default implementation of realize_children and unrealize_children. Signed-off-by: Paolo Bonzini pbonz...@redhat.com Since this patch is clearly an extended version of my realize patch http://patchwork.ozlabs.org/patch/148752/, it should carry my SoB, as reminded last night. If you don't want my SoB on the parts I didn't do - namely unrealize and *_childen - then feel free to split the patch in two. Simply dropping attribution in both cover letter and commit just because I didn't get around yet to sending a v2 with those requests addressed is not nice! Patch 24/25 was done differently (calling realized = true from init rather than the other way around) so this comment only applies to 23/25. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg