Re: [Qemu-devel] [RFC][PATCH 08/14 v4] introduce a new monitor command 'dump' to dump guest's memory

2012-01-13 Thread Wen Congyang
At 01/12/2012 09:49 PM, Luiz Capitulino Wrote:
 On Wed, 11 Jan 2012 08:59:24 +0800
 Wen Congyang we...@cn.fujitsu.com wrote:
 
 At 01/10/2012 09:30 PM, Luiz Capitulino Wrote:
 On Wed, 04 Jan 2012 14:11:01 +0800
 Wen Congyang we...@cn.fujitsu.com wrote:

 Signed-off-by: Wen Congyang we...@cn.fujitsu.com
 ---
  Makefile.target |8 +-
  dump.c  |  588 
 +++
  dump.h  |4 +
  hmp-commands.hx |   16 ++
  monitor.c   |3 +
  qmp-commands.hx |   26 +++
  6 files changed, 641 insertions(+), 4 deletions(-)
  create mode 100644 dump.c

 diff --git a/Makefile.target b/Makefile.target
 index 29562ad..f7cc2b9 100644
 --- a/Makefile.target
 +++ b/Makefile.target
 @@ -110,7 +110,7 @@ $(call set-vpath, 
 $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR
  QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) 
 -I$(SRC_PATH)/linux-user
  obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
 -  user-exec.o $(oslib-obj-y)
 +  user-exec.o $(oslib-obj-y) dump.o
  
  obj-$(TARGET_HAS_BFLT) += flatload.o
  
 @@ -148,7 +148,7 @@ LDFLAGS+=-Wl,-segaddr,__STD_PROG_ZONE,0x1000 
 -image_base 0x0e00
  LIBS+=-lmx
  
  obj-y = main.o commpage.o machload.o mmap.o signal.o syscall.o thunk.o \
 -gdbstub.o user-exec.o
 +gdbstub.o user-exec.o dump.o
  
  obj-i386-y += ioport-user.o
  
 @@ -170,7 +170,7 @@ $(call set-vpath, $(SRC_PATH)/bsd-user)
  QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ARCH)
  
  obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
 -gdbstub.o uaccess.o user-exec.o
 +gdbstub.o uaccess.o user-exec.o dump.o
  
  obj-i386-y += ioport-user.o
  
 @@ -186,7 +186,7 @@ endif #CONFIG_BSD_USER
  # System emulator target
  ifdef CONFIG_SOFTMMU
  
 -obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o 
 ioport.o
 +obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o 
 ioport.o dump.o
  # virtio has to be here due to weird dependency between PCI and 
 virtio-net.
  # need to fix this properly
  obj-$(CONFIG_NO_PCI) += pci-stub.o
 diff --git a/dump.c b/dump.c
 new file mode 100644
 index 000..ab29a4c
 --- /dev/null
 +++ b/dump.c
 @@ -0,0 +1,588 @@
 +/*
 + * QEMU dump
 + *
 + * Copyright Fujitsu, Corp. 2011
 + *
 + * Authors:
 + * Wen Congyang we...@cn.fujitsu.com
 + *
 + * This work is licensed under the terms of the GNU GPL, version 2.  See
 + * the COPYING file in the top-level directory.
 + *
 + */
 +
 +#include qemu-common.h
 +#include unistd.h
 +#include elf.h
 +#include sys/procfs.h
 +#include cpu.h
 +#include cpu-all.h
 +#include targphys.h
 +#include monitor.h
 +#include kvm.h
 +#include dump.h
 +#include sysemu.h
 +#include bswap.h
 +#include memory_mapping.h
 +
 +#define CPU_CONVERT_TO_TARGET16(val) \
 +({ \
 +uint16_t _val = (val); \
 +if (endian == ELFDATA2LSB) { \
 +_val = cpu_to_le16(_val); \
 +} else {\
 +_val = cpu_to_be16(_val); \
 +} \
 +_val; \
 +})
 +
 +#define CPU_CONVERT_TO_TARGET32(val) \
 +({ \
 +uint32_t _val = (val); \
 +if (endian == ELFDATA2LSB) { \
 +_val = cpu_to_le32(_val); \
 +} else {\
 +_val = cpu_to_be32(_val); \
 +} \
 +_val; \
 +})
 +
 +#define CPU_CONVERT_TO_TARGET64(val) \
 +({ \
 +uint64_t _val = (val); \
 +if (endian == ELFDATA2LSB) { \
 +_val = cpu_to_le64(_val); \
 +} else {\
 +_val = cpu_to_be64(_val); \
 +} \
 +_val; \
 +})
 +
 +enum {
 +DUMP_STATE_ERROR,
 +DUMP_STATE_SETUP,
 +DUMP_STATE_CANCELLED,
 +DUMP_STATE_ACTIVE,
 +DUMP_STATE_COMPLETED,
 +};
 +
 +typedef struct DumpState {
 +ArchDumpInfo dump_info;
 +MemoryMappingList list;
 +int phdr_num;
 +int state;
 +char *error;
 +Monitor *mon;
 +int fd;
 +target_phys_addr_t memory_offset;
 +} DumpState;
 +
 +static DumpState *dump_get_current(void)
 +{
 +static DumpState current_dump = {
 +.state = DUMP_STATE_SETUP,
 +};
 +
 +return current_dump;
 +}
 +
 +static int dump_cleanup(DumpState *s)
 +{
 +int ret = 0;
 +
 +free_memory_mapping_list(s-list);
 +if (s-fd != -1) {
 +close(s-fd);
 +s-fd = -1;
 +}
 +
 +return ret;
 +}
 +
 +static void dump_error(DumpState *s, const char *reason)
 +{
 +s-state = DUMP_STATE_ERROR;
 +s-error = g_strdup(reason);
 +dump_cleanup(s);
 +}
 +
 +static inline int cpuid(CPUState *env)
 +{
 +#if defined(CONFIG_USER_ONLY)  defined(CONFIG_USE_NPTL)
 +return env-host_tid;
 +#else
 +return env-cpu_index + 1;
 +#endif
 +}
 +
 +static int write_elf64_header(DumpState *s)
 +{
 +Elf64_Ehdr elf_header;
 +int ret;
 +int endian = s-dump_info.d_endian;
 +
 +memset(elf_header, 0, sizeof(Elf64_Ehdr));
 +memcpy(elf_header, ELFMAG, 4);
 +elf_header.e_ident[EI_CLASS] = ELFCLASS64;
 +

Re: [Qemu-devel] throwing away translated code on CPU reset

2012-01-13 Thread Peter Maydell
On 13 January 2012 07:55, 陳韋任 che...@iis.sinica.edu.tw wrote:
 On Thu, Jan 12, 2012 at 02:00:38PM +, Peter Maydell wrote:
 When doing TCG code translation, the target-foo translate.c
 code is allowed to bake assumptions into the generated code from
 the current values of various fields in the CPUState. This then
 imposes the requirement that if the field is changed then tb_flush
 must be called to throw away the now-incorrect generated code.

 However, cpu_reset() changes (unsurprisingly) lots of fields in
 the CPUState, but it doesn't call tb_flush()...

  I dig what tlb_flush does further and think maybe we don't need to call 
 tb_flush
 when tlb_flush is called.

  First, look at tlb_flush (exec.c). It clears env's tb_jmp_cache which use GHA
 as an index to search if there is a translated code. Since tb_jmp_cache is 
 reset
 now, QEMU is forced to call tb_find_slow which uses GPA as the index.

  In tb_find_slow's for loop, it compares hit TranslationBlock's various fields
 with current values. To be more specific,

 static TranslationBlock *tb_find_slow(...) {

    for(;;) {
        tb = *ptb1;
        if (!tb)
            goto not_found;
        if (tb-pc == pc                     --- Here
            tb-page_addr[0] == phys_page1 
            tb-cs_base == cs_base 
            tb-flags == flags) {
        }
   }
 }

  What do you think?

This is true, but the translated code may have assumptions about
fields which are not encoded in tb_flags, if it is handling those
fields with the tb_flush if field changes strategy (eg on ARM
env-teecr and others).

-- PMM



[Qemu-devel] [PATCH] hw/9pfs: Fix crash when mounting with synthfs

2012-01-13 Thread Aneesh Kumar K.V
From: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com

Some Fsdriver backend don't have fs_root. So check for that in
migrate message.

Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com
---
 hw/9pfs/virtio-9p.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index e6ba6ba..dfe2025 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -986,7 +986,7 @@ static void v9fs_attach(void *opaque)
 s-root_fid = fid;
 /* disable migration */
 error_set(s-migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
-  s-ctx.fs_root, s-tag);
+  s-ctx.fs_root ? s-ctx.fs_root : NULL, s-tag);
 migrate_add_blocker(s-migration_blocker);
 out:
 put_fid(pdu, fidp);
-- 
1.7.8.1.362.g5d6df




Re: [Qemu-devel] [PATCH][v8] megasas: LSI Megaraid SAS HBA emulation

2012-01-13 Thread Stefan Hajnoczi
On Thu, Jan 12, 2012 at 03:45:59PM +0100, Paolo Bonzini wrote:
 On 01/12/2012 11:43 AM, Hannes Reinecke wrote:
 +# hw/megasas.c
 +disable megasas_init_firmware(int xfer_len, uint64_t pa) xfer len %d pa % 
 PRIx64  
 +disable megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, 
 uint64_t tail, uint32_t flags) queue at % PRIx64  len %d head % PRIx64  
 tail % PRIx64  flags %x
 +megasas_initq_map_failed(int frame) scmd %d: failed to map queue
 +megasas_initq_mismatch(int queue_len, int fw_cmds) queue size %d max fw 
 cmds %d
 +disable megasas_qf_found(unsigned int index, uint64_t pa) found mapped 
 frame %x pa % PRIx64 
 +disable megasas_qf_new(unsigned int index, void *cmd) return new frame %x 
 cmd %p
 +megasas_qf_failed(unsigned long pa) all frames busy for frame %lx
 +disable megasas_qf_enqueue(unsigned int index, unsigned int count, uint64_t 
 context, unsigned int tail, int busy) enqueue frame %x count %d countext % 
 PRIx64  tail %x busy %d
 +disable megasas_qf_update(unsigned int head, unsigned int busy) update 
 reply queue head %x busy %d
 +disable megasas_qf_dequeue(unsigned int index) dequeue frame %x
 +disable megasas_qf_map_failed(int cmd, unsigned long frame) scmd %d: frame 
 %lu
 +disable megasas_qf_complete_noirq(uint64_t context) context % PRIx64  
 +disable megasas_qf_complete(uint64_t context, unsigned int tail, unsigned 
 int offset, int busy, unsigned int doorbell) context % PRIx64  tail %x 
 offset %d busy %d doorbell %x
 +disable megasas_handle_frame(const char *cmd, uint64_t addr, uint64_t 
 context, uint32_t count) MFI cmd %s addr % PRIx64  context % PRIx64  
 count %d
 +megasas_frame_busy(uint64_t addr) frame % PRIx64  busy
 +megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) scmd %d: Unhandled 
 MFI cmd %x
 +disable megasas_handle_scsi(const char *frame, const char *desc, int dev, 
 int lun, void *sdev, unsigned long size) %s %s dev %x/%x sdev %p xfer %lu
 +disable megasas_scsi_target_not_present(const char *frame, const char 
 *desc, int dev, int lun) %s %s dev %x/%x target not present
 +megasas_scsi_invalid_cdb_len(const char *frame, const char *desc, int dev, 
 int lun, int len) %s %s dev %x/%x invalid cdb len %d
 +megasas_scsi_overflow(int cmd, const char *dir, int bytes, int len) scmd 
 %d: %s %d of %d bytes
 +disable megasas_scsi_underflow(int cmd, const char *dir, int bytes, int 
 len) scmd %d: %s %d of %d bytes
 +megasas_scsi_req_alloc_failed(const char *frame, int dev, int lun) %s dev 
 %x/%x req allocation failed
 +disable megasas_scsi_start(int cmd, const char *desc, int len) scmd %d: %s 
 %d bytes of data
 +disable megasas_scsi_nodata(int cmd) scmd %d: no data to be transferred
 +disable megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) 
 scmd %d: finished with status %x, len %u/%u
 +disable megasas_command_complete(int cmd, uint32_t status) scmd %d: 
 command completed, status %x
 +disable megasas_handle_io(int cmd, const char *frame, int dev, int lun, 
 unsigned long lba, unsigned long count) scmd %d: %s dev %x/%x lba %lx count 
 %lu
 +disable megasas_io_target_not_present(int cmd, const char *frame, int dev, 
 int lun) scmd %d: %s dev %x/%x LUN not present
 +disable megasas_io_start(int cmd, const char *dir, unsigned long lba, 
 unsigned long count, unsigned long len) scmd %d: %s start LBA %lx %lu 
 blocks (%lu bytes)
 +disable megasas_io_complete(int cmd, uint32_t len) scmd %d: %d bytes 
 completed
 +disable megasas_io_copy(int cmd, const char *dir, int bytes, int len, 
 unsigned long offset) scmd %d: %s %d of %d bytes, iov offset %lu
 +disable megasas_io_continue(int cmd, int bytes) scmd %d: %d bytes left
 +megasas_iovec_map_failed(int cmd, int index, unsigned long iov_size) scmd 
 %d: iovec %d size %lu
 +megasas_iovec_sgl_overflow(int cmd, int index, int limit) scmd %d: iovec 
 count %d limit %d
 +megasas_iovec_sgl_underflow(int cmd, int index) scmd %d: iovec count %d
 +megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) 
 scmd %d: invalid sgl element %d pa % PRIx64  len %u
 +megasas_iovec_len(int cmd, const char *desc, int len, int limit) scmd %d: 
 iovec %s len %d limit %d
 +disable megasas_handle_dcmd(int cmd, int opcode) scmd %d: MFI DCMD opcode 
 %x
 +disable megasas_finish_dcmd(int cmd, int size) scmd %d: MFI DCMD wrote %d 
 bytes
 +megasas_dcmd_req_alloc_failed(int cmd, const char *desc) scmd %d: %s alloc 
 failed
 +disable megasas_dcmd_internal_submit(int cmd, const char *desc, int dev) 
 scmd %d: %s to dev %d
 +disable megasas_dcmd_internal_finish(int cmd, int opcode, int lun) scmd 
 %d: DCMD finish internal cmd %x lun %d
 +megasas_dcmd_internal_invalid(int cmd, int opcode) scmd %d: Invalid 
 internal DCMD %x
 +megasas_dcmd_unhandled(int cmd, int opcode, int len) scmd %d: opcode %x, 
 len %d
 +disable megasas_dcmd_zero_sge(int cmd) scmd %d: zero DCMD sge count
 +megasas_dcmd_invalid_sge(int cmd, int count) scmd %d: invalid DCMD sge 
 count %d
 +megasas_dcmd_map_failed(int cmd) scmd %d: Failed to 

Re: [Qemu-devel] [PATCH v3 8/8] prep: Use i82378 PCI-ISA bridge for 'prep' machine

2012-01-13 Thread Jan Kiszka
On 2012-01-13 04:09, Andreas Färber wrote:
 Speaker I/O, ISA bus, i8259 PIC, RTC and DMA are no longer set up
 individually by the machine. Effectively, no-op speaker I/O is replaced
 by pcspk; PIT and i82374 DMA are introduced.
 
 Signed-off-by: Hervé Poussineau hpous...@reactos.org
 
 Remove related dead, alternative code.
 Access i8259 IRQs via ISA bus to resolve cyclic dependency with PCI
 host bridge.
 
 Signed-off-by: Andreas Färber andreas.faer...@web.de
 Cc: Alexander Graf ag...@suse.de
 Cc: Jan Kiszka jan.kis...@siemens.com
 ---
  hw/ppc_prep.c |   54 +++---
  1 files changed, 11 insertions(+), 43 deletions(-)
 
 diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
 index 747539f..9485d45 100644
 --- a/hw/ppc_prep.c
 +++ b/hw/ppc_prep.c
 @@ -83,37 +83,9 @@ static const int ide_irq[2] = { 13, 13 };
  static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 
 0x280, 0x380 };
  static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
  
 -//static ISADevice *pit;
 -
  /* ISA IO ports bridge */
  #define PPC_IO_BASE 0x8000
  
 -#if 0
 -/* Speaker port 0x61 */
 -static int speaker_data_on;
 -static int dummy_refresh_clock;
 -#endif
 -
 -static void speaker_ioport_write (void *opaque, uint32_t addr, uint32_t val)
 -{
 -#if 0
 -speaker_data_on = (val  1)  1;
 -pit_set_gate(pit, 2, val  1);
 -#endif
 -}
 -
 -static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
 -{
 -#if 0
 -int out;
 -out = pit_get_out(pit, 2, qemu_get_clock_ns(vm_clock));
 -dummy_refresh_clock ^= 1;
 -return (speaker_data_on  1) | pit_get_gate(pit, 2) | (out  5) |
 -(dummy_refresh_clock  4);
 -#endif
 -return 0;
 -}
 -
  /* PCI intack register */
  /* Read-only register (?) */
  static void PPC_intack_write (void *opaque, target_phys_addr_t addr,
 @@ -526,6 +498,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
  SysBusDevice *sys;
  PCIHostState *pcihost;
  PCIBus *pci_bus;
 +PCIDevice *pci;
  ISABus *isa_bus;
  qemu_irq *i8259;
  qemu_irq *cpu_exit_irq;
 @@ -629,13 +602,9 @@ static void ppc_prep_init (ram_addr_t ram_size,
  }
  }
  
 -isa_mem_base = 0xc000;
  if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
  hw_error(Only 6xx bus is supported on PREP machine\n);
  }
 -/* Hmm, prep has no pci-isa bridge ??? */
 -isa_bus = isa_bus_new(NULL, get_system_io());
 -i8259 = i8259_init(isa_bus, first_cpu-irq_inputs[PPC6xx_INPUT_INT]);
  
  dev = qdev_create(NULL, raven-pcihost);
  sys = sysbus_from_qdev(dev);
 @@ -648,13 +617,21 @@ static void ppc_prep_init (ram_addr_t ram_size,
  fprintf(stderr, Couldn't create PCI host controller.\n);
  exit(1);
  }
 +
 +/* PCI - ISA bridge */
 +pci = pci_create_simple(pci_bus, PCI_DEVFN(1, 0), i82378);
 +cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
 +qdev_connect_gpio_out(pci-qdev, 0,
 +  first_cpu-irq_inputs[PPC6xx_INPUT_INT]);
 +qdev_connect_gpio_out(pci-qdev, 1, *cpu_exit_irq);
 +isa_bus = DO_UPCAST(ISABus, qbus, qdev_get_child_bus(pci-qdev, 
 isa.0));
 +
 +i8259 = isa_bus-irqs;

I think this is unneeded. You only access i8259[8] later on for
initializing the m48t59. But that one should be creatable as ISA device
now (m48t59_init_isa), no? Please check.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



Re: [Qemu-devel] throwing away translated code on CPU reset

2012-01-13 Thread 陳韋任
On Thu, Jan 12, 2012 at 02:00:38PM +, Peter Maydell wrote:
 When doing TCG code translation, the target-foo translate.c
 code is allowed to bake assumptions into the generated code from
 the current values of various fields in the CPUState. This then
 imposes the requirement that if the field is changed then tb_flush
 must be called to throw away the now-incorrect generated code.
 
 However, cpu_reset() changes (unsurprisingly) lots of fields in
 the CPUState, but it doesn't call tb_flush()...

  I dig what tlb_flush does further and think maybe we don't need to call 
tb_flush
when tlb_flush is called.

  First, look at tlb_flush (exec.c). It clears env's tb_jmp_cache which use GHA
as an index to search if there is a translated code. Since tb_jmp_cache is reset
now, QEMU is forced to call tb_find_slow which uses GPA as the index.

  In tb_find_slow's for loop, it compares hit TranslationBlock's various fields
with current values. To be more specific,

static TranslationBlock *tb_find_slow(...) {

for(;;) {
tb = *ptb1;
if (!tb)
goto not_found;
if (tb-pc == pc --- Here
tb-page_addr[0] == phys_page1 
tb-cs_base == cs_base 
tb-flags == flags) {
}
   }
}

  What do you think?

Regards,
chenwj

-- 
Wei-Ren Chen (陳韋任)
Computer Systems Lab, Institute of Information Science,
Academia Sinica, Taiwan (R.O.C.)
Tel:886-2-2788-3799 #1667
Homepage: http://people.cs.nctu.edu.tw/~chenwj



[Qemu-devel] [PATCH v5 09/15] qmp: add query-block-jobs

2012-01-13 Thread Stefan Hajnoczi
Add query-block-jobs, which shows the progress of ongoing block device
operations.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c   |   33 +
 hmp.c|   36 
 hmp.h|1 +
 monitor.c|7 +++
 qapi-schema.json |   32 
 qmp-commands.hx  |6 ++
 6 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 35de3bc..4549c9e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -989,3 +989,36 @@ void qmp_block_job_cancel(const char *device, Error **errp)
 trace_qmp_block_job_cancel(job);
 block_job_cancel(job);
 }
+
+static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
+{
+BlockJobInfoList **prev = opaque;
+BlockJob *job = bs-job;
+
+if (job) {
+BlockJobInfoList *elem;
+BlockJobInfo *info = g_new(BlockJobInfo, 1);
+*info = (BlockJobInfo){
+.type   = g_strdup(job-job_type-job_type),
+.device = g_strdup(bdrv_get_device_name(bs)),
+.len= job-len,
+.offset = job-offset,
+.speed  = job-speed,
+};
+
+elem = g_new0(BlockJobInfoList, 1);
+elem-value = info;
+
+(*prev)-next = elem;
+*prev = elem;
+}
+}
+
+BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+{
+/* Dummy is a fake list element for holding the head pointer */
+BlockJobInfoList dummy = {};
+BlockJobInfoList *prev = dummy;
+bdrv_iterate(do_qmp_query_block_jobs_one, prev);
+return dummy.next;
+}
diff --git a/hmp.c b/hmp.c
index 851885b..76e89f8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -507,6 +507,42 @@ void hmp_info_pci(Monitor *mon)
 qapi_free_PciInfoList(info);
 }
 
+void hmp_info_block_jobs(Monitor *mon)
+{
+BlockJobInfoList *list;
+Error *err = NULL;
+
+list = qmp_query_block_jobs(err);
+assert(!err);
+
+if (!list) {
+monitor_printf(mon, No active jobs\n);
+return;
+}
+
+while (list) {
+if (strcmp(list-value-type, stream) == 0) {
+monitor_printf(mon, Streaming device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+} else {
+monitor_printf(mon, Type %s, device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-type,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+}
+list = list-next;
+}
+}
+
 void hmp_quit(Monitor *mon, const QDict *qdict)
 {
 monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index 0ad2004..23bfca2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -32,6 +32,7 @@ void hmp_info_vnc(Monitor *mon);
 void hmp_info_spice(Monitor *mon);
 void hmp_info_balloon(Monitor *mon);
 void hmp_info_pci(Monitor *mon);
+void hmp_info_block_jobs(Monitor *mon);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 01850ca..f96a296 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2483,6 +2483,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.info = hmp_info_blockstats,
 },
 {
+.name   = block-jobs,
+.args_type  = ,
+.params = ,
+.help   = show progress of ongoing block device operations,
+.mhandler.info = hmp_info_block_jobs,
+},
+{
 .name   = registers,
 .args_type  = ,
 .params = ,
diff --git a/qapi-schema.json b/qapi-schema.json
index 3d23ce2..b4f6b15 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -845,6 +845,38 @@
 { 'command': 'query-pci', 'returns': ['PciInfo'] }
 
 ##
+# @BlockJobInfo:
+#
+# Information about a long-running block device operation.
+#
+# @type: the job type ('stream' for image streaming)
+#
+# @device: the block device name
+#
+# @len: the maximum progress value
+#
+# @offset: the current progress value
+#
+# @speed: the rate limit, bytes per second
+#
+# Since: 1.1
+##
+{ 'type': 'BlockJobInfo',
+  'data': {'type': 'str', 'device': 'str', 'len': 'int',
+   'offset': 'int', 'speed': 'int'} }
+
+##
+# @query-block-jobs:
+#
+# Return information about long-running block device operations.
+#
+# Returns: a list of @BlockJobInfo for each active block job
+#
+# Since: 1.1
+##
+{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }
+
+##
 # @quit:
 #
 # This command will cause the 

[Qemu-devel] [PATCH] do not chdir(/) in qemu-nbd

2012-01-13 Thread Michael Tokarev
When qemu-nbd becomes a daemon it calls daemon(3) with
nochdir=0, so daemon(3) changes current directory to /.
But at this time, qemu-nbd did not open any user-specified
files yet, so by changing current directory, all non-absolute
paths becomes wrong.  The solution is to pass nochdir=1 to
daemon(3) function.

This patch is applicable for -stable.

Signed-Off-By: Michael Tokarev m...@tls.msk.ru
---
 qemu-nbd.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index eb61c33..d84e2a7 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -429,7 +429,7 @@ int main(int argc, char **argv)
 pid = fork();
 if (pid == 0) {
 close(stderr_fd[0]);
-ret = qemu_daemon(0, 0);
+ret = qemu_daemon(1, 0);
 
 /* Temporarily redirect stderr to the parent's pipe...  */
 dup2(stderr_fd[1], STDERR_FILENO);
-- 
1.7.2.5




Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy

2012-01-13 Thread Benoit Hudzia
Yes we plan to release patch as soon as we cleaned up the code and we
get the green light from our company ( and sadly it can take month on
that point..)

On 13 January 2012 01:31, Takuya Yoshikawa
yoshikawa.tak...@oss.ntt.co.jp wrote:
 (2012/01/13 10:09), Benoit Hudzia wrote:

 Hi,

 Sorry to jump to hijack the thread  like that , however i would like
 to just to inform you  that we recently achieve a milestone out of the
 research project I'm leading. We enhanced KVM in order to deliver
 post copy live migration using RDMA at kernel level.

 Few point on the architecture of the system :

 * RDMA communication engine in kernel ( you can use soft iwarp or soft
 ROCE if you don't have hardware acceleration, however we also support
 standard RDMA enabled NIC) .
 * Naturally Page are transferred with Zerop copy protocol
 * Leverage the async page fault system.
 * Pre paging / faulting
 * No context switch as everything is handled within kernel and using
 the page fault system.
 * Hybrid migration ( pre + post copy) available
 * Rely on an independent Kernel Module
 * No modification to the KVM kernel Module
 * Minimal Modification to the Qemu-Kvm code
 * We plan to add the page prioritization algo in order to optimise the
 pre paging algo and background transfer


 You can learn a little bit more and see a demo here:
 http://tinyurl.com/8xa2bgl
 I hope to be able to provide more detail on the design soon. As well
 as more concrete demo of the system ( live migration of VM running
 large  enterprise apps such as ERP or In memory DB)

 Note: this is just a step stone as the post copy live migration mainly
 enable us to validate the architecture design and  code.


 Do you have any plan to send the patch series of your implementation?

        Takuya



-- 
 The production of too many useful things results in too many useless people



[Qemu-devel] [PATCH v5 15/15] test: add image streaming test cases

2012-01-13 Thread Stefan Hajnoczi
python test-stream.py

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 test-stream.py |  208 
 1 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 test-stream.py

diff --git a/test-stream.py b/test-stream.py
new file mode 100644
index 000..16cbe5d
--- /dev/null
+++ b/test-stream.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+import unittest
+import subprocess
+import re
+import os
+import sys; sys.path.append('QMP/')
+import qmp
+
+def qemu_img(*args):
+devnull = open('/dev/null', 'r+')
+return subprocess.call(['./qemu-img'] + list(args), stdin=devnull, 
stdout=devnull)
+
+def qemu_io(*args):
+args = ['./qemu-io'] + list(args)
+return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
+
+class VM(object):
+def __init__(self):
+self._monitor_path = '/tmp/qemu-mon.%d' % os.getpid()
+self._qemu_log_path = '/tmp/qemu-log.%d' % os.getpid()
+self._args = ['x86_64-softmmu/qemu-system-x86_64',
+  '-chardev', 'socket,id=mon,path=' + self._monitor_path,
+  '-mon', 'chardev=mon,mode=control', '-nographic']
+self._num_drives = 0
+
+def add_drive(self, path, opts=''):
+options = ['if=virtio',
+   'cache=none',
+   'file=%s' % path,
+   'id=drive%d' % self._num_drives]
+if opts:
+options.append(opts)
+
+self._args.append('-drive')
+self._args.append(','.join(options))
+self._num_drives += 1
+return self
+
+def launch(self):
+devnull = open('/dev/null', 'rb')
+qemulog = open(self._qemu_log_path, 'wb')
+self._qmp = qmp.QEMUMonitorProtocol(self._monitor_path, server=True)
+self._popen = subprocess.Popen(self._args, stdin=devnull, 
stdout=qemulog,
+   stderr=subprocess.STDOUT)
+self._qmp.accept()
+
+def shutdown(self):
+self._qmp.cmd('quit')
+self._popen.wait()
+os.remove(self._monitor_path)
+os.remove(self._qemu_log_path)
+
+def qmp(self, cmd, **args):
+return self._qmp.cmd(cmd, args=args)
+
+def get_qmp_events(self, wait=False):
+events = self._qmp.get_events(wait=wait)
+self._qmp.clear_events()
+return events
+
+index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
+
+class QMPTestCase(unittest.TestCase):
+def dictpath(self, d, path):
+Traverse a path in a nested dict
+for component in path.split('/'):
+m = index_re.match(component)
+if m:
+component, idx = m.groups()
+idx = int(idx)
+
+if not isinstance(d, dict) or component not in d:
+self.fail('failed path traversal for %s in %s' % (path, 
str(d)))
+d = d[component]
+
+if m:
+if not isinstance(d, list):
+self.fail('path component %s in %s is not a list in 
%s' % (component, path, str(d)))
+try:
+d = d[idx]
+except IndexError:
+self.fail('invalid index %s in path %s in %s' % 
(idx, path, str(d)))
+return d
+
+def assert_qmp(self, d, path, value):
+result = self.dictpath(d, path)
+self.assertEqual(result, value, 'values not equal %s and %s' % 
(str(result), str(value)))
+
+def assert_no_active_streams(self):
+result = self.vm.qmp('query-block-jobs')
+self.assert_qmp(result, 'return', [])
+
+class TestSingleDrive(QMPTestCase):
+image_len = 1 * 1024 * 1024 # MB
+
+def setUp(self):
+qemu_img('create', 'backing.img', str(TestSingleDrive.image_len))
+qemu_img('create', '-f', 'qed', '-o', 'backing_file=backing.img', 
'test.qed')
+self.vm = VM().add_drive('test.qed')
+self.vm.launch()
+
+def tearDown(self):
+self.vm.shutdown()
+os.remove('test.qed')
+os.remove('backing.img')
+
+def test_stream(self):
+self.assert_no_active_streams()
+
+result = self.vm.qmp('block_stream', device='drive0')
+self.assert_qmp(result, 'return', {})
+
+completed = False
+while not completed:
+for event in self.vm.get_qmp_events(wait=True):
+if event['event'] == 'BLOCK_JOB_COMPLETED':
+self.assert_qmp(event, 'data/type', 'stream')
+self.assert_qmp(event, 'data/device', 'drive0')
+self.assert_qmp(event, 'data/offset', self.image_len)
+self.assert_qmp(event, 'data/len', self.image_len)
+completed = True
+
+self.assert_no_active_streams()
+
+self.assertFalse('sectors not allocated' in qemu_io('-c', 'map', 
'test.qed'),
+ 'image file not fully populated after streaming')
+
+def 

Re: [Qemu-devel] [PATCH][v8] megasas: LSI Megaraid SAS HBA emulation

2012-01-13 Thread Hannes Reinecke
On 01/12/2012 07:04 PM, Stefan Hajnoczi wrote:
 On Thu, Jan 12, 2012 at 03:45:59PM +0100, Paolo Bonzini wrote:
 On 01/12/2012 11:43 AM, Hannes Reinecke wrote:
 +# hw/megasas.c
 +disable megasas_init_firmware(int xfer_len, uint64_t pa) xfer len %d pa 
 % PRIx64  
 +disable megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t 
 head, uint64_t tail, uint32_t flags) queue at % PRIx64  len %d head % 
 PRIx64  tail % PRIx64  flags %x
 +megasas_initq_map_failed(int frame) scmd %d: failed to map queue
 +megasas_initq_mismatch(int queue_len, int fw_cmds) queue size %d max fw 
 cmds %d
 +disable megasas_qf_found(unsigned int index, uint64_t pa) found mapped 
 frame %x pa % PRIx64 
 +disable megasas_qf_new(unsigned int index, void *cmd) return new frame %x 
 cmd %p
 +megasas_qf_failed(unsigned long pa) all frames busy for frame %lx
 +disable megasas_qf_enqueue(unsigned int index, unsigned int count, 
 uint64_t context, unsigned int tail, int busy) enqueue frame %x count %d 
 countext % PRIx64  tail %x busy %d
 +disable megasas_qf_update(unsigned int head, unsigned int busy) update 
 reply queue head %x busy %d
 +disable megasas_qf_dequeue(unsigned int index) dequeue frame %x
 +disable megasas_qf_map_failed(int cmd, unsigned long frame) scmd %d: 
 frame %lu
 +disable megasas_qf_complete_noirq(uint64_t context) context % PRIx64  
 +disable megasas_qf_complete(uint64_t context, unsigned int tail, unsigned 
 int offset, int busy, unsigned int doorbell) context % PRIx64  tail %x 
 offset %d busy %d doorbell %x
 +disable megasas_handle_frame(const char *cmd, uint64_t addr, uint64_t 
 context, uint32_t count) MFI cmd %s addr % PRIx64  context % PRIx64  
 count %d
 +megasas_frame_busy(uint64_t addr) frame % PRIx64  busy
 +megasas_unhandled_frame_cmd(int cmd, uint8_t frame_cmd) scmd %d: 
 Unhandled MFI cmd %x
 +disable megasas_handle_scsi(const char *frame, const char *desc, int dev, 
 int lun, void *sdev, unsigned long size) %s %s dev %x/%x sdev %p xfer %lu
 +disable megasas_scsi_target_not_present(const char *frame, const char 
 *desc, int dev, int lun) %s %s dev %x/%x target not present
 +megasas_scsi_invalid_cdb_len(const char *frame, const char *desc, int dev, 
 int lun, int len) %s %s dev %x/%x invalid cdb len %d
 +megasas_scsi_overflow(int cmd, const char *dir, int bytes, int len) scmd 
 %d: %s %d of %d bytes
 +disable megasas_scsi_underflow(int cmd, const char *dir, int bytes, int 
 len) scmd %d: %s %d of %d bytes
 +megasas_scsi_req_alloc_failed(const char *frame, int dev, int lun) %s dev 
 %x/%x req allocation failed
 +disable megasas_scsi_start(int cmd, const char *desc, int len) scmd %d: 
 %s %d bytes of data
 +disable megasas_scsi_nodata(int cmd) scmd %d: no data to be transferred
 +disable megasas_scsi_complete(int cmd, uint32_t status, int len, int xfer) 
 scmd %d: finished with status %x, len %u/%u
 +disable megasas_command_complete(int cmd, uint32_t status) scmd %d: 
 command completed, status %x
 +disable megasas_handle_io(int cmd, const char *frame, int dev, int lun, 
 unsigned long lba, unsigned long count) scmd %d: %s dev %x/%x lba %lx 
 count %lu
 +disable megasas_io_target_not_present(int cmd, const char *frame, int dev, 
 int lun) scmd %d: %s dev %x/%x LUN not present
 +disable megasas_io_start(int cmd, const char *dir, unsigned long lba, 
 unsigned long count, unsigned long len) scmd %d: %s start LBA %lx %lu 
 blocks (%lu bytes)
 +disable megasas_io_complete(int cmd, uint32_t len) scmd %d: %d bytes 
 completed
 +disable megasas_io_copy(int cmd, const char *dir, int bytes, int len, 
 unsigned long offset) scmd %d: %s %d of %d bytes, iov offset %lu
 +disable megasas_io_continue(int cmd, int bytes) scmd %d: %d bytes left
 +megasas_iovec_map_failed(int cmd, int index, unsigned long iov_size) scmd 
 %d: iovec %d size %lu
 +megasas_iovec_sgl_overflow(int cmd, int index, int limit) scmd %d: iovec 
 count %d limit %d
 +megasas_iovec_sgl_underflow(int cmd, int index) scmd %d: iovec count %d
 +megasas_iovec_sgl_invalid(int cmd, int index, uint64_t pa, uint32_t len) 
 scmd %d: invalid sgl element %d pa % PRIx64  len %u
 +megasas_iovec_len(int cmd, const char *desc, int len, int limit) scmd %d: 
 iovec %s len %d limit %d
 +disable megasas_handle_dcmd(int cmd, int opcode) scmd %d: MFI DCMD opcode 
 %x
 +disable megasas_finish_dcmd(int cmd, int size) scmd %d: MFI DCMD wrote %d 
 bytes
 +megasas_dcmd_req_alloc_failed(int cmd, const char *desc) scmd %d: %s 
 alloc failed
 +disable megasas_dcmd_internal_submit(int cmd, const char *desc, int dev) 
 scmd %d: %s to dev %d
 +disable megasas_dcmd_internal_finish(int cmd, int opcode, int lun) scmd 
 %d: DCMD finish internal cmd %x lun %d
 +megasas_dcmd_internal_invalid(int cmd, int opcode) scmd %d: Invalid 
 internal DCMD %x
 +megasas_dcmd_unhandled(int cmd, int opcode, int len) scmd %d: opcode %x, 
 len %d
 +disable megasas_dcmd_zero_sge(int cmd) scmd %d: zero DCMD sge count
 +megasas_dcmd_invalid_sge(int cmd, int count) scmd %d: invalid DCMD sge 
 count %d
 

Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy

2012-01-13 Thread Benoit Hudzia
On 13 January 2012 02:03, Isaku Yamahata yamah...@valinux.co.jp wrote:
 Very interesting. We can cooperate for better (postcopy) live migration.
 The code doesn't seem available yet, I'm eager for it.


 On Fri, Jan 13, 2012 at 01:09:30AM +, Benoit Hudzia wrote:
 Hi,

 Sorry to jump to hijack the thread  like that , however i would like
 to just to inform you  that we recently achieve a milestone out of the
 research project I'm leading. We enhanced KVM in order to deliver
 post copy live migration using RDMA at kernel level.

 Few point on the architecture of the system :

 * RDMA communication engine in kernel ( you can use soft iwarp or soft
 ROCE if you don't have hardware acceleration, however we also support
 standard RDMA enabled NIC) .

 Do you mean infiniband subsystem?

Yes, basically any software or hardware implementation that support
the standard RDMA / OFED vverbs  stack in kernel.


 * Naturally Page are transferred with Zerop copy protocol
 * Leverage the async page fault system.
 * Pre paging / faulting
 * No context switch as everything is handled within kernel and using
 the page fault system.
 * Hybrid migration ( pre + post copy) available

 Ah, I've been also planing this.
 After pre-copy phase, is the dirty bitmap sent?

We sent over the dirty bitmap yes. In order to identify what is left
to be transferred . And combined with the priority algo we will then
prioritise the page for the background transfer.


 So far I've thought naively that pre-copy phase would be finished by the
 number of iterations. On the other hand your choice is timeout of
 pre-copy phase. Do you have rationale? or it was just natural for you?


The main rational behind that is any normal sys admin tend to to be
human and live migration iteration cycle has no meaning for him. As a
result we preferred to provide a time constraint rather than an
iteration constraint. Also it is hard to estimate how much time
bandwidth would be use per iteration cycle which led to poor
determinism.



 * Rely on an independent Kernel Module
 * No modification to the KVM kernel Module
 * Minimal Modification to the Qemu-Kvm code
 * We plan to add the page prioritization algo in order to optimise the
 pre paging algo and background transfer

 Where do you plan to implement? in qemu or in your kernel module?
 This algo could be shared.

Yes we plan to actually release the algo first before the RDMA post
copy. The algo can be use for standard optimisation of the normal
pre-copy process (as demosntrated in my talk at KVM-forum). And if the
priority is reverse for the post copy page pull. My colleague Aidan
shribman is done with the implentation and we are now in testing phase
in order to quantify the improvement.



 thanks in advance.

 You can learn a little bit more and see a demo here:
 http://tinyurl.com/8xa2bgl
 I hope to be able to provide more detail on the design soon. As well
 as more concrete demo of the system ( live migration of VM running
 large  enterprise apps such as ERP or In memory DB)

 Note: this is just a step stone as the post copy live migration mainly
 enable us to validate the architecture design and  code.

 Regards
 Benoit







 Regards
 Benoit


 On 12 January 2012 13:59, Avi Kivity a...@redhat.com wrote:
  On 01/04/2012 05:03 AM, Isaku Yamahata wrote:
  Yes, it's quite doable in user space(qemu) with a kernel-enhancement.
  And it would be easy to convert a separated daemon process into a thread
  in qemu.
 
  I think it should be done out side of qemu process for some reasons.
  (I just repeat same discussion at the KVM-forum because no one remembers
  it)
 
  - ptrace (and its variant)
  ?? Some people want to investigate guest ram on host (qemu stopped or 
  lively).
  ?? For example, enhance crash utility and it will attach qemu process and
  ?? debug guest kernel.
 
  To debug the guest kernel you don't need to stop qemu itself. ?? I agree
  it's a problem for qemu debugging though.
 
 
  - core dump
  ?? qemu process may core-dump.
  ?? As postmortem analysis, people want to investigate guest RAM.
  ?? Again enhance crash utility and it will read the core file and analyze
  ?? guest kernel.
  ?? When creating core, the qemu process is already dead.
 
  Yes, strong point.
 
  It precludes the above possibilities to handle fault in qemu process.
 
  I agree.
 
 
  --
  error compiling committee.c: too many arguments to function
 
  --
  To unsubscribe from this list: send the line unsubscribe kvm in
  the body of a message to majord...@vger.kernel.org
  More majordomo info at ??http://vger.kernel.org/majordomo-info.html



 --
  The production of too many useful things results in too many useless 
 people


 --
 yamahata



-- 
 The production of too many useful things results in too many useless people



Re: [Qemu-devel] [PATCH 0/2][RFC] postcopy migration: Linux char device for postcopy

2012-01-13 Thread Benoit Hudzia
On 13 January 2012 02:15, Isaku Yamahata yamah...@valinux.co.jp wrote:
 One more question.
 Does your architecture/implementation (in theory) allow KVM memory
 features like swap, KSM, THP?

* Swap: Yes we support swap to disk ( the page is pulled from swap
before being send over), swap process do its job on the other side.
* KSM :  same , we support KSM, the KSMed page is broken down and
split and they are send individually ( yes sub optimal but make the
protocol less messy) and we let the KSM daemon do its job on the other
side.
* THP : more sticky here. Due to time constraint we decided that we
will be partially supporting it. What does it means: if we encounter
THP we break them down in standard page granularity as it is our
current memory unit we are manipulating. As a result you can have THP
on the source but you won't have THP on the other side.
   _ Note , we didn't explore fully the ramification of THP
with RDMA, i don't know if THP play well with the MMU of HW RDMA NIC,
One thing i would like to explore is if it is possible to break down
the THP in standard page and then reassemble them on the other side (
do any one fo you know if it is possible to aggregate page to for a
THP in kernel ? )
* cgroup  :  should be transparently working, but we need to do more
testing to confirm that .






 On Fri, Jan 13, 2012 at 11:03:23AM +0900, Isaku Yamahata wrote:
 Very interesting. We can cooperate for better (postcopy) live migration.
 The code doesn't seem available yet, I'm eager for it.


 On Fri, Jan 13, 2012 at 01:09:30AM +, Benoit Hudzia wrote:
  Hi,
 
  Sorry to jump to hijack the thread  like that , however i would like
  to just to inform you  that we recently achieve a milestone out of the
  research project I'm leading. We enhanced KVM in order to deliver
  post copy live migration using RDMA at kernel level.
 
  Few point on the architecture of the system :
 
  * RDMA communication engine in kernel ( you can use soft iwarp or soft
  ROCE if you don't have hardware acceleration, however we also support
  standard RDMA enabled NIC) .

 Do you mean infiniband subsystem?


  * Naturally Page are transferred with Zerop copy protocol
  * Leverage the async page fault system.
  * Pre paging / faulting
  * No context switch as everything is handled within kernel and using
  the page fault system.
  * Hybrid migration ( pre + post copy) available

 Ah, I've been also planing this.
 After pre-copy phase, is the dirty bitmap sent?

 So far I've thought naively that pre-copy phase would be finished by the
 number of iterations. On the other hand your choice is timeout of
 pre-copy phase. Do you have rationale? or it was just natural for you?


  * Rely on an independent Kernel Module
  * No modification to the KVM kernel Module
  * Minimal Modification to the Qemu-Kvm code
  * We plan to add the page prioritization algo in order to optimise the
  pre paging algo and background transfer

 Where do you plan to implement? in qemu or in your kernel module?
 This algo could be shared.

 thanks in advance.

  You can learn a little bit more and see a demo here:
  http://tinyurl.com/8xa2bgl
  I hope to be able to provide more detail on the design soon. As well
  as more concrete demo of the system ( live migration of VM running
  large  enterprise apps such as ERP or In memory DB)
 
  Note: this is just a step stone as the post copy live migration mainly
  enable us to validate the architecture design and  code.
 
  Regards
  Benoit
 
 
 
 
 
 
 
  Regards
  Benoit
 
 
  On 12 January 2012 13:59, Avi Kivity a...@redhat.com wrote:
   On 01/04/2012 05:03 AM, Isaku Yamahata wrote:
   Yes, it's quite doable in user space(qemu) with a kernel-enhancement.
   And it would be easy to convert a separated daemon process into a thread
   in qemu.
  
   I think it should be done out side of qemu process for some reasons.
   (I just repeat same discussion at the KVM-forum because no one remembers
   it)
  
   - ptrace (and its variant)
   ?? Some people want to investigate guest ram on host (qemu stopped or 
   lively).
   ?? For example, enhance crash utility and it will attach qemu process 
   and
   ?? debug guest kernel.
  
   To debug the guest kernel you don't need to stop qemu itself. ?? I agree
   it's a problem for qemu debugging though.
  
  
   - core dump
   ?? qemu process may core-dump.
   ?? As postmortem analysis, people want to investigate guest RAM.
   ?? Again enhance crash utility and it will read the core file and 
   analyze
   ?? guest kernel.
   ?? When creating core, the qemu process is already dead.
  
   Yes, strong point.
  
   It precludes the above possibilities to handle fault in qemu process.
  
   I agree.
  
  
   --
   error compiling committee.c: too many arguments to function
  
   --
   To unsubscribe from this list: send the line unsubscribe kvm in
   the body of a message to majord...@vger.kernel.org
   More majordomo info at ??http://vger.kernel.org/majordomo-info.html
 
 

Re: [Qemu-devel] [PATCH 4/4] target-i386: fix SSE rounding and flush to zero

2012-01-13 Thread Markus Armbruster
Dong Xu Wang wdon...@linux.vnet.ibm.com writes:

 After applied this patch, while I was compiling on my lap, there will
 be an error:

  ./configure --enable-kvm --target-list=x86_64-softmmu  make
 CCx86_64-softmmu/translate.o
 /qemu/target-i386/translate.c: In function ‘disas_insn’:
 /qemu/target-i386/translate.c:7547:17: error: incompatible type for
 argument 1 of ‘gen_helper_ldmxcsr’
 /qemu/target-i386/helper.h:200:1: note: expected ‘TCGv_i32’ but
 argument is of type ‘TCGv_i64’
 make[1]: *** [translate.o] Error 1
 make: *** [subdir-x86_64-softmmu] Error 2

I see this, too.



[Qemu-devel] [PATCH 1/2] qdev: Add a 'free' method to disassociate chardev from qdev device

2012-01-13 Thread Amit Shah
When a device is removed, remove the association with a chardev, if any,
so that the chardev can be re-used later for other devices.

Reported-by: Qunfang Zhang qzh...@redhat.com
Fix-suggested-by: Markus Armbruster arm...@redhat.com
Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/qdev-properties.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 663c2a0..02f0dae 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -680,6 +680,16 @@ static int parse_chr(DeviceState *dev, Property *prop, 
const char *str)
 return 0;
 }
 
+static void free_chr(DeviceState *dev, Property *prop)
+{
+CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
+}
+}
+
+
 static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
@@ -699,6 +709,7 @@ PropertyInfo qdev_prop_chr = {
 .print = print_chr,
 .get   = get_generic,
 .set   = set_generic,
+.free  = free_chr,
 };
 
 /* --- netdev device --- */
-- 
1.7.7.5




[Qemu-devel] [PATCH 0/2] qdev: disassociate chardev from device on device exit

2012-01-13 Thread Amit Shah
When the device is going away (e.g., hot-unplug), an associated
chardev should be freed and made available for use for other devices.

An earlier hack did this for virtio serial ports, do it in a generic
way and remove the virtio-serial specific hack.

Amit Shah (2):
  qdev: Add a 'free' method to disassociate chardev from qdev device
  virtio-console: no need to remove char handlers explicitly

 hw/qdev-properties.c |   11 +++
 hw/virtio-console.c  |   10 --
 2 files changed, 11 insertions(+), 10 deletions(-)

-- 
1.7.7.5




[Qemu-devel] [PATCH 2/2] virtio-console: no need to remove char handlers explicitly

2012-01-13 Thread Amit Shah
qdev is now equipped (thanks to the last commit) to disassociate
chardevs from the qdev devices on the devices going away.  So doing it
in the virtio-console driver is not necessary.

Since that was the only thing being done in the qdev exit method, drop
it entirely.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/virtio-console.c |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 73d866a..9275fd9 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -127,16 +127,6 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
 
 static int virtconsole_exitfn(VirtIOSerialPort *port)
 {
-VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
-if (vcon-chr) {
-   /*
-* Instead of closing the chardev, free it so it can be used
-* for other purposes.
-*/
-   qemu_chr_add_handlers(vcon-chr, NULL, NULL, NULL, NULL);
-}
-
 return 0;
 }
 
-- 
1.7.7.5




Re: [Qemu-devel] [PATCH 2/2] virtio-console: no need to remove char handlers explicitly

2012-01-13 Thread Amit Shah
On (Fri) 13 Jan 2012 [15:24:59], Amit Shah wrote:
 qdev is now equipped (thanks to the last commit) to disassociate
 chardevs from the qdev devices on the devices going away.  So doing it
 in the virtio-console driver is not necessary.
 
 Since that was the only thing being done in the qdev exit method, drop
 it entirely.

Commit message is correct, patch is not.  Updated patch coming soon..

 diff --git a/hw/virtio-console.c b/hw/virtio-console.c
 index 73d866a..9275fd9 100644
 --- a/hw/virtio-console.c
 +++ b/hw/virtio-console.c
 @@ -127,16 +127,6 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
  
  static int virtconsole_exitfn(VirtIOSerialPort *port)
  {
 -VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 -
 -if (vcon-chr) {
 - /*
 -  * Instead of closing the chardev, free it so it can be used
 -  * for other purposes.
 -  */
 - qemu_chr_add_handlers(vcon-chr, NULL, NULL, NULL, NULL);
 -}
 -
  return 0;
  }

Amit



[Qemu-devel] [PATCH v2 0/2] qdev: disassociate chardev from device on device exit

2012-01-13 Thread Amit Shah
When the device is going away (e.g., hot-unplug), an associated
chardev should be freed and made available for use for other devices.

An earlier hack did this for virtio serial ports, do it in a generic
way and remove the virtio-serial specific hack.

v2:
 - actually remove virtconsole_exitfn()

Amit Shah (2):
  qdev: Add a 'free' method to disassociate chardev from qdev device
  virtio-console: no need to remove char handlers explicitly

 hw/qdev-properties.c |   11 +++
 hw/virtio-console.c  |   17 -
 2 files changed, 11 insertions(+), 17 deletions(-)

-- 
1.7.7.5




Re: [Qemu-devel] [PATCH] qdev: fix hotplug when no -device is specified

2012-01-13 Thread Markus Armbruster
device_del is broken for me in master:

$ qemu-system-x86_64 -nodefaults -S -m 384 -vnc :0 -monitor stdio -usb
QEMU 1.0.50 monitor - type 'help' for more information
(qemu) device_add usb-mouse,id=foo
(qemu) device_del foo
Device 'foo' is in use

Same for any hot-pluggable device I tried, with and without -S.
git-bisect fingers this patch, which went in as commit 1de81d28.



[Qemu-devel] [PATCH v2 1/2] qdev: Add a 'free' method to disassociate chardev from qdev device

2012-01-13 Thread Amit Shah
When a device is removed, remove the association with a chardev, if any,
so that the chardev can be re-used later for other devices.

Reported-by: Qunfang Zhang qzh...@redhat.com
Fix-suggested-by: Markus Armbruster arm...@redhat.com
Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/qdev-properties.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 663c2a0..02f0dae 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -680,6 +680,16 @@ static int parse_chr(DeviceState *dev, Property *prop, 
const char *str)
 return 0;
 }
 
+static void free_chr(DeviceState *dev, Property *prop)
+{
+CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+if (*ptr) {
+qemu_chr_add_handlers(*ptr, NULL, NULL, NULL, NULL);
+}
+}
+
+
 static int print_chr(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
 CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);
@@ -699,6 +709,7 @@ PropertyInfo qdev_prop_chr = {
 .print = print_chr,
 .get   = get_generic,
 .set   = set_generic,
+.free  = free_chr,
 };
 
 /* --- netdev device --- */
-- 
1.7.7.5




[Qemu-devel] [PATCH v2 2/2] virtio-console: no need to remove char handlers explicitly

2012-01-13 Thread Amit Shah
qdev is now equipped (thanks to the last commit) to disassociate
chardevs from the qdev devices on the devices going away.  So doing it
in the virtio-console driver is not necessary.

Since that was the only thing being done in the qdev exit method, drop
it entirely.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 hw/virtio-console.c |   17 -
 1 files changed, 0 insertions(+), 17 deletions(-)

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 73d866a..0b28a30 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -125,27 +125,11 @@ static int virtconsole_initfn(VirtIOSerialPort *port)
 return 0;
 }
 
-static int virtconsole_exitfn(VirtIOSerialPort *port)
-{
-VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
-if (vcon-chr) {
-   /*
-* Instead of closing the chardev, free it so it can be used
-* for other purposes.
-*/
-   qemu_chr_add_handlers(vcon-chr, NULL, NULL, NULL, NULL);
-}
-
-return 0;
-}
-
 static VirtIOSerialPortInfo virtconsole_info = {
 .qdev.name = virtconsole,
 .qdev.size = sizeof(VirtConsole),
 .is_console= true,
 .init  = virtconsole_initfn,
-.exit  = virtconsole_exitfn,
 .have_data = flush_buf,
 .guest_open= guest_open,
 .guest_close   = guest_close,
@@ -165,7 +149,6 @@ static VirtIOSerialPortInfo virtserialport_info = {
 .qdev.name = virtserialport,
 .qdev.size = sizeof(VirtConsole),
 .init  = virtconsole_initfn,
-.exit  = virtconsole_exitfn,
 .have_data = flush_buf,
 .guest_open= guest_open,
 .guest_close   = guest_close,
-- 
1.7.7.5




Re: [Qemu-devel] [PATCH][v8] megasas: LSI Megaraid SAS HBA emulation

2012-01-13 Thread Paolo Bonzini

On 01/13/2012 10:46 AM, Hannes Reinecke wrote:

So, I should be removing the 'disable' keyword, then, correct?


Yes.


The strings are just there to avoid trace statement duplication. But
if that's not a problem then I can easily convert the strings to
individual trace statements.


No, don't bother.

Paolo



[Qemu-devel] [PULL 00/12] Trivial patches for 6 to 13 January 2012

2012-01-13 Thread Stefan Hajnoczi
The following changes since commit bee5a5fb11de34aa422cfc830adbd51cfc8f5b55:

  cris: Update paths to match the move of tests/cris (2012-01-13 11:09:56 +0100)

are available in the git repository at:
  git://github.com/stefanha/qemu.git trivial-patches

Aurelien Jarno (1):
  tcg-arm: fix a typo in comments

Stefan Berger (1):
  hmp: Fix freeing of PciInfoList

Stefan Hajnoczi (4):
  vvfat: avoid leaking file descriptor in commit_one_file()
  vnc: fix no-lock-key-sync strncmp() length
  omap_dss: correct chip[1] index in RFBI_READ/RFBI_STATUS
  bt-host: add missing break statement

Stefan Weil (6):
  configure: Modify detection of supported warning options
  Spelling fixes in comments and documentation
  Add 'fall through' comments to case statements without break
  virtfs-proxy-helper: Fix compilation on newer systems
  virtfs-proxy-helper: Clean include files
  virtfs-proxy-helper: Add missing printf format attribute

 block/vvfat.c |3 +++
 bt-host.c |1 +
 configure |2 +-
 docs/writing-qmp-commands.txt |2 +-
 exec.c|2 +-
 fsdev/virtfs-proxy-helper.c   |   19 ---
 hmp.c |8 
 hw/omap_dss.c |4 ++--
 hw/pcnet.c|1 +
 json-lexer.c  |1 +
 memory.h  |4 ++--
 qemu-ga.c |2 +-
 qemu-option.c |4 
 tcg/arm/tcg-target.c  |2 +-
 ui/vnc.c  |2 +-
 15 files changed, 28 insertions(+), 29 deletions(-)

-- 
1.7.7.3




[Qemu-devel] [PATCH 05/12] vnc: fix no-lock-key-sync strncmp() length

2012-01-13 Thread Stefan Hajnoczi
The no-lock-key-sync option is being parsed incorrectly because of an
outdated strcmp() length value.  Use the correct length so that invalid
option names do not match.

Reported-by: Dr David Alan Gilbert davidagilb...@uk.ibm.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 ui/vnc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 6767ada..1869a7a 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2763,7 +2763,7 @@ int vnc_display_open(DisplayState *ds, const char 
*display)
 password = 1; /* Require password auth */
 } else if (strncmp(options, reverse, 7) == 0) {
 reverse = 1;
-} else if (strncmp(options, no-lock-key-sync, 9) == 0) {
+} else if (strncmp(options, no-lock-key-sync, 16) == 0) {
 lock_key_sync = 0;
 #ifdef CONFIG_VNC_SASL
 } else if (strncmp(options, sasl, 4) == 0) {
-- 
1.7.7.3




[Qemu-devel] [PATCH 03/12] Spelling fixes in comments and documentation

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

Codespell detected these new spelling issues.

Signed-off-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 docs/writing-qmp-commands.txt |2 +-
 memory.h  |4 ++--
 qemu-ga.c |2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs/writing-qmp-commands.txt b/docs/writing-qmp-commands.txt
index 0472fc3..0ad51aa 100644
--- a/docs/writing-qmp-commands.txt
+++ b/docs/writing-qmp-commands.txt
@@ -435,7 +435,7 @@ There are a number of things to be noticed:
for all QMP functions)
 3. The clock variable (which will point to our QAPI type instance) is
allocated by the regular g_malloc0() function. Note that we chose to
-   initialize the memory to zero. This is recomended for all QAPI types, as
+   initialize the memory to zero. This is recommended for all QAPI types, as
it helps avoiding bad surprises (specially with booleans)
 4. Remember that next_deadline is optional? All optional members have a
'has_TYPE_NAME' member that should be properly set by the implementation,
diff --git a/memory.h b/memory.h
index 70f57fb..d48b08b 100644
--- a/memory.h
+++ b/memory.h
@@ -561,7 +561,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
  * memory_region_get_ram_addr: Get the ram address associated with a memory
  * region
  *
- * DO NOT USE THIS FUCNTION.  This is a temporary workaround while the Xen
+ * DO NOT USE THIS FUNCTION.  This is a temporary workaround while the Xen
  * code is being reworked.
  */
 ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
@@ -650,7 +650,7 @@ void memory_global_sync_dirty_bitmap(MemoryRegion 
*address_space);
  * memory_region_transaction_begin: Start a transaction.
  *
  * During a transaction, changes will be accumulated and made visible
- * only when the transaction ends (is commited).
+ * only when the transaction ends (is committed).
  */
 void memory_region_transaction_begin(void);
 
diff --git a/qemu-ga.c b/qemu-ga.c
index 200bb15..29e4f64 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -92,7 +92,7 @@ static void usage(const char *cmd)
   -v, --verbose log extra debugging information\n
   -V, --version print version information and exit\n
   -d, --daemonize   become a daemon\n
-  -b, --blacklist   comma-seperated list of RPCs to disable (no spaces, \?\
+  -b, --blacklist   comma-separated list of RPCs to disable (no spaces, \?\
 to list available RPCs)\n
   -h, --helpdisplay this help and exit\n
 \n
-- 
1.7.7.3




[Qemu-devel] [PATCH 02/12] tcg-arm: fix a typo in comments

2012-01-13 Thread Stefan Hajnoczi
From: Aurelien Jarno aurel...@aurel32.net

ARM still doesn't support 16GB buffers in 32-bit modes, replace the
16GB by 16MB in the comment.

Reviewed-by: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Aurelien Jarno aurel...@aurel32.net
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 exec.c   |2 +-
 tcg/arm/tcg-target.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index b1d6602..7f9f730 100644
--- a/exec.c
+++ b/exec.c
@@ -511,7 +511,7 @@ static void code_gen_alloc(unsigned long tb_size)
 if (code_gen_buffer_size  (512 * 1024 * 1024))
 code_gen_buffer_size = (512 * 1024 * 1024);
 #elif defined(__arm__)
-/* Keep the buffer no bigger than 16GB to branch between blocks */
+/* Keep the buffer no bigger than 16MB to branch between blocks */
 if (code_gen_buffer_size  16 * 1024 * 1024)
 code_gen_buffer_size = 16 * 1024 * 1024;
 #elif defined(__s390x__)
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 1d32798..5b233f5 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -843,7 +843,7 @@ static inline void tcg_out_st8(TCGContext *s, int cond,
 }
 
 /* The _goto case is normally between TBs within the same code buffer,
- * and with the code buffer limited to 16GB we shouldn't need the long
+ * and with the code buffer limited to 16MB we shouldn't need the long
  * case.
  *
  *  except to the prologue that is in its own buffer.
-- 
1.7.7.3




[Qemu-devel] [PATCH 01/12] configure: Modify detection of supported warning options

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

Reversing the order of the warning options and -Werror is important
when clang is used instead of gcc. It changes nothing for gcc.

Signed-off-by: Stefan Weil s...@weilnetz.de
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 eb9a01d..467e87b 100755
--- a/configure
+++ b/configure
@@ -1105,7 +1105,7 @@ cat  $TMPC  EOF
 int main(void) { return 0; }
 EOF
 for flag in $gcc_flags; do
-if compile_prog $flag -Werror  ; then
+if compile_prog -Werror $flag  ; then
QEMU_CFLAGS=$QEMU_CFLAGS $flag
 fi
 done
-- 
1.7.7.3




[Qemu-devel] [PATCH 04/12] vvfat: avoid leaking file descriptor in commit_one_file()

2012-01-13 Thread Stefan Hajnoczi
Reported-by: Dr David Alan Gilbert davidagilb...@uk.ibm.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block/vvfat.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index eeffc4a..9ef21dd 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2218,6 +2218,7 @@ static int commit_one_file(BDRVVVFATState* s,
 }
 if (offset  0) {
 if (lseek(fd, offset, SEEK_SET) != offset) {
+close(fd);
 g_free(cluster);
 return -3;
 }
@@ -2238,11 +2239,13 @@ static int commit_one_file(BDRVVVFATState* s,
(uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
 
 if (ret  0) {
+close(fd);
 g_free(cluster);
 return ret;
 }
 
 if (write(fd, cluster, rest_size)  0) {
+close(fd);
 g_free(cluster);
 return -2;
 }
-- 
1.7.7.3




[Qemu-devel] [PATCH 10/12] virtfs-proxy-helper: Clean include files

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

The common standard include files are already included via qemu-common.h,
and for the socket related include files there is qemu_socket.h, so the
code can be reduced by some lines.

Signed-off-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 fsdev/virtfs-proxy-helper.c |   15 ++-
 1 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index ce7eb79..21e9b16 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -8,31 +8,20 @@
  * This work is licensed under the terms of the GNU GPL, version 2. See
  * the COPYING file in the top-level directory.
  */
-#include stdio.h
-#include sys/socket.h
-#include string.h
-#include sys/un.h
-#include limits.h
-#include signal.h
-#include errno.h
-#include stdlib.h
+
 #include sys/resource.h
-#include sys/stat.h
 #include getopt.h
-#include unistd.h
 #include syslog.h
 #include sys/capability.h
 #include sys/fsuid.h
-#include stdarg.h
-#include stdbool.h
 #include sys/vfs.h
-#include sys/stat.h
 #include sys/ioctl.h
 #include linux/fs.h
 #ifdef CONFIG_LINUX_MAGIC_H
 #include linux/magic.h
 #endif
 #include qemu-common.h
+#include qemu_socket.h
 #include qemu-xattr.h
 #include virtio-9p-marshal.h
 #include hw/9pfs/virtio-9p-proxy.h
-- 
1.7.7.3




[Qemu-devel] [PATCH 06/12] omap_dss: correct chip[1] index in RFBI_READ/RFBI_STATUS

2012-01-13 Thread Stefan Hajnoczi
The RFBI_READ/RFBI_STATUS code incorrectly uses chip[0] when it should
be using chip[1].  Andrzej Zaborowski bal...@zabor.org confirmed this
bug since I don't know this code well.

Reported-by: Dr David Alan Gilbert davidagilb...@uk.ibm.com
Reviewed-by: Andrzej Zaborowski andrew.zaborow...@intel.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 hw/omap_dss.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/omap_dss.c b/hw/omap_dss.c
index ede640b..86ed6ea 100644
--- a/hw/omap_dss.c
+++ b/hw/omap_dss.c
@@ -793,7 +793,7 @@ static void omap_rfbi_write(void *opaque, 
target_phys_addr_t addr,
 if ((s-rfbi.control  (1  2))  s-rfbi.chip[0])
 s-rfbi.rxbuf = s-rfbi.chip[0]-read(s-rfbi.chip[0]-opaque, 1);
 else if ((s-rfbi.control  (1  3))  s-rfbi.chip[1])
-s-rfbi.rxbuf = s-rfbi.chip[0]-read(s-rfbi.chip[0]-opaque, 1);
+s-rfbi.rxbuf = s-rfbi.chip[1]-read(s-rfbi.chip[1]-opaque, 1);
 if (!-- s-rfbi.pixels)
 omap_rfbi_transfer_stop(s);
 break;
@@ -802,7 +802,7 @@ static void omap_rfbi_write(void *opaque, 
target_phys_addr_t addr,
 if ((s-rfbi.control  (1  2))  s-rfbi.chip[0])
 s-rfbi.rxbuf = s-rfbi.chip[0]-read(s-rfbi.chip[0]-opaque, 0);
 else if ((s-rfbi.control  (1  3))  s-rfbi.chip[1])
-s-rfbi.rxbuf = s-rfbi.chip[0]-read(s-rfbi.chip[0]-opaque, 0);
+s-rfbi.rxbuf = s-rfbi.chip[1]-read(s-rfbi.chip[1]-opaque, 0);
 if (!-- s-rfbi.pixels)
 omap_rfbi_transfer_stop(s);
 break;
-- 
1.7.7.3




[Qemu-devel] [PATCH 11/12] virtfs-proxy-helper: Add missing printf format attribute

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

Every function with printf like arguments must have it
(see file HACKING), so add it.

Signed-off-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 fsdev/virtfs-proxy-helper.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 21e9b16..4a507d8 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -54,7 +54,7 @@ static struct option helper_opts[] = {
 static bool is_daemon;
 static bool get_version; /* IOC getversion IOCTL supported */
 
-static void do_log(int loglevel, const char *format, ...)
+static void GCC_FMT_ATTR(2, 3) do_log(int loglevel, const char *format, ...)
 {
 va_list ap;
 
-- 
1.7.7.3




[Qemu-devel] [PATCH 09/12] virtfs-proxy-helper: Fix compilation on newer systems

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

Include file attr/xattr.h is not available on newer systems
(for example Fedora 12 or Debian Squeeze).

See comments in qemu-xattr.h for more information.
This file handles the system dependencies automatically.

Signed-off-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 fsdev/virtfs-proxy-helper.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
index 7f8def5..ce7eb79 100644
--- a/fsdev/virtfs-proxy-helper.c
+++ b/fsdev/virtfs-proxy-helper.c
@@ -27,13 +27,13 @@
 #include stdbool.h
 #include sys/vfs.h
 #include sys/stat.h
-#include attr/xattr.h
 #include sys/ioctl.h
 #include linux/fs.h
 #ifdef CONFIG_LINUX_MAGIC_H
 #include linux/magic.h
 #endif
 #include qemu-common.h
+#include qemu-xattr.h
 #include virtio-9p-marshal.h
 #include hw/9pfs/virtio-9p-proxy.h
 #include fsdev/virtio-9p-marshal.h
-- 
1.7.7.3




[Qemu-devel] [PATCH 07/12] Add 'fall through' comments to case statements without break

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Weil s...@weilnetz.de

These comments are used by static code analysis tools and in code reviews
to avoid false warnings because of missing break statements.

The case statements handled here were reported by coverity.

Reviewed-by: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 hw/pcnet.c|1 +
 json-lexer.c  |1 +
 qemu-option.c |4 
 3 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hw/pcnet.c b/hw/pcnet.c
index cba253b..306dc6e 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1505,6 +1505,7 @@ static void pcnet_bcr_writew(PCNetState *s, uint32_t rap, 
uint32_t val)
 #ifdef PCNET_DEBUG
printf(BCR_SWS=0x%04x\n, val);
 #endif
+/* fall through */
 case BCR_LNKST:
 case BCR_LED1:
 case BCR_LED2:
diff --git a/json-lexer.c b/json-lexer.c
index c21338f..3cd3285 100644
--- a/json-lexer.c
+++ b/json-lexer.c
@@ -301,6 +301,7 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, 
bool flush)
 case JSON_KEYWORD:
 case JSON_STRING:
 lexer-emit(lexer, lexer-token, new_state, lexer-x, lexer-y);
+/* fall through */
 case JSON_SKIP:
 QDECREF(lexer-token);
 lexer-token = qstring_new();
diff --git a/qemu-option.c b/qemu-option.c
index 6b23c31..a303f87 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -214,13 +214,17 @@ static int parse_option_size(const char *name, const char 
*value, uint64_t *ret)
 switch (*postfix) {
 case 'T':
 sizef *= 1024;
+/* fall through */
 case 'G':
 sizef *= 1024;
+/* fall through */
 case 'M':
 sizef *= 1024;
+/* fall through */
 case 'K':
 case 'k':
 sizef *= 1024;
+/* fall through */
 case 'b':
 case '\0':
 *ret = (uint64_t) sizef;
-- 
1.7.7.3




[Qemu-devel] --enable-check-utests gone, you may have to re-run configure (was: [PATCH 10/15] test: eliminate libcheck tests and have make check use gtester)

2012-01-13 Thread Markus Armbruster
Deserves more prominent notice, so here goes:

Anthony Liguori aligu...@us.ibm.com writes:

[...]
 @@ -733,10 +732,6 @@ for opt do
;;
--enable-fdt) fdt=yes
;;
 -  --disable-check-utests) check_utests=no
 -  ;;
 -  --enable-check-utests) check_utests=yes
 -  ;;
--disable-nptl) nptl=no
;;
--enable-nptl) nptl=yes

Just drop the option from your configure command line.

[...]



Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Benjamin Herrenschmidt
On Mon, 2012-01-02 at 18:51 -0600, Anthony Liguori wrote:
 This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
 fairly sure hardware doesn't exist anymore that you can run the KVM support
 with.

It does exist, I have one :-)

 So let's remove it.  It can always be restored later if there is interest 
 again.

Cheers,
Ben.

 Signed-off-by: Anthony Liguori aligu...@us.ibm.com
 ---
  Makefile.target|3 +-
  hw/ppc440.c|  106 ---
  hw/ppc440.h|   21 ---
  hw/ppc440_bamboo.c |  215 -
  hw/ppc4xx_pci.c|  381 
 
  hw/virtex_ml507.c  |1 -
  6 files changed, 1 insertions(+), 726 deletions(-)
  delete mode 100644 hw/ppc440.c
  delete mode 100644 hw/ppc440.h
  delete mode 100644 hw/ppc440_bamboo.c
  delete mode 100644 hw/ppc4xx_pci.c
 
 diff --git a/Makefile.target b/Makefile.target
 index 3261383..b8ccf07 100644
 --- a/Makefile.target
 +++ b/Makefile.target
 @@ -246,8 +246,7 @@ obj-ppc-$(CONFIG_PSERIES) += spapr.o spapr_hcall.o 
 spapr_rtas.o spapr_vio.o
  obj-ppc-$(CONFIG_PSERIES) += xics.o spapr_vty.o spapr_llan.o spapr_vscsi.o
  obj-ppc-$(CONFIG_PSERIES) += spapr_pci.o device-hotplug.o pci-hotplug.o
  # PowerPC 4xx boards
 -obj-ppc-y += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o
 -obj-ppc-y += ppc440.o ppc440_bamboo.o
 +obj-ppc-y += ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
  # PowerPC E500 boards
  obj-ppc-y += ppce500_mpc8544ds.o mpc8544_guts.o ppce500_spin.o
  # PowerPC 440 Xilinx ML507 reference board.
 diff --git a/hw/ppc440.c b/hw/ppc440.c
 deleted file mode 100644
 index cd8a95d..000
 --- a/hw/ppc440.c
 +++ /dev/null
 @@ -1,106 +0,0 @@
 -/*
 - * Qemu PowerPC 440 chip emulation
 - *
 - * Copyright 2007 IBM Corporation.
 - * Authors:
 - *   Jerone Young jyou...@us.ibm.com
 - *   Christian Ehrhardt ehrha...@linux.vnet.ibm.com
 - *   Hollis Blanchard holl...@us.ibm.com
 - *
 - * This work is licensed under the GNU GPL license version 2 or later.
 - *
 - */
 -
 -#include hw.h
 -#include pc.h
 -#include isa.h
 -#include ppc.h
 -#include ppc4xx.h
 -#include ppc440.h
 -#include ppc405.h
 -#include sysemu.h
 -#include kvm.h
 -
 -#define PPC440EP_PCI_CONFIG 0xeec0
 -#define PPC440EP_PCI_INTACK 0xeed0
 -#define PPC440EP_PCI_SPECIAL0xeed0
 -#define PPC440EP_PCI_REGS   0xef40
 -#define PPC440EP_PCI_IO 0xe800
 -#define PPC440EP_PCI_IOLEN  0x0001
 -
 -#define PPC440EP_SDRAM_NR_BANKS 4
 -
 -static const unsigned int ppc440ep_sdram_bank_sizes[] = {
 -25620, 12820, 6420, 3220, 1620, 820, 0
 -};
 -
 -CPUState *ppc440ep_init(MemoryRegion *address_space_mem, ram_addr_t 
 *ram_size,
 -PCIBus **pcip, const unsigned int pci_irq_nrs[4],
 -int do_init, const char *cpu_model)
 -{
 -MemoryRegion *ram_memories
 -= g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories));
 -target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
 -target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
 -CPUState *env;
 -qemu_irq *pic;
 -qemu_irq *irqs;
 -qemu_irq *pci_irqs;
 -
 -if (cpu_model == NULL) {
 -cpu_model = 440-Xilinx; // XXX: should be 440EP
 -}
 -env = cpu_init(cpu_model);
 -if (!env) {
 -fprintf(stderr, Unable to initialize CPU!\n);
 -exit(1);
 -}
 -
 -ppc_dcr_init(env, NULL, NULL);
 -
 -/* interrupt controller */
 -irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
 -irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq 
 *)env-irq_inputs)[PPC40x_INPUT_INT];
 -irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq 
 *)env-irq_inputs)[PPC40x_INPUT_CINT];
 -pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
 -
 -/* SDRAM controller */
 -memset(ram_bases, 0, sizeof(ram_bases));
 -memset(ram_sizes, 0, sizeof(ram_sizes));
 -*ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
 -ram_memories,
 -ram_bases, ram_sizes,
 -ppc440ep_sdram_bank_sizes);
 -/* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. 
 */
 -ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories,
 -  ram_bases, ram_sizes, do_init);
 -
 -/* PCI */
 -pci_irqs = g_malloc(sizeof(qemu_irq) * 4);
 -pci_irqs[0] = pic[pci_irq_nrs[0]];
 -pci_irqs[1] = pic[pci_irq_nrs[1]];
 -pci_irqs[2] = pic[pci_irq_nrs[2]];
 -pci_irqs[3] = pic[pci_irq_nrs[3]];
 -*pcip = ppc4xx_pci_init(env, pci_irqs,
 -PPC440EP_PCI_CONFIG,
 -PPC440EP_PCI_INTACK,
 -PPC440EP_PCI_SPECIAL,
 -PPC440EP_PCI_REGS);
 -if (!*pcip)
 -printf(couldn't create PCI controller!\n);
 -
 -isa_mmio_init(PPC440EP_PCI_IO, PPC440EP_PCI_IOLEN);
 -
 -if 

Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Andreas Färber
Am 13.01.2012 11:59, schrieb Benjamin Herrenschmidt:
 On Mon, 2012-01-02 at 18:51 -0600, Anthony Liguori wrote:
 This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
 fairly sure hardware doesn't exist anymore that you can run the KVM support
 with.
 
 It does exist, I have one :-)

Alex has already posted series to not only qdev'ify it but to also add
TCG support so other people can test it. Review and testing would
probably be appreciated. :)

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 12/12] bt-host: add missing break statement

2012-01-13 Thread Stefan Hajnoczi
The switch statement in bt_host_read() is missing a break in one case.
Andrzej Zaborowski andrew.zaborow...@intel.com confirmed that this is
not an intentional fall-through.

Reviewed-by: Stefan Weil s...@weilnetz.de
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 bt-host.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/bt-host.c b/bt-host.c
index df5b7cd..0d3ad28 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -130,6 +130,7 @@ static void bt_host_read(void *opaque)
 pktlen = MIN(pkt[2] + 3, s-len);
 s-len -= pktlen;
 pkt += pktlen;
+break;
 
 default:
 bad_pkt:
-- 
1.7.7.3




[Qemu-devel] [PATCH 08/12] hmp: Fix freeing of PciInfoList

2012-01-13 Thread Stefan Hajnoczi
From: Stefan Berger stef...@linux.vnet.ibm.com

Remember the original PciInfoList in info_list and use
the info variable to traverse the list.

Signed-off-by: Stefan Berger stef...@linux.vnet.ibm.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 hmp.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hmp.c b/hmp.c
index e7659d5..fd4f755 100644
--- a/hmp.c
+++ b/hmp.c
@@ -486,17 +486,17 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)
 
 void hmp_info_pci(Monitor *mon)
 {
-PciInfoList *info;
+PciInfoList *info_list, *info;
 Error *err = NULL;
 
-info = qmp_query_pci(err);
+info_list = qmp_query_pci(err);
 if (err) {
 monitor_printf(mon, PCI devices not supported\n);
 error_free(err);
 return;
 }
 
-for (; info; info = info-next) {
+for (info = info_list; info; info = info-next) {
 PciDeviceInfoList *dev;
 
 for (dev = info-value-devices; dev; dev = dev-next) {
@@ -504,7 +504,7 @@ void hmp_info_pci(Monitor *mon)
 }
 }
 
-qapi_free_PciInfoList(info);
+qapi_free_PciInfoList(info_list);
 }
 
 void hmp_quit(Monitor *mon, const QDict *qdict)
-- 
1.7.7.3




[Qemu-devel] [PULL 00/17] usb patch queue: audio, xhci, usbredir

2012-01-13 Thread Gerd Hoffmann
  Hi,

Here comes the usb patch queue.  It features the patches posted a week
ago for review with some minor tweaks according to the review comments:
The comment in usb-audio was fixed and xhci got a codestyle cleanup.  No
actual code changes.  I've also included the usb-redir patches posted by
Hans earlier this week.

please pull,
  Gerd

The following changes since commit 515aa3c57986b3e26558d72ecaeb7545ecd30510:

  check-qstring: remove check.h include (2012-01-12 11:33:22 -0600)

are available in the git repository at:
  git://git.kraxel.org/qemu usb.36

Gerd Hoffmann (10):
  usb-host: rip out legacy procfs support
  usb: track configuration and interface count in USBDevice.
  usb: track altsetting in USBDevice
  usb-desc: audio endpoint support
  usb: add USBEndpoint
  usb: add ifnum to USBEndpoint
  usb-desc: USBEndpoint support
  usb/debug: add usb_ep_dump
  usb: add max_packet_size to USBEndpoint
  usb: link packets to endpoints not devices

H. Peter Anvin (1):
  usb: add audio device model

Hans de Goede (5):
  usb-redir: Clear iso / irq error when stopping the stream
  usb-redir: Dynamically adjust iso buffering size based on ep interval
  usb-redir: Pre-fill our isoc input buffer before sending pkts to the host
  usb-redir: Try to keep our buffer size near the target size
  usb-redir: Improve some debugging messages

Hector Martin (1):
  xhci: Initial xHCI implementation

 Makefile.objs   |3 +-
 default-configs/pci.mak |1 +
 hw/pci_ids.h|3 +
 hw/usb-audio.c  |  704 
 hw/usb-bt.c |   22 -
 hw/usb-bus.c|1 +
 hw/usb-ccid.c   |8 -
 hw/usb-desc.c   |  143 +++-
 hw/usb-desc.h   |5 +
 hw/usb-ehci.c   |3 +-
 hw/usb-hid.c|7 -
 hw/usb-hub.c|7 -
 hw/usb-msd.c|   10 -
 hw/usb-musb.c   |3 +-
 hw/usb-net.c|   14 -
 hw/usb-ohci.c   |4 +-
 hw/usb-serial.c |7 -
 hw/usb-uhci.c   |3 +-
 hw/usb-wacom.c  |7 -
 hw/usb-xhci.c   | 2748 +++
 hw/usb.c|  125 +++-
 hw/usb.h|   44 +-
 trace-events|1 +
 usb-linux.c |  452 ++--
 usb-redir.c |  118 ++-
 25 files changed, 3972 insertions(+), 471 deletions(-)
 create mode 100644 hw/usb-audio.c
 create mode 100644 hw/usb-xhci.c



Re: [Qemu-devel] [PATCH v3 0/8] qdev'ify PReP PCI host bridge and add PCI-to-ISA bridge

2012-01-13 Thread Alexander Graf

On 13.01.2012, at 04:09, Andreas Färber wrote:

 Hello,
 
 Here's an updated initial qdev'ification series for PReP, as prerequisite
 for Anthony's second QOM series.
 
 As stated before, this is NOT a complete conversion of all PReP devices
 and of all those shared with x86. Please comment on what's there, not on
 what may be done, too. I'm sitting on these patches for over a year now,
 so let's start getting some of it merged so that we can move on with QOM
 and get some of the design issues fixed that kept the pc87312 Super I/O
 and 40P machine from getting merged in the first place!
 
 Regards,
 Andreas

Looks good to me.

Reviewed-by: Alexander Graf ag...@suse.de


Alex

 
 Changes since v2:
 * Simplify I/O byte swaps.
 * Convert I/O from old_mmio to MemoryRegion ops.
 * Drop pci_prep_init() and instantiate the PCI host bridge in the machine,
  reintroducing PREPPCIState extension.
 * Connect IRQs via qdev after instantiating. Suggested by Alex.
 * Add a rebased PCI-to-ISA-bridge from the 40P series on top, to show why
  some suggestions from v2 and IRC don't work out.
  * Merge fix-up by Hervé: Add indirection for late-connected out[0] IRQ.
  * Add VMState for i82374 and i82378.
  * From i82378 drop the I/O address translation duplicated from the board.
  * Rebase i82378 onto Memory API.
  http://patchwork.ozlabs.org/patch/100250/
  http://patchwork.ozlabs.org/patch/100272/
 * Add new patch from Hervé to wire up the PCI-to-ISA bridge for 'prep'.
 
 Changes since v1:
 * Use the new .vendor_id etc. in PCIDeviceInfo
 * Rename from PRePPCI to Raven, adopt naming scheme from i440FX
 * Rebase onto multiple Memory API conversions
 * Split into PCIDevice and SysBus patches, leave out PREPPCIState changes
 http://patchwork.ozlabs.org/patch/100268/
 
 Cc: Hervé Poussineau hpous...@reactos.org
 Cc: Anthony Liguori aligu...@us.ibm.com
 Cc: Alexander Graf ag...@suse.de
 
 Andreas Färber (8):
  prep: qdev'ify Raven host bridge (PCIDevice)
  prep_pci: Simplify I/O endianness
  prep_pci: Update I/O to MemoryRegion ops
  prep: qdev'ify Raven host bridge (SysBus)
  MAINTAINERS: Add PCI host bridge files to PReP machine
  prep: Add i82374 DMA emulation
  prep: Add i82378 PCI-to-ISA bridge emulation
  prep: Use i82378 PCI-ISA bridge for 'prep' machine
 
 MAINTAINERS |1 +
 Makefile.objs   |2 +
 default-configs/ppc-softmmu.mak |3 +
 hw/i82374.c |  154 
 hw/i82378.c |  252 +++
 hw/pci_ids.h|1 +
 hw/ppc_prep.c   |   77 +---
 hw/prep_pci.c   |  181 +---
 hw/prep_pci.h   |   11 --
 9 files changed, 553 insertions(+), 129 deletions(-)
 create mode 100644 hw/i82374.c
 create mode 100644 hw/i82378.c
 delete mode 100644 hw/prep_pci.h
 
 -- 
 1.7.7
 




[Qemu-devel] [PATCH 05/17] usb: add audio device model

2012-01-13 Thread Gerd Hoffmann
From: H. Peter Anvin h...@linux.intel.com

This brings a usb audio device to qemu.  Output only, fixed at
16bit stereo @ 48 Hz.  Based on a patch from
H. Peter Anvin h...@linux.intel.com

Usage: add '-device usb-audio' to your qemu command line.

Works sorta ok on a idle machine.  Known issues:

 * Is *very* sensitive to latencies.
 * Burns quite some CPU due to usb polling.

In short:  It brings the qemu usb emulation to its limits.  Enjoy!

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile.objs  |2 +-
 hw/usb-audio.c |  704 
 hw/usb-net.c   |3 -
 hw/usb.h   |7 +
 4 files changed, 712 insertions(+), 4 deletions(-)
 create mode 100644 hw/usb-audio.c

diff --git a/Makefile.objs b/Makefile.objs
index 4f6d26c..8956cb9 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -102,7 +102,7 @@ common-obj-y += scsi-disk.o cdrom.o
 common-obj-y += scsi-generic.o scsi-bus.o
 common-obj-y += hid.o
 common-obj-y += usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o 
usb-wacom.o
-common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o
+common-obj-y += usb-serial.o usb-net.o usb-bus.o usb-desc.o usb-audio.o
 common-obj-$(CONFIG_SSI) += ssi.o
 common-obj-$(CONFIG_SSI_SD) += ssi-sd.o
 common-obj-$(CONFIG_SD) += sd.o
diff --git a/hw/usb-audio.c b/hw/usb-audio.c
new file mode 100644
index 000..b22d578
--- /dev/null
+++ b/hw/usb-audio.c
@@ -0,0 +1,704 @@
+/*
+ * QEMU USB audio device
+ *
+ * written by:
+ *  H. Peter Anvin h...@linux.intel.com
+ *  Gerd Hoffmann kra...@redhat.com
+ *
+ * lousely based on usb net device code which is:
+ *
+ * Copyright (c) 2006 Thomas Sailer
+ * Copyright (c) 2008 Andrzej Zaborowski
+ *
+ * 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 usb.h
+#include usb-desc.h
+#include hw.h
+#include audiodev.h
+#include audio/audio.h
+
+#define USBAUDIO_VENDOR_NUM 0x46f4 /* CRC16() of QEMU */
+#define USBAUDIO_PRODUCT_NUM0x0002
+
+#define DEV_CONFIG_VALUE1 /* The one and only */
+
+/* Descriptor subtypes for AC interfaces */
+#define DST_AC_HEADER   1
+#define DST_AC_INPUT_TERMINAL   2
+#define DST_AC_OUTPUT_TERMINAL  3
+#define DST_AC_FEATURE_UNIT 6
+/* Descriptor subtypes for AS interfaces */
+#define DST_AS_GENERAL  1
+#define DST_AS_FORMAT_TYPE  2
+/* Descriptor subtypes for endpoints */
+#define DST_EP_GENERAL  1
+
+enum usb_audio_strings {
+STRING_NULL,
+STRING_MANUFACTURER,
+STRING_PRODUCT,
+STRING_SERIALNUMBER,
+STRING_CONFIG,
+STRING_USBAUDIO_CONTROL,
+STRING_INPUT_TERMINAL,
+STRING_FEATURE_UNIT,
+STRING_OUTPUT_TERMINAL,
+STRING_NULL_STREAM,
+STRING_REAL_STREAM,
+};
+
+static const USBDescStrings usb_audio_stringtable = {
+[STRING_MANUFACTURER]   = QEMU,
+[STRING_PRODUCT]= QEMU USB Audio,
+[STRING_SERIALNUMBER]   = 1,
+[STRING_CONFIG] = Audio Configuration,
+[STRING_USBAUDIO_CONTROL]   = Audio Device,
+[STRING_INPUT_TERMINAL] = Audio Output Pipe,
+[STRING_FEATURE_UNIT]   = Audio Output Volume Control,
+[STRING_OUTPUT_TERMINAL]= Audio Output Terminal,
+[STRING_NULL_STREAM]= Audio Output - Disabled,
+[STRING_REAL_STREAM]= Audio Output - 48 kHz Stereo,
+};
+
+#define U16(x) ((x)  0xff), (((x)  8)  0xff)
+#define U24(x) U16(x), (((x)  16)  0xff)
+#define U32(x) U24(x), (((x)  24)  0xff)
+
+/*
+ * A Basic Audio Device uses these specific values
+ */
+#define USBAUDIO_PACKET_SIZE 192
+#define USBAUDIO_SAMPLE_RATE 48000
+#define USBAUDIO_PACKET_INTERVAL 1
+
+static const USBDescIface desc_iface[] = {
+{
+.bInterfaceNumber  = 0,
+.bNumEndpoints = 0,
+.bInterfaceClass   = USB_CLASS_AUDIO,
+.bInterfaceSubClass= USB_SUBCLASS_AUDIO_CONTROL,
+.bInterfaceProtocol  

Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Paolo Bonzini

On 01/13/2012 12:04 PM, Andreas Färber wrote:

  This board never worked with TCG.  It hasn't been updated since 0.13.0.  I'm
  fairly sure hardware doesn't exist anymore that you can run the KVM support
  with.


  It does exist, I have one:-)

Alex has already posted series to not only qdev'ify it but to also add
TCG support so other people can test it. Review and testing would
probably be appreciated.:)


The work that you guys are putting in modernizing the PPC boards is 
really cool.  Please, let's start working on the 1.1 changelog now so 
that it doesn't get lost!


Paolo



Re: [Qemu-devel] [PATCH] do not chdir(/) in qemu-nbd

2012-01-13 Thread Stefan Hajnoczi
On Fri, Jan 13, 2012 at 9:04 AM, Michael Tokarev m...@tls.msk.ru wrote:
 When qemu-nbd becomes a daemon it calls daemon(3) with
 nochdir=0, so daemon(3) changes current directory to /.
 But at this time, qemu-nbd did not open any user-specified
 files yet, so by changing current directory, all non-absolute
 paths becomes wrong.  The solution is to pass nochdir=1 to
 daemon(3) function.

It's polite to chdir(/) so that file systems can be unmounted (even
more important when chroot was involved, but I think qemu-nbd doesn't
do that).  Is it possible to manually do a chdir(/) later on after
we've opened necessary files?

Stefan



Re: [Qemu-devel] [PATCH 0/3] acpi_piix4: Add CPU eject handling

2012-01-13 Thread Jan Kiszka
On 2012-01-13 12:11, Vasilis Liaskovitis wrote:
 This patch series adds support for CPU _EJ0 callback in Seabios and qemu-kvm.
 The first patch defines the CPU eject bitmap in Seabios and writes to it
 during the callback. The second patch adds empty stub functions to qemu-kvm to
 handle the bitmap writes.

Please work against upstream (uq/master for kvm-related patches), not
qemu-kvm. It possibly makes no technical difference here, but we do not
want to let the code bases needlessly diverge again. If if does make a
difference and upstream lacks further bits, push them first.

Thanks,
Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



Re: [Qemu-devel] [PATCH 3/3] acpi_piix4: Call KVM_SETSTATE_VCPU ioctl on cpu ejection

2012-01-13 Thread Jan Kiszka
On 2012-01-13 12:11, Vasilis Liaskovitis wrote:
 Signed-off-by: Vasilis Liaskovitis vasilis.liaskovi...@profitbricks.com
 ---
  hw/acpi_piix4.c |   21 +
  1 files changed, 21 insertions(+), 0 deletions(-)
 
 diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
 index 8bf30dd..12eef55 100644
 --- a/hw/acpi_piix4.c
 +++ b/hw/acpi_piix4.c
 @@ -502,6 +502,27 @@ static uint32_t cpuej_read(void *opaque, uint32_t addr)
  
  static void cpuej_write(void *opaque, uint32_t addr, uint32_t val)
  {
 +struct kvm_vcpu_state state;
 +CPUState *env;
 +int cpu;
 +int ret;
 +
 +cpu = ffs(val);
 +/* zero means no bit was set, i.e. no CPU ejection happened */
 +if (!cpu)
 +   return;
 +cpu--;
 +env = cpu_phyid_to_cpu((uint64_t)cpu);
 +if (env != NULL) {
 +if (env-state == CPU_STATE_ZAPREQ) {
 +state.vcpu_id = env-cpu_index;
 +state.state = 1;
 +ret = kvm_vm_ioctl(env-kvm_state, KVM_SETSTATE_VCPU, state);

That breaks in the absence of KVM or if it is not enabled.

Also, where was this IOCTL introduced? Where are the linux header changes?

 +if (ret)
 +fprintf(stderr, KVM_SETSTATE_VCPU failed: %s\n,
 +strerror(ret));
 +}
 +}
  PIIX4_DPRINTF(cpuej write %x == %d\n, addr, val);
  }
  

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



[Qemu-devel] [PATCH 15/17] usb-redir: Pre-fill our isoc input buffer before sending pkts to the host

2012-01-13 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

This is something which should have been done from the first version of
usb-redir, but wasn't.

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-redir.c |   16 
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/usb-redir.c b/usb-redir.c
index 99a12d5..cdd929a 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -60,7 +60,9 @@ struct endp_data {
 uint8_t iso_error; /* For reporting iso errors to the HC */
 uint8_t interrupt_started;
 uint8_t interrupt_error;
+uint8_t bufpq_prefilled;
 QTAILQ_HEAD(, buf_packet) bufpq;
+int bufpq_size;
 int bufpq_target_size;
 };
 
@@ -296,6 +298,7 @@ static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
 bufp-len= len;
 bufp-status = status;
 QTAILQ_INSERT_TAIL(dev-endpoint[EP2I(ep)].bufpq, bufp, next);
+dev-endpoint[EP2I(ep)].bufpq_size++;
 return bufp;
 }
 
@@ -303,6 +306,7 @@ static void bufp_free(USBRedirDevice *dev, struct 
buf_packet *bufp,
 uint8_t ep)
 {
 QTAILQ_REMOVE(dev-endpoint[EP2I(ep)].bufpq, bufp, next);
+dev-endpoint[EP2I(ep)].bufpq_size--;
 free(bufp-data);
 g_free(bufp);
 }
@@ -374,14 +378,26 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 usbredirparser_do_write(dev-parser);
 DPRINTF(iso stream started ep %02X\n, ep);
 dev-endpoint[EP2I(ep)].iso_started = 1;
+dev-endpoint[EP2I(ep)].bufpq_prefilled = 0;
 }
 
 if (ep  USB_DIR_IN) {
 struct buf_packet *isop;
 
+if (dev-endpoint[EP2I(ep)].iso_started 
+!dev-endpoint[EP2I(ep)].bufpq_prefilled) {
+if (dev-endpoint[EP2I(ep)].bufpq_size 
+dev-endpoint[EP2I(ep)].bufpq_target_size) {
+return usbredir_handle_status(dev, 0, 0);
+}
+dev-endpoint[EP2I(ep)].bufpq_prefilled = 1;
+}
+
 isop = QTAILQ_FIRST(dev-endpoint[EP2I(ep)].bufpq);
 if (isop == NULL) {
 DPRINTF2(iso-token-in ep %02X, no isop\n, ep);
+/* Re-fill the buffer */
+dev-endpoint[EP2I(ep)].bufpq_prefilled = 0;
 /* Check iso_error for stream errors, otherwise its an underrun */
 status = dev-endpoint[EP2I(ep)].iso_error;
 dev-endpoint[EP2I(ep)].iso_error = 0;
-- 
1.7.1




[Qemu-devel] [PATCH 13/17] usb-redir: Clear iso / irq error when stopping the stream

2012-01-13 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

And ignore status messages from the client which arrive after stream
stop (the stream stop send to the client and an error status reported by
the client my cross each other due to network latency).

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-redir.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/usb-redir.c b/usb-redir.c
index 2b53cf3..81a35c6 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -410,6 +410,7 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, 
uint8_t ep)
 DPRINTF(iso stream stopped ep %02X\n, ep);
 dev-endpoint[EP2I(ep)].iso_started = 0;
 }
+dev-endpoint[EP2I(ep)].iso_error = 0;
 usbredir_free_bufpq(dev, ep);
 }
 
@@ -522,6 +523,7 @@ static void 
usbredir_stop_interrupt_receiving(USBRedirDevice *dev,
 DPRINTF(interrupt recv stopped ep %02X\n, ep);
 dev-endpoint[EP2I(ep)].interrupt_started = 0;
 }
+dev-endpoint[EP2I(ep)].interrupt_error = 0;
 usbredir_free_bufpq(dev, ep);
 }
 
@@ -1029,7 +1031,7 @@ static void usbredir_iso_stream_status(void *priv, 
uint32_t id,
 DPRINTF(iso status %d ep %02X id %u\n, iso_stream_status-status,
 ep, id);
 
-if (!dev-dev.attached) {
+if (!dev-dev.attached || !dev-endpoint[EP2I(ep)].iso_started) {
 return;
 }
 
@@ -1050,7 +1052,7 @@ static void usbredir_interrupt_receiving_status(void 
*priv, uint32_t id,
 DPRINTF(interrupt recv status %d ep %02X id %u\n,
 interrupt_receiving_status-status, ep, id);
 
-if (!dev-dev.attached) {
+if (!dev-dev.attached || !dev-endpoint[EP2I(ep)].interrupt_started) {
 return;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH 01/17] usb-host: rip out legacy procfs support

2012-01-13 Thread Gerd Hoffmann
This patch removes support for parsing /proc/bus/usb/devices for device
discovery.  The code lacks a few features compared to the sysfs code and
is also bitrotting as everybody has sysfs these days.

This implies having sysfs mounted is mandatory now to use the usb-host
driver.  udev isn't required though.  qemu will prefer the udev-managed
device nodes below /dev/bus/usb, but in case this directory isn't preset
qemu will use the device nodes below /proc/bus/usb (default usbfs mount
point).

Bottom line: make sure you have both sysfs and usbfs mounted properly,
and everything should continue to work as it did before.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-linux.c |  327 ---
 1 files changed, 42 insertions(+), 285 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index 749ce71..c68e194 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -66,23 +66,9 @@ typedef int USBScanFunc(void *opaque, int bus_num, int addr, 
const char *port,
 #define DPRINTF(...)
 #endif
 
-#define USBDBG_DEVOPENED husb: opened %s/devices\n
-
-#define USBPROCBUS_PATH /proc/bus/usb
 #define PRODUCT_NAME_SZ 32
 #define MAX_ENDPOINTS 15
 #define MAX_PORTLEN 16
-#define USBDEVBUS_PATH /dev/bus/usb
-#define USBSYSBUS_PATH /sys/bus/usb
-
-static char *usb_host_device_path;
-
-#define USB_FS_NONE 0
-#define USB_FS_PROC 1
-#define USB_FS_DEV 2
-#define USB_FS_SYS 3
-
-static int usb_fs_type;
 
 /* endpoint association data */
 #define ISO_FRAME_DESC_PER_URB 32
@@ -431,6 +417,31 @@ static void usb_host_async_cancel(USBDevice *dev, 
USBPacket *p)
 }
 }
 
+static int usb_host_open_device(int bus, int addr)
+{
+const char *usbfs = NULL;
+char filename[32];
+struct stat st;
+int fd, rc;
+
+rc = stat(/dev/bus/usb, st);
+if (rc == 0  S_ISDIR(st.st_mode)) {
+/* udev-created device nodes available */
+usbfs = /dev/bus/usb;
+} else {
+/* fallback: usbfs mounted below /proc */
+usbfs = /proc/bus/usb;
+}
+
+snprintf(filename, sizeof(filename), %s/%03d/%03d,
+ usbfs, bus, addr);
+fd = open(filename, O_RDWR | O_NONBLOCK);
+if (fd  0) {
+fprintf(stderr, husb: open %s: %s\n, filename, strerror(errno));
+}
+return fd;
+}
+
 static int usb_host_claim_port(USBHostDevice *s)
 {
 #ifdef USBDEVFS_CLAIM_PORT
@@ -460,12 +471,7 @@ static int usb_host_claim_port(USBHostDevice *s)
 return -1;
 }
 
-if (!usb_host_device_path) {
-return -1;
-}
-snprintf(line, sizeof(line), %s/%03d/%03d,
- usb_host_device_path, s-match.bus_num, hub_addr);
-s-hub_fd = open(line, O_RDWR | O_NONBLOCK);
+s-hub_fd = usb_host_open_device(s-match.bus_num, hub_addr);
 if (s-hub_fd  0) {
 return -1;
 }
@@ -522,10 +528,6 @@ static int usb_linux_get_num_interfaces(USBHostDevice *s)
 char device_name[64], line[1024];
 int num_interfaces = 0;
 
-if (usb_fs_type != USB_FS_SYS) {
-return -1;
-}
-
 sprintf(device_name, %d-%s, s-bus_num, s-port);
 if (!usb_host_read_file(line, sizeof(line), bNumInterfaces,
 device_name)) {
@@ -1090,41 +1092,21 @@ static int usb_host_handle_control(USBDevice *dev, 
USBPacket *p,
 static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,
 uint8_t configuration, uint8_t interface)
 {
-uint8_t alt_setting;
-struct usb_ctrltransfer ct;
-int ret;
-
-if (usb_fs_type == USB_FS_SYS) {
-char device_name[64], line[1024];
-int alt_setting;
+char device_name[64], line[1024];
+int alt_setting;
 
-sprintf(device_name, %d-%s:%d.%d, s-bus_num, s-port,
-(int)configuration, (int)interface);
+sprintf(device_name, %d-%s:%d.%d, s-bus_num, s-port,
+(int)configuration, (int)interface);
 
-if (!usb_host_read_file(line, sizeof(line), bAlternateSetting,
-device_name)) {
-goto usbdevfs;
-}
-if (sscanf(line, %d, alt_setting) != 1) {
-goto usbdevfs;
-}
-return alt_setting;
-}
-
-usbdevfs:
-ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
-ct.bRequest = USB_REQ_GET_INTERFACE;
-ct.wValue = 0;
-ct.wIndex = interface;
-ct.wLength = 1;
-ct.data = alt_setting;
-ct.timeout = 50;
-ret = ioctl(s-fd, USBDEVFS_CONTROL, ct);
-if (ret  0) {
+if (!usb_host_read_file(line, sizeof(line), bAlternateSetting,
+device_name)) {
+/* Assume alt 0 on error */
+return 0;
+}
+if (sscanf(line, %d, alt_setting) != 1) {
 /* Assume alt 0 on error */
 return 0;
 }
-
 return alt_setting;
 }
 
@@ -1273,7 +1255,6 @@ static int usb_host_open(USBHostDevice *dev, int bus_num,
  const char *prod_name, int speed)
 {
 int fd = -1, ret;
-char buf[1024];
 
 trace_usb_host_open_started(bus_num, addr);
 
@@ 

[Qemu-devel] [PATCH 04/17] usb-desc: audio endpoint support

2012-01-13 Thread Gerd Hoffmann
Add support for audio endpoints which have two more fields in the
descriptor.  Also add support for extra class specific endpoint
descriptors.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-desc.c |   14 +++---
 hw/usb-desc.h |5 +
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index b9996a1..9c38661 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -192,9 +192,10 @@ int usb_desc_iface(const USBDescIface *iface, uint8_t 
*dest, size_t len)
 
 int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len)
 {
-uint8_t bLength = 0x07;
+uint8_t bLength = ep-is_audio ? 0x09 : 0x07;
+uint8_t extralen = ep-extra ? ep-extra[0] : 0;
 
-if (len  bLength) {
+if (len  bLength + extralen) {
 return -1;
 }
 
@@ -205,8 +206,15 @@ int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t 
*dest, size_t len)
 dest[0x04] = usb_lo(ep-wMaxPacketSize);
 dest[0x05] = usb_hi(ep-wMaxPacketSize);
 dest[0x06] = ep-bInterval;
+if (ep-is_audio) {
+dest[0x07] = ep-bRefresh;
+dest[0x08] = ep-bSynchAddress;
+}
+if (ep-extra) {
+memcpy(dest + bLength, ep-extra, extralen);
+}
 
-return bLength;
+return bLength + extralen;
 }
 
 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len)
diff --git a/hw/usb-desc.h b/hw/usb-desc.h
index 5c14e4a..d6e07ea 100644
--- a/hw/usb-desc.h
+++ b/hw/usb-desc.h
@@ -71,6 +71,11 @@ struct USBDescEndpoint {
 uint8_t   bmAttributes;
 uint16_t  wMaxPacketSize;
 uint8_t   bInterval;
+uint8_t   bRefresh;
+uint8_t   bSynchAddress;
+
+uint8_t   is_audio; /* has bRefresh + bSynchAddress */
+uint8_t   *extra;
 };
 
 struct USBDescOther {
-- 
1.7.1




[Qemu-devel] [PATCH 10/17] usb/debug: add usb_ep_dump

2012-01-13 Thread Gerd Hoffmann
Add function to dump endpoint data, for debugging purposes.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb.c|   40 
 hw/usb.h|1 +
 usb-linux.c |3 +++
 3 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/hw/usb.c b/hw/usb.c
index 6ba063a..f07cb9d 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -427,6 +427,46 @@ void usb_ep_init(USBDevice *dev)
 }
 }
 
+void usb_ep_dump(USBDevice *dev)
+{
+static const char *tname[] = {
+[USB_ENDPOINT_XFER_CONTROL] = control,
+[USB_ENDPOINT_XFER_ISOC]= isoc,
+[USB_ENDPOINT_XFER_BULK]= bulk,
+[USB_ENDPOINT_XFER_INT] = int,
+};
+int ifnum, ep, first;
+
+fprintf(stderr, Device \%s\, config %d\n,
+dev-product_desc, dev-configuration);
+for (ifnum = 0; ifnum  16; ifnum++) {
+first = 1;
+for (ep = 0; ep  USB_MAX_ENDPOINTS; ep++) {
+if (dev-ep_in[ep].type != USB_ENDPOINT_XFER_INVALID 
+dev-ep_in[ep].ifnum == ifnum) {
+if (first) {
+first = 0;
+fprintf(stderr,   Interface %d, alternative %d\n,
+ifnum, dev-altsetting[ifnum]);
+}
+fprintf(stderr, Endpoint %d, IN, %s\n, ep,
+tname[dev-ep_in[ep].type]);
+}
+if (dev-ep_out[ep].type != USB_ENDPOINT_XFER_INVALID 
+dev-ep_out[ep].ifnum == ifnum) {
+if (first) {
+first = 0;
+fprintf(stderr,   Interface %d, alternative %d\n,
+ifnum, dev-altsetting[ifnum]);
+}
+fprintf(stderr, Endpoint %d, OUT, %s\n, ep,
+tname[dev-ep_out[ep].type]);
+}
+}
+}
+fprintf(stderr, --\n);
+}
+
 struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
 {
 struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev-ep_in : dev-ep_out;
diff --git a/hw/usb.h b/hw/usb.h
index 60e8858..c35ff74 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -333,6 +333,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p);
 void usb_cancel_packet(USBPacket * p);
 
 void usb_ep_init(USBDevice *dev);
+void usb_ep_dump(USBDevice *dev);
 struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
 uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
 uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
diff --git a/usb-linux.c b/usb-linux.c
index cb66ef3..2a7b748 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1214,6 +1214,9 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
 i += descriptors[i];
 }
 }
+#ifdef DEBUG
+usb_ep_dump(s-dev);
+#endif
 return 0;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH 08/17] usb: add ifnum to USBEndpoint

2012-01-13 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb.c|   14 ++
 hw/usb.h|3 +++
 usb-linux.c |1 +
 3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/usb.c b/hw/usb.c
index 5d6baaf..6ba063a 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -422,6 +422,8 @@ void usb_ep_init(USBDevice *dev)
 for (ep = 0; ep  USB_MAX_ENDPOINTS; ep++) {
 dev-ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
 dev-ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
+dev-ep_in[ep].ifnum = 0;
+dev-ep_out[ep].ifnum = 0;
 }
 }
 
@@ -444,3 +446,15 @@ void usb_ep_set_type(USBDevice *dev, int pid, int ep, 
uint8_t type)
 struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
 uep-type = type;
 }
+
+uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+return uep-ifnum;
+}
+
+void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+uep-ifnum = ifnum;
+}
diff --git a/hw/usb.h b/hw/usb.h
index 85cbe71..60e8858 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -175,6 +175,7 @@ struct USBDescString {
 
 struct USBEndpoint {
 uint8_t type;
+uint8_t ifnum;
 };
 
 /* definition of a USB device */
@@ -334,7 +335,9 @@ void usb_cancel_packet(USBPacket * p);
 void usb_ep_init(USBDevice *dev);
 struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
 uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
+uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
 void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
+void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
 
 void usb_attach(USBPort *port);
 void usb_detach(USBPort *port);
diff --git a/usb-linux.c b/usb-linux.c
index 9967975..cb66ef3 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1206,6 +1206,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
 assert(usb_ep_get_type(s-dev, pid, ep) ==
USB_ENDPOINT_XFER_INVALID);
 usb_ep_set_type(s-dev, pid, ep, type);
+usb_ep_set_ifnum(s-dev, pid, ep, interface);
 
 epd = get_endp(s, pid, ep);
 epd-halted = 0;
-- 
1.7.1




[Qemu-devel] [PATCH 03/17] usb: track altsetting in USBDevice

2012-01-13 Thread Gerd Hoffmann
Also handle {GET,SET}_INTERFACE in common code (usb-desc.c).

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-bt.c |   22 -
 hw/usb-ccid.c   |8 --
 hw/usb-desc.c   |   71 +++
 hw/usb-hid.c|7 -
 hw/usb-hub.c|7 -
 hw/usb-msd.c|   10 ---
 hw/usb-net.c|   11 
 hw/usb-serial.c |7 -
 hw/usb-wacom.c  |7 -
 hw/usb.h|8 ++
 trace-events|1 +
 usb-linux.c |   10 +++
 12 files changed, 90 insertions(+), 79 deletions(-)

diff --git a/hw/usb-bt.c b/hw/usb-bt.c
index f30eec1..0c1270b 100644
--- a/hw/usb-bt.c
+++ b/hw/usb-bt.c
@@ -28,7 +28,6 @@ struct USBBtState {
 USBDevice dev;
 struct HCIInfo *hci;
 
-int altsetting;
 int config;
 
 #define CFIFO_LEN_MASK 255
@@ -362,7 +361,6 @@ static void usb_bt_handle_reset(USBDevice *dev)
 s-outcmd.len = 0;
 s-outacl.len = 0;
 s-outsco.len = 0;
-s-altsetting = 0;
 }
 
 static int usb_bt_handle_control(USBDevice *dev, USBPacket *p,
@@ -402,26 +400,6 @@ static int usb_bt_handle_control(USBDevice *dev, USBPacket 
*p,
 case EndpointOutRequest | USB_REQ_SET_FEATURE:
 goto fail;
 break;
-case InterfaceRequest | USB_REQ_GET_INTERFACE:
-if (value != 0 || (index  ~1) || length != 1)
-goto fail;
-if (index == 1)
-data[0] = s-altsetting;
-else
-data[0] = 0;
-ret = 1;
-break;
-case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
-if ((index  ~1) || length != 0 ||
-(index == 1  (value  0 || value  4)) ||
-(index == 0  value != 0)) {
-printf(%s: Wrong SET_INTERFACE request (%i, %i)\n,
-__FUNCTION__, index, value);
-goto fail;
-}
-s-altsetting = value;
-ret = 0;
-break;
 case ((USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_DEVICE)  8):
 if (s-config)
 usb_bt_fifo_out_enqueue(s, s-outcmd, s-hci-cmd_send,
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index cd349f3..e9935ad 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -611,14 +611,6 @@ static int ccid_handle_control(USBDevice *dev, USBPacket 
*p, int request,
 }
 
 switch (request) {
-case DeviceRequest | USB_REQ_GET_INTERFACE:
-data[0] = 0;
-ret = 1;
-break;
-case InterfaceOutRequest | USB_REQ_SET_INTERFACE:
-ret = 0;
-break;
-
 /* Class specific requests.  */
 case InterfaceOutClass | CCID_CONTROL_ABORT:
 DPRINTF(s, 1, ccid_control abort UNIMPLEMENTED\n);
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index b52561a..b9996a1 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -223,6 +223,54 @@ int usb_desc_other(const USBDescOther *desc, uint8_t 
*dest, size_t len)
 
 /* -- */
 
+static const USBDescIface *usb_desc_find_interface(USBDevice *dev,
+   int nif, int alt)
+{
+const USBDescIface *iface;
+int g, i;
+
+if (!dev-config) {
+return NULL;
+}
+for (g = 0; g  dev-config-nif_groups; g++) {
+for (i = 0; i  dev-config-if_groups[g].nif; i++) {
+iface = dev-config-if_groups[g].ifs[i];
+if (iface-bInterfaceNumber == nif 
+iface-bAlternateSetting == alt) {
+return iface;
+}
+}
+}
+for (i = 0; i  dev-config-nif; i++) {
+iface = dev-config-ifs[i];
+if (iface-bInterfaceNumber == nif 
+iface-bAlternateSetting == alt) {
+return iface;
+}
+}
+return NULL;
+}
+
+static int usb_desc_set_interface(USBDevice *dev, int index, int value)
+{
+const USBDescIface *iface;
+int old;
+
+iface = usb_desc_find_interface(dev, index, value);
+if (iface == NULL) {
+return -1;
+}
+
+old = dev-altsetting[index];
+dev-altsetting[index] = value;
+dev-ifaces[index] = iface;
+
+if (dev-info-set_interface  old != value) {
+dev-info-set_interface(dev, index, old, value);
+}
+return 0;
+}
+
 static int usb_desc_set_config(USBDevice *dev, int value)
 {
 int i;
@@ -237,12 +285,22 @@ static int usb_desc_set_config(USBDevice *dev, int value)
 dev-configuration = value;
 dev-ninterfaces   = dev-device-confs[i].bNumInterfaces;
 dev-config = dev-device-confs + i;
+assert(dev-ninterfaces = USB_MAX_INTERFACES);
 }
 }
 if (i  dev-device-bNumConfigurations) {
 return -1;
 }
 }
+
+for (i = 0; i  dev-ninterfaces; i++) {
+usb_desc_set_interface(dev, i, 0);
+}
+for (; i  USB_MAX_INTERFACES; i++) {
+dev-altsetting[i] = 0;
+dev-ifaces[i] = NULL;
+}
+
 return 0;
 

[Qemu-devel] [PATCH 09/17] usb-desc: USBEndpoint support

2012-01-13 Thread Gerd Hoffmann
Initialize USBEndpoint structs from USBDesc* data.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-desc.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 9c38661..0768334 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -231,6 +231,27 @@ int usb_desc_other(const USBDescOther *desc, uint8_t 
*dest, size_t len)
 
 /* -- */
 
+static void usb_desc_ep_init(USBDevice *dev)
+{
+const USBDescIface *iface;
+int i, e, pid, ep;
+
+usb_ep_init(dev);
+for (i = 0; i  dev-ninterfaces; i++) {
+iface = dev-ifaces[i];
+if (iface == NULL) {
+continue;
+}
+for (e = 0; e  iface-bNumEndpoints; e++) {
+pid = (iface-eps[e].bEndpointAddress  USB_DIR_IN) ?
+USB_TOKEN_IN : USB_TOKEN_OUT;
+ep = iface-eps[e].bEndpointAddress  0x0f;
+usb_ep_set_type(dev, pid, ep, iface-eps[e].bmAttributes  0x03);
+usb_ep_set_ifnum(dev, pid, ep, iface-bInterfaceNumber);
+}
+}
+}
+
 static const USBDescIface *usb_desc_find_interface(USBDevice *dev,
int nif, int alt)
 {
@@ -272,6 +293,7 @@ static int usb_desc_set_interface(USBDevice *dev, int 
index, int value)
 old = dev-altsetting[index];
 dev-altsetting[index] = value;
 dev-ifaces[index] = iface;
+usb_desc_ep_init(dev);
 
 if (dev-info-set_interface  old != value) {
 dev-info-set_interface(dev, index, old, value);
-- 
1.7.1




Re: [Qemu-devel] [PATCH v9 0/6] arm: add support for Calxeda Highbank SoC

2012-01-13 Thread Peter Maydell
On 11 January 2012 22:41, Peter Maydell peter.mayd...@linaro.org wrote:
 On 11 January 2012 16:31, Mark Langsdorf mark.langsd...@calxeda.com wrote:
 This patch series adds support for the Calxeda Highbank SoC.
 It depends on my previous patch series various ARM fixes for
 Calxeda Highbank and ahci: convert ahci_reset to use AHCIState.
 Some of the patches are carried over from Various ARM fixes
 for Calxeda Highbank and were reviewed but not accepted in
 that series.

 So, are there in fact any patches from the various ARM fixes for
 Calxeda Highbank series which this series depends on and which
 haven't been committed to master? It looks to me as if all the
 patches from that series either (a) were put into this one or
 (b) were committed, but did I miss anything?

Mark: ping? I'm just waiting for an answer to this and also to
the question about the secondary boot protocol (see my email
replying to patch 5/5) before I take these into arm-devs.next...

 Does anybody object to my taking the AHCI patches along with this
 series via arm-devs.next ? (other than patch v4 which goes via
 target-arm.next)

[I got an Acked-by: from Kevin over irc regarding these and will do this.]

-- PMM



Re: [Qemu-devel] [PATCH v2] qemu-ga: add guest-set-support-level command

2012-01-13 Thread Luiz Capitulino
On Thu, 12 Jan 2012 17:32:32 -0600
Michael Roth mdr...@linux.vnet.ibm.com wrote:

 On 01/12/2012 12:57 PM, Luiz Capitulino wrote:
  On Wed, 11 Jan 2012 17:56:05 -0600
  Michael Rothmdr...@linux.vnet.ibm.com  wrote:
 
  Recently commands where introduced on the mailing that involved adding
  commands to the guest agent that could potentially break older versions
  of QEMU. While it's okay to expect that qemu-ga can be updated to support
  newer host features, it's unrealistic to require a host to be updated to
  support qemu-ga features, or to expect that qemu-ga should be downgraded
  in these circumstances, especially considering that a large mix of
  guests/agents may be running on a particular host.
 
  To address this, we introduce here a mechanism to set qemu-ga's
  feature-set to one that is known to be compatible with
  the host/QEMU running the guest. As new commands/options are added, we
  can maintain backward-compatibility by adding conditional checks to filter
  out host-incompatible functionality based on the host-specified support
  level (generally analogous to the host QEMU version) set by the
  client.
 
  The current default/minimum support level supports all versions of QEMU
  that have had qemu-ga in-tree (0.15.0, 1.0.0) and so should be
  backward-compatible with existing hosts/clients.
 
  The approach looks fine to me. I have a few review comments below.
 
 
  Signed-off-by: Michael Rothmdr...@linux.vnet.ibm.com
  ---
qapi-schema-guest.json |   31 -
qemu-ga.c  |   46 
  
qga/guest-agent-commands.c |   13 
qga/guest-agent-core.h |   11 ++
4 files changed, 100 insertions(+), 1 deletions(-)
 
  diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
  index 5f8a18d..32bc041 100644
  --- a/qapi-schema-guest.json
  +++ b/qapi-schema-guest.json
  @@ -43,15 +43,44 @@
#
# Since: 0.15.0
##
  +{ 'type': 'GuestAgentSupportLevel',
  +  'data': { 'major': 'int', 'minor': 'int', 'micro': 'int' } }
 
  This and GuestAgentCommandInfo are missing good documentation. Looks like
  we don't document types as we do in qapi-schema.json. I think we should.
 
 
 Agreed, I'll precede this with a patch to add the documentation for 
 existing types, and update this patch accordingly.
 
{ 'type': 'GuestAgentCommandInfo',
  'data': { 'name': 'str', 'enabled': 'bool' } }
{ 'type': 'GuestAgentInfo',
  'data': { 'version': 'str',
  -'supported_commands': ['GuestAgentCommandInfo'] } }
  +'supported_commands': ['GuestAgentCommandInfo']
  +'support_level': 'GuestAgentSupportLevel' } }
{ 'command': 'guest-info',
  'returns': 'GuestAgentInfo' }
 
  For example, something important that's is not totally clear to me just by
  reading the command definition is if 'support_level' refers to the support
  level that can be changed by a client.
 
 
##
  +# @guest-set-support-level:
  +#
  +# Set guest agent feature-set to one that is compatible with/supported by
  +# the host.
  +#
  +# Certain commands/options may have dependencies on host
  +# version/support-level, such as specific QEMU features (such
  +# dependencies will be noted in this schema). By default we assume 1.0.0,
  +# which is backward-compatible with QEMU 0.15.0/1.0, and should be 
  compatible
  +# with later versions of QEMU as well. To enable newer guest agent 
  features,
  +# this command must be issued to raise the support-level to one 
  corresponding
  +# to supported host QEMU/KVM/etc capabilities.
  +#
  +# The currently set support level is obtainable via the guest-info 
  command.
  +#
  +# @level: Desired host support-level, generally= host QEMU version
  +# level. Note that undefined behavior may occur if a support-level is
  +# provided that exceeds the capabilities of the version of QEMU currently
  +# running the guest.
 
  It's also better to note that if @level  1.0.0 then the support level will
  be set to 1.0.0.
 
 
 I must've looked at this like 5 times and made a mental note to do that, 
 but in the end it escaped me...

Hehe, happens. There's one more issue below.

 
  +#
  +# Returns: Nothing on success
  +#
  +{ 'command': 'guest-set-support-level',
  +  'data':{ 'major': 'int', 'minor': 'int', '*micro': 'int' } }
  +
  +##
# @guest-shutdown:
#
# Initiate guest-activated shutdown. Note: this is an asynchronous
  diff --git a/qemu-ga.c b/qemu-ga.c
  index 200bb15..6840233 100644
  --- a/qemu-ga.c
  +++ b/qemu-ga.c
  @@ -28,6 +28,7 @@
#include qerror.h
#include error_int.h
#include qapi/qmp-core.h
  +#include qga-qapi-types.h
 
#define QGA_VIRTIO_PATH_DEFAULT 
  /dev/virtio-ports/org.qemu.guest_agent.0
#define QGA_PIDFILE_DEFAULT /var/run/qemu-ga.pid
  @@ -102,6 +103,45 @@ static void usage(const char *cmd)
 
static void conn_channel_close(GAState *s);
 
  +static 

Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Alexander Graf

On 13.01.2012, at 12:45, Paolo Bonzini wrote:

 On 01/13/2012 12:04 PM, Andreas Färber wrote:
   This board never worked with TCG.  It hasn't been updated since 
  0.13.0.  I'm
   fairly sure hardware doesn't exist anymore that you can run the KVM 
  support
   with.
 
   It does exist, I have one:-)
 Alex has already posted series to not only qdev'ify it but to also add
 TCG support so other people can test it. Review and testing would
 probably be appreciated.:)
 
 The work that you guys are putting in modernizing the PPC boards is really 
 cool.  Please, let's start working on the 1.1 changelog now so that it 
 doesn't get lost!

Good point :). I'm not sure how useful something like Qdev'ified board xxx 
really is in a changelog though. It's mostly invisible to users.


Alex




[Qemu-devel] [PATCH 11/17] usb: add max_packet_size to USBEndpoint

2012-01-13 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-desc.c |2 ++
 hw/usb.c  |   37 +
 hw/usb.h  |4 
 usb-linux.c   |   31 +--
 4 files changed, 44 insertions(+), 30 deletions(-)

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 0768334..b3eb97b 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -248,6 +248,8 @@ static void usb_desc_ep_init(USBDevice *dev)
 ep = iface-eps[e].bEndpointAddress  0x0f;
 usb_ep_set_type(dev, pid, ep, iface-eps[e].bmAttributes  0x03);
 usb_ep_set_ifnum(dev, pid, ep, iface-bInterfaceNumber);
+usb_ep_set_max_packet_size(dev, pid, ep,
+   iface-eps[e].wMaxPacketSize);
 }
 }
 }
diff --git a/hw/usb.c b/hw/usb.c
index f07cb9d..0f163b4 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -449,8 +449,9 @@ void usb_ep_dump(USBDevice *dev)
 fprintf(stderr,   Interface %d, alternative %d\n,
 ifnum, dev-altsetting[ifnum]);
 }
-fprintf(stderr, Endpoint %d, IN, %s\n, ep,
-tname[dev-ep_in[ep].type]);
+fprintf(stderr, Endpoint %d, IN, %s, %d max\n, ep,
+tname[dev-ep_in[ep].type],
+dev-ep_in[ep].max_packet_size);
 }
 if (dev-ep_out[ep].type != USB_ENDPOINT_XFER_INVALID 
 dev-ep_out[ep].ifnum == ifnum) {
@@ -459,8 +460,9 @@ void usb_ep_dump(USBDevice *dev)
 fprintf(stderr,   Interface %d, alternative %d\n,
 ifnum, dev-altsetting[ifnum]);
 }
-fprintf(stderr, Endpoint %d, OUT, %s\n, ep,
-tname[dev-ep_out[ep].type]);
+fprintf(stderr, Endpoint %d, OUT, %s, %d max\n, ep,
+tname[dev-ep_out[ep].type],
+dev-ep_out[ep].max_packet_size);
 }
 }
 }
@@ -498,3 +500,30 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, 
uint8_t ifnum)
 struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
 uep-ifnum = ifnum;
 }
+
+void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
+uint16_t raw)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+int size, microframes;
+
+size = raw  0x7ff;
+switch ((raw  11)  3) {
+case 1:
+microframes = 2;
+break;
+case 2:
+microframes = 3;
+break;
+default:
+microframes = 1;
+break;
+}
+uep-max_packet_size = size * microframes;
+}
+
+int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+return uep-max_packet_size;
+}
diff --git a/hw/usb.h b/hw/usb.h
index c35ff74..5ea984c 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -176,6 +176,7 @@ struct USBDescString {
 struct USBEndpoint {
 uint8_t type;
 uint8_t ifnum;
+int max_packet_size;
 };
 
 /* definition of a USB device */
@@ -339,6 +340,9 @@ uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
 uint8_t usb_ep_get_ifnum(USBDevice *dev, int pid, int ep);
 void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
 void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum);
+void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep,
+uint16_t raw);
+int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep);
 
 void usb_attach(USBPort *port);
 void usb_detach(USBPort *port);
diff --git a/usb-linux.c b/usb-linux.c
index 2a7b748..56898dd 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -83,7 +83,6 @@ struct endp_data {
 AsyncURB *iso_urb;
 int iso_urb_idx;
 int iso_buffer_used;
-int max_packet_size;
 int inflight;
 };
 
@@ -259,26 +258,6 @@ static int get_iso_buffer_used(USBHostDevice *s, int pid, 
int ep)
 return get_endp(s, pid, ep)-iso_buffer_used;
 }
 
-static void set_max_packet_size(USBHostDevice *s, int pid, int ep,
-uint8_t *descriptor)
-{
-int raw = descriptor[4] + (descriptor[5]  8);
-int size, microframes;
-
-size = raw  0x7ff;
-switch ((raw  11)  3) {
-case 1:  microframes = 2; break;
-case 2:  microframes = 3; break;
-default: microframes = 1; break;
-}
-get_endp(s, pid, ep)-max_packet_size = size * microframes;
-}
-
-static int get_max_packet_size(USBHostDevice *s, int pid, int ep)
-{
-return get_endp(s, pid, ep)-max_packet_size;
-}
-
 /*
  * Async URB state.
  * We always allocate iso packet descriptors even for bulk transfers
@@ -674,7 +653,7 @@ static void usb_host_handle_destroy(USBDevice *dev)
 static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, int pid, uint8_t ep)
 {
 AsyncURB *aurb;
-int i, j, len = get_max_packet_size(s, pid, ep);
+int i, j, len = 

[Qemu-devel] [PATCH 12/17] usb: link packets to endpoints not devices

2012-01-13 Thread Gerd Hoffmann
Add USBEndpoint for the control endpoint to USBDevices.  Link async
packets to the USBEndpoint instead of the USBDevice.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-ehci.c |3 ++-
 hw/usb-musb.c |3 ++-
 hw/usb-ohci.c |4 +++-
 hw/usb-uhci.c |3 ++-
 hw/usb.c  |   12 ++--
 hw/usb.h  |4 +++-
 6 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 7c926c0..a305661 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -715,7 +715,8 @@ static void ehci_queues_rip_device(EHCIState *ehci, 
USBDevice *dev)
 EHCIQueue *q, *tmp;
 
 QTAILQ_FOREACH_SAFE(q, ehci-queues, next, tmp) {
-if (q-packet.owner != dev) {
+if (q-packet.owner == NULL ||
+q-packet.owner-dev != dev) {
 continue;
 }
 ehci_free_queue(q);
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index 01e2e7c..4f528d2 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -812,7 +812,8 @@ static void musb_async_cancel_device(MUSBState *s, 
USBDevice *dev)
 
 for (ep = 0; ep  16; ep++) {
 for (dir = 0; dir  2; dir++) {
-if (s-ep[ep].packey[dir].p.owner != dev) {
+if (s-ep[ep].packey[dir].p.owner == NULL ||
+s-ep[ep].packey[dir].p.owner-dev != dev) {
 continue;
 }
 usb_cancel_packet(s-ep[ep].packey[dir].p);
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 81488c4..69463d2 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1707,7 +1707,9 @@ static void ohci_mem_write(void *opaque,
 
 static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev)
 {
-if (ohci-async_td  ohci-usb_packet.owner == dev) {
+if (ohci-async_td 
+ohci-usb_packet.owner != NULL 
+ohci-usb_packet.owner-dev == dev) {
 usb_cancel_packet(ohci-usb_packet);
 ohci-async_td = 0;
 }
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index f8912e2..25d4e8c 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -245,7 +245,8 @@ static void uhci_async_cancel_device(UHCIState *s, 
USBDevice *dev)
 UHCIAsync *curr, *n;
 
 QTAILQ_FOREACH_SAFE(curr, s-async_pending, next, n) {
-if (curr-packet.owner != dev) {
+if (curr-packet.owner == NULL ||
+curr-packet.owner-dev != dev) {
 continue;
 }
 uhci_async_unlink(s, curr);
diff --git a/hw/usb.c b/hw/usb.c
index 0f163b4..860538a 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -329,7 +329,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 ret = dev-info-handle_packet(dev, p);
 if (ret == USB_RET_ASYNC) {
 if (p-owner == NULL) {
-p-owner = dev;
+p-owner = usb_ep_get(dev, p-pid, p-devep);
 } else {
 /* We'll end up here when usb_handle_packet is called
  * recursively due to a hub being in the chain.  Nothing
@@ -357,7 +357,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 void usb_cancel_packet(USBPacket * p)
 {
 assert(p-owner != NULL);
-p-owner-info-cancel_packet(p-owner, p);
+p-owner-dev-info-cancel_packet(p-owner-dev, p);
 p-owner = NULL;
 }
 
@@ -419,11 +419,16 @@ void usb_ep_init(USBDevice *dev)
 {
 int ep;
 
+dev-ep_ctl.type = USB_ENDPOINT_XFER_CONTROL;
+dev-ep_ctl.ifnum = 0;
+dev-ep_ctl.dev = dev;
 for (ep = 0; ep  USB_MAX_ENDPOINTS; ep++) {
 dev-ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
 dev-ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
 dev-ep_in[ep].ifnum = 0;
 dev-ep_out[ep].ifnum = 0;
+dev-ep_in[ep].dev = dev;
+dev-ep_out[ep].dev = dev;
 }
 }
 
@@ -472,6 +477,9 @@ void usb_ep_dump(USBDevice *dev)
 struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
 {
 struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev-ep_in : dev-ep_out;
+if (ep == 0) {
+return dev-ep_ctl;
+}
 assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
 assert(ep  0  ep = USB_MAX_ENDPOINTS);
 return eps + ep - 1;
diff --git a/hw/usb.h b/hw/usb.h
index 5ea984c..0776463 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -177,6 +177,7 @@ struct USBEndpoint {
 uint8_t type;
 uint8_t ifnum;
 int max_packet_size;
+USBDevice *dev;
 };
 
 /* definition of a USB device */
@@ -204,6 +205,7 @@ struct USBDevice {
 int32_t setup_len;
 int32_t setup_index;
 
+USBEndpoint ep_ctl;
 USBEndpoint ep_in[USB_MAX_ENDPOINTS];
 USBEndpoint ep_out[USB_MAX_ENDPOINTS];
 
@@ -317,7 +319,7 @@ struct USBPacket {
 QEMUIOVector iov;
 int result; /* transfer length or USB_RET_* status code */
 /* Internal use by the USB layer.  */
-USBDevice *owner;
+USBEndpoint *owner;
 };
 
 void usb_packet_init(USBPacket *p);
-- 
1.7.1




[Qemu-devel] [PATCH 14/17] usb-redir: Dynamically adjust iso buffering size based on ep interval

2012-01-13 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

Note the bufpq_target_size id stored in the endpoint info struct,
even though it only used once. This is done because it will be
referenced from other code in a follow up patch.

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-redir.c |   53 -
 1 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/usb-redir.c b/usb-redir.c
index 81a35c6..99a12d5 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -61,6 +61,7 @@ struct endp_data {
 uint8_t interrupt_started;
 uint8_t interrupt_error;
 QTAILQ_HEAD(, buf_packet) bufpq;
+int bufpq_target_size;
 };
 
 struct USBRedirDevice {
@@ -332,15 +333,42 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
  uint8_t ep)
 {
 int status, len;
-
 if (!dev-endpoint[EP2I(ep)].iso_started 
 !dev-endpoint[EP2I(ep)].iso_error) {
 struct usb_redir_start_iso_stream_header start_iso = {
 .endpoint = ep,
-/* TODO maybe do something with these depending on ep interval? */
-.pkts_per_urb = 32,
-.no_urbs = 3,
 };
+int pkts_per_sec;
+
+if (dev-dev.speed == USB_SPEED_HIGH) {
+pkts_per_sec = 8000 / dev-endpoint[EP2I(ep)].interval;
+} else {
+pkts_per_sec = 1000 / dev-endpoint[EP2I(ep)].interval;
+}
+/* Testing has shown that we need circa 60 ms buffer */
+dev-endpoint[EP2I(ep)].bufpq_target_size = (pkts_per_sec * 60) / 1000;
+
+/* Aim for approx 100 interrupts / second on the client to
+   balance latency and interrupt load */
+start_iso.pkts_per_urb = pkts_per_sec / 100;
+if (start_iso.pkts_per_urb  1) {
+start_iso.pkts_per_urb = 1;
+} else if (start_iso.pkts_per_urb  32) {
+start_iso.pkts_per_urb = 32;
+}
+
+start_iso.no_urbs = (dev-endpoint[EP2I(ep)].bufpq_target_size +
+ start_iso.pkts_per_urb - 1) /
+start_iso.pkts_per_urb;
+/* Output endpoints pre-fill only 1/2 of the packets, keeping the rest
+   as overflow buffer. Also see the usbredir protocol documentation */
+if (!(ep  USB_DIR_IN)) {
+start_iso.no_urbs *= 2;
+}
+if (start_iso.no_urbs  16) {
+start_iso.no_urbs = 16;
+}
+
 /* No id, we look at the ep when receiving a status back */
 usbredirparser_send_start_iso_stream(dev-parser, 0, start_iso);
 usbredirparser_do_write(dev-parser);
@@ -961,9 +989,24 @@ static void usbredir_ep_info(void *priv,
 dev-endpoint[i].type = ep_info-type[i];
 dev-endpoint[i].interval = ep_info-interval[i];
 dev-endpoint[i].interface = ep_info-interface[i];
-if (dev-endpoint[i].type != usb_redir_type_invalid) {
+switch (dev-endpoint[i].type) {
+case usb_redir_type_invalid:
+break;
+case usb_redir_type_iso:
+case usb_redir_type_interrupt:
+if (dev-endpoint[i].interval == 0) {
+ERROR(Received 0 interval for isoc or irq endpoint\n);
+usbredir_device_disconnect(dev);
+}
+/* Fall through */
+case usb_redir_type_control:
+case usb_redir_type_bulk:
 DPRINTF(ep: %02X type: %d interface: %d\n, I2EP(i),
 dev-endpoint[i].type, dev-endpoint[i].interface);
+break;
+default:
+ERROR(Received invalid endpoint type\n);
+usbredir_device_disconnect(dev);
 }
 }
 }
-- 
1.7.1




[Qemu-devel] [PATCH 17/17] usb-redir: Improve some debugging messages

2012-01-13 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-redir.c |   13 -
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/usb-redir.c b/usb-redir.c
index 147e237..79d29ec 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -395,7 +395,8 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 /* No id, we look at the ep when receiving a status back */
 usbredirparser_send_start_iso_stream(dev-parser, 0, start_iso);
 usbredirparser_do_write(dev-parser);
-DPRINTF(iso stream started ep %02X\n, ep);
+DPRINTF(iso stream started pkts/sec %d pkts/urb %d urbs %d ep %02X\n,
+pkts_per_sec, start_iso.pkts_per_urb, start_iso.no_urbs, ep);
 dev-endpoint[EP2I(ep)].iso_started = 1;
 dev-endpoint[EP2I(ep)].bufpq_prefilled = 0;
 dev-endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
@@ -415,7 +416,8 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 
 isop = QTAILQ_FIRST(dev-endpoint[EP2I(ep)].bufpq);
 if (isop == NULL) {
-DPRINTF2(iso-token-in ep %02X, no isop\n, ep);
+DPRINTF(iso-token-in ep %02X, no isop, iso_error: %d\n,
+ep, dev-endpoint[EP2I(ep)].iso_error);
 /* Re-fill the buffer */
 dev-endpoint[EP2I(ep)].bufpq_prefilled = 0;
 /* Check iso_error for stream errors, otherwise its an underrun */
@@ -423,8 +425,8 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 dev-endpoint[EP2I(ep)].iso_error = 0;
 return usbredir_handle_status(dev, status, 0);
 }
-DPRINTF2(iso-token-in ep %02X status %d len %d\n, ep, isop-status,
- isop-len);
+DPRINTF2(iso-token-in ep %02X status %d len %d queue-size: %d\n, ep,
+ isop-status, isop-len, dev-endpoint[EP2I(ep)].bufpq_size);
 
 status = isop-status;
 if (status != usb_redir_success) {
@@ -434,7 +436,8 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 
 len = isop-len;
 if (len  p-iov.size) {
-ERROR(received iso data is larger then packet ep %02X\n, ep);
+ERROR(received iso data is larger then packet ep %02X (%d  
%d)\n,
+  ep, len, (int)p-iov.size);
 bufp_free(dev, isop, ep);
 return USB_RET_NAK;
 }
-- 
1.7.1




[Qemu-devel] [PATCH 07/17] usb: add USBEndpoint

2012-01-13 Thread Gerd Hoffmann
Start maintaining endpoint state at USBDevice level.  Add USBEndpoint
struct and some helper functions to deal with it.  For now it contains
the endpoint type only.  Moved over some bits from usb-linux.c

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-bus.c |1 +
 hw/usb.c |   30 +++
 hw/usb.h |   14 
 usb-linux.c  |   63 ++---
 4 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index bd4afa7..016a3f2 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -75,6 +75,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 dev-info = info;
 dev-auto_attach = 1;
 QLIST_INIT(dev-strings);
+usb_ep_init(dev);
 rc = usb_claim_port(dev);
 if (rc != 0) {
 return rc;
diff --git a/hw/usb.c b/hw/usb.c
index 2216efe..5d6baaf 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -414,3 +414,33 @@ void usb_packet_cleanup(USBPacket *p)
 {
 qemu_iovec_destroy(p-iov);
 }
+
+void usb_ep_init(USBDevice *dev)
+{
+int ep;
+
+for (ep = 0; ep  USB_MAX_ENDPOINTS; ep++) {
+dev-ep_in[ep].type = USB_ENDPOINT_XFER_INVALID;
+dev-ep_out[ep].type = USB_ENDPOINT_XFER_INVALID;
+}
+}
+
+struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep)
+{
+struct USBEndpoint *eps = pid == USB_TOKEN_IN ? dev-ep_in : dev-ep_out;
+assert(pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT);
+assert(ep  0  ep = USB_MAX_ENDPOINTS);
+return eps + ep - 1;
+}
+
+uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+return uep-type;
+}
+
+void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type)
+{
+struct USBEndpoint *uep = usb_ep_get(dev, pid, ep);
+uep-type = type;
+}
diff --git a/hw/usb.h b/hw/usb.h
index b2c9479..85cbe71 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -144,6 +144,7 @@
 #define USB_ENDPOINT_XFER_ISOC 1
 #define USB_ENDPOINT_XFER_BULK 2
 #define USB_ENDPOINT_XFER_INT  3
+#define USB_ENDPOINT_XFER_INVALID 255
 
 typedef struct USBBus USBBus;
 typedef struct USBBusOps USBBusOps;
@@ -151,6 +152,7 @@ typedef struct USBPort USBPort;
 typedef struct USBDevice USBDevice;
 typedef struct USBDeviceInfo USBDeviceInfo;
 typedef struct USBPacket USBPacket;
+typedef struct USBEndpoint USBEndpoint;
 
 typedef struct USBDesc USBDesc;
 typedef struct USBDescID USBDescID;
@@ -171,6 +173,10 @@ struct USBDescString {
 #define USB_MAX_ENDPOINTS  15
 #define USB_MAX_INTERFACES 16
 
+struct USBEndpoint {
+uint8_t type;
+};
+
 /* definition of a USB device */
 struct USBDevice {
 DeviceState qdev;
@@ -196,6 +202,9 @@ struct USBDevice {
 int32_t setup_len;
 int32_t setup_index;
 
+USBEndpoint ep_in[USB_MAX_ENDPOINTS];
+USBEndpoint ep_out[USB_MAX_ENDPOINTS];
+
 QLIST_HEAD(, USBDescString) strings;
 const USBDescDevice *device;
 
@@ -322,6 +331,11 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p);
 void usb_packet_complete(USBDevice *dev, USBPacket *p);
 void usb_cancel_packet(USBPacket * p);
 
+void usb_ep_init(USBDevice *dev);
+struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep);
+uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep);
+void usb_ep_set_type(USBDevice *dev, int pid, int ep, uint8_t type);
+
 void usb_attach(USBPort *port);
 void usb_detach(USBPort *port);
 void usb_reset(USBPort *port);
diff --git a/usb-linux.c b/usb-linux.c
index ded0726..9967975 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -67,12 +67,10 @@ typedef int USBScanFunc(void *opaque, int bus_num, int 
addr, const char *port,
 #endif
 
 #define PRODUCT_NAME_SZ 32
-#define MAX_ENDPOINTS 15
 #define MAX_PORTLEN 16
 
 /* endpoint association data */
 #define ISO_FRAME_DESC_PER_URB 32
-#define INVALID_EP_TYPE 255
 
 /* devio.c limits single requests to 16k */
 #define MAX_USBFS_BUFFER_SIZE 16384
@@ -80,7 +78,6 @@ typedef int USBScanFunc(void *opaque, int bus_num, int addr, 
const char *port,
 typedef struct AsyncURB AsyncURB;
 
 struct endp_data {
-uint8_t type;
 uint8_t halted;
 uint8_t iso_started;
 AsyncURB *iso_urb;
@@ -110,8 +107,8 @@ typedef struct USBHostDevice {
 uint32_t  iso_urb_count;
 Notifier  exit;
 
-struct endp_data ep_in[MAX_ENDPOINTS];
-struct endp_data ep_out[MAX_ENDPOINTS];
+struct endp_data ep_in[USB_MAX_ENDPOINTS];
+struct endp_data ep_out[USB_MAX_ENDPOINTS];
 QLIST_HEAD(, AsyncURB) aurbs;
 
 /* Host side address */
@@ -133,6 +130,19 @@ static int usb_host_read_file(char *line, size_t line_size,
 const char *device_file, const char *device_name);
 static int usb_linux_update_endp_table(USBHostDevice *s);
 
+static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p)
+{
+static const int usbfs[] = {
+[USB_ENDPOINT_XFER_CONTROL] = USBDEVFS_URB_TYPE_CONTROL,
+[USB_ENDPOINT_XFER_ISOC]= 

[Qemu-devel] [PATCH 16/17] usb-redir: Try to keep our buffer size near the target size

2012-01-13 Thread Gerd Hoffmann
From: Hans de Goede hdego...@redhat.com

Before this patch we would allow the (iso) buffer to grow unlimited
(and it would under certain circumstances) leading to way too high
latencies for iso data streams.

Signed-off-by: Hans de Goede hdego...@redhat.com
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 usb-redir.c |   30 +++---
 1 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/usb-redir.c b/usb-redir.c
index cdd929a..147e237 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -61,6 +61,7 @@ struct endp_data {
 uint8_t interrupt_started;
 uint8_t interrupt_error;
 uint8_t bufpq_prefilled;
+uint8_t bufpq_dropping_packets;
 QTAILQ_HEAD(, buf_packet) bufpq;
 int bufpq_size;
 int bufpq_target_size;
@@ -290,16 +291,34 @@ static void usbredir_cancel_packet(USBDevice *udev, 
USBPacket *p)
 }
 }
 
-static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
+static void bufp_alloc(USBRedirDevice *dev,
 uint8_t *data, int len, int status, uint8_t ep)
 {
-struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
+struct buf_packet *bufp;
+
+if (!dev-endpoint[EP2I(ep)].bufpq_dropping_packets 
+dev-endpoint[EP2I(ep)].bufpq_size 
+2 * dev-endpoint[EP2I(ep)].bufpq_target_size) {
+DPRINTF(bufpq overflow, dropping packets ep %02X\n, ep);
+dev-endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
+}
+/* Since we're interupting the stream anyways, drop enough packets to get
+   back to our target buffer size */
+if (dev-endpoint[EP2I(ep)].bufpq_dropping_packets) {
+if (dev-endpoint[EP2I(ep)].bufpq_size 
+dev-endpoint[EP2I(ep)].bufpq_target_size) {
+free(data);
+return;
+}
+dev-endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
+}
+
+bufp = g_malloc(sizeof(struct buf_packet));
 bufp-data   = data;
 bufp-len= len;
 bufp-status = status;
 QTAILQ_INSERT_TAIL(dev-endpoint[EP2I(ep)].bufpq, bufp, next);
 dev-endpoint[EP2I(ep)].bufpq_size++;
-return bufp;
 }
 
 static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
@@ -379,6 +398,7 @@ static int usbredir_handle_iso_data(USBRedirDevice *dev, 
USBPacket *p,
 DPRINTF(iso stream started ep %02X\n, ep);
 dev-endpoint[EP2I(ep)].iso_started = 1;
 dev-endpoint[EP2I(ep)].bufpq_prefilled = 0;
+dev-endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
 }
 
 if (ep  USB_DIR_IN) {
@@ -505,6 +525,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice 
*dev,
 usbredirparser_do_write(dev-parser);
 DPRINTF(interrupt recv started ep %02X\n, ep);
 dev-endpoint[EP2I(ep)].interrupt_started = 1;
+/* We don't really want to drop interrupt packets ever, but
+   having some upper limit to how much we buffer is good. */
+dev-endpoint[EP2I(ep)].bufpq_target_size = 1000;
+dev-endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
 }
 
 intp = QTAILQ_FIRST(dev-endpoint[EP2I(ep)].bufpq);
-- 
1.7.1




[Qemu-devel] [PATCH 02/17] usb: track configuration and interface count in USBDevice.

2012-01-13 Thread Gerd Hoffmann
Move fields from USBHostDevice to USBDevice.
Add bits to usb-desc.c to fill them for emulated devices too.
Also allow to set configuration 0 (== None) for emulated devices.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb-desc.c |   34 ++
 hw/usb.h  |3 +++
 usb-linux.c   |   21 +
 3 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index ae2d384..b52561a 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -223,6 +223,29 @@ int usb_desc_other(const USBDescOther *desc, uint8_t 
*dest, size_t len)
 
 /* -- */
 
+static int usb_desc_set_config(USBDevice *dev, int value)
+{
+int i;
+
+if (value == 0) {
+dev-configuration = 0;
+dev-ninterfaces   = 0;
+dev-config = NULL;
+} else {
+for (i = 0; i  dev-device-bNumConfigurations; i++) {
+if (dev-device-confs[i].bConfigurationValue == value) {
+dev-configuration = value;
+dev-ninterfaces   = dev-device-confs[i].bNumInterfaces;
+dev-config = dev-device-confs + i;
+}
+}
+if (i  dev-device-bNumConfigurations) {
+return -1;
+}
+}
+return 0;
+}
+
 static void usb_desc_setdefaults(USBDevice *dev)
 {
 const USBDesc *desc = dev-info-usb_desc;
@@ -237,7 +260,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
 dev-device = desc-high;
 break;
 }
-dev-config = dev-device-confs;
+usb_desc_set_config(dev, 0);
 }
 
 void usb_desc_init(USBDevice *dev)
@@ -408,7 +431,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
 int request, int value, int index, int length, uint8_t *data)
 {
 const USBDesc *desc = dev-info-usb_desc;
-int i, ret = -1;
+int ret = -1;
 
 assert(desc != NULL);
 switch(request) {
@@ -427,12 +450,7 @@ int usb_desc_handle_control(USBDevice *dev, USBPacket *p,
 ret = 1;
 break;
 case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
-for (i = 0; i  dev-device-bNumConfigurations; i++) {
-if (dev-device-confs[i].bConfigurationValue == value) {
-dev-config = dev-device-confs + i;
-ret = 0;
-}
-}
+ret = usb_desc_set_config(dev, value);
 trace_usb_set_config(dev-addr, value, ret);
 break;
 
diff --git a/hw/usb.h b/hw/usb.h
index c6e1870..1ef53a1 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -188,6 +188,9 @@ struct USBDevice {
 
 QLIST_HEAD(, USBDescString) strings;
 const USBDescDevice *device;
+
+int configuration;
+int ninterfaces;
 const USBDescConfig *config;
 };
 
diff --git a/usb-linux.c b/usb-linux.c
index c68e194..3aaa93b 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -106,8 +106,6 @@ typedef struct USBHostDevice {
 
 uint8_t   descr[8192];
 int   descr_len;
-int   configuration;
-int   ninterfaces;
 int   closing;
 uint32_t  iso_urb_count;
 Notifier  exit;
@@ -547,8 +545,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, 
int configuration)
 int ret, i;
 
 if (configuration == 0) { /* address state - ignore */
-dev-ninterfaces   = 0;
-dev-configuration = 0;
+dev-dev.ninterfaces   = 0;
+dev-dev.configuration = 0;
 return 1;
 }
 
@@ -606,8 +604,8 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, 
int configuration)
 trace_usb_host_claim_interfaces(dev-bus_num, dev-addr,
 nb_interfaces, configuration);
 
-dev-ninterfaces   = nb_interfaces;
-dev-configuration = configuration;
+dev-dev.ninterfaces   = nb_interfaces;
+dev-dev.configuration = configuration;
 return 1;
 
 fail:
@@ -624,7 +622,7 @@ static int usb_host_release_interfaces(USBHostDevice *s)
 
 trace_usb_host_release_interfaces(s-bus_num, s-addr);
 
-for (i = 0; i  s-ninterfaces; i++) {
+for (i = 0; i  s-dev.ninterfaces; i++) {
 ret = ioctl(s-fd, USBDEVFS_RELEASEINTERFACE, i);
 if (ret  0) {
 perror(USBDEVFS_RELEASEINTERFACE);
@@ -1123,7 +1121,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
 s-ep_out[i].type = INVALID_EP_TYPE;
 }
 
-if (s-configuration == 0) {
+if (s-dev.configuration == 0) {
 /* not configured yet -- leave all endpoints disabled */
 return 0;
 }
@@ -1138,12 +1136,11 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
 if (descriptors[i + 1] != USB_DT_CONFIG) {
 fprintf(stderr, invalid descriptor data\n);
 return 1;
-} else if (descriptors[i + 5] != s-configuration) {
-DPRINTF(not requested configuration %d\n, s-configuration);
+} else if (descriptors[i + 5] != s-dev.configuration) {
+DPRINTF(not requested configuration 

Re: [Qemu-devel] [PATCH] do not chdir(/) in qemu-nbd

2012-01-13 Thread Michael Tokarev
On 13.01.2012 15:57, Stefan Hajnoczi wrote:
 On Fri, Jan 13, 2012 at 9:04 AM, Michael Tokarev m...@tls.msk.ru wrote:
 When qemu-nbd becomes a daemon it calls daemon(3) with
 nochdir=0, so daemon(3) changes current directory to /.
 But at this time, qemu-nbd did not open any user-specified
 files yet, so by changing current directory, all non-absolute
 paths becomes wrong.  The solution is to pass nochdir=1 to
 daemon(3) function.
 
 It's polite to chdir(/) so that file systems can be unmounted (even
 more important when chroot was involved, but I think qemu-nbd doesn't
 do that).  Is it possible to manually do a chdir(/) later on after
 we've opened necessary files?

Yes that was something I wasn't happy about too -- lack of chdir(/) in
daemons is annoying.

But instead of adding a chdir later, I'll try to rearrange code a bit
to do all init in the parent instead.

Will send a follow-up.

Thanks,

/mjt



Re: [Qemu-devel] [PATCH] do not chdir(/) in qemu-nbd

2012-01-13 Thread Daniel P. Berrange
On Fri, Jan 13, 2012 at 04:47:35PM +0400, Michael Tokarev wrote:
 On 13.01.2012 15:57, Stefan Hajnoczi wrote:
  On Fri, Jan 13, 2012 at 9:04 AM, Michael Tokarev m...@tls.msk.ru wrote:
  When qemu-nbd becomes a daemon it calls daemon(3) with
  nochdir=0, so daemon(3) changes current directory to /.
  But at this time, qemu-nbd did not open any user-specified
  files yet, so by changing current directory, all non-absolute
  paths becomes wrong.  The solution is to pass nochdir=1 to
  daemon(3) function.
  
  It's polite to chdir(/) so that file systems can be unmounted (even
  more important when chroot was involved, but I think qemu-nbd doesn't
  do that).  Is it possible to manually do a chdir(/) later on after
  we've opened necessary files?
 
 Yes that was something I wasn't happy about too -- lack of chdir(/) in
 daemons is annoying.
 
 But instead of adding a chdir later, I'll try to rearrange code a bit
 to do all init in the parent instead.

Or just canonicalize all relative paths before daemonizing.


Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



[Qemu-devel] [PATCH v5 00/15] block: generic image streaming

2012-01-13 Thread Stefan Hajnoczi
Note: This is a resend of v5 because the emails I sent earlier today
disappeared.

This series adds the 'block_stream' command which copies the contents of a
backing file into the image file while the VM is running.  The series builds on
the zero detection features which I sent out before Christmas. I suggest
grabbing my git tree to try it out without merging this dependency:

https://github.com/stefanha/qemu/tree/image-streaming-api

The image streaming HMP/QMP commands are documented in the patch and also
described here:

http://wiki.qemu.org/Features/LiveBlockMigration/ImageStreamingAPI

The basic idea is to execute 'block_stream virtio0' while the guest is running.
Progress can be monitored using 'info block-jobs'.  When the streaming
operation completes it raises a QMP event.

Note: The last patch includes includes a Python test script called
test-stream.py, I do not propose to merge it.  When run in a QEMU source tree
it performs basic image streaming QMP tests.

v5:
 * Handle block_job_create() failure [Luiz]
 * Mark BLOCK_JOB_COMPLETED error field optional [Luiz]
 * Mark block_stream base parameter optional [Luiz]
 * Check bdrv_getlength() failure and don't call twice [Kevin]
 * Rename id to backing_file in bdrv_find_backing_image() [Kevin]
 * Rename BaseIdNotFound qerror to BaseNotFound [Kevin]
 * Document BaseNotFound qerror from block_stream
 * Document that qemu_co_sleep_ns() needs main loop [Kevin]
 * Make bdrv_co_is_allocated_base() private to block/stream.c [Kevin]
 * Clean up commit messages

v4:
 * Drop SQMP/EQMP docs from qmp-commands.hx [Luiz]
 * Follow QAPI doc conventions [Luiz]
 * Document QMP events in QMP/qmp-events.txt [Luiz]
 * Protect against hotplug, resize, eject, etc [Kevin]
 * Move block job functions from header to block.c [Kevin]
 * Return error from bdrg_change_backing_file() [Kevin]
 * Merge Marcelo's block_stream base partial streaming series [Marcelo]

Marcelo Tosatti (4):
  block: add bdrv_find_backing_image
  add QERR_BASE_NOT_FOUND
  block: add support for partial streaming
  docs: describe live block operations

Stefan Hajnoczi (11):
  coroutine: add co_sleep_ns() coroutine sleep function
  block: check bdrv_in_use() before blockdev operations
  block: add BlockJob interface for long-running operations
  block: add image streaming block job
  block: rate-limit streaming operations
  qmp: add block_stream command
  qmp: add block_job_set_speed command
  qmp: add block_job_cancel command
  qmp: add query-block-jobs
  blockdev: make image streaming safe across hotplug
  test: add image streaming test cases

 Makefile.objs   |2 +
 QMP/qmp-events.txt  |   53 ++
 block.c |   70 +
 block.h |2 +
 block/stream.c  |  260 +++
 block_int.h |   44 
 blockdev.c  |  199 +++-
 docs/live-block-ops.txt |   58 +++
 hmp-commands.hx |   41 
 hmp.c   |   68 
 hmp.h   |4 +
 monitor.c   |   13 +++
 monitor.h   |2 +
 qapi-schema.json|  116 +
 qemu-coroutine-sleep.c  |   38 +++
 qemu-coroutine.h|9 ++
 qerror.c|8 ++
 qerror.h|6 +
 qmp-commands.hx |   24 +
 test-stream.py  |  208 +
 trace-events|9 ++
 21 files changed, 1233 insertions(+), 1 deletions(-)
 create mode 100644 block/stream.c
 create mode 100644 docs/live-block-ops.txt
 create mode 100644 qemu-coroutine-sleep.c
 create mode 100644 test-stream.py

-- 
1.7.7.3




[Qemu-devel] [PATCH v5 01/15] coroutine: add co_sleep_ns() coroutine sleep function

2012-01-13 Thread Stefan Hajnoczi
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 Makefile.objs  |1 +
 qemu-coroutine-sleep.c |   38 ++
 qemu-coroutine.h   |9 +
 3 files changed, 48 insertions(+), 0 deletions(-)
 create mode 100644 qemu-coroutine-sleep.c

diff --git a/Makefile.objs b/Makefile.objs
index 4f6d26c..f4f52e0 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -13,6 +13,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
 ifeq ($(CONFIG_UCONTEXT_COROUTINE),y)
 coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o
 else
diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c
new file mode 100644
index 000..fd65274
--- /dev/null
+++ b/qemu-coroutine-sleep.c
@@ -0,0 +1,38 @@
+/*
+ * QEMU coroutine sleep
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Stefan Hajnoczistefa...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include qemu-coroutine.h
+#include qemu-timer.h
+
+typedef struct CoSleepCB {
+QEMUTimer *ts;
+Coroutine *co;
+} CoSleepCB;
+
+static void co_sleep_cb(void *opaque)
+{
+CoSleepCB *sleep_cb = opaque;
+
+qemu_free_timer(sleep_cb-ts);
+qemu_coroutine_enter(sleep_cb-co, NULL);
+}
+
+void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns)
+{
+CoSleepCB sleep_cb = {
+.co = qemu_coroutine_self(),
+};
+sleep_cb.ts = qemu_new_timer(clock, SCALE_NS, co_sleep_cb, sleep_cb);
+qemu_mod_timer(sleep_cb.ts, qemu_get_clock_ns(clock) + ns);
+qemu_coroutine_yield();
+}
diff --git a/qemu-coroutine.h b/qemu-coroutine.h
index 8a55fe1..34c15d4 100644
--- a/qemu-coroutine.h
+++ b/qemu-coroutine.h
@@ -17,6 +17,7 @@
 
 #include stdbool.h
 #include qemu-queue.h
+#include qemu-timer.h
 
 /**
  * Coroutines are a mechanism for stack switching and can be used for
@@ -199,4 +200,12 @@ void qemu_co_rwlock_wrlock(CoRwlock *lock);
  */
 void qemu_co_rwlock_unlock(CoRwlock *lock);
 
+/**
+ * Yield the coroutine for a given duration
+ *
+ * Note this function uses timers and hence only works when a main loop is in
+ * use.  See main-loop.h and do not use from qemu-tool programs.
+ */
+void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns);
+
 #endif /* QEMU_COROUTINE_H */
-- 
1.7.7.3




[Qemu-devel] [PATCH v5 15/15] test: add image streaming test cases

2012-01-13 Thread Stefan Hajnoczi
python test-stream.py

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 test-stream.py |  208 
 1 files changed, 208 insertions(+), 0 deletions(-)
 create mode 100644 test-stream.py

diff --git a/test-stream.py b/test-stream.py
new file mode 100644
index 000..16cbe5d
--- /dev/null
+++ b/test-stream.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+import unittest
+import subprocess
+import re
+import os
+import sys; sys.path.append('QMP/')
+import qmp
+
+def qemu_img(*args):
+devnull = open('/dev/null', 'r+')
+return subprocess.call(['./qemu-img'] + list(args), stdin=devnull, 
stdout=devnull)
+
+def qemu_io(*args):
+args = ['./qemu-io'] + list(args)
+return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
+
+class VM(object):
+def __init__(self):
+self._monitor_path = '/tmp/qemu-mon.%d' % os.getpid()
+self._qemu_log_path = '/tmp/qemu-log.%d' % os.getpid()
+self._args = ['x86_64-softmmu/qemu-system-x86_64',
+  '-chardev', 'socket,id=mon,path=' + self._monitor_path,
+  '-mon', 'chardev=mon,mode=control', '-nographic']
+self._num_drives = 0
+
+def add_drive(self, path, opts=''):
+options = ['if=virtio',
+   'cache=none',
+   'file=%s' % path,
+   'id=drive%d' % self._num_drives]
+if opts:
+options.append(opts)
+
+self._args.append('-drive')
+self._args.append(','.join(options))
+self._num_drives += 1
+return self
+
+def launch(self):
+devnull = open('/dev/null', 'rb')
+qemulog = open(self._qemu_log_path, 'wb')
+self._qmp = qmp.QEMUMonitorProtocol(self._monitor_path, server=True)
+self._popen = subprocess.Popen(self._args, stdin=devnull, 
stdout=qemulog,
+   stderr=subprocess.STDOUT)
+self._qmp.accept()
+
+def shutdown(self):
+self._qmp.cmd('quit')
+self._popen.wait()
+os.remove(self._monitor_path)
+os.remove(self._qemu_log_path)
+
+def qmp(self, cmd, **args):
+return self._qmp.cmd(cmd, args=args)
+
+def get_qmp_events(self, wait=False):
+events = self._qmp.get_events(wait=wait)
+self._qmp.clear_events()
+return events
+
+index_re = re.compile(r'([^\[]+)\[([^\]]+)\]')
+
+class QMPTestCase(unittest.TestCase):
+def dictpath(self, d, path):
+Traverse a path in a nested dict
+for component in path.split('/'):
+m = index_re.match(component)
+if m:
+component, idx = m.groups()
+idx = int(idx)
+
+if not isinstance(d, dict) or component not in d:
+self.fail('failed path traversal for %s in %s' % (path, 
str(d)))
+d = d[component]
+
+if m:
+if not isinstance(d, list):
+self.fail('path component %s in %s is not a list in 
%s' % (component, path, str(d)))
+try:
+d = d[idx]
+except IndexError:
+self.fail('invalid index %s in path %s in %s' % 
(idx, path, str(d)))
+return d
+
+def assert_qmp(self, d, path, value):
+result = self.dictpath(d, path)
+self.assertEqual(result, value, 'values not equal %s and %s' % 
(str(result), str(value)))
+
+def assert_no_active_streams(self):
+result = self.vm.qmp('query-block-jobs')
+self.assert_qmp(result, 'return', [])
+
+class TestSingleDrive(QMPTestCase):
+image_len = 1 * 1024 * 1024 # MB
+
+def setUp(self):
+qemu_img('create', 'backing.img', str(TestSingleDrive.image_len))
+qemu_img('create', '-f', 'qed', '-o', 'backing_file=backing.img', 
'test.qed')
+self.vm = VM().add_drive('test.qed')
+self.vm.launch()
+
+def tearDown(self):
+self.vm.shutdown()
+os.remove('test.qed')
+os.remove('backing.img')
+
+def test_stream(self):
+self.assert_no_active_streams()
+
+result = self.vm.qmp('block_stream', device='drive0')
+self.assert_qmp(result, 'return', {})
+
+completed = False
+while not completed:
+for event in self.vm.get_qmp_events(wait=True):
+if event['event'] == 'BLOCK_JOB_COMPLETED':
+self.assert_qmp(event, 'data/type', 'stream')
+self.assert_qmp(event, 'data/device', 'drive0')
+self.assert_qmp(event, 'data/offset', self.image_len)
+self.assert_qmp(event, 'data/len', self.image_len)
+completed = True
+
+self.assert_no_active_streams()
+
+self.assertFalse('sectors not allocated' in qemu_io('-c', 'map', 
'test.qed'),
+ 'image file not fully populated after streaming')
+
+def 

[Qemu-devel] [PATCH v5 02/15] block: check bdrv_in_use() before blockdev operations

2012-01-13 Thread Stefan Hajnoczi
Long-running block operations like block migration and image streaming
must have continual access to their block device.  It is not safe to
perform operations like hotplug, eject, change, resize, commit, or
external snapshot while a long-running operation is in progress.

This patch adds the missing bdrv_in_use() checks so that block migration
and image streaming never have the rug pulled out from underneath them.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c|4 
 blockdev.c |   16 +++-
 2 files changed, 19 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index 967a583..daf92c2 100644
--- a/block.c
+++ b/block.c
@@ -1020,6 +1020,10 @@ int bdrv_commit(BlockDriverState *bs)
 return -EACCES;
 }
 
+if (bdrv_in_use(bs) || bdrv_in_use(bs-backing_hd)) {
+return -EBUSY;
+}
+
 backing_drv = bs-backing_hd-drv;
 ro = bs-backing_hd-read_only;
 strncpy(filename, bs-backing_hd-filename, sizeof(filename));
diff --git a/blockdev.c b/blockdev.c
index c832782..6d78b36 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -592,12 +592,18 @@ void do_commit(Monitor *mon, const QDict *qdict)
 if (!strcmp(device, all)) {
 bdrv_commit_all();
 } else {
+int ret;
+
 bs = bdrv_find(device);
 if (!bs) {
 qerror_report(QERR_DEVICE_NOT_FOUND, device);
 return;
 }
-bdrv_commit(bs);
+ret = bdrv_commit(bs);
+if (ret == -EBUSY) {
+qerror_report(QERR_DEVICE_IN_USE, device);
+return;
+}
 }
 }
 
@@ -616,6 +622,10 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
char *snapshot_file,
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
+if (bdrv_in_use(bs)) {
+error_set(errp, QERR_DEVICE_IN_USE, device);
+return;
+}
 
 pstrcpy(old_filename, sizeof(old_filename), bs-filename);
 
@@ -667,6 +677,10 @@ void qmp_blockdev_snapshot_sync(const char *device, const 
char *snapshot_file,
 
 static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
 {
+if (bdrv_in_use(bs)) {
+qerror_report(QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
+return -1;
+}
 if (!bdrv_dev_has_removable_media(bs)) {
 qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs));
 return -1;
-- 
1.7.7.3




[Qemu-devel] [PATCH] usb-ehci: Clear the portstatus powner bit on device disconnect

2012-01-13 Thread Hans de Goede
According to the EHCI spec port ownerhsip should revert to the EHCI controller
on device disconnect. This fixes the problem of a port getting stuck on USB 1
when using redirection and plugging in a USB 2 device after a USB 1 device
has been redirected.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb-ehci.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index a946e1d..69bcc4b 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -764,6 +764,11 @@ static void ehci_detach(USBPort *port)
 USBPort *companion = s-companion_ports[port-index];
 companion-ops-detach(companion);
 companion-dev = NULL;
+/*
+ * EHCI spec 4.2.2: When a disconnect occurs... On the event,
+ * the port ownership is returned immediately to the EHCI controller.
+ */
+*portsc = ~PORTSC_POWNER;
 return;
 }
 
-- 
1.7.7.4




[Qemu-devel] [PATCH v5 07/15] qmp: add block_job_set_speed command

2012-01-13 Thread Stefan Hajnoczi
Add block_job_set_speed, which sets the maximum speed for a background
block operation.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c   |   25 +
 hmp-commands.hx  |   14 ++
 hmp.c|   11 +++
 hmp.h|1 +
 qapi-schema.json |   22 ++
 qmp-commands.hx  |6 ++
 6 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index ba973b0..2dfca40 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -947,3 +947,28 @@ void qmp_block_stream(const char *device, bool has_base,
 
 trace_qmp_block_stream(bs, bs-job);
 }
+
+static BlockJob *find_block_job(const char *device)
+{
+BlockDriverState *bs;
+
+bs = bdrv_find(device);
+if (!bs || !bs-job) {
+return NULL;
+}
+return bs-job;
+}
+
+void qmp_block_job_set_speed(const char *device, int64_t value, Error **errp)
+{
+BlockJob *job = find_block_job(device);
+
+if (!job) {
+error_set(errp, QERR_DEVICE_NOT_ACTIVE, device);
+return;
+}
+
+if (block_job_set_speed(job, value)  0) {
+error_set(errp, QERR_NOT_SUPPORTED);
+}
+}
diff --git a/hmp-commands.hx b/hmp-commands.hx
index dc6c8c3..12b8433 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -84,6 +84,20 @@ Copy data from a backing file into a block device.
 ETEXI
 
 {
+.name   = block_job_set_speed,
+.args_type  = device:B,value:o,
+.params = device value,
+.help   = set maximum speed for a background block operation,
+.mhandler.cmd = hmp_block_job_set_speed,
+},
+
+STEXI
+@item block_job_set_stream
+@findex block_job_set_stream
+Set maximum speed for a background block operation.
+ETEXI
+
+{
 .name   = eject,
 .args_type  = force:-f,device:B,
 .params = [-f] device,
diff --git a/hmp.c b/hmp.c
index b6e5913..1144d53 100644
--- a/hmp.c
+++ b/hmp.c
@@ -690,3 +690,14 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
 
 hmp_handle_error(mon, error);
 }
+
+void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
+{
+Error *error = NULL;
+const char *device = qdict_get_str(qdict, device);
+int64_t value = qdict_get_int(qdict, value);
+
+qmp_block_job_set_speed(device, value, error);
+
+hmp_handle_error(mon, error);
+}
diff --git a/hmp.h b/hmp.h
index b55c295..2c871ea 100644
--- a/hmp.h
+++ b/hmp.h
@@ -50,5 +50,6 @@ void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict);
 void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_stream(Monitor *mon, const QDict *qdict);
+void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 3821982..5872096 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1307,3 +1307,25 @@
 # Since: 1.1
 ##
 { 'command': 'block_stream', 'data': { 'device': 'str', '*base': 'str' } }
+
+##
+# @block_job_set_speed:
+#
+# Set maximum speed for a background block operation.
+#
+# This command can only be issued when there is an active block job.
+#
+# Throttling can be disabled by setting the speed to 0.
+#
+# @device: the device name
+#
+# @value:  the maximum speed, in bytes per second
+#
+# Returns: Nothing on success
+#  If the job type does not support throttling, NotSupported
+#  If streaming is not active on this device, DeviceNotActive
+#
+# Since: 1.1
+##
+{ 'command': 'block_job_set_speed',
+  'data': { 'device': 'str', 'value': 'int' } }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index b9ebb76..dc6bc2e 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -661,6 +661,12 @@ EQMP
 },
 
 {
+.name   = block_job_set_speed,
+.args_type  = device:B,value:o,
+.mhandler.cmd_new = qmp_marshal_input_block_job_set_speed,
+},
+
+{
 .name   = blockdev-snapshot-sync,
 .args_type  = device:B,snapshot-file:s,format:s?,
 .mhandler.cmd_new = qmp_marshal_input_blockdev_snapshot_sync,
-- 
1.7.7.3




Re: [Qemu-devel] Mixed USB 1.1 and USB 2.0 on the same port

2012-01-13 Thread Hans de Goede



On 01/04/2012 05:52 PM, Erik Rull wrote:

erik.r...@rdsoftware.de wrote:

On 12/31/11 13:11, Erik Rull wrote:

Hi all,

how can I use a USB 1.1 device on the USB 2.0 bus? Currently the EHCI
implementation complains that the device is mismatches the USB version.


-readconfig docs/ich9-ehci-uhci.cfg

cheers,
Gerd


Thanks for the hint.

It looks better now. But some things are still a bit strange.Hi,

Sequence:
device_add usb-host,bus=ehci.0,hostbus=2,hostport=1.4
Plug in a USB 2.0 printer
(gets detected by the guest, printing is possible, no bluescreen, it just
works)
Remove the USB 2.0 printer
Plug in a USB 1.1 dongle
Gets detected, etc., fine
Remove the USB 1.1 dongle
Plug in the USB 2.0 printer again
Guest complains now, that a USB 2.0 device was plugged into a USB 1.1 port
= printer is now 1.1 and does not work as if EHCI is missing now
= reboot guest, everything is fine again??

Any idea what could have happened here?
Same behavior when using a 2.0 USB key and the USB 1.1 dongle - also on
other ports - the transfer rate is horrible after having removed the USB
1.1 device and reconnected the 2.0 device.
Exchanging the two USB 2.0 devices on the same port without having the 1.1
device plugged in is fine!

Any hint what is wrong here would be great.

Best regards,

Erik



Additional Information:
This behavior is present on a Linux guest as well! After having removed the 1.1 
Dongle and plugged in the printer, the Linux guest detects the hardware via the 
UHCI kernel drivers and tells me to use a faster hub for max. performance.
It looks as if the speed downgrade by the 1.1 device cannot be reversed at 
runtime.


I've managed to reproduce this and written a fix for it. I've just send
a patch for this to the list. I've also attached this patch here for
your convenience.

Regards,

Hans
From 0b5059a8c0ae45c66caf5947f66b5c5cae81f622 Mon Sep 17 00:00:00 2001
From: Hans de Goede hdego...@redhat.com
Date: Fri, 13 Jan 2012 14:26:26 +0100
Subject: [PATCH] usb-ehci: Clear the portstatus powner bit on device
 disconnect

According to the EHCI spec port ownerhsip should revert to the EHCI controller
on device disconnect. This fixes the problem of a port getting stuck on USB 1
when using redirection and plugging in a USB 2 device after a USB 1 device
has been redirected.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb-ehci.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index a946e1d..69bcc4b 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -764,6 +764,11 @@ static void ehci_detach(USBPort *port)
 USBPort *companion = s-companion_ports[port-index];
 companion-ops-detach(companion);
 companion-dev = NULL;
+/*
+ * EHCI spec 4.2.2: When a disconnect occurs... On the event,
+ * the port ownership is returned immediately to the EHCI controller.
+ */
+*portsc = ~PORTSC_POWNER;
 return;
 }
 
-- 
1.7.7.4



Re: [Qemu-devel] [PATCH] do not chdir(/) in qemu-nbd

2012-01-13 Thread Paolo Bonzini

On 01/13/2012 01:47 PM, Michael Tokarev wrote:

But instead of adding a chdir later, I'll try to rearrange code a bit
to do all init in the parent instead.


That's not possible, because when you fork you lose all threads except 
the main thread.  That's why the daemon() was moved very early.  Your 
patch is okay if you also add a chdir(/) later on.


Paolo



[Qemu-devel] [PATCH 1/3][Seabios] Add bitmap for cpu _EJ0 callback

2012-01-13 Thread Vasilis Liaskovitis

Signed-off-by: Vasilis Liaskovitis vasilis.liaskovi...@profitbricks.com
---
 src/acpi-dsdt.dsl |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
index 7082b65..71d8ac4 100644
--- a/src/acpi-dsdt.dsl
+++ b/src/acpi-dsdt.dsl
@@ -650,8 +650,15 @@ DefinitionBlock (
 Store(DerefOf(Index(CPON, Arg0)), Local0)
 If (Local0) { Return(0xF) } Else { Return(0x0) }
 }
+/* CPU eject notify method */
+OperationRegion(PREJ, SystemIO, 0xaf20, 32)
+Field (PREJ, ByteAcc, NoLock, Preserve)
+{
+PRE, 256
+}
 Method (CPEJ, 2, NotSerialized) {
 // _EJ0 method - eject callback
+Store(ShiftLeft(1, Arg0), PRE)
 Sleep(200)
 }
 
-- 
1.7.7.3




[Qemu-devel] [PATCH v5 11/15] block: add bdrv_find_backing_image

2012-01-13 Thread Stefan Hajnoczi
From: Marcelo Tosatti mtosa...@redhat.com

Add bdrv_find_backing_image: given a BlockDriverState pointer, and an id,
traverse the backing image chain to locate the id.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |   18 ++
 block.h |2 ++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index d588ee8..d8ae716 100644
--- a/block.c
+++ b/block.c
@@ -2614,6 +2614,24 @@ int bdrv_snapshot_load_tmp(BlockDriverState *bs,
 return -ENOTSUP;
 }
 
+BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
+const char *backing_file)
+{
+if (!bs-drv) {
+return NULL;
+}
+
+if (bs-backing_hd) {
+if (strcmp(bs-backing_file, backing_file) == 0) {
+return bs-backing_hd;
+} else {
+return bdrv_find_backing_image(bs-backing_hd, backing_file);
+}
+}
+
+return NULL;
+}
+
 #define NB_SUFFIXES 4
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size)
diff --git a/block.h b/block.h
index 51b90c7..05c8c83 100644
--- a/block.h
+++ b/block.h
@@ -153,6 +153,8 @@ int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, 
int64_t sector_num,
 int nb_sectors);
 int coroutine_fn bdrv_co_is_allocated(BlockDriverState *bs, int64_t sector_num,
 int nb_sectors, int *pnum);
+BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
+const char *backing_file);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
 int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
-- 
1.7.7.3




[Qemu-devel] [PATCH 2/3] acpi_piix4: Add stub functions for CPU eject callback

2012-01-13 Thread Vasilis Liaskovitis

Signed-off-by: Vasilis Liaskovitis vasilis.liaskovi...@profitbricks.com
---
 hw/acpi_piix4.c |   15 +++
 1 files changed, 15 insertions(+), 0 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index d5743b6..8bf30dd 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -37,6 +37,7 @@
 
 #define GPE_BASE 0xafe0
 #define PROC_BASE 0xaf00
+#define PROC_EJ_BASE 0xaf20
 #define GPE_LEN 4
 #define PCI_BASE 0xae00
 #define PCI_EJ_BASE 0xae08
@@ -493,6 +494,17 @@ static void pcihotplug_write(void *opaque, uint32_t addr, 
uint32_t val)
 PIIX4_DPRINTF(pcihotplug write %x == %d\n, addr, val);
 }
 
+static uint32_t cpuej_read(void *opaque, uint32_t addr)
+{
+PIIX4_DPRINTF(cpuej read %x\n, addr);
+return 0;
+}
+
+static void cpuej_write(void *opaque, uint32_t addr, uint32_t val)
+{
+PIIX4_DPRINTF(cpuej write %x == %d\n, addr, val);
+}
+
 static uint32_t pciej_read(void *opaque, uint32_t addr)
 {
 PIIX4_DPRINTF(pciej read %x\n, addr);
@@ -553,6 +565,9 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, 
PIIX4PMState *s)
 register_ioport_write(PROC_BASE, 32, 1, gpe_writeb, s);
 register_ioport_read(PROC_BASE, 32, 1,  gpe_readb, s);
 
+register_ioport_write(PROC_EJ_BASE, 32, 1, cpuej_write, s);
+register_ioport_read(PROC_EJ_BASE, 32, 1,  cpuej_read, s);
+
 register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
 register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
 
-- 
1.7.7.3




[Qemu-devel] [PATCH] qdev: fix device_del by refactoring reference counting

2012-01-13 Thread Anthony Liguori
Commit 8eb0283 broken device_del by having too overzealous reference counting
checks.  Move the reference count checks to qdev_free(), make sure to remove
the parent link on free, and decrement the reference count on property removal.

Reported-by: Markus Armbruster arm...@redhat.com
Signed-off-by: Anthony Liguori aligu...@us.ibm.com
---
 hw/qdev.c |   45 +++--
 1 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index d0cf66d..e59f345 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -376,11 +376,6 @@ int qdev_unplug(DeviceState *dev)
 }
 assert(dev-info-unplug != NULL);
 
-if (dev-ref != 0) {
-qerror_report(QERR_DEVICE_IN_USE, dev-id?:);
-return -1;
-}
-
 qdev_hot_removed = true;
 
 return dev-info-unplug(dev);
@@ -465,6 +460,29 @@ static void qdev_property_del_all(DeviceState *dev)
 }
 }
 
+static void qdev_property_del_child(DeviceState *dev, DeviceState *child, 
Error **errp)
+{
+DeviceProperty *prop;
+
+QTAILQ_FOREACH(prop, dev-properties, node) {
+if (strstart(prop-type, child, NULL)  prop-opaque == child) {
+break;
+}
+}
+
+g_assert(prop != NULL);
+
+QTAILQ_REMOVE(dev-properties, prop, node);
+
+if (prop-release) {
+prop-release(dev, prop-name, prop-opaque);
+}
+
+g_free(prop-name);
+g_free(prop-type);
+g_free(prop);
+}
+
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
@@ -491,6 +509,12 @@ void qdev_free(DeviceState *dev)
 prop-info-free(dev, prop);
 }
 }
+if (dev-parent) {
+qdev_property_del_child(dev-parent, dev, NULL);
+}
+if (dev-ref != 0) {
+qerror_report(QERR_DEVICE_IN_USE, dev-id?:);
+}
 g_free(dev);
 }
 
@@ -1239,6 +1263,14 @@ static void qdev_get_child_property(DeviceState *dev, 
Visitor *v, void *opaque,
 g_free(path);
 }
 
+static void qdev_release_child_property(DeviceState *dev, const char *name,
+void *opaque)
+{
+DeviceState *child = opaque;
+
+qdev_unref(child);
+}
+
 void qdev_property_add_child(DeviceState *dev, const char *name,
  DeviceState *child, Error **errp)
 {
@@ -1247,7 +1279,8 @@ void qdev_property_add_child(DeviceState *dev, const char 
*name,
 type = g_strdup_printf(child%s, child-info-name);
 
 qdev_property_add(dev, name, type, qdev_get_child_property,
-  NULL, NULL, child, errp);
+  NULL, qdev_release_child_property,
+  child, errp);
 
 qdev_ref(child);
 g_assert(child-parent == NULL);
-- 
1.7.4.1




[Qemu-devel] [PATCH v5 13/15] block: add support for partial streaming

2012-01-13 Thread Stefan Hajnoczi
From: Marcelo Tosatti mtosa...@redhat.com

Add support for streaming data from an intermediate section of the
image chain (see patch and documentation for details).

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block/stream.c |   91 +--
 block_int.h|3 +-
 blockdev.c |   11 --
 3 files changed, 96 insertions(+), 9 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 93f0305..7532f5e 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -57,6 +57,7 @@ typedef struct StreamBlockJob {
 BlockJob common;
 RateLimit limit;
 BlockDriverState *base;
+char backing_file_id[1024];
 } StreamBlockJob;
 
 static int coroutine_fn stream_populate(BlockDriverState *bs,
@@ -75,10 +76,76 @@ static int coroutine_fn stream_populate(BlockDriverState 
*bs,
 return bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
 }
 
+/*
+ * Given an image chain: [BASE] - [INTER1] - [INTER2] - [TOP]
+ *
+ * Return true if the given sector is allocated in top.
+ * Return false if the given sector is allocated in intermediate images.
+ * Return true otherwise.
+ *
+ * 'pnum' is set to the number of sectors (including and immediately following
+ *  the specified sector) that are known to be in the same
+ *  allocated/unallocated state.
+ *
+ */
+static int coroutine_fn is_allocated_base(BlockDriverState *top,
+  BlockDriverState *base,
+  int64_t sector_num,
+  int nb_sectors, int *pnum)
+{
+BlockDriverState *intermediate;
+int ret, n;
+
+ret = bdrv_co_is_allocated(top, sector_num, nb_sectors, n);
+if (ret) {
+*pnum = n;
+return ret;
+}
+
+/*
+ * Is the unallocated chunk [sector_num, n] also
+ * unallocated between base and top?
+ */
+intermediate = top-backing_hd;
+
+while (intermediate) {
+int pnum_inter;
+
+/* reached base */
+if (intermediate == base) {
+*pnum = n;
+return 1;
+}
+ret = bdrv_co_is_allocated(intermediate, sector_num, nb_sectors,
+   pnum_inter);
+if (ret  0) {
+return ret;
+} else if (ret) {
+*pnum = pnum_inter;
+return 0;
+}
+
+/*
+ * [sector_num, nb_sectors] is unallocated on top but intermediate
+ * might have
+ *
+ * [sector_num+x, nr_sectors] allocated.
+ */
+if (n  pnum_inter) {
+n = pnum_inter;
+}
+
+intermediate = intermediate-backing_hd;
+}
+
+return 1;
+}
+
 static void coroutine_fn stream_run(void *opaque)
 {
 StreamBlockJob *s = opaque;
 BlockDriverState *bs = s-common.bs;
+BlockDriverState *base = s-base;
 int64_t sector_num, end;
 int ret = 0;
 int n;
@@ -101,8 +168,15 @@ retry:
 break;
 }
 
-ret = bdrv_co_is_allocated(bs, sector_num,
-   STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, n);
+
+if (base) {
+ret = is_allocated_base(bs, base, sector_num,
+STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, n);
+} else {
+ret = bdrv_co_is_allocated(bs, sector_num,
+   STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE,
+   n);
+}
 trace_stream_one_iteration(s, sector_num, n, ret);
 if (ret == 0) {
 if (s-common.speed) {
@@ -119,6 +193,7 @@ retry:
 if (ret  0) {
 break;
 }
+ret = 0;
 
 /* Publish progress */
 s-common.offset += n * BDRV_SECTOR_SIZE;
@@ -132,7 +207,11 @@ retry:
 bdrv_disable_copy_on_read(bs);
 
 if (sector_num == end  ret == 0) {
-ret = bdrv_change_backing_file(bs, NULL, NULL);
+const char *base_id = NULL;
+if (base) {
+base_id = s-backing_file_id;
+}
+ret = bdrv_change_backing_file(bs, base_id, NULL);
 }
 
 qemu_vfree(buf);
@@ -158,7 +237,8 @@ static BlockJobType stream_job_type = {
 };
 
 int stream_start(BlockDriverState *bs, BlockDriverState *base,
- BlockDriverCompletionFunc *cb, void *opaque)
+ const char *base_id, BlockDriverCompletionFunc *cb,
+ void *opaque)
 {
 StreamBlockJob *s;
 Coroutine *co;
@@ -169,6 +249,9 @@ int stream_start(BlockDriverState *bs, BlockDriverState 
*base,
 }
 
 s-base = base;
+if (base_id) {
+pstrcpy(s-backing_file_id, sizeof(s-backing_file_id), base_id);
+}
 
 co = qemu_coroutine_create(stream_run);
 trace_stream_start(bs, base, s, co, opaque);
diff --git a/block_int.h b/block_int.h
index c7c9178..ed92884 100644
--- a/block_int.h
+++ b/block_int.h
@@ 

[Qemu-devel] [PATCH] qemu-test: add device-del test case

2012-01-13 Thread Anthony Liguori
Signed-off-by: Anthony Liguori aligu...@us.ibm.com
---
 tests/device-del.sh |   91 +++
 1 files changed, 91 insertions(+), 0 deletions(-)
 create mode 100755 tests/device-del.sh

diff --git a/tests/device-del.sh b/tests/device-del.sh
new file mode 100755
index 000..3af4e2f
--- /dev/null
+++ b/tests/device-del.sh
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+canary=** waiting for hotplug **
+canary2=** waiting for remove **
+
+in_host() {
+tmpdisk=$tmpdir/disk.img
+
+# make sure to test various of -device, anonymous, and named
+extra_arg=`choose -device virtio-balloon-pci -device 
virtio-balloon-pci,id=balloon0 none`
+
+if test $extra_arg = none; then
+   extra_arg=
+fi
+
+qemu-img create -f qcow2 $tmpdisk 10G
+
+start_qemu -nographic -enable-kvm $extra_arg
+
+while qemu_is_okay; do
+   if grep $canary $tmplog /dev/null; then
+   out=`hmp drive_add auto file=$tmpdisk,if=none,id=hd0`
+   if test $(echo $out) != OK; then
+   echo drive_add failed!
+   echo $out
+   rm $tmpdisk
+   kill $pid
+   return 1
+   fi
+
+   qmp device_add --driver=virtio-blk-pci --drive=hd0 --id=hd0
+   rc=$?
+   if test $rc != 0; then
+   echo device_add failed!
+   rm $tmpdisk
+   kill $pid
+   return 1
+   fi
+
+   echo ** waiting for guest to see device **
+
+   while qemu_is_okay; do
+   if grep $canary2 $tmplog /dev/null; then
+   qmp device_del --id=hd0
+   rc=$?
+   if test $rc != 0; then
+   echo device_del failed!
+   rm $tmpdisk
+   kill $pid
+   return 1
+   fi
+
+   while qemu_is_okay; do
+   sleep 1
+   done
+
+   break
+   fi
+   sleep 1
+   done
+
+   break
+   fi
+   sleep 1
+done
+
+get_qemu_status
+rc=$?
+
+rm -f $tmpdisk
+
+return $rc
+}
+
+in_guest() {
+echo
+echo $canary
+while ! grep vda /proc/partitions /dev/null; do
+   sleep 1
+done
+echo $canary2
+while grep vda /proc/partitions /dev/null; do
+   sleep 1
+done
+}
+
+if test $QEMU_TEST; then
+in_host
+else
+in_guest
+fi
-- 
1.7.4.1




[Qemu-devel] [PATCH v5 12/15] add QERR_BASE_NOT_FOUND

2012-01-13 Thread Stefan Hajnoczi
From: Marcelo Tosatti mtosa...@redhat.com

This qerror will be raised when a given streaming base (backing file)
cannot be found.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 qapi-schema.json |1 +
 qerror.c |4 
 qerror.h |3 +++
 3 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index b4f6b15..b778639 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1335,6 +1335,7 @@
 #  If streaming is already active on this device, DeviceInUse
 #  If @device does not exist, DeviceNotFound
 #  If image streaming is not supported by this device, NotSupported
+#  If @base does not exist, BaseNotFound
 #
 # Since: 1.1
 ##
diff --git a/qerror.c b/qerror.c
index feb3d35..272243491 100644
--- a/qerror.c
+++ b/qerror.c
@@ -49,6 +49,10 @@ static const QErrorStringTable qerror_table[] = {
 .desc  = Device '%(device)' can't go on a %(bad_bus_type) bus,
 },
 {
+.error_fmt = QERR_BASE_NOT_FOUND,
+.desc  = Base '%(base)' not found,
+},
+{
 .error_fmt = QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
 .desc  = Block format '%(format)' used by device '%(name)' does 
not support feature '%(feature)',
 },
diff --git a/qerror.h b/qerror.h
index 095ba9d..4351fe3 100644
--- a/qerror.h
+++ b/qerror.h
@@ -54,6 +54,9 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_BAD_BUS_FOR_DEVICE \
 { 'class': 'BadBusForDevice', 'data': { 'device': %s, 'bad_bus_type': %s 
} }
 
+#define QERR_BASE_NOT_FOUND \
+{ 'class': 'BaseNotFound', 'data': { 'base': %s } }
+
 #define QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED \
 { 'class': 'BlockFormatFeatureNotSupported', 'data': { 'format': %s, 
'name': %s, 'feature': %s } }
 
-- 
1.7.7.3




[Qemu-devel] [PATCH 3/3] acpi_piix4: Call KVM_SETSTATE_VCPU ioctl on cpu ejection

2012-01-13 Thread Vasilis Liaskovitis

Signed-off-by: Vasilis Liaskovitis vasilis.liaskovi...@profitbricks.com
---
 hw/acpi_piix4.c |   21 +
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 8bf30dd..12eef55 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -502,6 +502,27 @@ static uint32_t cpuej_read(void *opaque, uint32_t addr)
 
 static void cpuej_write(void *opaque, uint32_t addr, uint32_t val)
 {
+struct kvm_vcpu_state state;
+CPUState *env;
+int cpu;
+int ret;
+
+cpu = ffs(val);
+/* zero means no bit was set, i.e. no CPU ejection happened */
+if (!cpu)
+   return;
+cpu--;
+env = cpu_phyid_to_cpu((uint64_t)cpu);
+if (env != NULL) {
+if (env-state == CPU_STATE_ZAPREQ) {
+state.vcpu_id = env-cpu_index;
+state.state = 1;
+ret = kvm_vm_ioctl(env-kvm_state, KVM_SETSTATE_VCPU, state);
+if (ret)
+fprintf(stderr, KVM_SETSTATE_VCPU failed: %s\n,
+strerror(ret));
+}
+}
 PIIX4_DPRINTF(cpuej write %x == %d\n, addr, val);
 }
 
-- 
1.7.7.3




[Qemu-devel] [PATCH v5 10/15] blockdev: make image streaming safe across hotplug

2012-01-13 Thread Stefan Hajnoczi
Unplugging a storage interface like virtio-blk causes the host block
device to be deleted too.  Long-running operations like block migration
must take a DriveInfo reference to prevent the BlockDriverState from
being freed.  For image streaming we can do the same thing.

Note that it is not possible to acquire/release the drive reference in
block.c where the block job functions live because
drive_get_ref()/drive_put_ref() are blockdev.c functions.  Calling them
from block.c would be a layering violation - tools like qemu-img don't
even link against blockdev.c.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c |   38 ++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 4549c9e..45a6ba6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -202,6 +202,37 @@ void drive_get_ref(DriveInfo *dinfo)
 dinfo-refcount++;
 }
 
+typedef struct {
+QEMUBH *bh;
+DriveInfo *dinfo;
+} DrivePutRefBH;
+
+static void drive_put_ref_bh(void *opaque)
+{
+DrivePutRefBH *s = opaque;
+
+drive_put_ref(s-dinfo);
+qemu_bh_delete(s-bh);
+g_free(s);
+}
+
+/*
+ * Release a drive reference in a BH
+ *
+ * It is not possible to use drive_put_ref() from a callback function when the
+ * callers still need the drive.  In such cases we schedule a BH to release the
+ * reference.
+ */
+static void drive_put_ref_bh_schedule(DriveInfo *dinfo)
+{
+DrivePutRefBH *s;
+
+s = g_new(DrivePutRefBH, 1);
+s-bh = qemu_bh_new(drive_put_ref_bh, s);
+s-dinfo = dinfo;
+qemu_bh_schedule(s-bh);
+}
+
 static int parse_block_error_action(const char *buf, int is_read)
 {
 if (!strcmp(buf, ignore)) {
@@ -917,6 +948,8 @@ static void block_stream_cb(void *opaque, int ret)
 monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj);
 }
 qobject_decref(obj);
+
+drive_put_ref_bh_schedule(drive_get_by_blockdev(bs));
 }
 
 void qmp_block_stream(const char *device, bool has_base,
@@ -949,6 +982,11 @@ void qmp_block_stream(const char *device, bool has_base,
 }
 }
 
+/* Grab a reference so hotplug does not delete the BlockDriverState from
+ * underneath us.
+ */
+drive_get_ref(drive_get_by_blockdev(bs));
+
 trace_qmp_block_stream(bs, bs-job);
 }
 
-- 
1.7.7.3




[Qemu-devel] [PATCH v5 06/15] qmp: add block_stream command

2012-01-13 Thread Stefan Hajnoczi
Add the block_stream command, which starts copy backing file contents
into the image file.  Also add the BLOCK_JOB_COMPLETED QMP event which
is emitted when image streaming completes.  Later patches add control
over the background copy speed, cancelation, and querying running
streaming operations.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 QMP/qmp-events.txt |   29 ++
 blockdev.c |   67 
 hmp-commands.hx|   13 ++
 hmp.c  |   11 
 hmp.h  |1 +
 monitor.c  |3 ++
 monitor.h  |1 +
 qapi-schema.json   |   32 
 qerror.c   |4 +++
 qerror.h   |3 ++
 qmp-commands.hx|6 
 trace-events   |4 +++
 12 files changed, 174 insertions(+), 0 deletions(-)

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index af586ec..0cd2275 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -264,3 +264,32 @@ Example:
 
 Note: If action is reset, shutdown, or pause the WATCHDOG event is
 followed respectively by the RESET, SHUTDOWN, or STOP events.
+
+
+BLOCK_JOB_COMPLETED
+---
+
+Emitted when a block job has completed.
+
+Data:
+
+- type: Job type (stream for image streaming, json-string)
+- device:   Device name (json-string)
+- len:  Maximum progress value (json-int)
+- offset:   Current progress value (json-int)
+  On success this is equal to len.
+  On failure this is less than len.
+- speed:Rate limit, bytes per second (json-int)
+- error:Error message (json-string, optional)
+  Only present on failure.  This field contains a human-readable
+  error message.  There are no semantics other than that streaming
+  has failed and clients should not try to interpret the error
+  string.
+
+Example:
+
+{ event: BLOCK_JOB_COMPLETED,
+ data: { type: stream, device: virtio-disk0,
+   len: 10737418240, offset: 10737418240,
+   speed: 0 },
+ timestamp: { seconds: 1267061043, microseconds: 959568 } }
diff --git a/blockdev.c b/blockdev.c
index 6d78b36..ba973b0 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -13,9 +13,11 @@
 #include qerror.h
 #include qemu-option.h
 #include qemu-config.h
+#include qemu-objects.h
 #include sysemu.h
 #include block_int.h
 #include qmp-commands.h
+#include trace.h
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = 
QTAILQ_HEAD_INITIALIZER(drives);
 
@@ -880,3 +882,68 @@ void qmp_block_resize(const char *device, int64_t size, 
Error **errp)
 return;
 }
 }
+
+static QObject *qobject_from_block_job(BlockJob *job)
+{
+return qobject_from_jsonf({ 'type': %s,
+  'device': %s,
+  'len': % PRId64 ,
+  'offset': % PRId64 ,
+  'speed': % PRId64  },
+  job-job_type-job_type,
+  bdrv_get_device_name(job-bs),
+  job-len,
+  job-offset,
+  job-speed);
+}
+
+static void block_stream_cb(void *opaque, int ret)
+{
+BlockDriverState *bs = opaque;
+QObject *obj;
+
+trace_block_stream_cb(bs, bs-job, ret);
+
+assert(bs-job);
+obj = qobject_from_block_job(bs-job);
+if (ret  0) {
+QDict *dict = qobject_to_qdict(obj);
+qdict_put(dict, error, qstring_from_str(strerror(-ret)));
+}
+
+monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj);
+qobject_decref(obj);
+}
+
+void qmp_block_stream(const char *device, bool has_base,
+  const char *base, Error **errp)
+{
+BlockDriverState *bs;
+int ret;
+
+bs = bdrv_find(device);
+if (!bs) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+return;
+}
+
+/* Base device not supported */
+if (base) {
+error_set(errp, QERR_NOT_SUPPORTED);
+return;
+}
+
+ret = stream_start(bs, NULL, block_stream_cb, bs);
+if (ret  0) {
+switch (ret) {
+case -EBUSY:
+error_set(errp, QERR_DEVICE_IN_USE, device);
+return;
+default:
+error_set(errp, QERR_NOT_SUPPORTED);
+return;
+}
+}
+
+trace_qmp_block_stream(bs, bs-job);
+}
diff --git a/hmp-commands.hx b/hmp-commands.hx
index a586498..dc6c8c3 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -69,6 +69,19 @@ but should be used with extreme caution.  Note that this 
command only
 resizes image files, it can not resize block devices like LVM volumes.
 ETEXI
 
+{
+.name   = block_stream,
+.args_type  = device:B,base:s?,
+.params = device [base],
+.help   = copy data from a backing file into a block device,
+.mhandler.cmd = hmp_block_stream,
+},
+

Re: [Qemu-devel] [PATCH 0/3] acpi_piix4: Add CPU eject handling

2012-01-13 Thread Vasilis Liaskovitis
On Fri, Jan 13, 2012 at 12:58:10PM +0100, Jan Kiszka wrote:
 Please work against upstream (uq/master for kvm-related patches), not
 qemu-kvm. It possibly makes no technical difference here, but we do not
 want to let the code bases needlessly diverge again. If if does make a
 difference and upstream lacks further bits, push them first.

Apologies, I will from now on.

thanks,

- Vasilis




[Qemu-devel] [PATCH v5 09/15] qmp: add query-block-jobs

2012-01-13 Thread Stefan Hajnoczi
Add query-block-jobs, which shows the progress of ongoing block device
operations.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c   |   33 +
 hmp.c|   36 
 hmp.h|1 +
 monitor.c|7 +++
 qapi-schema.json |   32 
 qmp-commands.hx  |6 ++
 6 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 35de3bc..4549c9e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -989,3 +989,36 @@ void qmp_block_job_cancel(const char *device, Error **errp)
 trace_qmp_block_job_cancel(job);
 block_job_cancel(job);
 }
+
+static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
+{
+BlockJobInfoList **prev = opaque;
+BlockJob *job = bs-job;
+
+if (job) {
+BlockJobInfoList *elem;
+BlockJobInfo *info = g_new(BlockJobInfo, 1);
+*info = (BlockJobInfo){
+.type   = g_strdup(job-job_type-job_type),
+.device = g_strdup(bdrv_get_device_name(bs)),
+.len= job-len,
+.offset = job-offset,
+.speed  = job-speed,
+};
+
+elem = g_new0(BlockJobInfoList, 1);
+elem-value = info;
+
+(*prev)-next = elem;
+*prev = elem;
+}
+}
+
+BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+{
+/* Dummy is a fake list element for holding the head pointer */
+BlockJobInfoList dummy = {};
+BlockJobInfoList *prev = dummy;
+bdrv_iterate(do_qmp_query_block_jobs_one, prev);
+return dummy.next;
+}
diff --git a/hmp.c b/hmp.c
index 851885b..76e89f8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -507,6 +507,42 @@ void hmp_info_pci(Monitor *mon)
 qapi_free_PciInfoList(info);
 }
 
+void hmp_info_block_jobs(Monitor *mon)
+{
+BlockJobInfoList *list;
+Error *err = NULL;
+
+list = qmp_query_block_jobs(err);
+assert(!err);
+
+if (!list) {
+monitor_printf(mon, No active jobs\n);
+return;
+}
+
+while (list) {
+if (strcmp(list-value-type, stream) == 0) {
+monitor_printf(mon, Streaming device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+} else {
+monitor_printf(mon, Type %s, device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-type,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+}
+list = list-next;
+}
+}
+
 void hmp_quit(Monitor *mon, const QDict *qdict)
 {
 monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index 0ad2004..23bfca2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -32,6 +32,7 @@ void hmp_info_vnc(Monitor *mon);
 void hmp_info_spice(Monitor *mon);
 void hmp_info_balloon(Monitor *mon);
 void hmp_info_pci(Monitor *mon);
+void hmp_info_block_jobs(Monitor *mon);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 01850ca..f96a296 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2483,6 +2483,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.info = hmp_info_blockstats,
 },
 {
+.name   = block-jobs,
+.args_type  = ,
+.params = ,
+.help   = show progress of ongoing block device operations,
+.mhandler.info = hmp_info_block_jobs,
+},
+{
 .name   = registers,
 .args_type  = ,
 .params = ,
diff --git a/qapi-schema.json b/qapi-schema.json
index 3d23ce2..b4f6b15 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -845,6 +845,38 @@
 { 'command': 'query-pci', 'returns': ['PciInfo'] }
 
 ##
+# @BlockJobInfo:
+#
+# Information about a long-running block device operation.
+#
+# @type: the job type ('stream' for image streaming)
+#
+# @device: the block device name
+#
+# @len: the maximum progress value
+#
+# @offset: the current progress value
+#
+# @speed: the rate limit, bytes per second
+#
+# Since: 1.1
+##
+{ 'type': 'BlockJobInfo',
+  'data': {'type': 'str', 'device': 'str', 'len': 'int',
+   'offset': 'int', 'speed': 'int'} }
+
+##
+# @query-block-jobs:
+#
+# Return information about long-running block device operations.
+#
+# Returns: a list of @BlockJobInfo for each active block job
+#
+# Since: 1.1
+##
+{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }
+
+##
 # @quit:
 #
 # This command will cause the 

[Qemu-devel] [PATCH v5 08/15] qmp: add block_job_cancel command

2012-01-13 Thread Stefan Hajnoczi
Add block_job_cancel, which stops an active block streaming operation.
When the operation has been cancelled the new BLOCK_JOB_CANCELLED event
is emitted.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 QMP/qmp-events.txt |   24 
 blockdev.c |   19 ++-
 hmp-commands.hx|   14 ++
 hmp.c  |   10 ++
 hmp.h  |1 +
 monitor.c  |3 +++
 monitor.h  |1 +
 qapi-schema.json   |   29 +
 qmp-commands.hx|6 ++
 trace-events   |1 +
 10 files changed, 107 insertions(+), 1 deletions(-)

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index 0cd2275..06cb404 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -293,3 +293,27 @@ Example:
len: 10737418240, offset: 10737418240,
speed: 0 },
  timestamp: { seconds: 1267061043, microseconds: 959568 } }
+
+
+BLOCK_JOB_CANCELLED
+---
+
+Emitted when a block job has been cancelled.
+
+Data:
+
+- type: Job type (stream for image streaming, json-string)
+- device:   Device name (json-string)
+- len:  Maximum progress value (json-int)
+- offset:   Current progress value (json-int)
+  On success this is equal to len.
+  On failure this is less than len.
+- speed:Rate limit, bytes per second (json-int)
+
+Example:
+
+{ event: BLOCK_JOB_CANCELLED,
+ data: { type: stream, device: virtio-disk0,
+   len: 10737418240, offset: 134217728,
+   speed: 0 },
+ timestamp: { seconds: 1267061043, microseconds: 959568 } }
diff --git a/blockdev.c b/blockdev.c
index 2dfca40..35de3bc 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -911,7 +911,11 @@ static void block_stream_cb(void *opaque, int ret)
 qdict_put(dict, error, qstring_from_str(strerror(-ret)));
 }
 
-monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj);
+if (block_job_is_cancelled(bs-job)) {
+monitor_protocol_event(QEVENT_BLOCK_JOB_CANCELLED, obj);
+} else {
+monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj);
+}
 qobject_decref(obj);
 }
 
@@ -972,3 +976,16 @@ void qmp_block_job_set_speed(const char *device, int64_t 
value, Error **errp)
 error_set(errp, QERR_NOT_SUPPORTED);
 }
 }
+
+void qmp_block_job_cancel(const char *device, Error **errp)
+{
+BlockJob *job = find_block_job(device);
+
+if (!job) {
+error_set(errp, QERR_DEVICE_NOT_ACTIVE, device);
+return;
+}
+
+trace_qmp_block_job_cancel(job);
+block_job_cancel(job);
+}
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 12b8433..b991ee0 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -98,6 +98,20 @@ Set maximum speed for a background block operation.
 ETEXI
 
 {
+.name   = block_job_cancel,
+.args_type  = device:B,
+.params = device,
+.help   = stop an active block streaming operation,
+.mhandler.cmd = hmp_block_job_cancel,
+},
+
+STEXI
+@item block_job_cancel
+@findex block_job_cancel
+Stop an active block streaming operation.
+ETEXI
+
+{
 .name   = eject,
 .args_type  = force:-f,device:B,
 .params = [-f] device,
diff --git a/hmp.c b/hmp.c
index 1144d53..851885b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -701,3 +701,13 @@ void hmp_block_job_set_speed(Monitor *mon, const QDict 
*qdict)
 
 hmp_handle_error(mon, error);
 }
+
+void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
+{
+Error *error = NULL;
+const char *device = qdict_get_str(qdict, device);
+
+qmp_block_job_cancel(device, error);
+
+hmp_handle_error(mon, error);
+}
diff --git a/hmp.h b/hmp.h
index 2c871ea..0ad2004 100644
--- a/hmp.h
+++ b/hmp.h
@@ -51,5 +51,6 @@ void hmp_migrate_set_downtime(Monitor *mon, const QDict 
*qdict);
 void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_stream(Monitor *mon, const QDict *qdict);
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
+void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/monitor.c b/monitor.c
index bb42580..01850ca 100644
--- a/monitor.c
+++ b/monitor.c
@@ -482,6 +482,9 @@ void monitor_protocol_event(MonitorEvent event, QObject 
*data)
 case QEVENT_BLOCK_JOB_COMPLETED:
 event_name = BLOCK_JOB_COMPLETED;
 break;
+case QEVENT_BLOCK_JOB_CANCELLED:
+event_name = BLOCK_JOB_CANCELLED;
+break;
 default:
 abort();
 break;
diff --git a/monitor.h b/monitor.h
index 7324236..86c997d 100644
--- a/monitor.h
+++ b/monitor.h
@@ -36,6 +36,7 @@ typedef enum MonitorEvent {
 QEVENT_SPICE_INITIALIZED,
 QEVENT_SPICE_DISCONNECTED,
 QEVENT_BLOCK_JOB_COMPLETED,
+QEVENT_BLOCK_JOB_CANCELLED,
 QEVENT_MAX,
 } MonitorEvent;
 
diff --git a/qapi-schema.json b/qapi-schema.json
index 

Re: [Qemu-devel] [0/9] Bugfixes and pseries enhancements

2012-01-13 Thread Alexander Graf

On 12.01.2012, at 06:46, David Gibson wrote:

 This series has two parts.  THe first has a few bugfixes for generic
 qemu code.  The second has a number of pseries machine specific
 enhancements and bugfixes.  They are included in the one series
 because some of the pseries specific patches rely on the generic
 bugfixes (in the sense that they expose the bugs more badly than they
 were previously).
 
 I've posted some of the generic fixes before, this series respins the
 first one (load_image_targphys()) with a minor tweak, the rest are
 unchanged.
 


I put all of them in my tree for now, waiting for you to figure the PCI host 
limit piece out with Michael.


Alex




Re: [Qemu-devel] [PATCH v9 0/6] arm: add support for Calxeda Highbank SoC

2012-01-13 Thread Andreas Färber
Am 13.01.2012 13:14, schrieb Peter Maydell:
 On 11 January 2012 22:41, Peter Maydell peter.mayd...@linaro.org wrote:
 Does anybody object to my taking the AHCI patches along with this
 series via arm-devs.next ? (other than patch v4 which goes via
 target-arm.next)
 
 [I got an Acked-by: from Kevin over irc regarding these and will do this.]

FWIW I don't object. Either the maintainership of AHCI doesn't fall
under IDE or Kevin is busy - possibly both?

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 v9 0/6] arm: add support for Calxeda Highbank SoC

2012-01-13 Thread Alexander Graf

On 13.01.2012, at 15:15, Andreas Färber wrote:

 Am 13.01.2012 13:14, schrieb Peter Maydell:
 On 11 January 2012 22:41, Peter Maydell peter.mayd...@linaro.org wrote:
 Does anybody object to my taking the AHCI patches along with this
 series via arm-devs.next ? (other than patch v4 which goes via
 target-arm.next)
 
 [I got an Acked-by: from Kevin over irc regarding these and will do this.]
 
 FWIW I don't object. Either the maintainership of AHCI doesn't fall
 under IDE or Kevin is busy - possibly both?

It falls under IDE and Kevin acked them :)


Alex




[Qemu-devel] [PATCH 0/3] acpi_piix4: Add CPU eject handling

2012-01-13 Thread Vasilis Liaskovitis
This patch series adds support for CPU _EJ0 callback in Seabios and qemu-kvm.
The first patch defines the CPU eject bitmap in Seabios and writes to it
during the callback. The second patch adds empty stub functions to qemu-kvm to
handle the bitmap writes.

The third patch defines the eject method to handle the CPU_DEAD event
in Liu Ping Fan's cpu lifecycle/destruction patchseries, see:
http://patchwork.ozlabs.org/patch/127832/
This ACPI implementation can be used instead of the cpustate virtio/pci device
in the original series.

Vasilis Liaskovitis (2):
  acpi_piix4: Add CPU ejection handling
  acpi_piix4: Call KVM_SETSTATE_VCPU ioctl on cpu ejection

 hw/acpi_piix4.c |   36 
 1 files changed, 36 insertions(+), 0 deletions(-)

-- 
1.7.7.3




[Qemu-devel] [PATCH v5 03/15] block: add BlockJob interface for long-running operations

2012-01-13 Thread Stefan Hajnoczi
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block.c |   48 
 block_int.h |   40 
 2 files changed, 88 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index daf92c2..d588ee8 100644
--- a/block.c
+++ b/block.c
@@ -3877,3 +3877,51 @@ out:
 
 return ret;
 }
+
+void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
+   BlockDriverCompletionFunc *cb, void *opaque)
+{
+BlockJob *job;
+
+if (bs-job || bdrv_in_use(bs)) {
+return NULL;
+}
+bdrv_set_in_use(bs, 1);
+
+job = g_malloc0(job_type-instance_size);
+job-job_type  = job_type;
+job-bs= bs;
+job-cb= cb;
+job-opaque= opaque;
+bs-job = job;
+return job;
+}
+
+void block_job_complete(BlockJob *job, int ret)
+{
+BlockDriverState *bs = job-bs;
+
+assert(bs-job == job);
+job-cb(job-opaque, ret);
+bs-job = NULL;
+g_free(job);
+bdrv_set_in_use(bs, 0);
+}
+
+int block_job_set_speed(BlockJob *job, int64_t value)
+{
+if (!job-job_type-set_speed) {
+return -ENOTSUP;
+}
+return job-job_type-set_speed(job, value);
+}
+
+void block_job_cancel(BlockJob *job)
+{
+job-cancelled = true;
+}
+
+bool block_job_is_cancelled(BlockJob *job)
+{
+return job-cancelled;
+}
diff --git a/block_int.h b/block_int.h
index 5362180..316443e 100644
--- a/block_int.h
+++ b/block_int.h
@@ -69,6 +69,36 @@ typedef struct BlockIOBaseValue {
 uint64_t ios[2];
 } BlockIOBaseValue;
 
+typedef void BlockJobCancelFunc(void *opaque);
+typedef struct BlockJob BlockJob;
+typedef struct BlockJobType {
+/** Derived BlockJob struct size */
+size_t instance_size;
+
+/** String describing the operation, part of query-block-jobs QMP API */
+const char *job_type;
+
+/** Optional callback for job types that support setting a speed limit */
+int (*set_speed)(BlockJob *job, int64_t value);
+} BlockJobType;
+
+/**
+ * Long-running operation on a BlockDriverState
+ */
+struct BlockJob {
+const BlockJobType *job_type;
+BlockDriverState *bs;
+bool cancelled;
+
+/* These fields are published by the query-block-jobs QMP API */
+int64_t offset;
+int64_t len;
+int64_t speed;
+
+BlockDriverCompletionFunc *cb;
+void *opaque;
+};
+
 struct BlockDriver {
 const char *format_name;
 int instance_size;
@@ -269,6 +299,9 @@ struct BlockDriverState {
 void *private;
 
 QLIST_HEAD(, BdrvTrackedRequest) tracked_requests;
+
+/* long-running background operation */
+BlockJob *job;
 };
 
 struct BlockDriverAIOCB {
@@ -292,4 +325,11 @@ void bdrv_set_io_limits(BlockDriverState *bs,
 int is_windows_drive(const char *filename);
 #endif
 
+void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
+   BlockDriverCompletionFunc *cb, void *opaque);
+void block_job_complete(BlockJob *job, int ret);
+int block_job_set_speed(BlockJob *job, int64_t value);
+void block_job_cancel(BlockJob *job);
+bool block_job_is_cancelled(BlockJob *job);
+
 #endif /* BLOCK_INT_H */
-- 
1.7.7.3




Re: [Qemu-devel] [PATCH 3/3] acpi_piix4: Call KVM_SETSTATE_VCPU ioctl on cpu ejection

2012-01-13 Thread Vasilis Liaskovitis
On Fri, Jan 13, 2012 at 12:58:53PM +0100, Jan Kiszka wrote:
 On 2012-01-13 12:11, Vasilis Liaskovitis wrote:
  Signed-off-by: Vasilis Liaskovitis vasilis.liaskovi...@profitbricks.com
  ---
   hw/acpi_piix4.c |   21 +
   1 files changed, 21 insertions(+), 0 deletions(-)
  
  diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
  index 8bf30dd..12eef55 100644
  --- a/hw/acpi_piix4.c
  +++ b/hw/acpi_piix4.c
  @@ -502,6 +502,27 @@ static uint32_t cpuej_read(void *opaque, uint32_t addr)
   
   static void cpuej_write(void *opaque, uint32_t addr, uint32_t val)
   {
  +struct kvm_vcpu_state state;
  +CPUState *env;
  +int cpu;
  +int ret;
  +
  +cpu = ffs(val);
  +/* zero means no bit was set, i.e. no CPU ejection happened */
  +if (!cpu)
  +   return;
  +cpu--;
  +env = cpu_phyid_to_cpu((uint64_t)cpu);
  +if (env != NULL) {
  +if (env-state == CPU_STATE_ZAPREQ) {
  +state.vcpu_id = env-cpu_index;
  +state.state = 1;
  +ret = kvm_vm_ioctl(env-kvm_state, KVM_SETSTATE_VCPU, state);
 
 That breaks in the absence of KVM or if it is not enabled.

Right, I will rework.

Do we expect icc-bus related changes on a CPU unplug? This patch does not
handle this yet.

 
 Also, where was this IOCTL introduced? Where are the linux header changes?


The headers are here:
http://patchwork.ozlabs.org/patch/127834/

And the ioctl is introduced here:
http://patchwork.ozlabs.org/patch/127828/

Though the actual ioctl code seems to have dropped through the cracks in the
above patch. A sample implementation against 3.1.0 is below, but I have not
included it in the patch series. I expect the ioctl implementation to be part
of Liu 's kernel kvm-related series. In any case, this third patch depends on
the cpu zap/lifecycle patchseries and perhaps should be reviewed separately
from the first 2.

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6d3a724..8dd9ebd 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2095,6 +2095,22 @@ static long kvm_vm_ioctl(struct file *filp,
r = kvm_ioeventfd(kvm, data);
break;
}
+   case KVM_SETSTATE_VCPU: {
+   struct kvm_vcpu_state vcpu_state;
+   struct kvm_vcpu *vcpu;
+   int idx;
+   r = -EFAULT;
+   if (copy_from_user(vcpu_state, argp,
+   sizeof(struct kvm_vcpu_state)))
+   goto out;
+   idx = srcu_read_lock(kvm-srcu);
+   kvm_for_each_vcpu(vcpu, kvm)
+   if (vcpu_state.vcpu_id == vcpu-vcpu_id)
+   vcpu-state = vcpu_state.state;
+   srcu_read_unlock(kvm-srcu, idx);
+   r = 0;
+   break;
+   }
 #ifdef CONFIG_KVM_APIC_ARCHITECTURE
case KVM_SET_BOOT_CPU_ID:
r = 0;



Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Andreas Färber
Am 13.01.2012 13:30, schrieb Alexander Graf:
 
 On 13.01.2012, at 12:45, Paolo Bonzini wrote:
 
 On 01/13/2012 12:04 PM, Andreas Färber wrote:
  This board never worked with TCG.  It hasn't been updated since 
 0.13.0.  I'm
  fairly sure hardware doesn't exist anymore that you can run the KVM 
 support
  with.

  It does exist, I have one:-)
 Alex has already posted series to not only qdev'ify it but to also add
 TCG support so other people can test it. Review and testing would
 probably be appreciated.:)

 The work that you guys are putting in modernizing the PPC boards is really 
 cool.  Please, let's start working on the 1.1 changelog now so that it 
 doesn't get lost!
 
 Good point :). I'm not sure how useful something like Qdev'ified board xxx 
 really is in a changelog though. It's mostly invisible to users.

This is inviting a flame war on whether users read Change Logs and
whether a Change Log needs to be useful to them. ;)

I concur with Paolo that TCG support for Bamboo is worth mentioning
(user-visible feature) and so would a new, real PReP machine if we
manage in time. The conversions could be summarized under a QOM heading.
But since neither has been applied to master yet, we should wait with
the Change Log update. But thanks for the reminder, good idea!

Andreas

http://wiki.qemu.org/ChangeLog/1.1

-- 
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] Serious regression of 9p read performance, huge amount of openat syscalls on plain file descriptors

2012-01-13 Thread Lutz Vieweg

The regression does not exist in the way that I suspected - it's just
that the default for 9p mount option msize=4096 causes the bad
performance when reading large files on the guest.

I was mislead because...

a) mount -o remount,msize=...,...
   seems to work (with mount reporting the changed value afterwards),
   but it doesn't - only the msize chosen at first mount time is relevant/used.

b) gdb lied to me:
  catch syscall openat
 Catchpoint 1 (syscall 'openat' [295])
   I learned the hard way that the system supplied gdb made wrong assumptions
   on which syscall number is associated with what function.
   In fact, the so often used syscall was preadv, not openat.

Thus my only suggestion is to change the default for msize=
to 131072 (128k), this results in a speed up from ~ 30MB/s to ~ 290MB/s
in the large-file reading use case.

Regards,

Lutz Vieweg


On 01/12/2012 07:42 PM, Lutz Vieweg wrote:

Hi all,

I have been using 9p mounts on guests for quite some time, and enjoyed
their nice performance.

But not anymore: I noticed that just dd-ing large plain files to /dev/zero
on the guest system became very slow, even if the data is completely
in the cache of the host. The rate maxes at ~ 30MB/s while the qemu process
on the host eats lots of CPU).
Both qemu (from source repository) and host kernel (3.1.6)
were upgraded since the last good benchmark, so this could be the
result of some recent change...

Looking for the cause I noticed that the qemu process, according to strace,
does an insane amount of openat syscalls - about 820 per second! - while
the guest system is reading the file (in 64kB chunks, if that matters).
I guess it's no wonder that this huge amount of open operations per
second will slow down whatever I/O qemu is trying to do.

Especially strange is that the fds passed into the openat syscall as the
first parameter refers to the file being read (not the directory it is in,
which has a different fd), according to lsof.
And the openat syscall always returns 0x1000 as a result (if strace is not
lying), which is neither a credible fd, nor an errno I'd know of:


[pid 29236] syscall_295(0x1b, 0x7fe46044a670, 0x1, 0x109e000, 0, 0, 
0x7fe46034ae00,
0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 
0x7fe46034ae00,
0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 
0x7fe46034ae00,
0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 
0x7fe46034ae00,
0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 0x7fe46034ae00, 
0x7fe46034ae00,
0x7fe46034ae00 unfinished ...
[pid 29236] ... syscall_295 resumed ) = 0x1000
[pid 29235] syscall_295(0x1c, 0x7fe4659d8070, 0x1, 0x16df000, 0, 0, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800 unfinished ...
[pid 29235] ... syscall_295 resumed ) = 0x1000
[pid 29234] syscall_295(0x1b, 0x7fe4659d8070, 0x1, 0x109f000, 0, 0, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 0x7fe4658d8800, 
0x7fe4658d8800,
0x7fe4658d8800 unfinished ...
[pid 29234] ... syscall_295 resumed ) = 0x1000


Alas, I could not get gdb to tell me exactly where those openat calls are
made from (in the qemu-kvm source) - the functions that contain those calls
are static and seem to become inlined.

Does anyone have an idea what may have caused this? Do you still see
good read performance when reading big plain files from a 9p mount.

Regards,

Lutz Vieweg









Re: [Qemu-devel] [PATCH 03/30] ppc: remove ppc440 bamboo board support

2012-01-13 Thread Alexander Graf

On 13.01.2012, at 15:24, Andreas Färber wrote:

 Am 13.01.2012 13:30, schrieb Alexander Graf:
 
 On 13.01.2012, at 12:45, Paolo Bonzini wrote:
 
 On 01/13/2012 12:04 PM, Andreas Färber wrote:
 This board never worked with TCG.  It hasn't been updated since 
 0.13.0.  I'm
 fairly sure hardware doesn't exist anymore that you can run the KVM 
 support
 with.
 
 It does exist, I have one:-)
 Alex has already posted series to not only qdev'ify it but to also add
 TCG support so other people can test it. Review and testing would
 probably be appreciated.:)
 
 The work that you guys are putting in modernizing the PPC boards is really 
 cool.  Please, let's start working on the 1.1 changelog now so that it 
 doesn't get lost!
 
 Good point :). I'm not sure how useful something like Qdev'ified board xxx 
 really is in a changelog though. It's mostly invisible to users.
 
 This is inviting a flame war on whether users read Change Logs and
 whether a Change Log needs to be useful to them. ;)

Users read changelogs. Packagers read changelogs. QEMU Developers read mailing 
lists. Libvirt developers might read changelogs. Qdev is a QEMU developer 
visible feature, so it doesn't belong into the changelog. Unless you want to 
argue that it makes stuff available through -device at which point it's 
management tool visible. Oh well. I probably just don't want to bloat it too 
much :).

 I concur with Paolo that TCG support for Bamboo is worth mentioning
 (user-visible feature) and so would a new, real PReP machine if we
 manage in time.

Yes, both definitely should show up!

 The conversions could be summarized under a QOM heading.
 But since neither has been applied to master yet, we should wait with
 the Change Log update. But thanks for the reminder, good idea!

If it's been posted on the ML, nobody complained on it and it's in the 
maintainer's queue, it's fine to update the changelog imho :).


Alex

 
 Andreas
 
 http://wiki.qemu.org/ChangeLog/1.1
 
 -- 
 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 v9 0/6] arm: add support for Calxeda Highbank SoC

2012-01-13 Thread Andreas Färber
Am 13.01.2012 15:18, schrieb Alexander Graf:
 
 On 13.01.2012, at 15:15, Andreas Färber wrote:
 
 Am 13.01.2012 13:14, schrieb Peter Maydell:
 On 11 January 2012 22:41, Peter Maydell peter.mayd...@linaro.org wrote:
 Does anybody object to my taking the AHCI patches along with this
 series via arm-devs.next ? (other than patch v4 which goes via
 target-arm.next)

 [I got an Acked-by: from Kevin over irc regarding these and will do this.]

 FWIW I don't object. Either the maintainership of AHCI doesn't fall
 under IDE or Kevin is busy - possibly both?
 
 It falls under IDE and Kevin acked them :)

My RFC didn't get any review or testing yet, not from you either. ;(

(But that is foremost waiting for Juan to comment on the VMState size
issue the Samsung guys and me ran into. And it's in no way urgent for me
currently or I would've ping'ed it already.)

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 v9 0/6] arm: add support for Calxeda Highbank SoC

2012-01-13 Thread Alexander Graf

On 13.01.2012, at 15:31, Andreas Färber wrote:

 Am 13.01.2012 15:18, schrieb Alexander Graf:
 
 On 13.01.2012, at 15:15, Andreas Färber wrote:
 
 Am 13.01.2012 13:14, schrieb Peter Maydell:
 On 11 January 2012 22:41, Peter Maydell peter.mayd...@linaro.org wrote:
 Does anybody object to my taking the AHCI patches along with this
 series via arm-devs.next ? (other than patch v4 which goes via
 target-arm.next)
 
 [I got an Acked-by: from Kevin over irc regarding these and will do this.]
 
 FWIW I don't object. Either the maintainership of AHCI doesn't fall
 under IDE or Kevin is busy - possibly both?
 
 It falls under IDE and Kevin acked them :)
 
 My RFC didn't get any review or testing yet, not from you either. ;(

I'm sure he's still busy catching up on his email. He only got back this week :)

 (But that is foremost waiting for Juan to comment on the VMState size
 issue the Samsung guys and me ran into. And it's in no way urgent for me
 currently or I would've ping'ed it already.)

Yup, that's the one big thing I would like to see addressed first too.


Alex




[Qemu-devel] [PATCH v5 05/15] block: rate-limit streaming operations

2012-01-13 Thread Stefan Hajnoczi
This patch implements rate-limiting for image streaming.  If we've
exceeded the bandwidth quota for a 100 ms time slice we sleep the
coroutine until the next slice begins.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 block/stream.c |   65 ++-
 1 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/block/stream.c b/block/stream.c
index 5255a61..93f0305 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -23,8 +23,39 @@ enum {
 STREAM_BUFFER_SIZE = 512 * 1024, /* in bytes */
 };
 
+#define SLICE_TIME 1ULL /* ns */
+
+typedef struct {
+int64_t next_slice_time;
+uint64_t slice_quota;
+uint64_t dispatched;
+} RateLimit;
+
+static int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
+{
+int64_t delay_ns = 0;
+int64_t now = qemu_get_clock_ns(rt_clock);
+
+if (limit-next_slice_time  now) {
+limit-next_slice_time = now + SLICE_TIME;
+limit-dispatched = 0;
+}
+if (limit-dispatched + n  limit-slice_quota) {
+delay_ns = limit-next_slice_time - now;
+} else {
+limit-dispatched += n;
+}
+return delay_ns;
+}
+
+static void ratelimit_set_speed(RateLimit *limit, uint64_t speed)
+{
+limit-slice_quota = speed / (10ULL / SLICE_TIME);
+}
+
 typedef struct StreamBlockJob {
 BlockJob common;
+RateLimit limit;
 BlockDriverState *base;
 } StreamBlockJob;
 
@@ -65,20 +96,24 @@ static void coroutine_fn stream_run(void *opaque)
 bdrv_enable_copy_on_read(bs);
 
 for (sector_num = 0; sector_num  end; sector_num += n) {
+retry:
 if (block_job_is_cancelled(s-common)) {
 break;
 }
 
-/* TODO rate-limit */
-/* Note that even when no rate limit is applied we need to yield with
- * no pending I/O here so that qemu_aio_flush() is able to return.
- */
-co_sleep_ns(rt_clock, 0);
-
 ret = bdrv_co_is_allocated(bs, sector_num,
STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, n);
 trace_stream_one_iteration(s, sector_num, n, ret);
 if (ret == 0) {
+if (s-common.speed) {
+uint64_t delay_ns = ratelimit_calculate_delay(s-limit, n);
+if (delay_ns  0) {
+co_sleep_ns(rt_clock, delay_ns);
+
+/* Recheck cancellation and that sectors are unallocated */
+goto retry;
+}
+}
 ret = stream_populate(bs, sector_num, n, buf);
 }
 if (ret  0) {
@@ -87,6 +122,11 @@ static void coroutine_fn stream_run(void *opaque)
 
 /* Publish progress */
 s-common.offset += n * BDRV_SECTOR_SIZE;
+
+/* Note that even when no rate limit is applied we need to yield
+ * with no pending I/O here so that qemu_aio_flush() returns.
+ */
+co_sleep_ns(rt_clock, 0);
 }
 
 bdrv_disable_copy_on_read(bs);
@@ -99,9 +139,22 @@ static void coroutine_fn stream_run(void *opaque)
 block_job_complete(s-common, ret);
 }
 
+static int stream_set_speed(BlockJob *job, int64_t value)
+{
+StreamBlockJob *s = container_of(job, StreamBlockJob, common);
+
+if (value  0) {
+return -EINVAL;
+}
+job-speed = value;
+ratelimit_set_speed(s-limit, value / BDRV_SECTOR_SIZE);
+return 0;
+}
+
 static BlockJobType stream_job_type = {
 .instance_size = sizeof(StreamBlockJob),
 .job_type  = stream,
+.set_speed = stream_set_speed,
 };
 
 int stream_start(BlockDriverState *bs, BlockDriverState *base,
-- 
1.7.7.3




[Qemu-devel] [PATCH v5 04/15] block: add image streaming block job

2012-01-13 Thread Stefan Hajnoczi
Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 Makefile.objs  |1 +
 block/stream.c |  124 
 block_int.h|3 +
 trace-events   |4 ++
 4 files changed, 132 insertions(+), 0 deletions(-)
 create mode 100644 block/stream.c

diff --git a/Makefile.objs b/Makefile.objs
index f4f52e0..949308d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -35,6 +35,7 @@ block-nested-y += qcow2.o qcow2-refcount.o qcow2-cluster.o 
qcow2-snapshot.o qcow
 block-nested-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-nested-y += qed-check.o
 block-nested-y += parallels.o nbd.o blkdebug.o sheepdog.o blkverify.o
+block-nested-y += stream.o
 block-nested-$(CONFIG_WIN32) += raw-win32.o
 block-nested-$(CONFIG_POSIX) += raw-posix.o
 block-nested-$(CONFIG_LIBISCSI) += iscsi.o
diff --git a/block/stream.c b/block/stream.c
new file mode 100644
index 000..5255a61
--- /dev/null
+++ b/block/stream.c
@@ -0,0 +1,124 @@
+/*
+ * Image streaming
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Stefan Hajnoczi   stefa...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include trace.h
+#include block_int.h
+
+enum {
+/*
+ * Size of data buffer for populating the image file.  This should be large
+ * enough to process multiple clusters in a single call, so that populating
+ * contiguous regions of the image is efficient.
+ */
+STREAM_BUFFER_SIZE = 512 * 1024, /* in bytes */
+};
+
+typedef struct StreamBlockJob {
+BlockJob common;
+BlockDriverState *base;
+} StreamBlockJob;
+
+static int coroutine_fn stream_populate(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors,
+void *buf)
+{
+struct iovec iov = {
+.iov_base = buf,
+.iov_len  = nb_sectors * BDRV_SECTOR_SIZE,
+};
+QEMUIOVector qiov;
+
+qemu_iovec_init_external(qiov, iov, 1);
+
+/* Copy-on-read the unallocated clusters */
+return bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+}
+
+static void coroutine_fn stream_run(void *opaque)
+{
+StreamBlockJob *s = opaque;
+BlockDriverState *bs = s-common.bs;
+int64_t sector_num, end;
+int ret = 0;
+int n;
+void *buf;
+
+s-common.len = bdrv_getlength(bs);
+if (s-common.len  0) {
+block_job_complete(s-common, s-common.len);
+return;
+}
+
+end = s-common.len  BDRV_SECTOR_BITS;
+buf = qemu_blockalign(bs, STREAM_BUFFER_SIZE);
+
+bdrv_enable_copy_on_read(bs);
+
+for (sector_num = 0; sector_num  end; sector_num += n) {
+if (block_job_is_cancelled(s-common)) {
+break;
+}
+
+/* TODO rate-limit */
+/* Note that even when no rate limit is applied we need to yield with
+ * no pending I/O here so that qemu_aio_flush() is able to return.
+ */
+co_sleep_ns(rt_clock, 0);
+
+ret = bdrv_co_is_allocated(bs, sector_num,
+   STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, n);
+trace_stream_one_iteration(s, sector_num, n, ret);
+if (ret == 0) {
+ret = stream_populate(bs, sector_num, n, buf);
+}
+if (ret  0) {
+break;
+}
+
+/* Publish progress */
+s-common.offset += n * BDRV_SECTOR_SIZE;
+}
+
+bdrv_disable_copy_on_read(bs);
+
+if (sector_num == end  ret == 0) {
+ret = bdrv_change_backing_file(bs, NULL, NULL);
+}
+
+qemu_vfree(buf);
+block_job_complete(s-common, ret);
+}
+
+static BlockJobType stream_job_type = {
+.instance_size = sizeof(StreamBlockJob),
+.job_type  = stream,
+};
+
+int stream_start(BlockDriverState *bs, BlockDriverState *base,
+ BlockDriverCompletionFunc *cb, void *opaque)
+{
+StreamBlockJob *s;
+Coroutine *co;
+
+s = block_job_create(stream_job_type, bs, cb, opaque);
+if (!s) {
+return -EBUSY; /* bs must already be in use */
+}
+
+s-base = base;
+
+co = qemu_coroutine_create(stream_run);
+trace_stream_start(bs, base, s, co, opaque);
+qemu_coroutine_enter(co, s);
+return 0;
+}
diff --git a/block_int.h b/block_int.h
index 316443e..c7c9178 100644
--- a/block_int.h
+++ b/block_int.h
@@ -332,4 +332,7 @@ int block_job_set_speed(BlockJob *job, int64_t value);
 void block_job_cancel(BlockJob *job);
 bool block_job_is_cancelled(BlockJob *job);
 
+int stream_start(BlockDriverState *bs, BlockDriverState *base,
+ BlockDriverCompletionFunc *cb, void *opaque);
+
 #endif /* BLOCK_INT_H */
diff --git a/trace-events b/trace-events
index 360f039..c5368fa 100644
--- a/trace-events
+++ b/trace-events
@@ -70,6 +70,10 @@ bdrv_co_write_zeroes(void *bs, int64_t sector_num, int 
nb_sector) bs %p sector_
 bdrv_co_io_em(void *bs, 

  1   2   3   >