Re: [Qemu-devel] [PATCH 0/3] vga: add mmio bar

2012-10-15 Thread Gerd Hoffmann
  Hi,

 Patches don't apply, please rebase:
 Applying: vga: add mmio bar to standard vga
 error: patch failed: hw/pc_piix.c:371
 error: hw/pc_piix.c: patch does not apply
 error: patch failed: hw/vga-pci.c:47
 error: hw/vga-pci.c: patch does not apply
 Patch failed at 0001 vga: add mmio bar to standard vga

Rebased  resolved.

 Also checkpatch.pl complains for 1/3:
 WARNING: suspect code indent for conditional statements (5, 9)
 #212: FILE: hw/vga-pci.c:158:
 + if (d-flags  (1  PCI_VGA_FLAG_ENABLE_MMIO)) {
 + memory_region_init(d-mmio, vga.mmio, 4096);

Ah, finally figured where this comes from.  It's not in this patch, but
the *existing* intention is wrong (5 instead of 4 spaces).  Fixed.

v2 is on the way.

cheers,
  Gerd



[Qemu-devel] [PATCH v2 0/4] vga: add mmio bar

2012-10-15 Thread Gerd Hoffmann
  Hi,

This patch series adds a mmio bar to the standard vga.  It also drops
a file into docs/specs/ describing the mmio bar and the other properties
of the qemu standard vga and does a little cleanup by removing
CONFIG_BOCHS_VBE.

v2:
 - rebase to latest master and resolve conflicts.
 - add patch which fixes indention to fix the WARNING: suspect code
   indent checkpatch warning.

cheers,
  Gerd

Gerd Hoffmann (4):
  vga: fix indention
  vga: add mmio bar to standard vga
  vga: add specs for standard vga
  vga: remove CONFIG_BOCHS_VBE

 docs/specs/standard-vga.txt |   64 
 hw/pc_piix.c|4 +
 hw/vga-isa.c|2 +
 hw/vga-pci.c|  138 ++
 hw/vga.c|   40 +++--
 hw/vga_int.h|   30 --
 6 files changed, 213 insertions(+), 65 deletions(-)
 create mode 100644 docs/specs/standard-vga.txt




[Qemu-devel] [PATCH v2 3/4] vga: add specs for standard vga

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 docs/specs/standard-vga.txt |   64 +++
 hw/vga-isa.c|2 +
 hw/vga-pci.c|2 +
 3 files changed, 68 insertions(+), 0 deletions(-)
 create mode 100644 docs/specs/standard-vga.txt

diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt
new file mode 100644
index 000..1cecccd
--- /dev/null
+++ b/docs/specs/standard-vga.txt
@@ -0,0 +1,64 @@
+
+QEMU Standard VGA
+=
+
+Exists in two variants, for isa and pci.
+
+command line switches:
+-vga std[ picks isa for -M isapc, otherwise pci ]
+-device VGA [ pci variant ]
+-device isa-vga [ isa variant ]
+
+
+PCI spec
+
+
+Applies to the pci variant only for obvious reasons.
+
+PCI ID: 1234:
+
+PCI Region 0:
+   Framebuffer memory, 16 MB in size (by default).
+   Size is tunable via vga_mem_mb property.
+
+PCI Region 1:
+   Reserved (so we have the option to make the framebuffer bar 64bit).
+
+PCI Region 2:
+   MMIO bar, 4096 bytes in size (qemu 1.3+)
+
+PCI ROM Region:
+   Holds the vgabios (qemu 0.14+).
+
+
+IO ports used
+-
+
+03c0 - 03df : standard vga ports
+01ce: bochs vbe interface index port
+01cf: bochs vbe interface data port
+
+
+Memory regions used
+---
+
+0xe000 : Framebuffer memory, isa variant only.
+
+The pci variant used to mirror the framebuffer bar here, qemu 0.14+
+stops doing that (except when in -M pc-$old compat mode).
+
+
+MMIO area spec
+--
+
+Likewise applies to the pci variant only for obvious reasons.
+
+ - 03ff : reserved, for possible virtio extension.
+0400 - 041f : vga ioports (0x3c0 - 0x3df), remapped 1:1.
+  word access is supported, bytes are written
+  in little endia order (aka index port first),
+  so indexed registers can be updated with a
+  single mmio write (and thus only one vmexit).
+0500 - 0515 : bochs dispi interface registers, mapped flat
+  without index/data ports.  Use (index  1)
+  as offset for (16bit) register access.
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index d290473..046602b 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -1,6 +1,8 @@
 /*
  * QEMU ISA VGA Emulator.
  *
+ * see docs/specs/standard-vga.txt for virtual hardware specs.
+ *
  * Copyright (c) 2003 Fabrice Bellard
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index f7d0256..5c4daee 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -1,6 +1,8 @@
 /*
  * QEMU PCI VGA Emulator.
  *
+ * see docs/specs/standard-vga.txt for virtual hardware specs.
+ *
  * Copyright (c) 2003 Fabrice Bellard
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
-- 
1.7.1




[Qemu-devel] [PATCH v2 4/4] vga: remove CONFIG_BOCHS_VBE

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/vga.c |   34 +-
 hw/vga_int.h |   28 +++-
 2 files changed, 12 insertions(+), 50 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index 053f89d..679cabc 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -582,7 +582,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t 
val)
 }
 }
 
-#ifdef CONFIG_BOCHS_VBE
 static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
 {
 VGACommonState *s = opaque;
@@ -784,7 +783,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, 
uint32_t val)
 }
 }
 }
-#endif
 
 /* called for accesses between 0xa and 0xc */
 uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
@@ -1129,14 +1127,12 @@ static void vga_get_offsets(VGACommonState *s,
 uint32_t *pline_compare)
 {
 uint32_t start_addr, line_offset, line_compare;
-#ifdef CONFIG_BOCHS_VBE
+
 if (s-vbe_regs[VBE_DISPI_INDEX_ENABLE]  VBE_DISPI_ENABLED) {
 line_offset = s-vbe_line_offset;
 start_addr = s-vbe_start_addr;
 line_compare = 65535;
-} else
-#endif
-{
+} else {
 /* compute line_offset in bytes */
 line_offset = s-cr[VGA_CRTC_OFFSET];
 line_offset = 3;
@@ -1572,12 +1568,10 @@ static vga_draw_line_func * const 
vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_
 static int vga_get_bpp(VGACommonState *s)
 {
 int ret;
-#ifdef CONFIG_BOCHS_VBE
+
 if (s-vbe_regs[VBE_DISPI_INDEX_ENABLE]  VBE_DISPI_ENABLED) {
 ret = s-vbe_regs[VBE_DISPI_INDEX_BPP];
-} else
-#endif
-{
+} else {
 ret = 0;
 }
 return ret;
@@ -1587,13 +1581,10 @@ static void vga_get_resolution(VGACommonState *s, int 
*pwidth, int *pheight)
 {
 int width, height;
 
-#ifdef CONFIG_BOCHS_VBE
 if (s-vbe_regs[VBE_DISPI_INDEX_ENABLE]  VBE_DISPI_ENABLED) {
 width = s-vbe_regs[VBE_DISPI_INDEX_XRES];
 height = s-vbe_regs[VBE_DISPI_INDEX_YRES];
-} else
-#endif
-{
+} else {
 width = (s-cr[VGA_CRTC_H_DISP] + 1) * 8;
 height = s-cr[VGA_CRTC_V_DISP_END] |
 ((s-cr[VGA_CRTC_OVERFLOW]  0x02)  7) |
@@ -1948,14 +1939,12 @@ void vga_common_reset(VGACommonState *s)
 s-dac_8bit = 0;
 memset(s-palette, '\0', sizeof(s-palette));
 s-bank_offset = 0;
-#ifdef CONFIG_BOCHS_VBE
 s-vbe_index = 0;
 memset(s-vbe_regs, '\0', sizeof(s-vbe_regs));
 s-vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID5;
 s-vbe_start_addr = 0;
 s-vbe_line_offset = 0;
 s-vbe_bank_mask = (s-vram_size  16) - 1;
-#endif
 memset(s-font_offsets, '\0', sizeof(s-font_offsets));
 s-graphic_mode = -1; /* force full update */
 s-shift_control = 0;
@@ -2229,13 +2218,11 @@ const VMStateDescription vmstate_vga_common = {
 
 VMSTATE_INT32(bank_offset, VGACommonState),
 VMSTATE_UINT8_EQUAL(is_vbe_vmstate, VGACommonState),
-#ifdef CONFIG_BOCHS_VBE
 VMSTATE_UINT16(vbe_index, VGACommonState),
 VMSTATE_UINT16_ARRAY(vbe_regs, VGACommonState, VBE_DISPI_INDEX_NB),
 VMSTATE_UINT32(vbe_start_addr, VGACommonState),
 VMSTATE_UINT32(vbe_line_offset, VGACommonState),
 VMSTATE_UINT32(vbe_bank_mask, VGACommonState),
-#endif
 VMSTATE_END_OF_LIST()
 }
 };
@@ -2275,11 +2262,7 @@ void vga_common_init(VGACommonState *s)
 }
 s-vram_size_mb = s-vram_size  20;
 
-#ifdef CONFIG_BOCHS_VBE
 s-is_vbe_vmstate = 1;
-#else
-s-is_vbe_vmstate = 0;
-#endif
 memory_region_init_ram(s-vram, vga.vram, s-vram_size);
 vmstate_register_ram_global(s-vram);
 xen_register_framebuffer(s-vram);
@@ -2314,7 +2297,6 @@ static const MemoryRegionPortio vga_portio_list[] = {
 PORTIO_END_OF_LIST(),
 };
 
-#ifdef CONFIG_BOCHS_VBE
 static const MemoryRegionPortio vbe_portio_list[] = {
 { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index 
},
 # ifdef TARGET_I386
@@ -2324,7 +2306,6 @@ static const MemoryRegionPortio vbe_portio_list[] = {
 # endif
 PORTIO_END_OF_LIST(),
 };
-#endif /* CONFIG_BOCHS_VBE */
 
 /* Used by both ISA and PCI */
 MemoryRegion *vga_init_io(VGACommonState *s,
@@ -2334,10 +2315,7 @@ MemoryRegion *vga_init_io(VGACommonState *s,
 MemoryRegion *vga_mem;
 
 *vga_ports = vga_portio_list;
-*vbe_ports = NULL;
-#ifdef CONFIG_BOCHS_VBE
 *vbe_ports = vbe_portio_list;
-#endif
 
 vga_mem = g_malloc(sizeof(*vga_mem));
 memory_region_init_io(vga_mem, vga_mem_ops, s,
@@ -2379,7 +2357,6 @@ void vga_init(VGACommonState *s, MemoryRegion 
*address_space,
 
 void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
 {
-#ifdef CONFIG_BOCHS_VBE
 /* With pc-0.12 and below we map both the PCI BAR and the fixed VBE region,
  * so use an alias to avoid double-mapping the same region.
  */
@@ -2390,7 +2367,6 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion 
*system_memory)
 

[Qemu-devel] [PATCH v2 1/4] vga: fix indention

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/vga-pci.c |   28 ++--
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 996d47f..5f55f36 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -48,25 +48,25 @@ static const VMStateDescription vmstate_vga_pci = {
 
 static int pci_std_vga_initfn(PCIDevice *dev)
 {
- PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
- VGACommonState *s = d-vga;
+PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
+VGACommonState *s = d-vga;
 
- // vga + console init
- vga_common_init(s);
- vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
+/* vga + console init */
+vga_common_init(s);
+vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
 
- s-ds = graphic_console_init(s-update, s-invalidate,
-  s-screen_dump, s-text_update, s);
+s-ds = graphic_console_init(s-update, s-invalidate,
+ s-screen_dump, s-text_update, s);
 
- /* XXX: VGA_RAM_SIZE must be a power of two */
- pci_register_bar(d-dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, s-vram);
+/* XXX: VGA_RAM_SIZE must be a power of two */
+pci_register_bar(d-dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, s-vram);
 
- if (!dev-rom_bar) {
- /* compatibility with pc-0.13 and older */
- vga_init_vbe(s, pci_address_space(dev));
- }
+if (!dev-rom_bar) {
+/* compatibility with pc-0.13 and older */
+vga_init_vbe(s, pci_address_space(dev));
+}
 
- return 0;
+return 0;
 }
 
 static Property vga_pci_properties[] = {
-- 
1.7.1




[Qemu-devel] [PATCH v2 2/4] vga: add mmio bar to standard vga

2012-10-15 Thread Gerd Hoffmann
This patch adds a mmio bar to the qemu standard vga which allows to
access the standard vga registers and bochs dispi interface registers
via mmio.

Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/pc_piix.c |4 ++
 hw/vga-pci.c |  108 ++
 hw/vga.c |6 ++--
 hw/vga_int.h |6 +++
 4 files changed, 121 insertions(+), 3 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 82364ab..5bd4572 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -379,6 +379,10 @@ static QEMUMachine pc_machine_v1_3 = {
 .driver   = qxl-vga,\
 .property = revision,\
 .value= stringify(3),\
+},{\
+.driver   = VGA,\
+.property = mmio,\
+.value= off,\
 }
 
 static QEMUMachine pc_machine_v1_2 = {
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 5f55f36..f7d0256 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -29,9 +29,23 @@
 #include qemu-timer.h
 #include loader.h
 
+#define PCI_VGA_IOPORT_OFFSET 0x400
+#define PCI_VGA_IOPORT_SIZE   (0x3e0 - 0x3c0)
+#define PCI_VGA_BOCHS_OFFSET  0x500
+#define PCI_VGA_BOCHS_SIZE(0x0b * 2)
+#define PCI_VGA_MMIO_SIZE 0x1000
+
+enum vga_pci_flags {
+PCI_VGA_FLAG_ENABLE_MMIO = 1,
+};
+
 typedef struct PCIVGAState {
 PCIDevice dev;
 VGACommonState vga;
+uint32_t flags;
+MemoryRegion mmio;
+MemoryRegion ioport;
+MemoryRegion bochs;
 } PCIVGAState;
 
 static const VMStateDescription vmstate_vga_pci = {
@@ -46,6 +60,84 @@ static const VMStateDescription vmstate_vga_pci = {
 }
 };
 
+static uint64_t pci_vga_ioport_read(void *ptr, target_phys_addr_t addr,
+unsigned size)
+{
+PCIVGAState *d = ptr;
+uint64_t ret = 0;
+
+switch (size) {
+case 1:
+ret = vga_ioport_read(d-vga, addr);
+break;
+case 2:
+ret  = vga_ioport_read(d-vga, addr);
+ret |= vga_ioport_read(d-vga, addr+1)  8;
+break;
+}
+return ret;
+}
+
+static void pci_vga_ioport_write(void *ptr, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
+{
+PCIVGAState *d = ptr;
+switch (size) {
+case 1:
+vga_ioport_write(d-vga, addr, val);
+break;
+case 2:
+/*
+ * Update bytes in little endian order.  Allows to update
+ * indexed registers with a single word write because the
+ * index byte is updated first.
+ */
+vga_ioport_write(d-vga, addr, val  0xff);
+vga_ioport_write(d-vga, addr+1, (val  8)  0xff);
+break;
+}
+}
+
+static const MemoryRegionOps pci_vga_ioport_ops = {
+.read = pci_vga_ioport_read,
+.write = pci_vga_ioport_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.impl.min_access_size = 1,
+.impl.max_access_size = 2,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t pci_vga_bochs_read(void *ptr, target_phys_addr_t addr,
+   unsigned size)
+{
+PCIVGAState *d = ptr;
+int index = addr  1;
+
+vbe_ioport_write_index(d-vga, 0, index);
+return vbe_ioport_read_data(d-vga, 0);
+}
+
+static void pci_vga_bochs_write(void *ptr, target_phys_addr_t addr,
+uint64_t val, unsigned size)
+{
+PCIVGAState *d = ptr;
+int index = addr  1;
+
+vbe_ioport_write_index(d-vga, 0, index);
+vbe_ioport_write_data(d-vga, 0, val);
+}
+
+static const MemoryRegionOps pci_vga_bochs_ops = {
+.read = pci_vga_bochs_read,
+.write = pci_vga_bochs_write,
+.valid.min_access_size = 1,
+.valid.max_access_size = 4,
+.impl.min_access_size = 2,
+.impl.max_access_size = 2,
+.endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int pci_std_vga_initfn(PCIDevice *dev)
 {
 PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -61,6 +153,21 @@ static int pci_std_vga_initfn(PCIDevice *dev)
 /* XXX: VGA_RAM_SIZE must be a power of two */
 pci_register_bar(d-dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, s-vram);
 
+/* mmio bar for vga register access */
+if (d-flags  (1  PCI_VGA_FLAG_ENABLE_MMIO)) {
+memory_region_init(d-mmio, vga.mmio, 4096);
+memory_region_init_io(d-ioport, pci_vga_ioport_ops, d,
+  vga ioports remapped, PCI_VGA_IOPORT_SIZE);
+memory_region_init_io(d-bochs, pci_vga_bochs_ops, d,
+  bochs dispi interface, PCI_VGA_BOCHS_SIZE);
+
+memory_region_add_subregion(d-mmio, PCI_VGA_IOPORT_OFFSET,
+d-ioport);
+memory_region_add_subregion(d-mmio, PCI_VGA_BOCHS_OFFSET,
+d-bochs);
+pci_register_bar(d-dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, d-mmio);
+}
+
 if (!dev-rom_bar) {
 /* compatibility with pc-0.13 and older */
 

Re: [Qemu-devel] [PATCH v2] chardev: add hotplug support.

2012-10-15 Thread Lei Li

On 10/12/2012 08:39 PM, Gerd Hoffmann wrote:

This patch adds chardev_add and chardev_del monitor commands.

chardev_del is pretty straight forward, it just takes an id argument and
zaps the chardev specified.

chardev_add is more tricky as there are tons of arguments for the
different backends.  The hmp version limited to the most common use
cases, especially when it comes to sockets:  You can only specify port
(tcp) or path (unix) and qemu will create a listening socket.  For
example this ...

(qemu) chardev_add foo socket 42

... will do the same as ...

-chardev socket,id=foo,port=42,server,nowait

on the qemu command line.

The qmp version has full support for everything the -chardev command
line switch can handle.  The implementation is pretty straight
forward: It just puts all arguments it got into a QemuOpts, then goes
call qemu_chr_new_from_opts().

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
  hmp-commands.hx  |   32 
  hmp.c|   31 +++
  hmp.h|2 +
  qapi-schema.json |   39 ++
  qemu-char.c  |   50 +++-
  qemu-char.h  |2 +
  qmp-commands.hx  |   61 ++
  7 files changed, 216 insertions(+), 1 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e0b537d..48504d1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1404,6 +1404,38 @@ passed since 1970, i.e. unix epoch.
  ETEXI

  {
+.name   = chardev_add,
+.args_type  = args:s,
+.params = args,
+.help   = add chardev,
+.mhandler.cmd = hmp_chardev_add,
+},
+
+STEXI
+@item chardev_add args
+@findex chardev_add
+
+chardev_add accepts the same parameters as the -chardev command line switch.
+
+ETEXI
+
+{
+.name   = chardev_del,
+.args_type  = id:s,
+.params = id,
+.help   = del chardev,
+.mhandler.cmd = hmp_chardev_del,
+},
+
+STEXI
+@item chardev_del id
+@findex chardev_del
+
+Removes the chardev @var{id}.
+
+ETEXI
+
+{
  .name   = info,
  .args_type  = item:s?,
  .params = [subcommand],
diff --git a/hmp.c b/hmp.c
index 70bdec2..b494d05 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1209,3 +1209,34 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
  qmp_screendump(filename, err);
  hmp_handle_error(mon, err);
  }
+
+void hmp_chardev_add(Monitor *mon, const QDict *qdict)
+{
+const char *args = qdict_get_str(qdict, args);
+CharDriverState *chr;
+Error *err = NULL;
+QemuOpts *opts;
+
+opts = qemu_opts_parse(qemu_find_opts(chardev), args, 1);
+if (opts == NULL) {
+error_setg(err, Parsing chardev args failed\n);
+goto out;
+}
+
+chr = qemu_chr_new_from_opts(opts, NULL);
+if (chr == NULL) {
+qemu_opts_del(opts);
+error_setg(err, Creating chardev failed\n);
+}
+
+out:
+hmp_handle_error(mon, err);
+}
+
+void hmp_chardev_del(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+qmp_chardev_del(qdict_get_str(qdict, id),
+err);
+hmp_handle_error(mon, err);
+}
diff --git a/hmp.h b/hmp.h
index 71ea384..080afaa 100644
--- a/hmp.h
+++ b/hmp.h
@@ -75,5 +75,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
  void hmp_closefd(Monitor *mon, const QDict *qdict);
  void hmp_send_key(Monitor *mon, const QDict *qdict);
  void hmp_screen_dump(Monitor *mon, const QDict *qdict);
+void hmp_chardev_add(Monitor *mon, const QDict *qdict);
+void hmp_chardev_del(Monitor *mon, const QDict *qdict);

  #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index f9dbdae..550e4c7 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2796,3 +2796,42 @@
  # Since: 0.14.0
  ##
  { 'command': 'screendump', 'data': {'filename': 'str'} }
+
+##
+# @chardev_add:
+#
+# Add a chardev
+#
+# @id: the chardev's ID, must be unique
+# @backend: the chardev backend: file, socket, ...
+# @path: file / device / unix socket path
+# @name: spice channel name
+# @host: host name
+# @port: port number
+# @server: create socket in server mode
+# @wait: wait for connect
+# @ipv4: force ipv4-only
+# @ipv6: force ipv6-only
+# @telnet: telnet negotiation
+#
+# Returns: Nothing on success
+#
+# Since: 1.3.0
+##
+{ 'command': 'chardev_add', 'data': {'id'  : 'str',
+ 'backend' : 'str',
+ '*props'  : '**' },
+  'gen': 'no' }
+
+##
+# @chardev_del:
+#
+# Remove a chardev
+#
+# @id: the chardev's ID, must exist and not be in use
+#
+# Returns: Nothing on success
+#
+# Since: 1.3.0
+##
+{ 'command': 'chardev_del', 'data': {'id': 'str'} }
diff --git a/qemu-char.c b/qemu-char.c
index b082bae..7bbc490 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2805,6 +2805,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
  

Re: [Qemu-devel] Silent filesystem/qcow2 corruptions with qemu-kvm-1.0 and 1.1.1

2012-10-15 Thread Stefan Hajnoczi
On Fri, Oct 12, 2012 at 10:53:29AM +0200, Tiziano Müller wrote:
 Am Freitag, den 12.10.2012, 10:33 +0200 schrieb Stefan Hajnoczi:
  On Thu, Oct 11, 2012 at 03:33:23PM +0200, Tiziano Müller wrote:
   Checking the image using `qemu-img check` then gives something like
   this:
   
   ERROR OFLAG_COPIED: offset=3bc3 refcount=1
   ERROR offset=c7e331: Cluster is not properly aligned; L2 entry
   corrupted.
  
  Is any other program accessing the qcow2 image on the host while the VM
  is running?
 
  For example, are you running qemu-img on the image while the VM is
  running?
 
 On some VMs we tried to extract filesystem snapshots at runtime:
 
   qemu-img convert -s snapshot-id original.qcow2 snapshot.qcow2
 
 (yes, that's not consistent, we're switching to external snapshots).
 But that should open the image read-only, right?
 
 Other operations where the qemu-monitor-commands savevm and delvm. 
 
 Although: we created a new qcow2 and even in that the filesystem got
 corrupted without any of the above actions. So we're pretty confident
 that those operations are not the sole cause.

Okay, that's consistent with the other symptoms you've reported.

It's not clear whether the corruption arises inside qcow2 or if
something else is causing corruption and qcow2/xfs get upset.  That is
the next step to debugging this - hopefully it will become possible to
reproduce it reliably, at which point it is much easier to debug :).

Stefan



Re: [Qemu-devel] Any alternative to kqemu ?

2012-10-15 Thread Paolo Bonzini
Il 14/10/2012 12:52, Timothy Madden ha scritto:
 Hello
 
 Is kqemu deprecated ?

It is simply not supported anymore.

 Is there an alternative to it ?

No.

 `qemu-system-i386 -net nic ...` keeps saying upon invocation that vlan0
 is not connected to host network. My `vconfig add eth1` command
 completed successfully, and I can `ifconfig eth1.0`, although I see no
 IP address on the new interface, only the mac address.

QEMU VLANs have nothing to do with Linux VLANs.  Yes, that is confusing. :(

If you install libvirt, you can use -net nic -net bridge,br=virbr0.

Otherwise, you could configure a bridge yourself and just use -net nic
-net bridge.

Paolo

 I have qemu 1.2.0 compiled on Slackware 14.0.
 
 Thank you,
 Timothy Madden
 
 
 




[Qemu-devel] [PATCH v3 0/9] serial device hotplug patch series.

2012-10-15 Thread Gerd Hoffmann
This patch series tackles serial device hotplug.

The first four patches have been on the list before, they implement
pci-serial devices featuring a hot-pluggable 16550 uart and got some
minor tweaks only.

The next two patches update the usb-serial device.  It will only show up
in the guest when the chardev is open.  You'll see the difference with
socket chardevs:  If you open the chardev (by connecting to the socket)
the device will show up in the guest, on close (disconnect) it will
disappear.

Final three patches cleanup chardev a bit and adds chardev hotplug to
the mix, which makes the other patches alot more useful.  It is the
missing bit needed to really hotplug serial devices:

   (qemu) chardev_add file,id=pciserial,path=/root/hotchardev.log
   (qemu) device_add pci-serial,id=pciserial,chardev=pciserial

And the reverse:

   (qemu) device_del pciserial
   (qemu) chardev_del pciserial

New in v2:
 - added two chardev cleanup patches.
 - switched chardev_{add,del} commands to netdev_{add,del} style.

cheers,
  Gerd

The following changes since commit 8b4a3df8081f3e6f1061ed5cbb303ad623ade66b:

  Fix popcnt in long mode (2012-10-14 14:55:09 +0400)

are available in the git repository at:
  git://git.kraxel.org/qemu serial.2

Gerd Hoffmann (9):
  serial: split serial.c
  serial: add pci variant
  serial: add windows inf file for the pci card to docs
  serial: add 2x + 4x pci variant
  usb-serial: don't magically zap chardev on umplug
  usb-serial: only expose device in guest when the chardev is open
  chardev: add error reporting for qemu_chr_new_from_opts
  chardev: fix QemuOpts lifecycle
  chardev: add hotplug support.

 default-configs/pci.mak  |2 +
 docs/qemupciserial.inf   |  109 ++
 hmp-commands.hx  |   32 ++
 hmp.c|   23 
 hmp.h|2 +
 hw/Makefile.objs |3 +-
 hw/alpha_dp264.c |1 +
 hw/kzm.c |2 +-
 hw/mips_fulong2e.c   |1 +
 hw/mips_jazz.c   |1 +
 hw/mips_malta.c  |1 +
 hw/mips_mipssim.c|2 +-
 hw/mips_r4k.c|1 +
 hw/musicpal.c|2 +-
 hw/omap_uart.c   |3 +-
 hw/openrisc_sim.c|3 +-
 hw/pc.c  |1 +
 hw/pc.h  |   27 -
 hw/pci_ids.h |1 +
 hw/petalogix_ml605_mmu.c |2 +-
 hw/ppc/e500.c|2 +-
 hw/ppc405_uc.c   |2 +-
 hw/ppc440_bamboo.c   |2 +-
 hw/ppc_prep.c|1 +
 hw/pxa2xx.c  |2 +-
 hw/serial-isa.c  |  130 ++
 hw/serial-pci.c  |  272 ++
 hw/serial.c  |  149 ++---
 hw/serial.h  |   74 +
 hw/sm501.c   |2 +-
 hw/sun4u.c   |1 +
 hw/usb/dev-serial.c  |   21 +++-
 hw/virtex_ml507.c|2 +-
 hw/xtensa_lx60.c |3 +-
 qapi-schema.json |   39 +++
 qemu-char.c  |   83 ---
 qemu-char.h  |5 +-
 qmp-commands.hx  |   61 ++
 vl.c |7 +-
 39 files changed, 878 insertions(+), 199 deletions(-)
 create mode 100644 docs/qemupciserial.inf
 create mode 100644 hw/serial-isa.c
 create mode 100644 hw/serial-pci.c
 create mode 100644 hw/serial.h



[Qemu-devel] [PATCH v3 7/9] chardev: add error reporting for qemu_chr_new_from_opts

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 qemu-char.c |   24 +++-
 qemu-char.h |3 ++-
 vl.c|7 ++-
 3 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index b082bae..e2e1da8 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2755,19 +2755,20 @@ static const struct {
 };
 
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
-void (*init)(struct CharDriverState *s))
+void (*init)(struct CharDriverState *s),
+Error **errp)
 {
 CharDriverState *chr;
 int i;
 
 if (qemu_opts_id(opts) == NULL) {
-fprintf(stderr, chardev: no id specified\n);
+error_setg(errp, chardev: no id specified\n);
 return NULL;
 }
 
 if (qemu_opt_get(opts, backend) == NULL) {
-fprintf(stderr, chardev: \%s\ missing backend\n,
-qemu_opts_id(opts));
+error_setg(errp, chardev: \%s\ missing backend\n,
+   qemu_opts_id(opts));
 return NULL;
 }
 for (i = 0; i  ARRAY_SIZE(backend_table); i++) {
@@ -2775,15 +2776,15 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 break;
 }
 if (i == ARRAY_SIZE(backend_table)) {
-fprintf(stderr, chardev: backend \%s\ not found\n,
-qemu_opt_get(opts, backend));
+error_setg(errp, chardev: backend \%s\ not found\n,
+   qemu_opt_get(opts, backend));
 return NULL;
 }
 
 chr = backend_table[i].open(opts);
 if (!chr) {
-fprintf(stderr, chardev: opening backend \%s\ failed\n,
-qemu_opt_get(opts, backend));
+error_setg(errp, chardev: opening backend \%s\ failed\n,
+   qemu_opt_get(opts, backend));
 return NULL;
 }
 
@@ -2813,6 +2814,7 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename, void (*in
 const char *p;
 CharDriverState *chr;
 QemuOpts *opts;
+Error *err = NULL;
 
 if (strstart(filename, chardev:, p)) {
 return qemu_chr_find(p);
@@ -2822,7 +2824,11 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename, void (*in
 if (!opts)
 return NULL;
 
-chr = qemu_chr_new_from_opts(opts, init);
+chr = qemu_chr_new_from_opts(opts, init, err);
+if (error_is_set(err)) {
+fprintf(stderr, %s\n, error_get_pretty(err));
+error_free(err);
+}
 if (chr  qemu_opt_get_bool(opts, mux, 0)) {
 monitor_init(chr, MONITOR_USE_READLINE);
 }
diff --git a/qemu-char.h b/qemu-char.h
index 486644b..adae13e 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -88,7 +88,8 @@ struct CharDriverState {
  * Returns: a new character backend
  */
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
-void (*init)(struct CharDriverState *s));
+void (*init)(struct CharDriverState *s),
+Error **errp);
 
 /**
  * @qemu_chr_new:
diff --git a/vl.c b/vl.c
index 5b357a3..35eb627 100644
--- a/vl.c
+++ b/vl.c
@@ -1940,8 +1940,13 @@ static int device_init_func(QemuOpts *opts, void *opaque)
 static int chardev_init_func(QemuOpts *opts, void *opaque)
 {
 CharDriverState *chr;
+Error *err = NULL;
 
-chr = qemu_chr_new_from_opts(opts, NULL);
+chr = qemu_chr_new_from_opts(opts, NULL, err);
+if (error_is_set(err)) {
+fprintf(stderr, %s\n, error_get_pretty(err));
+error_free(err);
+}
 if (!chr)
 return -1;
 return 0;
-- 
1.7.1




[Qemu-devel] [PATCH v3 8/9] chardev: fix QemuOpts lifecycle

2012-10-15 Thread Gerd Hoffmann
qemu_chr_new_from_opts handles QemuOpts release now, so callers don't
have to worry.  It will either be saved in CharDriverState, then
released in qemu_chr_delete, or in the error case released instantly.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 qemu-char.c |   15 ++-
 qemu-char.h |1 +
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index e2e1da8..be4ec61 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2763,13 +2763,13 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 
 if (qemu_opts_id(opts) == NULL) {
 error_setg(errp, chardev: no id specified\n);
-return NULL;
+goto err;
 }
 
 if (qemu_opt_get(opts, backend) == NULL) {
 error_setg(errp, chardev: \%s\ missing backend\n,
qemu_opts_id(opts));
-return NULL;
+goto err;
 }
 for (i = 0; i  ARRAY_SIZE(backend_table); i++) {
 if (strcmp(backend_table[i].name, qemu_opt_get(opts, backend)) == 0)
@@ -2778,14 +2778,14 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 if (i == ARRAY_SIZE(backend_table)) {
 error_setg(errp, chardev: backend \%s\ not found\n,
qemu_opt_get(opts, backend));
-return NULL;
+goto err;
 }
 
 chr = backend_table[i].open(opts);
 if (!chr) {
 error_setg(errp, chardev: opening backend \%s\ failed\n,
qemu_opt_get(opts, backend));
-return NULL;
+goto err;
 }
 
 if (!chr-filename)
@@ -2806,7 +2806,12 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 chr-avail_connections = 1;
 }
 chr-label = g_strdup(qemu_opts_id(opts));
+chr-opts = opts;
 return chr;
+
+err:
+qemu_opts_del(opts);
+return NULL;
 }
 
 CharDriverState *qemu_chr_new(const char *label, const char *filename, void 
(*init)(struct CharDriverState *s))
@@ -2832,7 +2837,6 @@ CharDriverState *qemu_chr_new(const char *label, const 
char *filename, void (*in
 if (chr  qemu_opt_get_bool(opts, mux, 0)) {
 monitor_init(chr, MONITOR_USE_READLINE);
 }
-qemu_opts_del(opts);
 return chr;
 }
 
@@ -2864,6 +2868,7 @@ void qemu_chr_delete(CharDriverState *chr)
 chr-chr_close(chr);
 g_free(chr-filename);
 g_free(chr-label);
+qemu_opts_del(chr-opts);
 g_free(chr);
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index adae13e..99bc132 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -74,6 +74,7 @@ struct CharDriverState {
 char *filename;
 int opened;
 int avail_connections;
+QemuOpts *opts;
 QTAILQ_ENTRY(CharDriverState) next;
 };
 
-- 
1.7.1




[Qemu-devel] [PATCH v3 4/9] serial: add 2x + 4x pci variant

2012-10-15 Thread Gerd Hoffmann
Add multiport serial card implementation, with two variants,
one featuring two and one featuring four ports.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 docs/qemupciserial.inf |2 +
 hw/serial-pci.c|  157 
 2 files changed, 159 insertions(+), 0 deletions(-)

diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
index c7cea99..3474310 100644
--- a/docs/qemupciserial.inf
+++ b/docs/qemupciserial.inf
@@ -11,6 +11,8 @@
 ; (Com+Lpt) from the list.  Click Have a disk.  Select this file.
 ; Procedure may vary a bit depending on the windows version.
 
+; FIXME: This file covers the single port version only.
+
 [Version]
 Signature=$CHICAGO$
 Class=Ports
diff --git a/hw/serial-pci.c b/hw/serial-pci.c
index 17247a8..c89e8b0 100644
--- a/hw/serial-pci.c
+++ b/hw/serial-pci.c
@@ -28,6 +28,14 @@
  *pci region 0 is a io bar, 8 bytes long, with the 16550 uart mapped to it.
  *interrupt is wired to pin A.
  *
+ * pci-serial-4x spec:
+ *pci region 0 is a io bar, with four 16550 uarts mapped after each other,
+ *the first at offset 0, second at 8, third at 16 and fourth at 24.
+ *interrupt is wired to pin A.
+ *
+ * pci-serial-2x spec:
+ *same as pci-serial-4x but with two uarts only.
+ *
  * [root@fedora ~]# lspci -vnse
  * 00:0e.0 0700: 1b36:0002 (rev 01) (prog-if 00 [8250])
  * Subsystem: 1af4:1100
@@ -40,11 +48,23 @@
 #include serial.h
 #include pci.h
 
+#define PCI_SERIAL_MAX_PORTS 4
+
 typedef struct PCISerialState {
 PCIDevice dev;
 SerialState state;
 } PCISerialState;
 
+typedef struct PCIMultiSerialState {
+PCIDevicedev;
+MemoryRegion iobar;
+uint32_t ports;
+char *name[PCI_SERIAL_MAX_PORTS];
+SerialState  state[PCI_SERIAL_MAX_PORTS];
+uint32_t level[PCI_SERIAL_MAX_PORTS];
+qemu_irq *irqs;
+} PCIMultiSerialState;
+
 static int serial_pci_init(PCIDevice *dev)
 {
 PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
@@ -61,6 +81,56 @@ static int serial_pci_init(PCIDevice *dev)
 return 0;
 }
 
+static void multi_serial_irq_mux(void *opaque, int n, int level)
+{
+PCIMultiSerialState *pci = opaque;
+int i, pending = 0;
+
+pci-level[n] = level;
+for (i = 0; i  pci-ports; i++) {
+if (pci-level[i]) {
+pending = 1;
+}
+}
+qemu_set_irq(pci-dev.irq[0], pending);
+}
+
+static int multi_serial_pci_init(PCIDevice *dev)
+{
+PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+SerialState *s;
+int i;
+
+switch (pc-device_id) {
+case 0x0003:
+pci-ports = 2;
+break;
+case 0x0004:
+pci-ports = 4;
+break;
+}
+assert(pci-ports  0);
+assert(pci-ports = PCI_SERIAL_MAX_PORTS);
+
+pci-dev.config[PCI_INTERRUPT_PIN] = 0x01;
+memory_region_init(pci-iobar, multiserial, 8 * pci-ports);
+pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, pci-iobar);
+pci-irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci,
+   pci-ports);
+
+for (i = 0; i  pci-ports; i++) {
+s = pci-state + i;
+s-baudbase = 115200;
+serial_init_core(s);
+s-irq = pci-irqs[i];
+pci-name[i] = g_strdup_printf(uart #%d, i+1);
+memory_region_init_io(s-io, serial_io_ops, s, pci-name[i], 8);
+memory_region_add_subregion(pci-iobar, 8 * i, s-io);
+}
+return 0;
+}
+
 static void serial_pci_exit(PCIDevice *dev)
 {
 PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
@@ -70,6 +140,22 @@ static void serial_pci_exit(PCIDevice *dev)
 memory_region_destroy(s-io);
 }
 
+static void multi_serial_pci_exit(PCIDevice *dev)
+{
+PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
+SerialState *s;
+int i;
+
+for (i = 0; i  pci-ports; i++) {
+s = pci-state + i;
+serial_exit_core(s);
+memory_region_destroy(s-io);
+g_free(pci-name[i]);
+}
+memory_region_destroy(pci-iobar);
+qemu_free_irqs(pci-irqs);
+}
+
 static const VMStateDescription vmstate_pci_serial = {
 .name = pci-serial,
 .version_id = 1,
@@ -81,11 +167,38 @@ static const VMStateDescription vmstate_pci_serial = {
 }
 };
 
+static const VMStateDescription vmstate_pci_multi_serial = {
+.name = pci-serial-multi,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
+VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
+ 0, vmstate_serial, SerialState),
+VMSTATE_UINT32_ARRAY(level, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS),
+VMSTATE_END_OF_LIST()
+}
+};
+
 static Property serial_pci_properties[] = {
 DEFINE_PROP_CHR(chardev,  PCISerialState, state.chr),
 DEFINE_PROP_END_OF_LIST(),
 };
 

Re: [Qemu-devel] [PATCH v4 00/26] Add infrastructure for QIDL-based device serialization

2012-10-15 Thread Paolo Bonzini
Il 12/10/2012 23:10, Michael Roth ha scritto:
 
 These patches add infrastructure and unit tests for QIDL, which provides
 a serialization framework for QEMU device structures by generating visitor
 routines for device structs based on simple field annotations. Examples of
 how this is done are included in patch 17, but, for brevity, a sample struct
 such as this:
 
 typedef struct SerialDevice {
 SysBusDevice parent;
 
 uint8_t thr;/* transmit holding register */
 uint8_t lsr;/* line status register */
 uint8_t ier;/* interrupt enable register */
 
 int int_pending;/* whether we have a pending queued interrupt 
 */
 CharDriverState *chr;   /* backend */
 } SerialDevice;
 
 can now be made serializable with the following changes:
 
 typedef struct SerialDevice SerialDevice;
 
 QIDL_DECLARE(SerialDevice) {
 SysBusDevice parent;
 
 uint8_t thr;  /* transmit holding register */
 uint8_t lsr;  /* line status register */
 uint8_t ier;  /* interrupt enable register */
 
 int q_derived int_pending; /* whether we have a pending queued 
 interrupt */
 CharDriverState q_immutable *chr; /* backend */
 };
 
 To make use of generated visitor code, and .c file need only call the
 QIDL_ENABLE() somewhere in the code body, which will then give it access to
 visitor routines for any QIDL-ified device structures in that file, or 
 included
 from other files. These routines can then be used for
 serialization/deserialization of the device state in a manner suitable for 
 tasks
 such as introspection/testing (generally via a r/w 'state' QOM property) or
 migration.
 
 The overall goal is to expose all migrateable device state in this manner so
 that we can decouple serialization duties from savevm/VMState and convert them
 into a stable, code-agnostic wire protocol, relying instead on intermediate
 translation routines to handle the work of massaging serialized state into a
 format suitable for the wire and vice-versa.
 
 The following WIP branch contains the first set of QIDL conversions:
 
 https://github.com/mdroth/qemu/commits/qidl
 
 So far i440fx, pcibus, cirrus_vga, uhci, rtc, and isa/piix ide have been
 converted, and I'm hoping to have most common PC devices converted over
 within the next few weeks.

Do you have any plan for scripted conversion?

Paolo



Re: [Qemu-devel] [PATCH v4 24/26] qidl: add QAPI-based code generator

2012-10-15 Thread Paolo Bonzini
Il 12/10/2012 23:11, Michael Roth ha scritto:
 +elif field['type'].startswith('enum '):
 +typename = 'int'

Note that there is support for enum properties in qdev.  Please consider
adding it, though it can be done as a follow-up.

I'm going to play a bit with the series and convert 1 or 2 devices
myself to see how it looks, then I'll give my acked-by.

Paolo



[Qemu-devel] [PATCH v3 5/9] usb-serial: don't magically zap chardev on umplug

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb/dev-serial.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 69b6e48..43214cd 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -421,7 +421,7 @@ static void usb_serial_handle_destroy(USBDevice *dev)
 {
 USBSerialState *s = (USBSerialState *)dev;
 
-qemu_chr_delete(s-cs);
+qemu_chr_add_handlers(s-cs, NULL, NULL, NULL, NULL);
 }
 
 static int usb_serial_can_read(void *opaque)
-- 
1.7.1




Re: [Qemu-devel] Problems using netdev_del+netdev_add w/o corresponding device_del+device_add

2012-10-15 Thread Stefan Hajnoczi
On Sat, Oct 13, 2012 at 04:47:14PM -0400, Laine Stump wrote:
 Here is the sequence sent to disconnect only the host side, then
 reconnect it with a new tap device. (although the fd is the same, this
 is because the old tap device had already been closed, so the number is
 just being used - the same thing happens when doing sequential full
 detach/attach cycles, and they all work with no problems):
 
 
 168.750  0x7f8e2c90
 {execute:netdev_del,arguments:{id:hostnet0},id:libvirt-30}
 168.762  0x7f8e2c90 {return: {}, id: libvirt-30}
 168.800  0x7f8e2c90
 {execute:getfd,arguments:{fdname:fd-net0},id:libvirt-31}
 (fd=27)
 168.801  0x7f8e2c90 {return: {}, id: libvirt-31}
 168.801  0x7f8e2c90
 {execute:netdev_add,arguments:{type:tap,fd:fd-net0,id:hostnet0},id:libvirt-32}
 168.802  0x7f8e2c90 {return: {}, id: libvirt-32}
 168.802  0x7f8e2c90
 {execute:set_link,arguments:{name:net0,up:true},id:libvirt-33}
 168.803  0x7f8e2c90 {return: {}, id: libvirt-33}
 
 After this sequence is done, everything about the network device
 *appears* normal on both the guest and host (at least the things I know
 to look at), but no traffic from the host shows up in a tcpdump of the
 interface on the guest, and no traffic from the guest shows up in a
 tcpdump of the tap device on the host.

What you are trying to do isn't possible today.

The device associates with the netdev during initialization only - there
is no command to associate at a later point in time.  That is why your
example works only when the device is deleted together with the netdev.

It is certainly possible to implement a command to switch netdevs but
I'm curious what the use case is.  Is this necessary just because QEMU
doesn't provide a way to modify the existing netdev or because you
really want to switch to a completely different netdev?

Stefan



[Qemu-devel] [PATCH v3 9/9] chardev: add hotplug support.

2012-10-15 Thread Gerd Hoffmann
This patch adds chardev_add and chardev_del monitor commands.

They work simliar to the netdev_{add,del} commands.  The hmp version of
chardev_add accepts like the -chardev command line option does.  The qmp
version expects the arguments being passed as named parameters.

chardev_del just takes an id argument and zaps the chardev specified.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hmp-commands.hx  |   32 
 hmp.c|   23 
 hmp.h|2 +
 qapi-schema.json |   39 ++
 qemu-char.c  |   44 ++
 qemu-char.h  |1 +
 qmp-commands.hx  |   61 ++
 7 files changed, 202 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e0b537d..48504d1 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1404,6 +1404,38 @@ passed since 1970, i.e. unix epoch.
 ETEXI
 
 {
+.name   = chardev_add,
+.args_type  = args:s,
+.params = args,
+.help   = add chardev,
+.mhandler.cmd = hmp_chardev_add,
+},
+
+STEXI
+@item chardev_add args
+@findex chardev_add
+
+chardev_add accepts the same parameters as the -chardev command line switch.
+
+ETEXI
+
+{
+.name   = chardev_del,
+.args_type  = id:s,
+.params = id,
+.help   = del chardev,
+.mhandler.cmd = hmp_chardev_del,
+},
+
+STEXI
+@item chardev_del id
+@findex chardev_del
+
+Removes the chardev @var{id}.
+
+ETEXI
+
+{
 .name   = info,
 .args_type  = item:s?,
 .params = [subcommand],
diff --git a/hmp.c b/hmp.c
index 70bdec2..96bb900 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1209,3 +1209,26 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
 qmp_screendump(filename, err);
 hmp_handle_error(mon, err);
 }
+
+void hmp_chardev_add(Monitor *mon, const QDict *qdict)
+{
+const char *args = qdict_get_str(qdict, args);
+Error *err = NULL;
+QemuOpts *opts;
+
+opts = qemu_opts_parse(qemu_find_opts(chardev), args, 1);
+if (opts == NULL) {
+error_setg(err, Parsing chardev args failed\n);
+} else {
+qemu_chr_new_from_opts(opts, NULL, err);
+}
+hmp_handle_error(mon, err);
+}
+
+void hmp_chardev_del(Monitor *mon, const QDict *qdict)
+{
+Error *err = NULL;
+qmp_chardev_del(qdict_get_str(qdict, id),
+err);
+hmp_handle_error(mon, err);
+}
diff --git a/hmp.h b/hmp.h
index 71ea384..080afaa 100644
--- a/hmp.h
+++ b/hmp.h
@@ -75,5 +75,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
 void hmp_closefd(Monitor *mon, const QDict *qdict);
 void hmp_send_key(Monitor *mon, const QDict *qdict);
 void hmp_screen_dump(Monitor *mon, const QDict *qdict);
+void hmp_chardev_add(Monitor *mon, const QDict *qdict);
+void hmp_chardev_del(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index f9dbdae..550e4c7 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2796,3 +2796,42 @@
 # Since: 0.14.0
 ##
 { 'command': 'screendump', 'data': {'filename': 'str'} }
+
+##
+# @chardev_add:
+#
+# Add a chardev
+#
+# @id: the chardev's ID, must be unique
+# @backend: the chardev backend: file, socket, ...
+# @path: file / device / unix socket path
+# @name: spice channel name
+# @host: host name
+# @port: port number
+# @server: create socket in server mode
+# @wait: wait for connect
+# @ipv4: force ipv4-only
+# @ipv6: force ipv6-only
+# @telnet: telnet negotiation
+#
+# Returns: Nothing on success
+#
+# Since: 1.3.0
+##
+{ 'command': 'chardev_add', 'data': {'id'  : 'str',
+ 'backend' : 'str',
+ '*props'  : '**' },
+  'gen': 'no' }
+
+##
+# @chardev_del:
+#
+# Remove a chardev
+#
+# @id: the chardev's ID, must exist and not be in use
+#
+# Returns: Nothing on success
+#
+# Since: 1.3.0
+##
+{ 'command': 'chardev_del', 'data': {'id': 'str'} }
diff --git a/qemu-char.c b/qemu-char.c
index be4ec61..dae3e3c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2911,3 +2911,47 @@ CharDriverState *qemu_char_get_next_serial(void)
 return serial_hds[next_serial++];
 }
 
+int qmp_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+Error *err = NULL;
+QemuOptsList *opts_list;
+QemuOpts *opts;
+
+opts_list = qemu_find_opts_err(chardev, err);
+if (error_is_set(err)) {
+goto exit_err;
+}
+
+opts = qemu_opts_from_qdict(opts_list, qdict, err);
+if (error_is_set(err)) {
+goto exit_err;
+}
+
+qemu_chr_new_from_opts(opts, NULL, err);
+if (error_is_set(err)) {
+goto exit_err;
+}
+return 0;
+
+exit_err:
+qerror_report_err(err);
+error_free(err);
+return -1;
+}
+
+void qmp_chardev_del(const char *id, Error **errp)
+{
+CharDriverState *chr;
+
+chr = 

[Qemu-devel] [PATCH v3 1/9] serial: split serial.c

2012-10-15 Thread Gerd Hoffmann
Split serial.c into serial.c, serial.h and serial-isa.c.  While being at
creating a serial.h header file move the serial prototypes from pc.h to
the new serial.h.  The latter leads to s/pc.h/serial.h/ in tons of
boards which just want the serial bits from pc.h

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/Makefile.objs |2 +-
 hw/alpha_dp264.c |1 +
 hw/kzm.c |2 +-
 hw/mips_fulong2e.c   |1 +
 hw/mips_jazz.c   |1 +
 hw/mips_malta.c  |1 +
 hw/mips_mipssim.c|2 +-
 hw/mips_r4k.c|1 +
 hw/musicpal.c|2 +-
 hw/omap_uart.c   |3 +-
 hw/openrisc_sim.c|3 +-
 hw/pc.c  |1 +
 hw/pc.h  |   27 -
 hw/petalogix_ml605_mmu.c |2 +-
 hw/ppc/e500.c|2 +-
 hw/ppc405_uc.c   |2 +-
 hw/ppc440_bamboo.c   |2 +-
 hw/ppc_prep.c|1 +
 hw/pxa2xx.c  |2 +-
 hw/serial-isa.c  |  130 +
 hw/serial.c  |  143 ++
 hw/serial.h  |   73 +++
 hw/sm501.c   |2 +-
 hw/sun4u.c   |1 +
 hw/virtex_ml507.c|2 +-
 hw/xtensa_lx60.c |3 +-
 26 files changed, 232 insertions(+), 180 deletions(-)
 create mode 100644 hw/serial-isa.c
 create mode 100644 hw/serial.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 854faa9..16e7a1e 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -20,7 +20,7 @@ common-obj-$(CONFIG_M48T59) += m48t59.o
 common-obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 
-common-obj-$(CONFIG_SERIAL) += serial.o
+common-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
 common-obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_PCSPK) += pcspk.o
diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
index 5ea04c7..8ce04e5 100644
--- a/hw/alpha_dp264.c
+++ b/hw/alpha_dp264.c
@@ -15,6 +15,7 @@
 #include mc146818rtc.h
 #include ide.h
 #include i8254.h
+#include serial.h
 
 #define MAX_IDE_BUS 2
 
diff --git a/hw/kzm.c b/hw/kzm.c
index 68cd1b4..1f3082b 100644
--- a/hw/kzm.c
+++ b/hw/kzm.c
@@ -21,7 +21,7 @@
 #include net.h
 #include sysemu.h
 #include boards.h
-#include pc.h /* for the FPGA UART that emulates a 16550 */
+#include serial.h
 #include imx.h
 
 /* Memory map for Kzm Emulation Baseboard:
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index d4a8672..a3cb3ab 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -20,6 +20,7 @@
 
 #include hw.h
 #include pc.h
+#include serial.h
 #include fdc.h
 #include net.h
 #include boards.h
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index db927f1..d35cd54 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -26,6 +26,7 @@
 #include mips.h
 #include mips_cpudevs.h
 #include pc.h
+#include serial.h
 #include isa.h
 #include fdc.h
 #include sysemu.h
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 632b466..8f73b1b 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -24,6 +24,7 @@
 
 #include hw.h
 #include pc.h
+#include serial.h
 #include fdc.h
 #include net.h
 #include boards.h
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 830f635..0ee6756 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -27,7 +27,7 @@
 #include hw.h
 #include mips.h
 #include mips_cpudevs.h
-#include pc.h
+#include serial.h
 #include isa.h
 #include net.h
 #include sysemu.h
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 967a76e..b3be80b 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -11,6 +11,7 @@
 #include mips.h
 #include mips_cpudevs.h
 #include pc.h
+#include serial.h
 #include isa.h
 #include net.h
 #include sysemu.h
diff --git a/hw/musicpal.c b/hw/musicpal.c
index f305e21..346fe41 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -15,7 +15,7 @@
 #include net.h
 #include sysemu.h
 #include boards.h
-#include pc.h
+#include serial.h
 #include qemu-timer.h
 #include ptimer.h
 #include block.h
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 167d5c4..1c16a54 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -20,8 +20,7 @@
 #include qemu-char.h
 #include hw.h
 #include omap.h
-/* We use pc-style serial ports.  */
-#include pc.h
+#include serial.h
 #include exec-memory.h
 
 /* UARTs */
diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
index 55e97f0..e484613 100644
--- a/hw/openrisc_sim.c
+++ b/hw/openrisc_sim.c
@@ -21,7 +21,8 @@
 #include hw.h
 #include boards.h
 #include elf.h
-#include pc.h
+#include serial.h
+#include net.h
 #include loader.h
 #include exec-memory.h
 #include sysemu.h
diff --git a/hw/pc.c b/hw/pc.c
index 6c0722d..805e8ca 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -23,6 +23,7 @@
  */
 #include hw.h
 #include pc.h
+#include serial.h
 #include apic.h
 #include fdc.h
 #include ide.h
diff --git a/hw/pc.h b/hw/pc.h
index 9923d96..6cba7ce 

Re: [Qemu-devel] Any alternative to kqemu ?

2012-10-15 Thread Stefan Hajnoczi
On Sun, Oct 14, 2012 at 01:52:54PM +0300, Timothy Madden wrote:
 `qemu-system-i386 -net nic ...` keeps saying upon invocation that
 vlan0 is not connected to host network. My `vconfig add eth1`
 command completed successfully, and I can `ifconfig eth1.0`,
 although I see no IP address on the new interface, only the mac
 address.

QEMU VLANs are not 802.1Q VLANs.  The terminology is confusing but it
has nothing to do with vconfig.

This error is displayed because there are two parts to the network
configuration options:
1. Emulated guest device, for example rtl8139 or virtio-net.
2. Host netdev, for example tap or the userspace SLIRP stack.

The error means you have only defined the emulated guest device but no
host netdev.  QEMU needs to know how you wish to connect the guest to
the outside world.

Here is a complete network configuration to try:

  qemu -net nic,model=rtl8139 -net user

There is more detail here:
http://wiki.qemu.org/Documentation/Networking

Stefan



[Qemu-devel] [PATCH v3 2/9] serial: add pci variant

2012-10-15 Thread Gerd Hoffmann
So we get a hot-pluggable 16550 uart.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 default-configs/pci.mak |2 +
 hw/Makefile.objs|1 +
 hw/pci_ids.h|1 +
 hw/serial-pci.c |  115 +++
 hw/serial.c |6 +++
 hw/serial.h |1 +
 6 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 hw/serial-pci.c

diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index 69e18f1..ae9d1eb 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -19,3 +19,5 @@ CONFIG_IDE_PCI=y
 CONFIG_AHCI=y
 CONFIG_ESP=y
 CONFIG_ESP_PCI=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_PCI=y
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 16e7a1e..af4ab0c 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -21,6 +21,7 @@ common-obj-$(CONFIG_ESCC) += escc.o
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 
 common-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
+common-obj-$(CONFIG_SERIAL_PCI) += serial-pci.o
 common-obj-$(CONFIG_PARALLEL) += parallel.o
 common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_PCSPK) += pcspk.o
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index 301bf1c..c017a79 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -37,6 +37,7 @@
 #define PCI_CLASS_BRIDGE_PCI 0x0604
 #define PCI_CLASS_BRIDGE_OTHER   0x0680
 
+#define PCI_CLASS_COMMUNICATION_SERIAL   0x0700
 #define PCI_CLASS_COMMUNICATION_OTHER0x0780
 
 #define PCI_CLASS_PROCESSOR_CO   0x0b40
diff --git a/hw/serial-pci.c b/hw/serial-pci.c
new file mode 100644
index 000..17247a8
--- /dev/null
+++ b/hw/serial-pci.c
@@ -0,0 +1,115 @@
+/*
+ * QEMU 16550A UART emulation
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ * 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.
+ */
+
+/*
+ * pci-serial spec:
+ *pci region 0 is a io bar, 8 bytes long, with the 16550 uart mapped to it.
+ *interrupt is wired to pin A.
+ *
+ * [root@fedora ~]# lspci -vnse
+ * 00:0e.0 0700: 1b36:0002 (rev 01) (prog-if 00 [8250])
+ * Subsystem: 1af4:1100
+ * Physical Slot: 14
+ * Flags: fast devsel, IRQ 11
+ * I/O ports at c130 [size=8]
+ * Kernel driver in use: serial
+ */
+
+#include serial.h
+#include pci.h
+
+typedef struct PCISerialState {
+PCIDevice dev;
+SerialState state;
+} PCISerialState;
+
+static int serial_pci_init(PCIDevice *dev)
+{
+PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+SerialState *s = pci-state;
+
+s-baudbase = 115200;
+serial_init_core(s);
+
+pci-dev.config[PCI_INTERRUPT_PIN] = 0x01;
+s-irq = pci-dev.irq[0];
+
+memory_region_init_io(s-io, serial_io_ops, s, serial, 8);
+pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, s-io);
+return 0;
+}
+
+static void serial_pci_exit(PCIDevice *dev)
+{
+PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
+SerialState *s = pci-state;
+
+serial_exit_core(s);
+memory_region_destroy(s-io);
+}
+
+static const VMStateDescription vmstate_pci_serial = {
+.name = pci-serial,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, PCISerialState),
+VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static Property serial_pci_properties[] = {
+DEFINE_PROP_CHR(chardev,  PCISerialState, state.chr),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void serial_pci_class_initfn(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass);
+pc-init = serial_pci_init;
+pc-exit = serial_pci_exit;
+pc-vendor_id = 0x1b36; /* Red Hat */
+pc-device_id = 0x0002;
+pc-revision = 1;
+pc-class_id = PCI_CLASS_COMMUNICATION_SERIAL;
+dc-vmsd = 

Re: [Qemu-devel] [RFC v1 7/7] vhost: abort if an emulated iommu is used

2012-10-15 Thread liu ping fan
On Thu, Oct 11, 2012 at 11:48 PM, Avi Kivity a...@redhat.com wrote:
 On 10/11/2012 05:34 PM, Michael S. Tsirkin wrote:
 On Thu, Oct 11, 2012 at 04:35:23PM +0200, Avi Kivity wrote:
 On 10/11/2012 04:35 PM, Michael S. Tsirkin wrote:

  No, qemu should configure virtio devices to bypass the iommu, even if it
  is on.
 
  Okay so there will be some API that virtio devices should call
  to achieve this?

 The iommu should probably call pci_device_bypasses_iommu() to check for
 such devices.

 So maybe this patch should depend on the introduction of such
 an API.

 I've dropped it for now.

 In fact, virtio/vhost are safe since they use cpu_physical_memory_rw()
 and the memory listener watches address_space_memory, no iommu there.

Not quite sure your meaning.  My understanding is that as a pci
device, vhost can lie behind a iommu in topology, which result in the
transaction launched can be snapped by the emulated iommu. BUT we make
a exception for vhost-dev and enforce
address_space_rw(address_space_memory, ..) NOT
address_space_rw(pci_dev-bus_master_as,..)  for vhost device, so we
bypass the iommu.  Right?

Regards,
pingfan
 vfio needs to change to listen to pci_dev-bus_master_as, and need
 special handling for iommu regions (abort for now, type 2 iommu later).

 --
 error compiling committee.c: too many arguments to function



[Qemu-devel] [PATCH v3 6/9] usb-serial: only expose device in guest when the chardev is open

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/usb/dev-serial.c |   19 +--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index 43214cd..a466f99 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -427,6 +427,10 @@ static void usb_serial_handle_destroy(USBDevice *dev)
 static int usb_serial_can_read(void *opaque)
 {
 USBSerialState *s = opaque;
+
+if (!s-dev.attached) {
+return 0;
+}
 return RECV_BUF - s-recv_used;
 }
 
@@ -469,8 +473,14 @@ static void usb_serial_event(void *opaque, int event)
 case CHR_EVENT_FOCUS:
 break;
 case CHR_EVENT_OPENED:
-usb_serial_reset(s);
-/* TODO: Reset USB port */
+if (!s-dev.attached) {
+usb_device_attach(s-dev);
+}
+break;
+case CHR_EVENT_CLOSED:
+if (s-dev.attached) {
+usb_device_detach(s-dev);
+}
 break;
 }
 }
@@ -481,6 +491,7 @@ static int usb_serial_initfn(USBDevice *dev)
 
 usb_desc_create_serial(dev);
 usb_desc_init(dev);
+dev-auto_attach = 0;
 
 if (!s-cs) {
 error_report(Property chardev is required);
@@ -490,6 +501,10 @@ static int usb_serial_initfn(USBDevice *dev)
 qemu_chr_add_handlers(s-cs, usb_serial_can_read, usb_serial_read,
   usb_serial_event, s);
 usb_serial_handle_reset(dev);
+
+if (s-cs-opened  !dev-attached) {
+usb_device_attach(dev);
+}
 return 0;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH v3 3/9] serial: add windows inf file for the pci card to docs

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 docs/qemupciserial.inf |  107 
 1 files changed, 107 insertions(+), 0 deletions(-)
 create mode 100644 docs/qemupciserial.inf

diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
new file mode 100644
index 000..c7cea99
--- /dev/null
+++ b/docs/qemupciserial.inf
@@ -0,0 +1,107 @@
+; qemupciserial.inf for QEMU, based on MSPORTS.INF
+
+; The driver itself is shipped with Windows (serial.sys).  This is
+; just a inf file to tell windows which pci id the serial pci card
+; emulated by qemu has, and to apply a name tag to it which windows
+; will show in the device manager.
+
+; Installing the driver: Go to device manager.  You should find a pci
+; serial card tagged with a yellow question mark.  Open properties.
+; Pick update driver.  Then select driver manually.  Pick Ports
+; (Com+Lpt) from the list.  Click Have a disk.  Select this file.
+; Procedure may vary a bit depending on the windows version.
+
+[Version]
+Signature=$CHICAGO$
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%QEMU%
+DriverVer=09/24/2012,1.3.0
+
+[SourceDisksNames]
+3426=windows cd
+
+[SourceDisksFiles]
+serial.sys = 3426
+serenum.sys= 3426
+
+[DestinationDirs]
+DefaultDestDir  = 11;LDID_SYS
+ComPort.NT.Copy = 12;DIRID_DRIVERS
+SerialEnumerator.NT.Copy=12 ;DIRID_DRIVERS
+
+; Drivers
+;--
+[Manufacturer]
+%QEMU%=QEMU,NTx86
+
+[QEMU.NTx86]
+%QEMU-PCI_SERIAL.DeviceDesc% = ComPort, PCI\VEN_1b36DEV_0002CC_0700
+
+; COM sections
+;--
+[ComPort.AddReg]
+HKR,,PortSubClass,1,01
+
+[ComPort.NT]
+AddReg=ComPort.AddReg, ComPort.NT.AddReg
+LogConfig=caa
+SyssetupPnPFlags = 1
+
+[ComPort.NT.HW]
+AddReg=ComPort.NT.HW.AddReg
+
+[ComPort.NT.AddReg]
+HKR,,EnumPropPages32,,MsPorts.dll,SerialPortPropPageProvider
+
+[ComPort.NT.HW.AddReg]
+HKR,,UpperFilters,0x0001,serenum
+
+;-- Service installation
+; Port Driver (function driver for this device)
+[ComPort.NT.Services]
+AddService = Serial, 0x0002, Serial_Service_Inst, Serial_EventLog_Inst
+AddService = Serenum,,Serenum_Service_Inst
+
+; -- Serial Port Driver install sections
+[Serial_Service_Inst]
+DisplayName= %Serial.SVCDESC%
+ServiceType= 1   ; SERVICE_KERNEL_DRIVER
+StartType  = 1   ; SERVICE_SYSTEM_START (this driver may do 
detection)
+ErrorControl   = 0   ; SERVICE_ERROR_IGNORE
+ServiceBinary  = %12%\serial.sys
+LoadOrderGroup = Extended base
+
+; -- Serenum Driver install section
+[Serenum_Service_Inst]
+DisplayName= %Serenum.SVCDESC%
+ServiceType= 1   ; SERVICE_KERNEL_DRIVER
+StartType  = 3   ; SERVICE_DEMAND_START
+ErrorControl   = 1   ; SERVICE_ERROR_NORMAL
+ServiceBinary  = %12%\serenum.sys
+LoadOrderGroup = PNP Filter
+
+[Serial_EventLog_Inst]
+AddReg = Serial_EventLog_AddReg
+
+[Serial_EventLog_AddReg]
+HKR,,EventMessageFile,0x0002,%%SystemRoot%%\System32\IoLogMsg.dll;%%SystemRoot%%\System32\drivers\serial.sys
+HKR,,TypesSupported,0x00010001,7
+
+; The following sections are COM port resource configs.
+; Section name format means:
+; Char 1 = c (COM port)
+; Char 2 = I/O config: 1 (3f8), 2 (2f8), 3 (3e8), 4 (2e8), a (any)
+; Char 3 = IRQ config: #, a (any)
+
+[caa]   ; Any base, any IRQ
+ConfigPriority=HARDRECONFIG
+IOConfig=8@100-%fff8(3ff::)
+IRQConfig=S:3,4,5,7,9,10,11,12,14,15
+
+[Strings]
+QEMU=QEMU
+QEMU-PCI_SERIAL.DeviceDesc=QEMU Serial PCI Card
+
+Serial.SVCDESC   = Serial port driver
+Serenum.SVCDESC = Serenum Filter Driver
-- 
1.7.1




Re: [Qemu-devel] [PATCH 2/2] qemu-iotests: Test qemu-img operation on zero size image

2012-10-15 Thread Kevin Wolf
Am 12.10.2012 18:57, schrieb Paolo Bonzini:
 FWIW, this will require renaming the mirror test to 042 :(  Since I have
 multiple patches touching the file while you have just one, any chance
 you can hold up this series for a week or so?

So is 042 still free? Then I'd just change this patch to use 042.
There's no strict rule that 041 must be committed earlier than 042.

Kevin



Re: [Qemu-devel] [PATCH v3 22/22] qidl: unit tests and build infrastructure

2012-10-15 Thread Kevin Wolf
Am 12.10.2012 23:39, schrieb Michael Roth:
 On Fri, Oct 05, 2012 at 10:24:30AM +0200, Paolo Bonzini wrote:
 Il 04/10/2012 19:33, Michael Roth ha scritto:
 +
 +%.qidl.c: %.c $(SRC_PATH)/qidl.h $(addprefix $(SRC_PATH)/scripts/,lexer.py 
 qidl.py qidl_parser.py qapi.py qapi_visit.py)
 +   $(call rm -f $(*D)/qidl-generated/$(*F).qidl.c)
 +   $(if $(strip $(shell grep QIDL_ENABLE() $ 1/dev/null  echo 
 true)), \
 + $(call quiet-command, \
 +   $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -E -c -DQIDL_GEN $ 
 | \
 +   $(PYTHON) $(SRC_PATH)/scripts/qidl.py \
 +   --output-filepath=$(*D)/qidl-generated/$(*F).qidl.c || [ $$? -eq 
 2 ], \
 +   qidl PP $(*D)/$(*F).c),)
 +%.o: %.c %.qidl.c
 +   $(if $(strip $(shell test -f $(*D)/qidl-generated/$(*F).qidl.c  echo 
 true)), \
 + $(call quiet-command, \
 +   $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
 +   -DQIDL_ENABLED -include $ -o $@ 
 $(*D)/qidl-generated/$(*F).qidl.c, \
 +   qidl CC $@), \
 + $(call quiet-command, \
 +   $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
 + -o $@ $,  CC$@))


 Because the .qidl.c files are not created for files without a QIDL_ENABLE()
 directive, all those files will be grepped on every invocation of the 
 makefile.

 It is better to define the list of QIDL_ENABLEd files in an auxiliary 
 makefile
 like this (untested):
 
 Thanks for the suggestion / example.
 
 FYI, I tried to get this working but didn't manage to get it in for v4. 
 Everything
 seems to be falling back to the non-qidl %o: target, and I haven't had time to
 debug it.
 
 FWIW, it doesn't seem to be a major factor performance-wise. Current build
 times on my laptop are (for all-target builds):
 
 QIDL v4:
  real8m35.383s
  user31m1.844s
  sys 1m33.998s
 
 upstream:
  real8m28.181s
  user30m44.983s
  sys 1m29.926s

Isn't the more interesting case that I only touched block/qcow2.c and
run make to update my binaries? I haven't really looked at the code, but
Paolo's comment suggests that even in this case a lot of files would be
grepped, and I think that losing a few seconds in such cases would
really hurt.

Kevin



Re: [Qemu-devel] [Bug 1066055] [NEW] Network performance regression with vde_switch

2012-10-15 Thread Stefan Hajnoczi
On Fri, Oct 12, 2012 at 05:34:23PM -, Edivaldo de Araujo Pereira wrote:
 I've noticed a significant network performance regression when using
 vde_switch, starting about one week ago (10/05/2012); before that date,
 I used to get about 1.5 Gbits host to guest, but now I can only get
 about 320 Mbits; I didn't find any modification in net/vde.*, just in
 hw/virtio*.
 
 My command line: 
  qemu-system-i386 -cdrom /bpd/bpd.iso -m 512 -boot d -enable-kvm \
   -localtime -ctrl-grab -usbdevice tablet \
   -device 
 virtio-net-pci,mac=52:54:00:18:01:01,netdev=vde0,tx=bh,ioeventfd=on,x-txburst=32
  \
   -netdev vde,id=vde0 -vga std -tb-size 2M -cpu host -clock unix
 
 My host runs a kernel 3.6.1 and my guest runs a kernel 3.5.4; the same
 problem happens with other host and guest versions, too.
 
 I know there are better ways of running a guest, but using vde I get a
 cleaner environment in the host (just one tun/tap interface to
 manage...), which is quite good when running some accademic experiments.
 
 Interestingly, at the same time I've noticed a performance enhancement
 of about 25~30 % when using a tun/tap interface, bridged or not.

Hi Edivaldo,
It would be great if you can help find the commit that caused this
regression.

The basic process is:

1. Identify a QEMU release or git tree that gives you 1.5 Gbit/s.
2. Double-check that qemu.git/master suffers reduced performance.
3. git bisect start bad good
   where bad and good are the git commits that show differing
   performance (for example, bad=HEAD good=v1.1.0)

Then git will step through the commit history and ask you to test at
each step.  (This is a binary search so even finding regressions that
happened many commits ago requires few steps.)

You can read more about git-bisect(1) here:
http://git-scm.com/book/en/Git-Tools-Debugging-with-Git#Binary-Search
http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html

The end result is the commit introduced the regression.  Please post
what you find!

Stefan



Re: [Qemu-devel] qemu-img: document 'info --backing-chain

2012-10-15 Thread Stefan Hajnoczi
On Sun, Oct 14, 2012 at 11:00:55AM +0530, Kashyap Chamarthy wrote:
 From a6233277e17338f571dda27cd9192d764f824b18 Mon Sep 17 00:00:00 2001
 From: Kashyap Chamarthy kashyap...@gmail.com
 Date: Sun, 14 Oct 2012 09:51:18 +0530
 Subject: [PATCH v2] qemu-img: document 'info --backing-chain'
 
 Signed-off-by: Kashyap Chamarthy kashyap...@gmail.com
 ---
  qemu-img-cmds.hx |  4 ++--
  qemu-img.texi| 19 ++-
  2 files changed, 20 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com



Re: [Qemu-devel] fixing qemu-0.1X endless loop in qcow2_alloc_cluster_offset

2012-10-15 Thread Kevin Wolf
Am 12.10.2012 17:52, schrieb Andreas Färber:
 Am 12.06.2012 15:44, schrieb Kevin Wolf:
 Am 12.06.2012 15:33, schrieb Andreas Färber:
 Am 14.05.2012 14:20, schrieb Kevin Wolf:
 Am 13.05.2012 10:03, schrieb Zhouyi Zhou:
 hi all
   
   sometimes, qemu/kvm-0.1x will hang in endless loop in 
 qcow2_alloc_cluster_offset.
   after some investigation, I found that:
   in function posix_aio_process_queue(void *opaque)
 440 ret = qemu_paio_error(acb);
 441 if (ret == ECANCELED) {
 442 /* remove the request */
 443 *pacb = acb-next;
 444 qemu_aio_release(acb);
 445 result = 1;
 446 } else if (ret != EINPROGRESS) {
   in line 444 acb got released but acb-common.opaque does not.
 which will be released via guest OS via ide_dma_cancel which 
 will in term call qcow_aio_cancel which does not check its argument
 is in flight list or not.
   The fix is as follows: (debian 6's qemu-kvm-0.12.5)
 ###
 --- block/qcow2.h~  2010-07-27 08:43:53.0 +0800
 +++ block/qcow2.h   2012-05-13 15:51:39.0 +0800
 @@ -143,6 +143,7 @@
  QLIST_HEAD(QCowAioDependencies, QCowAIOCB) dependent_requests;
  
  QLIST_ENTRY(QCowL2Meta) next_in_flight;
 +int inflight;   
  } QCowL2Meta;
 --- block/qcow2.c~  2012-05-13 15:57:09.0 +0800
 +++ block/qcow2.c   2012-05-13 15:57:24.0 +0800
 @@ -349,6 +349,10 @@
  QCowAIOCB *acb = (QCowAIOCB *)blockacb;
  if (acb-hd_aiocb)
  bdrv_aio_cancel(acb-hd_aiocb);
 +if (acb-l2meta.inflight) {
 +QLIST_REMOVE(acb-l2meta, next_in_flight);
 +   acb-l2meta.inflight = 0;
 +}
  qemu_aio_release(acb);
  }
  
 @@ -506,6 +510,7 @@
  acb-n = 0;
  acb-cluster_offset = 0;
  acb-l2meta.nb_clusters = 0;
 +acb-l2meta.inflight = 0;
  QLIST_INIT(acb-l2meta.dependent_requests);
  return acb;
  }
 @@ -534,6 +539,7 @@
  /* Take the request off the list of running requests */
  if (m-nb_clusters != 0) {
  QLIST_REMOVE(m, next_in_flight);
 +   m-inflight = 0;
  }
  
  /*
 @@ -632,6 +638,7 @@
  fail:
  if (acb-l2meta.nb_clusters != 0) {
  QLIST_REMOVE(acb-l2meta, next_in_flight);
 +   acb-l2meta.inflight  = 0;
  }
  done:
  if (acb-qiov-niov  1)
 --- block/qcow2-cluster.c~  2010-07-27 08:43:53.0 +0800
 +++ block/qcow2-cluster.c   2012-05-13 15:53:53.0 +0800
 @@ -827,6 +827,7 @@
  m-offset = offset;
  m-n_start = n_start;
  m-nb_clusters = nb_clusters;
 +m-inflight = 1;
  
  out:
  m-nb_available = MIN(nb_clusters  (s-cluster_bits - 9), n_end);

  Thanks for investigation
 Zhouyi

 The patch looks reasonable to me. Note however that while it fixes the
 hang, it still causes cluster leaks. I'm not sure if someone is
 interested in picking these up for old stable releases. Andreas, I think
 you were going to take 0.15? The first version that doesn't have the
 problem is 1.0.

 Kevin, the policy as I understood it is to cherry-pick patches from
 qemu.git into qemu-stable-x.y.git. So I don't think me applying this
 patch to stable-0.15 would be right. I don't spot a particular qcow2 fix
 among our 0.15 backports that I have now pushed. Do you have a pointer
 which one(s) would fix this issue so that I can recheck?

 It's fixed as a side effect of the block layer conversion to
 coroutines. Not exactly the kind of patches you'd want to cherry-pick
 for stable-0.15.

 The better fix for 0.15 could be to backport the new behaviour of
 coroutine based requests with bdrv_aio_cancel:

 static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
 {
 qemu_aio_flush();
 }

 Using that as the implementation for qcow2_aio_cancel should be safe and
 fix this problem.
 
 Kevin, I have stable-0.15 in a state where I'm about to tag 0.15.2 now.
 The original patch does not have a Signed-off-by nor your Acked-by, so I
 can't apply it as-is. stable-0.15 does not have coroutines, so I don't
 understand what exactly you're suggesting as alternative here: Backport
 the whole coroutine feature including coroutine function above? Or just
 call qemu_aio_flush() in place of what? This is old qcow2_aio_cancel():

No, that was qcow2_aio_flush. ;-)

What I'm suggesting (not even compile tested!) is:

Signed-off-by: Kevin Wolf kw...@redhat.com

diff --git a/block/qcow2.c b/block/qcow2.c
index 48e1b95..d665675 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -388,10 +388,7 @@ typedef struct QCowAIOCB {

 static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
 {
-QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-if (acb-hd_aiocb)
-bdrv_aio_cancel(acb-hd_aiocb);
-qemu_aio_release(acb);
+qemu_aio_flush();
 }

 static AIOPool qcow2_aio_pool = {



Re: [Qemu-devel] [libvirt] Problems using netdev_del+netdev_add w/o corresponding device_del+device_add

2012-10-15 Thread Daniel P. Berrange
On Mon, Oct 15, 2012 at 10:30:07AM +0200, Stefan Hajnoczi wrote:
 On Sat, Oct 13, 2012 at 04:47:14PM -0400, Laine Stump wrote:
  Here is the sequence sent to disconnect only the host side, then
  reconnect it with a new tap device. (although the fd is the same, this
  is because the old tap device had already been closed, so the number is
  just being used - the same thing happens when doing sequential full
  detach/attach cycles, and they all work with no problems):
  
  
  168.750  0x7f8e2c90
  {execute:netdev_del,arguments:{id:hostnet0},id:libvirt-30}
  168.762  0x7f8e2c90 {return: {}, id: libvirt-30}
  168.800  0x7f8e2c90
  {execute:getfd,arguments:{fdname:fd-net0},id:libvirt-31}
  (fd=27)
  168.801  0x7f8e2c90 {return: {}, id: libvirt-31}
  168.801  0x7f8e2c90
  {execute:netdev_add,arguments:{type:tap,fd:fd-net0,id:hostnet0},id:libvirt-32}
  168.802  0x7f8e2c90 {return: {}, id: libvirt-32}
  168.802  0x7f8e2c90
  {execute:set_link,arguments:{name:net0,up:true},id:libvirt-33}
  168.803  0x7f8e2c90 {return: {}, id: libvirt-33}
  
  After this sequence is done, everything about the network device
  *appears* normal on both the guest and host (at least the things I know
  to look at), but no traffic from the host shows up in a tcpdump of the
  interface on the guest, and no traffic from the guest shows up in a
  tcpdump of the tap device on the host.
 
 What you are trying to do isn't possible today.
 
 The device associates with the netdev during initialization only - there
 is no command to associate at a later point in time.  That is why your
 example works only when the device is deleted together with the netdev.
 
 It is certainly possible to implement a command to switch netdevs but
 I'm curious what the use case is.  Is this necessary just because QEMU
 doesn't provide a way to modify the existing netdev or because you
 really want to switch to a completely different netdev?

We have end users who want to be able to dynamically change the guest'
networking attachment, without restarting/hotplugging devices in the
guest[1]. If it is just a case of changing from one bridge, to another
bridge we can do that just by moving the TAP Device from one to another.
This doesn't work if we want to support more general changes in config.
eg from a macvtap setup to a TAP setup, or vica-verca.

Another requirement is to be able to start a guest with a null backend
(akin to not plugging in the ethernet cable on a physical host), and
then attach it to a bridge/macvtap device on the fly later on (akin
to then plugging in the ethernet cable once running).

Regards,
Daniel

[1] Obviously the guest might need to reconfigure its IP or re-run DHCP
though.
-- 
|: 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 :|



Re: [Qemu-devel] Silent filesystem/qcow2 corruptions with qemu-kvm-1.0 and 1.1.1

2012-10-15 Thread Tiziano Müller
Am Montag, den 15.10.2012, 09:48 +0200 schrieb Stefan Hajnoczi:
 Okay, that's consistent with the other symptoms you've reported.
 
 It's not clear whether the corruption arises inside qcow2 or if
 something else is causing corruption and qcow2/xfs get upset.  That is
 the next step to debugging this - hopefully it will become possible to
 reproduce it reliably, at which point it is much easier to debug :).

Yes, we have now 3 different VM-configurations deployed on the server
where we saw the most corruptions so far:

* config 1: as-is
* config 2: raw-image format instead of qcow2 as you suggested
* config 3: vhost=off for the network

The third test-case is because we figured out that one major difference
between the two servers is that on the server with the most corruptions
we have vhost=on (automatically turned on by qemu/libvirt because the
vhost-net module got loaded). I know this does not make a lot of sense.

In fact, on the server without vhost-net (and with qemu-1.0) we only saw
one corruption after all (where the qcow2 got really messed up), so one
could assume that this was a single event and may have been a user
error. To summarize it:

* server 1 (qemu-kvm-1.1, host-kernel 3.5.2, vhost-net loaded and used)
has had +5 machines with corrupt filesystems (ext4 and xfs) and 1
machine with a corrupt qcow2.
* server 2 (qemu-kvm-1.0, host-kernel 3.2.6, vhost-net not loaded) has
had only 1 machine with a corrupt qcow2.

The mentioned Test-VMs are running since Friday and unfortunately none
of them had the decency to go corrupt again.

We will keep you posted,
thanks a lot for your help.

Best regards,
Tiziano

-- 
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.muel...@stepping-stone.ch




Re: [Qemu-devel] [PATCH 2/2] qemu-iotests: Test qemu-img operation on zero size image

2012-10-15 Thread Paolo Bonzini
 Am 12.10.2012 18:57, schrieb Paolo Bonzini:
  FWIW, this will require renaming the mirror test to 042 :(  Since I
  have
  multiple patches touching the file while you have just one, any
  chance
  you can hold up this series for a week or so?
 
 So is 042 still free? Then I'd just change this patch to use 042.
 There's no strict rule that 041 must be committed earlier than 042.

Yes, that would work too--thanks!

Paolo



[Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener

2012-10-15 Thread Gerd Hoffmann
Also change the way the gui_timer is initialized: each time a
displaychangelistener is registered or unregistered we'll check
whenever we need a timer (due to dpy_refresh callback being present)
and if so setup a timer, otherwise zap it.  This way the gui timer works
correctly with displaychangelisteners coming and going.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.h |   10 ++
 vl.c  |   31 +++
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/console.h b/console.h
index 646ad4b..48fef22 100644
--- a/console.h
+++ b/console.h
@@ -229,9 +229,19 @@ static inline int is_buffer_shared(DisplaySurface *surface)
 !(surface-flags  QEMU_REALPIXELS_FLAG));
 }
 
+void gui_setup_refresh(DisplayState *ds);
+
 static inline void register_displaychangelistener(DisplayState *ds, 
DisplayChangeListener *dcl)
 {
 QLIST_INSERT_HEAD(ds-listeners, dcl, next);
+gui_setup_refresh(ds);
+}
+
+static inline void unregister_displaychangelistener(DisplayState *ds,
+DisplayChangeListener *dcl)
+{
+QLIST_REMOVE(dcl, next);
+gui_setup_refresh(ds);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
diff --git a/vl.c b/vl.c
index 23743af..9faab75 100644
--- a/vl.c
+++ b/vl.c
@@ -1287,6 +1287,29 @@ static void gui_update(void *opaque)
 qemu_mod_timer(ds-gui_timer, interval + qemu_get_clock_ms(rt_clock));
 }
 
+void gui_setup_refresh(DisplayState *ds)
+{
+DisplayChangeListener *dcl;
+bool need_timer = false;
+
+QLIST_FOREACH(dcl, ds-listeners, next) {
+if (dcl-dpy_refresh != NULL) {
+need_timer = true;
+break;
+}
+}
+
+if (need_timer  ds-gui_timer == NULL) {
+ds-gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
+qemu_mod_timer(ds-gui_timer, qemu_get_clock_ms(rt_clock));
+}
+if (!need_timer  ds-gui_timer != NULL) {
+qemu_del_timer(ds-gui_timer);
+qemu_free_timer(ds-gui_timer);
+ds-gui_timer = NULL;
+}
+}
+
 struct vm_change_state_entry {
 VMChangeStateHandler *cb;
 void *opaque;
@@ -2370,7 +2393,6 @@ int main(int argc, char **argv, char **envp)
 const char *kernel_filename, *kernel_cmdline;
 char boot_devices[33] = cad; /* default to HD-floppy-CD-ROM */
 DisplayState *ds;
-DisplayChangeListener *dcl;
 int cyls, heads, secs, translation;
 QemuOpts *hda_opts = NULL, *opts, *machine_opts;
 QemuOptsList *olist;
@@ -3725,13 +3747,6 @@ int main(int argc, char **argv, char **envp)
 
 /* display setup */
 dpy_resize(ds);
-QLIST_FOREACH(dcl, ds-listeners, next) {
-if (dcl-dpy_refresh != NULL) {
-ds-gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
-qemu_mod_timer(ds-gui_timer, qemu_get_clock_ms(rt_clock));
-break;
-}
-}
 text_consoles_set_display(ds);
 
 if (foreach_device_config(DEV_GDB, gdbserver_start)  0) {
-- 
1.7.1




[Qemu-devel] [PATCH 6/8] console: init displaychangelisteners on register

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.h |3 +++
 vl.c  |1 -
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/console.h b/console.h
index 9d008b2..bd56f3c 100644
--- a/console.h
+++ b/console.h
@@ -241,6 +241,9 @@ static inline void 
register_displaychangelistener(DisplayState *ds, DisplayChang
 {
 QLIST_INSERT_HEAD(ds-listeners, dcl, next);
 gui_setup_refresh(ds);
+if (dcl-dpy_gfx_resize) {
+dcl-dpy_gfx_resize(ds);
+}
 }
 
 static inline void unregister_displaychangelistener(DisplayState *ds,
diff --git a/vl.c b/vl.c
index ec94626..91514c8 100644
--- a/vl.c
+++ b/vl.c
@@ -3756,7 +3756,6 @@ int main(int argc, char **argv, char **envp)
 #endif
 
 /* display setup */
-dpy_gfx_resize(ds);
 text_consoles_set_display(ds);
 
 if (foreach_device_config(DEV_GDB, gdbserver_start)  0) {
-- 
1.7.1




[Qemu-devel] [PATCH 3/8] console: move set_mouse + cursor_define callbacks

2012-10-15 Thread Gerd Hoffmann
When adding DisplayChangeListeners the set_mouse and cursor_define
callbacks have been left in DisplayState for some reason.  Fix it.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.c  |2 +-
 console.h  |   39 +++
 hw/jazz_led.c  |2 +-
 hw/qxl-render.c|2 +-
 hw/vga.c   |   10 +-
 hw/vmware_vga.c|   11 ++-
 ui/sdl.c   |8 
 ui/spice-display.c |4 ++--
 ui/vnc.c   |8 
 9 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/console.c b/console.c
index 3f3d254..260a029 100644
--- a/console.c
+++ b/console.c
@@ -1242,7 +1242,7 @@ static void text_console_update(void *opaque, 
console_ch_t *chardata)
 s-text_y[1] = 0;
 }
 if (s-cursor_invalidate) {
-dpy_cursor(s-ds, s-x, s-y);
+dpy_text_cursor(s-ds, s-x, s-y);
 s-cursor_invalidate = 0;
 }
 }
diff --git a/console.h b/console.h
index 48fef22..bef2d2d 100644
--- a/console.h
+++ b/console.h
@@ -164,6 +164,9 @@ struct DisplayChangeListener {
  int w, int h, uint32_t c);
 void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
+void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
+void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
+
 QLIST_ENTRY(DisplayChangeListener) next;
 };
 
@@ -181,9 +184,6 @@ struct DisplayState {
 struct DisplayAllocator* allocator;
 QLIST_HEAD(, DisplayChangeListener) listeners;
 
-void (*mouse_set)(int x, int y, int on);
-void (*cursor_define)(QEMUCursor *cursor);
-
 struct DisplayState *next;
 };
 
@@ -304,7 +304,7 @@ static inline void dpy_fill(struct DisplayState *s, int x, 
int y,
 }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y)
+static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
 struct DisplayChangeListener *dcl;
 QLIST_FOREACH(dcl, s-listeners, next) {
@@ -314,6 +314,37 @@ static inline void dpy_cursor(struct DisplayState *s, int 
x, int y)
 }
 }
 
+static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_mouse_set) {
+dcl-dpy_mouse_set(s, x, y, on);
+}
+}
+}
+
+static inline void dpy_cursor_define(struct DisplayState *s, QEMUCursor 
*cursor)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_cursor_define) {
+dcl-dpy_cursor_define(s, cursor);
+}
+}
+}
+
+static inline bool dpy_cursor_define_supported(struct DisplayState *s)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_cursor_define) {
+return true;
+}
+}
+return false;
+}
+
 static inline int ds_get_linesize(DisplayState *ds)
 {
 return ds-surface-linesize;
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 6486523..c4d54e2 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -210,7 +210,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t 
*chardata)
 LedState *s = opaque;
 char buf[2];
 
-dpy_cursor(s-ds, -1, -1);
+dpy_text_cursor(s-ds, -1, -1);
 qemu_console_resize(s-ds, 2, 1);
 
 /* TODO: draw the segments */
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index b66c168..e8cf29e 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -234,7 +234,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
 return 1;
 }
 
-if (!qxl-ssd.ds-mouse_set || !qxl-ssd.ds-cursor_define) {
+if (!dpy_cursor_define_supported(qxl-ssd.ds)) {
 return 0;
 }
 
diff --git a/hw/vga.c b/hw/vga.c
index afaef0d..ec4f0c5 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2081,11 +2081,11 @@ static void vga_update_text(void *opaque, console_ch_t 
*chardata)
 s-cr[VGA_CRTC_CURSOR_END] != s-cursor_end || full_update) {
 cursor_visible = !(s-cr[VGA_CRTC_CURSOR_START]  0x20);
 if (cursor_visible  cursor_offset  size  cursor_offset = 0)
-dpy_cursor(s-ds,
-   TEXTMODE_X(cursor_offset),
-   TEXTMODE_Y(cursor_offset));
+dpy_text_cursor(s-ds,
+TEXTMODE_X(cursor_offset),
+TEXTMODE_Y(cursor_offset));
 else
-dpy_cursor(s-ds, -1, -1);
+dpy_text_cursor(s-ds, -1, -1);
 s-cursor_offset = cursor_offset;
 s-cursor_start = s-cr[VGA_CRTC_CURSOR_START];
 s-cursor_end = s-cr[VGA_CRTC_CURSOR_END];
@@ -2146,7 +2146,7 @@ static void vga_update_text(void *opaque, console_ch_t 
*chardata)
 /* Display a message */
 s-last_width = 60;
 s-last_height = height = 3;
-dpy_cursor(s-ds, -1, -1);
+

[Qemu-devel] [PATCH 8/8] console: remove dpy_gfx_fill

2012-10-15 Thread Gerd Hoffmann
Unused code.  'nuff said.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.h |   13 -
 ui/sdl.c  |7 ---
 2 files changed, 0 insertions(+), 20 deletions(-)

diff --git a/console.h b/console.h
index bd56f3c..78e842f 100644
--- a/console.h
+++ b/console.h
@@ -161,8 +161,6 @@ struct DisplayChangeListener {
 void (*dpy_gfx_setdata)(struct DisplayState *s);
 void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
  int dst_x, int dst_y, int w, int h);
-void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
- int w, int h, uint32_t c);
 
 void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
@@ -306,17 +304,6 @@ static inline void dpy_gfx_copy(struct DisplayState *s, 
int src_x, int src_y,
 }
 }
 
-static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
-int w, int h, uint32_t c)
-{
-struct DisplayChangeListener *dcl;
-QLIST_FOREACH(dcl, s-listeners, next) {
-if (dcl-dpy_gfx_fill) {
-dcl-dpy_gfx_fill(s, x, y, w, h, c);
-}
-}
-}
-
 static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
 struct DisplayChangeListener *dcl;
diff --git a/ui/sdl.c b/ui/sdl.c
index fac1a47..c3ba79f 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -899,12 +899,6 @@ static void sdl_refresh(DisplayState *ds)
 }
 }
 
-static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
-{
-SDL_Rect dst = { x, y, w, h };
-SDL_FillRect(real_screen, dst, c);
-}
-
 static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
 {
 if (on) {
@@ -1024,7 +1018,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, 
int no_frame)
 dcl-dpy_gfx_resize = sdl_resize;
 dcl-dpy_refresh = sdl_refresh;
 dcl-dpy_gfx_setdata = sdl_setdata;
-dcl-dpy_gfx_fill = sdl_fill;
 dcl-dpy_mouse_set = sdl_mouse_warp;
 dcl-dpy_cursor_define = sdl_mouse_define;
 register_displaychangelistener(ds, dcl);
-- 
1.7.1




[Qemu-devel] [PATCH 5/8] console: untangle gfx txt updates

2012-10-15 Thread Gerd Hoffmann
Stop abusing displaysurface fields for text mode displays.
(bpp = 0, width = cols, height = lines).

Add flags to displaystate indicating whenever text mode display
(curses) or gfx mode displays (sdl, vnc, ...) are present.

Add separate displaychangelistener callbacks for text / gfx mode
resize  updates.

This allows to enable gfx and txt diplays at the same time and also
paves the way for more cleanups in the future.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.c|   59 +---
 console.h|   74 +++---
 hw/blizzard.c|4 +-
 hw/exynos4210_fimd.c |2 +-
 hw/g364fb.c  |7 +++--
 hw/jazz_led.c|4 +-
 hw/milkymist-vgafb.c |2 +-
 hw/musicpal.c|2 +-
 hw/nseries.c |2 +-
 hw/omap_lcdc.c   |2 +-
 hw/palm.c|2 +-
 hw/pl110.c   |2 +-
 hw/pxa2xx_lcd.c  |8 +++---
 hw/qxl-render.c  |   10 +++---
 hw/qxl.c |4 +-
 hw/sm501.c   |4 +-
 hw/ssd0303.c |2 +-
 hw/ssd0323.c |2 +-
 hw/tc6393xb.c|4 +-
 hw/tcx.c |   16 +-
 hw/vga.c |   34 ++-
 hw/vmware_vga.c  |4 +-
 ui/curses.c  |   21 +-
 ui/sdl.c |   12 
 ui/spice-display.c   |4 +-
 ui/vnc.c |8 +++---
 vl.c |   14 -
 27 files changed, 171 insertions(+), 138 deletions(-)

diff --git a/console.c b/console.c
index b53dc1b..61812c7 100644
--- a/console.c
+++ b/console.c
@@ -638,30 +638,33 @@ static void console_refresh(QemuConsole *s)
 
 if (s != active_console)
 return;
-if (!ds_get_bits_per_pixel(s-ds)) {
+
+if (s-ds-have_text) {
 s-text_x[0] = 0;
 s-text_y[0] = 0;
 s-text_x[1] = s-width - 1;
 s-text_y[1] = s-height - 1;
 s-cursor_invalidate = 1;
-return;
 }
 
-vga_fill_rect(s-ds, 0, 0, ds_get_width(s-ds), ds_get_height(s-ds),
-  color_table[0][COLOR_BLACK]);
-y1 = s-y_displayed;
-for(y = 0; y  s-height; y++) {
-c = s-cells + y1 * s-width;
-for(x = 0; x  s-width; x++) {
-vga_putcharxy(s-ds, x, y, c-ch,
-  (c-t_attrib));
-c++;
+if (s-ds-have_gfx) {
+vga_fill_rect(s-ds, 0, 0, ds_get_width(s-ds), ds_get_height(s-ds),
+  color_table[0][COLOR_BLACK]);
+y1 = s-y_displayed;
+for (y = 0; y  s-height; y++) {
+c = s-cells + y1 * s-width;
+for (x = 0; x  s-width; x++) {
+vga_putcharxy(s-ds, x, y, c-ch,
+  (c-t_attrib));
+c++;
+}
+if (++y1 == s-total_height) {
+y1 = 0;
+}
 }
-if (++y1 == s-total_height)
-y1 = 0;
+console_show_cursor(s, 1);
+dpy_gfx_update(s-ds, 0, 0, ds_get_width(s-ds), ds_get_height(s-ds));
 }
-console_show_cursor(s, 1);
-dpy_update(s-ds, 0, 0, ds_get_width(s-ds), ds_get_height(s-ds));
 }
 
 static void console_scroll(int ydelta)
@@ -1094,17 +1097,17 @@ void console_select(unsigned int index)
 qemu_del_timer(active_console-cursor_timer);
 }
 active_console = s;
-if (ds_get_bits_per_pixel(s-ds)) {
+if (ds-have_gfx) {
 ds-surface = qemu_resize_displaysurface(ds, s-g_width, 
s-g_height);
-} else {
-s-ds-surface-width = s-width;
-s-ds-surface-height = s-height;
+dpy_gfx_resize(ds);
+}
+if (ds-have_text) {
+dpy_text_resize(ds, s-width, s-height);
 }
 if (s-cursor_timer) {
 qemu_mod_timer(s-cursor_timer,
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
 }
-dpy_resize(s-ds);
 vga_hw_invalidate();
 }
 }
@@ -1123,10 +1126,10 @@ static int console_puts(CharDriverState *chr, const 
uint8_t *buf, int len)
 console_putchar(s, buf[i]);
 }
 console_show_cursor(s, 1);
-if (ds_get_bits_per_pixel(s-ds)  s-update_x0  s-update_x1) {
-dpy_update(s-ds, s-update_x0, s-update_y0,
-   s-update_x1 - s-update_x0,
-   s-update_y1 - s-update_y0);
+if (s-ds-have_gfx  s-update_x0  s-update_x1) {
+dpy_gfx_update(s-ds, s-update_x0, s-update_y0,
+   s-update_x1 - s-update_x0,
+   s-update_y1 - s-update_y0);
 }
 return len;
 }
@@ -1234,8 +1237,8 @@ static void text_console_update(void *opaque, 
console_ch_t *chardata)
 (s-cells[src].t_attrib.fgcol  12) |
 (s-cells[src].t_attrib.bgcol  8) |
 (s-cells[src].t_attrib.bold  21));
-dpy_update(s-ds, s-text_x[0], 

Re: [Qemu-devel] [PATCH v4 26/26] qidl: unit tests and build infrastructure

2012-10-15 Thread Paolo Bonzini
Il 12/10/2012 23:11, Michael Roth ha scritto:
 +%.qidl.c: %.c $(SRC_PATH)/qidl.h $(addprefix $(SRC_PATH)/scripts/,lexer.py 
 qidl.py qidl_parser.py qapi.py qapi_visit.py)

The rule here is wrong, because %.qidl.c is never produced by the
commands.  The output is in the qidl-generated subdirectory, and that
cannot be expressed with pattern rules.

I was worried that this causes many greps on every invocation of the
Makefile---even though the way you hid them in makefile functions would
hide them from the make output.

However, this is not the case.  What happens is quite complex.
hw/foo.qidl.c (as opposed to hw/qidl-generated/foo.qidl.c) will never
exist, but it is a dependency of hw/foo.o, so it is always rebuilt
before it.  But it is not rebuilt on every invocation even though it
doesn't exist, because it only comes into play via implicit rules.

I think this is quite clever and does exactly what you want.  If you
want to keep the qidl-generated directory, I cannot imagine any other
way to do it.  However, please rename %.qidl.c to something QIDL-PP-% so
that it is clear that it is not a real file name.

If we decide this is too clever (and it's not all of it, it took me a
while to understand that Makefile functions are needed because
quiet-command expands to a @-prefixed command...), we can drop the
qidl-generated directory.

 + $(call rm -f $(*D)/qidl-generated/$(*F).qidl.*)

I think this $(call) is not what you want, you need just @rm -f ...

Paolo

 + $(if $(strip $(shell grep QIDL_ENABLE() $ 1/dev/null  echo 
 true)), \
 +   $(call quiet-command, \
 + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -E -c -DQIDL_GEN $ 
 | \
 + $(PYTHON) $(SRC_PATH)/scripts/qidl.py $(QIDL_FLAGS) \
 + --output-filepath=$(*D)/qidl-generated/$(*F).qidl.c || [ $$? -eq 
 2 ], \
 + qidl PP $(*D)/$(*F).c),)
 +
 +%.o: %.c %.qidl.c
 + $(if $(strip $(shell test -f $(*D)/qidl-generated/$(*F).qidl.c  echo 
 true)), \
 +   $(call quiet-command, \
 + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
 + -DQIDL_ENABLED -include $ -o $@ 
 $(*D)/qidl-generated/$(*F).qidl.c, \
 + qidl CC $@), \
 +   $(call quiet-command, \
 + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
 +   -o $@ $,  CC$@))




[Qemu-devel] [PATCH 1/8] console: QLIST-ify display change listeners.

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.h  |   72 +++
 hw/xenfb.c |2 +-
 vl.c   |9 ++-
 3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/console.h b/console.h
index f990684..646ad4b 100644
--- a/console.h
+++ b/console.h
@@ -164,7 +164,7 @@ struct DisplayChangeListener {
  int w, int h, uint32_t c);
 void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
-struct DisplayChangeListener *next;
+QLIST_ENTRY(DisplayChangeListener) next;
 };
 
 struct DisplayAllocator {
@@ -179,7 +179,7 @@ struct DisplayState {
 struct QEMUTimer *gui_timer;
 
 struct DisplayAllocator* allocator;
-struct DisplayChangeListener* listeners;
+QLIST_HEAD(, DisplayChangeListener) listeners;
 
 void (*mouse_set)(int x, int y, int on);
 void (*cursor_define)(QEMUCursor *cursor);
@@ -231,72 +231,76 @@ static inline int is_buffer_shared(DisplaySurface 
*surface)
 
 static inline void register_displaychangelistener(DisplayState *ds, 
DisplayChangeListener *dcl)
 {
-dcl-next = ds-listeners;
-ds-listeners = dcl;
+QLIST_INSERT_HEAD(ds-listeners, dcl, next);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
 {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
 dcl-dpy_update(s, x, y, w, h);
-dcl = dcl-next;
 }
 }
 
 static inline void dpy_resize(DisplayState *s)
 {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
 dcl-dpy_resize(s);
-dcl = dcl-next;
 }
 }
 
 static inline void dpy_setdata(DisplayState *s)
 {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
-if (dcl-dpy_setdata) dcl-dpy_setdata(s);
-dcl = dcl-next;
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_setdata) {
+dcl-dpy_setdata(s);
+}
 }
 }
 
 static inline void dpy_refresh(DisplayState *s)
 {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
-if (dcl-dpy_refresh) dcl-dpy_refresh(s);
-dcl = dcl-next;
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_refresh) {
+dcl-dpy_refresh(s);
+}
 }
 }
 
 static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
- int dst_x, int dst_y, int w, int h) {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
-if (dcl-dpy_copy)
+ int dst_x, int dst_y, int w, int h)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_copy) {
 dcl-dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
-else /* TODO */
+} else { /* TODO */
 dcl-dpy_update(s, dst_x, dst_y, w, h);
-dcl = dcl-next;
+}
 }
 }
 
 static inline void dpy_fill(struct DisplayState *s, int x, int y,
- int w, int h, uint32_t c) {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
-if (dcl-dpy_fill) dcl-dpy_fill(s, x, y, w, h, c);
-dcl = dcl-next;
+ int w, int h, uint32_t c)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_fill) {
+dcl-dpy_fill(s, x, y, w, h, c);
+}
 }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
-struct DisplayChangeListener *dcl = s-listeners;
-while (dcl != NULL) {
-if (dcl-dpy_text_cursor) dcl-dpy_text_cursor(s, x, y);
-dcl = dcl-next;
+static inline void dpy_cursor(struct DisplayState *s, int x, int y)
+{
+struct DisplayChangeListener *dcl;
+QLIST_FOREACH(dcl, s-listeners, next) {
+if (dcl-dpy_text_cursor) {
+dcl-dpy_text_cursor(s, x, y);
+}
 }
 }
 
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 338800a..ef24c33 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -717,7 +717,7 @@ static void xenfb_update(void *opaque)
if (xenfb_queue_full(xenfb))
return;
 
-for (l = xenfb-c.ds-listeners; l != NULL; l = l-next) {
+QLIST_FOREACH(l, xenfb-c.ds-listeners, next) {
 if (l-idle)
 continue;
 idle = 0;
diff --git a/vl.c b/vl.c
index 5b357a3..23743af 100644
--- a/vl.c
+++ b/vl.c
@@ -1275,15 +1275,14 @@ static void gui_update(void *opaque)
 {
 uint64_t interval = GUI_REFRESH_INTERVAL;
 DisplayState *ds = opaque;
-DisplayChangeListener *dcl = ds-listeners;
+DisplayChangeListener *dcl;
 
 

[Qemu-devel] [PATCH 4/8] console: s/TextConsole/QemuConsole/

2012-10-15 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 console.c |   72 
 qemu-common.h |3 +-
 2 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/console.c b/console.c
index 260a029..b53dc1b 100644
--- a/console.c
+++ b/console.c
@@ -114,20 +114,20 @@ typedef enum {
 TEXT_CONSOLE_FIXED_SIZE
 } console_type_t;
 
-/* ??? This is mis-named.
-   It is used for both text and graphical consoles.  */
-struct TextConsole {
+struct QemuConsole {
 int index;
 console_type_t console_type;
 DisplayState *ds;
+
 /* Graphic console state.  */
 vga_hw_update_ptr hw_update;
 vga_hw_invalidate_ptr hw_invalidate;
 vga_hw_screen_dump_ptr hw_screen_dump;
 vga_hw_text_update_ptr hw_text_update;
 void *hw;
-
 int g_width, g_height;
+
+/* Text console state */
 int width;
 int height;
 int total_height;
@@ -161,8 +161,8 @@ struct TextConsole {
 };
 
 static DisplayState *display_state;
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
+static QemuConsole *active_console;
+static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
 
 void vga_hw_update(void)
@@ -179,7 +179,7 @@ void vga_hw_invalidate(void)
 
 void qmp_screendump(const char *filename, Error **errp)
 {
-TextConsole *previous_active_console;
+QemuConsole *previous_active_console;
 bool cswitch;
 
 previous_active_console = active_console;
@@ -521,7 +521,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, 
int ch,
 }
 }
 
-static void text_console_resize(TextConsole *s)
+static void text_console_resize(QemuConsole *s)
 {
 TextCell *cells, *c, *c1;
 int w1, x, y, last_width;
@@ -553,7 +553,7 @@ static void text_console_resize(TextConsole *s)
 s-cells = cells;
 }
 
-static inline void text_update_xy(TextConsole *s, int x, int y)
+static inline void text_update_xy(QemuConsole *s, int x, int y)
 {
 s-text_x[0] = MIN(s-text_x[0], x);
 s-text_x[1] = MAX(s-text_x[1], x);
@@ -561,7 +561,7 @@ static inline void text_update_xy(TextConsole *s, int x, 
int y)
 s-text_y[1] = MAX(s-text_y[1], y);
 }
 
-static void invalidate_xy(TextConsole *s, int x, int y)
+static void invalidate_xy(QemuConsole *s, int x, int y)
 {
 if (s-update_x0  x * FONT_WIDTH)
 s-update_x0 = x * FONT_WIDTH;
@@ -573,7 +573,7 @@ static void invalidate_xy(TextConsole *s, int x, int y)
 s-update_y1 = (y + 1) * FONT_HEIGHT;
 }
 
-static void update_xy(TextConsole *s, int x, int y)
+static void update_xy(QemuConsole *s, int x, int y)
 {
 TextCell *c;
 int y1, y2;
@@ -597,7 +597,7 @@ static void update_xy(TextConsole *s, int x, int y)
 }
 }
 
-static void console_show_cursor(TextConsole *s, int show)
+static void console_show_cursor(QemuConsole *s, int show)
 {
 TextCell *c;
 int y, y1;
@@ -631,7 +631,7 @@ static void console_show_cursor(TextConsole *s, int show)
 }
 }
 
-static void console_refresh(TextConsole *s)
+static void console_refresh(QemuConsole *s)
 {
 TextCell *c;
 int x, y, y1;
@@ -666,7 +666,7 @@ static void console_refresh(TextConsole *s)
 
 static void console_scroll(int ydelta)
 {
-TextConsole *s;
+QemuConsole *s;
 int i, y1;
 
 s = active_console;
@@ -698,7 +698,7 @@ static void console_scroll(int ydelta)
 console_refresh(s);
 }
 
-static void console_put_lf(TextConsole *s)
+static void console_put_lf(QemuConsole *s)
 {
 TextCell *c;
 int x, y1;
@@ -749,7 +749,7 @@ static void console_put_lf(TextConsole *s)
  * NOTE: I know this code is not very efficient (checking every color for it
  * self) but it is more readable and better maintainable.
  */
-static void console_handle_escape(TextConsole *s)
+static void console_handle_escape(QemuConsole *s)
 {
 int i;
 
@@ -842,7 +842,7 @@ static void console_handle_escape(TextConsole *s)
 }
 }
 
-static void console_clear_xy(TextConsole *s, int x, int y)
+static void console_clear_xy(QemuConsole *s, int x, int y)
 {
 int y1 = (s-y_base + y) % s-total_height;
 TextCell *c = s-cells[y1 * s-width + x];
@@ -852,7 +852,7 @@ static void console_clear_xy(TextConsole *s, int x, int y)
 }
 
 /* set cursor, checking bounds */
-static void set_cursor(TextConsole *s, int x, int y)
+static void set_cursor(QemuConsole *s, int x, int y)
 {
 if (x  0) {
 x = 0;
@@ -871,7 +871,7 @@ static void set_cursor(TextConsole *s, int x, int y)
 s-y = y;
 }
 
-static void console_putchar(TextConsole *s, int ch)
+static void console_putchar(QemuConsole *s, int ch)
 {
 TextCell *c;
 int y1, i;
@@ -1078,7 +1078,7 @@ static void console_putchar(TextConsole *s, int ch)
 
 void console_select(unsigned int index)
 {
-TextConsole *s;
+QemuConsole *s;
 
 if (index = MAX_CONSOLES)
 return;
@@ -,7 +,7 @@ void console_select(unsigned int index)
 
 static int console_puts(CharDriverState *chr, const uint8_t *buf, int 

[Qemu-devel] KVM call agenda for 2012-10-16

2012-10-15 Thread Juan Quintela

Hi

Please send in any agenda topics you are interested in.

Later, Juan.



[Qemu-devel] [PATCH 0/8] console cleanups

2012-10-15 Thread Gerd Hoffmann
  Hi,

First step in making qemu use pixman:  A bunch of console subsystem
cleanups.

cheers,
  Gerd

The following changes since commit 8b4a3df8081f3e6f1061ed5cbb303ad623ade66b:

  Fix popcnt in long mode (2012-10-14 14:55:09 +0400)

are available in the git repository at:
  git://git.kraxel.org/qemu pixman.v2

Gerd Hoffmann (8):
  console: QLIST-ify display change listeners.
  console: add unregister_displaychangelistener
  console: move set_mouse + cursor_define callbacks
  console: s/TextConsole/QemuConsole/
  console: untangle gfx  txt updates
  console: init displaychangelisteners on register
  vga: fix text mode updating
  console: remove dpy_gfx_fill

 console.c|  133 ---
 console.h|  171 ++---
 hw/blizzard.c|4 +-
 hw/exynos4210_fimd.c |2 +-
 hw/g364fb.c  |7 +-
 hw/jazz_led.c|6 +-
 hw/milkymist-vgafb.c |2 +-
 hw/musicpal.c|2 +-
 hw/nseries.c |2 +-
 hw/omap_lcdc.c   |2 +-
 hw/palm.c|2 +-
 hw/pl110.c   |2 +-
 hw/pxa2xx_lcd.c  |8 +-
 hw/qxl-render.c  |   12 ++--
 hw/qxl.c |4 +-
 hw/sm501.c   |4 +-
 hw/ssd0303.c |2 +-
 hw/ssd0323.c |2 +-
 hw/tc6393xb.c|4 +-
 hw/tcx.c |   16 +++---
 hw/vga.c |   63 +++---
 hw/vga_int.h |2 +
 hw/vmware_vga.c  |   15 +++--
 hw/xenfb.c   |2 +-
 qemu-common.h|3 +-
 ui/curses.c  |   21 ++
 ui/sdl.c |   25 +++-
 ui/spice-display.c   |8 +-
 ui/vnc.c |   16 +++---
 vl.c |   49 ++
 30 files changed, 342 insertions(+), 249 deletions(-)



[Qemu-devel] [PATCH 7/8] vga: fix text mode updating

2012-10-15 Thread Gerd Hoffmann
With both text (curses) and graphics (vnc/sdl/spice/...) display active
vga text mode emulation fails to update both correctly.  Depending on
whenever vga_update_text() or vga_draw_text() happens to be called first
only the text display or only the graphics display will see display
resolution changes and full redraws.

Fix it by calling both text/gfx resize functions in both code paths and
keep track of full screen redraws needed in VGACommonState fields.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/vga.c |   19 +++
 hw/vga_int.h |2 ++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index 19a68ff..a0ba94d 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1350,6 +1350,7 @@ static void vga_draw_text(VGACommonState *s, int 
full_update)
 s-last_scr_width = width * cw;
 s-last_scr_height = height * cheight;
 qemu_console_resize(s-ds, s-last_scr_width, s-last_scr_height);
+dpy_text_resize(s-ds, width, height);
 s-last_depth = 0;
 s-last_width = width;
 s-last_height = height;
@@ -1363,6 +1364,14 @@ static void vga_draw_text(VGACommonState *s, int 
full_update)
 palette = s-last_palette;
 x_incr = cw * ((ds_get_bits_per_pixel(s-ds) + 7)  3);
 
+if (full_update) {
+s-full_update_text = 1;
+}
+if (s-full_update_gfx) {
+s-full_update_gfx = 0;
+full_update |= 1;
+}
+
 cursor_offset = ((s-cr[VGA_CRTC_CURSOR_HI]  8) |
  s-cr[VGA_CRTC_CURSOR_LO]) - s-start_addr;
 if (cursor_offset != s-cursor_offset ||
@@ -2063,7 +2072,9 @@ static void vga_update_text(void *opaque, console_ch_t 
*chardata)
 cw != s-last_cw || cheight != s-last_ch) {
 s-last_scr_width = width * cw;
 s-last_scr_height = height * cheight;
+qemu_console_resize(s-ds, s-last_scr_width, s-last_scr_height);
 dpy_text_resize(s-ds, width, height);
+s-last_depth = 0;
 s-last_width = width;
 s-last_height = height;
 s-last_ch = cheight;
@@ -2071,6 +2082,14 @@ static void vga_update_text(void *opaque, console_ch_t 
*chardata)
 full_update = 1;
 }
 
+if (full_update) {
+s-full_update_gfx = 1;
+}
+if (s-full_update_text) {
+s-full_update_text = 0;
+full_update |= 1;
+}
+
 /* Update hardware cursor */
 cursor_offset = ((s-cr[VGA_CRTC_CURSOR_HI]  8) |
  s-cr[VGA_CRTC_CURSOR_LO]) - s-start_addr;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 330a32f..713f53f 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -166,6 +166,8 @@ typedef struct VGACommonState {
 vga_hw_invalidate_ptr invalidate;
 vga_hw_screen_dump_ptr screen_dump;
 vga_hw_text_update_ptr text_update;
+bool full_update_text;
+bool full_update_gfx;
 /* hardware mouse cursor support */
 uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
 void (*cursor_invalidate)(struct VGACommonState *s);
-- 
1.7.1




Re: [Qemu-devel] [RFC v1 7/7] vhost: abort if an emulated iommu is used

2012-10-15 Thread Avi Kivity
On 10/11/2012 09:38 PM, Alex Williamson wrote:
 On Thu, 2012-10-11 at 17:48 +0200, Avi Kivity wrote:
 On 10/11/2012 05:34 PM, Michael S. Tsirkin wrote:
  On Thu, Oct 11, 2012 at 04:35:23PM +0200, Avi Kivity wrote:
  On 10/11/2012 04:35 PM, Michael S. Tsirkin wrote:
  
   No, qemu should configure virtio devices to bypass the iommu, even if 
   it
   is on.
   
   Okay so there will be some API that virtio devices should call
   to achieve this?
  
  The iommu should probably call pci_device_bypasses_iommu() to check for
  such devices.
  
  So maybe this patch should depend on the introduction of such
  an API.
 
 I've dropped it for now.
 
 In fact, virtio/vhost are safe since they use cpu_physical_memory_rw()
 and the memory listener watches address_space_memory, no iommu there.
 vfio needs to change to listen to pci_dev-bus_master_as, and need
 special handling for iommu regions (abort for now, type 2 iommu later).
 
 I don't see how we can ever support an assigned device with the
 translate function.  

We cannot.

 Don't we want a flat address space at run time
 anyway?  

Not if we want vfio-in-the-guest (for nested virt or OS bypass).

 IOMMU drivers go to pains to make IOTLB updates efficient and
 drivers optimize for long running translations, but here we impose a
 penalty on every access.  I think we'd be more efficient and better able
 to support assigned devices if the per device/bus address space was
 updated and flattened when it changes.  

A flattened address space cannot be efficiently implemented with a
-translate() callback.  Describing the transformed address space
requires walking all the iommu page tables; these can change very
frequently for some use cases, and the io page tables can be built after
the iommu is configured but before dma is initiated, so you have no hook
from which to call -translate(); and the representation of the address
space can be huge.

 Being able to implement an XOR
 IOMMU is impressive, but is it practical?  

The XOR IOMMU is just a way for me to test and demonstrate the API.

 We could be doing much more
 practical things like nested device assignment with a flatten
 translation ;)  Thanks,

No, a flattened translation is impractical, at least when driven from qemu.

My plans wrt vfio/kvm here are to have memory_region_init_iommu()
provide, in addition to -translate(), a declarative description of the
translation function.  In practical terms, this means that the API will
receive the name of the spec that the iommu implements:

  MemoryRegionIOMMUOps amd_iommu_v2_ops = {
  .translate = amd_iommu_v2_ops,
  .translation_type = IOMMU_AMD_V2,
  };

qemu-side vfio would then match -translation_type with what the kernel
provides, and configure the kernel for this type of translation.  As
some v2 hardware supports two levels of translations, all vfio has to do
is to set up the lower translation level to match the guest-host
translation (which it does already), and to set up the upper translation
level to follow the guest configuration.  From then on the hardware does
the rest.

If the hardware supports only one translation level, we may still be
able to implement nested iommu using the same techniques we use for the
processor page tables - shadowing.  kvm would write-protect the iommu
page tables and pass any updates to vfio, which would update the shadow
io page tables that implement the ngpa-gpa-hpa translation.  However
given the complexity and performance problems on one side, and the size
of the niche that nested device assignment serves, we'll probably limit
ourselves to hardware that supports two levels of translations.  If
nested virtualization really takes off we can use shadowing to provide
the guest with emulated hardware that supports two translation level
(the solution above uses host hardware with two levels to expose guest
hardware with one level).

-- 
error compiling committee.c: too many arguments to function



Re: [Qemu-devel] [RFC v1 4/7] pci: switch iommu to using the memory API

2012-10-15 Thread Avi Kivity
On 10/13/2012 11:13 AM, Blue Swirl wrote:
  struct PCIBus {
  BusState qbus;
 -PCIDMAContextFunc dma_context_fn;
 -void *dma_context_opaque;
 +PCIIOMMUFunc iommu_fn;
 +PCIIOMMUDestructorFunc iommu_dtor_fn;
 +void *iommu_opaque;
 
 Maybe the opaque could be avoided (in later patches) by clever use of
 container_of() by the functions to get the parent structure?

Indeed yes.  This requires replacing pci_bus_new() and
pci_register_bus() by a conventional pci_bus_init().  I think it's the
right direction to move and the memory API always uses caller-managed
allocation and objects, instead of API-managed allocation and
pointers/handles.


-- 
error compiling committee.c: too many arguments to function



Re: [Qemu-devel] [RFC v1 7/7] vhost: abort if an emulated iommu is used

2012-10-15 Thread Avi Kivity
On 10/15/2012 10:44 AM, liu ping fan wrote:
 On Thu, Oct 11, 2012 at 11:48 PM, Avi Kivity a...@redhat.com wrote:
 On 10/11/2012 05:34 PM, Michael S. Tsirkin wrote:
 On Thu, Oct 11, 2012 at 04:35:23PM +0200, Avi Kivity wrote:
 On 10/11/2012 04:35 PM, Michael S. Tsirkin wrote:

  No, qemu should configure virtio devices to bypass the iommu, even if it
  is on.
 
  Okay so there will be some API that virtio devices should call
  to achieve this?

 The iommu should probably call pci_device_bypasses_iommu() to check for
 such devices.

 So maybe this patch should depend on the introduction of such
 an API.

 I've dropped it for now.

 In fact, virtio/vhost are safe since they use cpu_physical_memory_rw()
 and the memory listener watches address_space_memory, no iommu there.
 
 Not quite sure your meaning.  My understanding is that as a pci
 device, vhost can lie behind a iommu in topology, which result in the
 transaction launched can be snapped by the emulated iommu. BUT we make
 a exception for vhost-dev and enforce
 address_space_rw(address_space_memory, ..) NOT
 address_space_rw(pci_dev-bus_master_as,..)  for vhost device, so we
 bypass the iommu.  Right?

The exception is not just for vhost, but for every virtio device.  So
the iommu needs to be aware of that, and if it manages a virtio device,
it needs to provide a 1:1 translation.


-- 
error compiling committee.c: too many arguments to function



[Qemu-devel] RFC: usb input pipelining / speedup patchset v2

2012-10-15 Thread Hans de Goede
Here is v2 of my usb input pipelining and speedup patchset + some assorted
fixes, taking into account all the remarks from the discussion surrounding
v1, Please review!

Note this is still RFC status as I would like to run some more tests before
this going upstream.

Thanks  Regards,

Hans



[Qemu-devel] [PATCH 07/22] ehci: Detect going in circles when filling the queue

2012-10-15 Thread Hans de Goede
For ctrl endpoints Windows (atleast Win7) creates circular td lists, so far
these were not a problem because we would stop filling the queue if altnext
was set. Since further patches in this patchset remove the altnext check this
does become a problem and we need detection for going in circles.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-ehci.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 58e788b..79a9ad5 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2072,7 +2072,7 @@ static int ehci_fill_queue(EHCIPacket *p)
 {
 EHCIQueue *q = p-queue;
 EHCIqtd qtd = p-qtd;
-uint32_t qtdaddr;
+uint32_t qtdaddr, start_addr = p-qtdaddr;
 
 for (;;) {
 if (NLPTR_TBIT(qtd.altnext) == 0) {
@@ -2082,6 +2082,13 @@ static int ehci_fill_queue(EHCIPacket *p)
 break;
 }
 qtdaddr = qtd.next;
+/*
+ * Detect circular td lists, Windows creates these, counting on the
+ * active bit going low after exection to make the queue stop.
+ */
+if (qtdaddr == start_addr) {
+break;
+}
 get_dwords(q-ehci, NLPTR_GET(qtdaddr),
(uint32_t *) qtd, sizeof(EHCIqtd)  2);
 ehci_trace_qtd(q, NLPTR_GET(qtdaddr), qtd);
-- 
1.7.12.1




[Qemu-devel] [PATCH 05/22] ehci: Improve latency of interrupt delivery and async schedule scanning

2012-10-15 Thread Hans de Goede
While doing various performance tests of reading from USB mass storage devices
I noticed the following::
1) When an async handled packet completes, we don't immediately report an
   interrupt to the guest, instead we wait for the frame-timer to run and
   report it from there
2) If 1) has been fixed and an async handled packet takes a while to complete,
   then async_stepdown will become a high value, which means that there
   will be a large latency before any new packets queued by the guest in
   response to the interrupt get seen

1) was done deliberately as part of commit f0ad01f92:
http://www.kraxel.org/cgit/qemu/commit/?h=usb.57id=f0ad01f92ca02eee7cadbfd225c5de753ebd5fce
Since setting the interrupt immediately on async packet completion was causing
issues with Linux guests, I believe this recently fixed Linux bug explains
why this is happening:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=361aabf395e4a23cf554cf4ec0c0c6963b8beb01

Note that we can *not* count on this fix being present in all Linux guests!

I was hoping that the recently added support for Interrupt Threshold Control
would fix the issues with Linux guests, but adding a simple ehci_commit_irq()
call to ehci_async_bh() still caused problems with Linux guests.

The problem is, that when doing ehci_commit_irq() from ehci_async_bh(),
the old frindex value is used to calculate usbsts_frindex, and when
the frame-timer then runs possibly very shortly after ehci_async_bh(),
it increases the frame-timer, and thus any interrupts raised from that
frame-timer run, will also get reported to the guest immediately, rather
then being delayed to the next frame-timer run.

Luckily the solution for this is simple, this means that we need to
increase frindex before calling ehci_commit_irq() from ehci_async_bh(),
which in the end boils down to simple calling ehci_frame_timer() instead
of ehci_async_bh() from the bh.

This may seem like it causes a lot of extra work to be done, but this
is not true. Any work done from the frame-timer processing the periodic
schedule is work which then does not need to be done the next time the
frame timer runs, also the frame-timer will re-arm itself at (possibly)
a later time then it was armed for saving a vmexit at that time.

As an additional advantage moving to simply calling the frame-timer also
fixes 2) as the packet completion will set async_stepdown to 0, and the
re-arming of the timer with an async_stepdown of 0 ensures that any
newly queued up packets get seen in a reasonable amount of time.

This improves the speed (MB/s) of a Linux guest reading from a USB mass
storage device by a factor of 1.5 - 1.7 with input pipelining disabled,
and by a factor of 1.8 with input pipelining enabled.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-ehci.c | 10 ++
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index d9d4918..bbfa441 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1244,7 +1244,7 @@ static void ehci_opreg_write(void *ptr, 
target_phys_addr_t addr,
 s-usbcmd = val; /* Set usbcmd for ehci_update_halt() */
 ehci_update_halt(s);
 s-async_stepdown = 0;
-qemu_mod_timer(s-frame_timer, qemu_get_clock_ns(vm_clock));
+qemu_bh_schedule(s-async_bh);
 }
 break;
 
@@ -2509,12 +2509,6 @@ static void ehci_frame_timer(void *opaque)
 }
 }
 
-static void ehci_async_bh(void *opaque)
-{
-EHCIState *ehci = opaque;
-ehci_advance_async_state(ehci);
-}
-
 static const MemoryRegionOps ehci_mmio_caps_ops = {
 .read = ehci_caps_read,
 .valid.min_access_size = 1,
@@ -2743,7 +2737,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
 }
 
 s-frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
-s-async_bh = qemu_bh_new(ehci_async_bh, s);
+s-async_bh = qemu_bh_new(ehci_frame_timer, s);
 QTAILQ_INIT(s-aqueues);
 QTAILQ_INIT(s-pqueues);
 usb_packet_init(s-ipacket);
-- 
1.7.12.1




[Qemu-devel] [PATCH 09/22] usb: Rename __usb_packet_complete to usb_packet_complete_one

2012-10-15 Thread Hans de Goede
And make it available for use outside of core.c

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

diff --git a/hw/usb.h b/hw/usb.h
index 48c8926..01dd423 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -370,6 +370,7 @@ USBDevice *usb_find_device(USBPort *port, uint8_t addr);
 
 int usb_handle_packet(USBDevice *dev, USBPacket *p);
 void usb_packet_complete(USBDevice *dev, USBPacket *p);
+void usb_packet_complete_one(USBDevice *dev, USBPacket *p);
 void usb_cancel_packet(USBPacket * p);
 
 void usb_ep_init(USBDevice *dev);
diff --git a/hw/usb/core.c b/hw/usb/core.c
index b9f1f7a..e2e31ca 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -412,10 +412,11 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 return ret;
 }
 
-static void __usb_packet_complete(USBDevice *dev, USBPacket *p)
+void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
 {
 USBEndpoint *ep = p-ep;
 
+assert(QTAILQ_FIRST(ep-queue) == p);
 assert(p-result != USB_RET_ASYNC  p-result != USB_RET_NAK);
 
 if (p-result  0) {
@@ -435,8 +436,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 int ret;
 
 usb_packet_check_state(p, USB_PACKET_ASYNC);
-assert(QTAILQ_FIRST(ep-queue) == p);
-__usb_packet_complete(dev, p);
+usb_packet_complete_one(dev, p);
 
 while (!ep-halted  !QTAILQ_EMPTY(ep-queue)) {
 p = QTAILQ_FIRST(ep-queue);
@@ -450,7 +450,7 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 break;
 }
 p-result = ret;
-__usb_packet_complete(ep-dev, p);
+usb_packet_complete_one(ep-dev, p);
 }
 }
 
-- 
1.7.12.1




[Qemu-devel] [PATCH 11/22] usb: Move clearing of queue on halt to the core

2012-10-15 Thread Hans de Goede
hcds which queue up more then one packet at once (uhci, ehci and xhci),
must clear the queue after an error which has caused the queue to halt.

Currently this is handled as a special case inside the hcd code, this
patch instead adds an USB_RET_REMOVE_FROM_QUEUE packet result code, teaches
the 3 hcds about this and moves the clearing of the queue on a halt into
the USB core.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb.h  |  1 +
 hw/usb/core.c |  8 +++-
 hw/usb/hcd-ehci.c | 22 --
 hw/usb/hcd-uhci.c | 22 ++
 hw/usb/hcd-xhci.c |  4 
 5 files changed, 26 insertions(+), 31 deletions(-)

diff --git a/hw/usb.h b/hw/usb.h
index 435cd42..ead03c9 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -45,6 +45,7 @@
 #define USB_RET_IOERROR   (-5)
 #define USB_RET_ASYNC (-6)
 #define USB_RET_ADD_TO_QUEUE  (-7)
+#define USB_RET_REMOVE_FROM_QUEUE (-8)
 
 #define USB_SPEED_LOW   0
 #define USB_SPEED_FULL  1
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 014e3ac..5a97a0e 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -442,8 +442,14 @@ void usb_packet_complete(USBDevice *dev, USBPacket *p)
 usb_packet_check_state(p, USB_PACKET_ASYNC);
 usb_packet_complete_one(dev, p);
 
-while (!ep-halted  !QTAILQ_EMPTY(ep-queue)) {
+while (!QTAILQ_EMPTY(ep-queue)) {
 p = QTAILQ_FIRST(ep-queue);
+if (ep-halted) {
+/* Empty the queue on a halt */
+p-result = USB_RET_REMOVE_FROM_QUEUE;
+dev-port-ops-complete(dev-port, p);
+continue;
+}
 if (p-state == USB_PACKET_ASYNC) {
 break;
 }
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 29365d9..e6f7642 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1456,8 +1456,15 @@ static void ehci_async_complete_packet(USBPort *port, 
USBPacket *packet)
 }
 
 p = container_of(packet, EHCIPacket, packet);
-trace_usb_ehci_packet_action(p-queue, p, wakeup);
 assert(p-async == EHCI_ASYNC_INFLIGHT);
+
+if (packet-result == USB_RET_REMOVE_FROM_QUEUE) {
+trace_usb_ehci_packet_action(p-queue, p, remove);
+ehci_free_packet(p);
+return;
+}
+
+trace_usb_ehci_packet_action(p-queue, p, wakeup);
 p-async = EHCI_ASYNC_FINISHED;
 p-usb_status = packet-result;
 
@@ -2214,19 +2221,6 @@ static int ehci_state_writeback(EHCIQueue *q)
  * bit is clear.
  */
 if (q-qh.token  QTD_TOKEN_HALT) {
-/*
- * We should not do any further processing on a halted queue!
- * This is esp. important for bulk endpoints with pipelining enabled
- * (redirection to a real USB device), where we must cancel all the
- * transfers after this one so that:
- * 1) If they've completed already, they are not processed further
- *causing more stalls, originating from the same failed transfer
- * 2) If still in flight, they are cancelled before the guest does
- *a clear stall, otherwise the guest and device can loose sync!
- */
-while ((p = QTAILQ_FIRST(q-packets)) != NULL) {
-ehci_free_packet(p);
-}
 ehci_set_state(q-ehci, q-async, EST_HORIZONTALQH);
 again = 1;
 } else {
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 46e544b..00dc9d5 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -744,22 +744,6 @@ static int uhci_complete_td(UHCIState *s, UHCI_TD *td, 
UHCIAsync *async, uint32_
 return TD_RESULT_COMPLETE;
 
 out:
-/*
- * We should not do any further processing on a queue with errors!
- * This is esp. important for bulk endpoints with pipelining enabled
- * (redirection to a real USB device), where we must cancel all the
- * transfers after this one so that:
- * 1) If they've completed already, they are not processed further
- *causing more stalls, originating from the same failed transfer
- * 2) If still in flight, they are cancelled before the guest does
- *a clear stall, otherwise the guest and device can loose sync!
- */
-while (!QTAILQ_EMPTY(async-queue-asyncs)) {
-UHCIAsync *as = QTAILQ_FIRST(async-queue-asyncs);
-uhci_async_unlink(as);
-uhci_async_cancel(as);
-}
-
 switch(ret) {
 case USB_RET_STALL:
 td-ctrl |= TD_CTRL_STALL;
@@ -918,6 +902,12 @@ static void uhci_async_complete(USBPort *port, USBPacket 
*packet)
 UHCIAsync *async = container_of(packet, UHCIAsync, packet);
 UHCIState *s = async-queue-uhci;
 
+if (packet-result == USB_RET_REMOVE_FROM_QUEUE) {
+uhci_async_unlink(async);
+uhci_async_cancel(async);
+return;
+}
+
 if (async-isoc) {
 UHCI_TD td;
 uint32_t link = async-td;
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 53e1ea3..5648cc7 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2834,6 +2834,10 @@ static void 

[Qemu-devel] [PATCH 14/22] usb: Add packet combining functions

2012-10-15 Thread Hans de Goede
Currently we only do pipelining for output endpoints, since to properly
support short-not-ok semantics we can only have one outstanding input
packet. Since the ehci and uhci controllers have a limited per td packet
size guests will split large input transfers to into multiple packets,
and since we don't pipeline these, this comes with a serious performance
penalty.

This patch adds helper functions to (re-)combine packets which belong to 1
transfer at the guest device-driver level into 1 large transger. This can be
used by (redirection) usb-devices to enable pipelining for input endpoints.

This patch will combine packets together until a transfer terminating packet
is encountered. A terminating packet is a packet which meets one or more of
the following conditions:
1) The packet size is *not* a multiple of the endpoint max packet size
2) The packet does *not* have its short-not-ok flag set
3) The packet has its interrupt-on-complete flag set

The short-not-ok flag of the combined packet is that of the terminating packet.
Multiple combined packets may be submitted to the device, if the combined
packets do not have their short-not-ok flag set, enabling true pipelining.

If a combined packet does have its short-not-ok flag set the queue will
wait with submitting further packets to the device until that packet has
completed.

Once enabled in the usb-redir and ehci code, this improves the speed (MB/s)
of a Linux guest reading from a USB mass storage device by a factor of
1.2 - 1.5.

And the main reason why I started working on this, when reading from a pl2303
USB-serial converter, it combines the previous 4 packets submitted per
device-driver level read into 1 big read, reducing the number of packets / sec
by a factor 4, and it allows to have multiple reads outstanding. This allows
for much better latency tolerance without the pl2303's internal buffer
overflowing (which was happening at 115200 bps, without serial flow control).

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb.h |  21 ++
 hw/usb/Makefile.objs |   2 +-
 hw/usb/combined-packet.c | 183 +++
 hw/usb/core.c|   1 +
 4 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 hw/usb/combined-packet.c

diff --git a/hw/usb.h b/hw/usb.h
index 3a6cc84..3c8ba01 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -160,6 +160,7 @@ typedef struct USBBusOps USBBusOps;
 typedef struct USBPort USBPort;
 typedef struct USBDevice USBDevice;
 typedef struct USBPacket USBPacket;
+typedef struct USBCombinedPacket USBCombinedPacket;
 typedef struct USBEndpoint USBEndpoint;
 
 typedef struct USBDesc USBDesc;
@@ -292,6 +293,14 @@ typedef struct USBDeviceClass {
  */
 int (*handle_data)(USBDevice *dev, USBPacket *p);
 
+/*
+ * Process / cancel combined packets, called from
+ * usb_ep_combine_input_packets() / usb_combined_packet_cancel().
+ * Only called for devices which call these functions themselves.
+ */
+int (*handle_combined_data)(USBDevice *dev, USBPacket *p);
+void (*cancel_combined_packet)(USBDevice *dev, USBPacket *p);
+
 void (*set_interface)(USBDevice *dev, int interface,
   int alt_old, int alt_new);
 
@@ -356,7 +365,15 @@ struct USBPacket {
 int result; /* transfer length or USB_RET_* status code */
 /* Internal use by the USB layer.  */
 USBPacketState state;
+USBCombinedPacket *combined;
 QTAILQ_ENTRY(USBPacket) queue;
+QTAILQ_ENTRY(USBPacket) combined_entry;
+};
+
+struct USBCombinedPacket {
+USBPacket *first;
+QTAILQ_HEAD(packets_head, USBPacket) packets;
+QEMUIOVector iov;
 };
 
 void usb_packet_init(USBPacket *p);
@@ -399,6 +416,10 @@ void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, 
bool enabled);
 USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep,
 uint64_t id);
 
+void usb_ep_combine_input_packets(USBEndpoint *ep);
+void usb_combined_input_packet_complete(USBDevice *dev, USBPacket *p);
+void usb_combined_packet_cancel(USBDevice *dev, USBPacket *p);
+
 void usb_attach(USBPort *port);
 void usb_detach(USBPort *port);
 void usb_port_reset(USBPort *port);
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 4225136..b193321 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -7,7 +7,7 @@ hw-obj-y += libhw.o
 hw-obj-$(CONFIG_SMARTCARD) += dev-smartcard-reader.o
 hw-obj-$(CONFIG_USB_REDIR) += redirect.o
 
-common-obj-y += core.o bus.o desc.o dev-hub.o
+common-obj-y += core.o combined-packet.o bus.o desc.o dev-hub.o
 common-obj-y += host-$(HOST_USB).o dev-bluetooth.o
 common-obj-y += dev-hid.o dev-storage.o dev-wacom.o
 common-obj-y += dev-serial.o dev-network.o dev-audio.o
diff --git a/hw/usb/combined-packet.c b/hw/usb/combined-packet.c
new file mode 100644
index 000..b6fcb2c
--- /dev/null
+++ b/hw/usb/combined-packet.c
@@ -0,0 +1,183 @@
+/*
+ * QEMU USB packet combining code 

[Qemu-devel] [PATCH 18/22] usb-redir: Add support for input pipelining

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 67 ++-
 1 file changed, 57 insertions(+), 10 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 030522e..f715281 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -29,6 +29,7 @@
 #include qemu-timer.h
 #include monitor.h
 #include sysemu.h
+#include iov.h
 
 #include dirent.h
 #include sys/ioctl.h
@@ -322,6 +323,11 @@ static void usbredir_cancel_packet(USBDevice *udev, 
USBPacket *p)
 {
 USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
 
+if (p-combined) {
+usb_combined_packet_cancel(udev, p);
+return;
+}
+
 packet_id_queue_add(dev-cancelled, p-id);
 usbredirparser_send_cancel_data_packet(dev-parser, p-id);
 usbredirparser_do_write(dev-parser);
@@ -575,17 +581,18 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, 
USBPacket *p,
   uint8_t ep)
 {
 struct usb_redir_bulk_packet_header bulk_packet;
+size_t size = (p-combined) ? p-combined-iov.size : p-iov.size;
 
-DPRINTF(bulk-out ep %02X len %zd id %PRIu64\n, ep, p-iov.size, p-id);
+DPRINTF(bulk-out ep %02X len %zd id %PRIu64\n, ep, size, p-id);
 
 if (usbredir_already_in_flight(dev, p-id)) {
 return USB_RET_ASYNC;
 }
 
 bulk_packet.endpoint  = ep;
-bulk_packet.length= p-iov.size;
+bulk_packet.length= size;
 bulk_packet.stream_id = 0;
-bulk_packet.length_high = p-iov.size  16;
+bulk_packet.length_high = size  16;
 assert(bulk_packet.length_high == 0 ||
usbredirparser_peer_has_cap(dev-parser,
usb_redir_cap_32bits_bulk_length));
@@ -594,11 +601,16 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, 
USBPacket *p,
 usbredirparser_send_bulk_packet(dev-parser, p-id,
 bulk_packet, NULL, 0);
 } else {
-uint8_t buf[p-iov.size];
-usb_packet_copy(p, buf, p-iov.size);
-usbredir_log_data(dev, bulk data out:, buf, p-iov.size);
+uint8_t buf[size];
+if (p-combined) {
+iov_to_buf(p-combined-iov.iov, p-combined-iov.niov,
+   0, buf, size);
+} else {
+usb_packet_copy(p, buf, size);
+}
+usbredir_log_data(dev, bulk data out:, buf, size);
 usbredirparser_send_bulk_packet(dev-parser, p-id,
-bulk_packet, buf, p-iov.size);
+bulk_packet, buf, size);
 }
 usbredirparser_do_write(dev-parser);
 return USB_RET_ASYNC;
@@ -715,6 +727,9 @@ static int usbredir_handle_data(USBDevice *udev, USBPacket 
*p)
 case USB_ENDPOINT_XFER_ISOC:
 return usbredir_handle_iso_data(dev, p, ep);
 case USB_ENDPOINT_XFER_BULK:
+if (p-pid == USB_TOKEN_IN  p-ep-pipeline) {
+return USB_RET_ADD_TO_QUEUE;
+}
 return usbredir_handle_bulk_data(dev, p, ep);
 case USB_ENDPOINT_XFER_INT:
 return usbredir_handle_interrupt_data(dev, p, ep);
@@ -725,6 +740,20 @@ static int usbredir_handle_data(USBDevice *udev, USBPacket 
*p)
 }
 }
 
+static void usbredir_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
+{
+if (ep-pid == USB_TOKEN_IN  ep-pipeline) {
+usb_ep_combine_input_packets(ep);
+}
+}
+
+static int usbredir_handle_combined_data(USBDevice *udev, USBPacket *p)
+{
+USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+
+return usbredir_handle_bulk_data(dev, p, p-ep-nr | USB_DIR_IN);
+}
+
 static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
 int config)
 {
@@ -1310,6 +1339,11 @@ static void usbredir_set_pipeline(USBRedirDevice *dev, 
struct USBEndpoint *uep)
 if (uep-pid == USB_TOKEN_OUT) {
 uep-pipeline = true;
 }
+if (uep-pid == USB_TOKEN_IN  uep-max_packet_size != 0 
+usbredirparser_peer_has_cap(dev-parser,
+usb_redir_cap_32bits_bulk_length)) {
+uep-pipeline = true;
+}
 }
 
 static void usbredir_ep_info(void *priv,
@@ -1492,11 +1526,17 @@ static void usbredir_bulk_packet(void *priv, uint64_t 
id,
 
 p = usbredir_find_packet_by_id(dev, ep, id);
 if (p) {
+size_t size = (p-combined) ? p-combined-iov.size : p-iov.size;
 len = usbredir_handle_status(dev, bulk_packet-status, len);
 if (len  0) {
 usbredir_log_data(dev, bulk data in:, data, data_len);
-if (data_len = p-iov.size) {
-usb_packet_copy(p, data, data_len);
+if (data_len = size) {
+if (p-combined) {
+iov_from_buf(p-combined-iov.iov, p-combined-iov.niov,
+ 0, data, data_len);
+} else {
+usb_packet_copy(p, data, data_len);
+}

[Qemu-devel] [PATCH 20/22] usb-redir: Use reject rather the disconnect on bad ep info

2012-10-15 Thread Hans de Goede
So that the client gets a notification about us disconnecting the device.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 9e88779..26f501a 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1382,7 +1382,8 @@ static void usbredir_ep_info(void *priv,
 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);
+usbredir_reject_device(dev);
+return;
 }
 /* Fall through */
 case usb_redir_type_control:
@@ -1392,7 +1393,7 @@ static void usbredir_ep_info(void *priv,
 break;
 default:
 ERROR(Received invalid endpoint type\n);
-usbredir_device_disconnect(dev);
+usbredir_reject_device(dev);
 return;
 }
 }
-- 
1.7.12.1




[Qemu-devel] [PATCH 13/22] usb: Add an int_req flag to USBPacket

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb.h  |  3 ++-
 hw/usb/core.c |  3 ++-
 hw/usb/hcd-ehci.c |  6 --
 hw/usb/hcd-musb.c |  2 +-
 hw/usb/hcd-ohci.c |  7 +--
 hw/usb/hcd-uhci.c |  3 ++-
 hw/usb/hcd-xhci.c | 13 +++--
 7 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/hw/usb.h b/hw/usb.h
index 1fcf79c..3a6cc84 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -352,6 +352,7 @@ struct USBPacket {
 QEMUIOVector iov;
 uint64_t parameter; /* control transfers */
 bool short_not_ok;
+bool int_req;
 int result; /* transfer length or USB_RET_* status code */
 /* Internal use by the USB layer.  */
 USBPacketState state;
@@ -362,7 +363,7 @@ void usb_packet_init(USBPacket *p);
 void usb_packet_set_state(USBPacket *p, USBPacketState state);
 void usb_packet_check_state(USBPacket *p, USBPacketState expected);
 void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id,
-  bool short_not_ok);
+  bool short_not_ok, bool int_req);
 void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
 int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
 void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
diff --git a/hw/usb/core.c b/hw/usb/core.c
index f4a5ad2..87a513f 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -533,7 +533,7 @@ void usb_packet_set_state(USBPacket *p, USBPacketState 
state)
 }
 
 void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id,
-  bool short_not_ok)
+  bool short_not_ok, bool int_req)
 {
 assert(!usb_packet_is_inflight(p));
 assert(p-iov.iov != NULL);
@@ -543,6 +543,7 @@ void usb_packet_setup(USBPacket *p, int pid, USBEndpoint 
*ep, uint64_t id,
 p-result = 0;
 p-parameter = 0;
 p-short_not_ok = short_not_ok;
+p-int_req = int_req;
 qemu_iovec_reset(p-iov);
 usb_packet_set_state(p, USB_PACKET_SETUP);
 }
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 4dfe0f3..18cf097 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1591,7 +1591,8 @@ static int ehci_execute(EHCIPacket *p, const char *action)
 }
 
 spd = (p-pid == USB_TOKEN_IN  NLPTR_TBIT(p-qtd.altnext) == 0);
-usb_packet_setup(p-packet, p-pid, ep, p-qtdaddr, spd);
+usb_packet_setup(p-packet, p-pid, ep, p-qtdaddr, spd,
+ (p-qtd.token  QTD_TOKEN_IOC) != 0);
 usb_packet_map(p-packet, p-sgl);
 p-async = EHCI_ASYNC_INITIALIZED;
 }
@@ -1661,7 +1662,8 @@ static int ehci_process_itd(EHCIState *ehci,
 dev = ehci_find_device(ehci, devaddr);
 ep = usb_ep_get(dev, pid, endp);
 if (ep  ep-type == USB_ENDPOINT_XFER_ISOC) {
-usb_packet_setup(ehci-ipacket, pid, ep, addr, false);
+usb_packet_setup(ehci-ipacket, pid, ep, addr, false,
+ (itd-transact[i]  ITD_XACT_IOC) != 0);
 usb_packet_map(ehci-ipacket, ehci-isgl);
 ret = usb_handle_packet(dev, ehci-ipacket);
 assert(ret != USB_RET_ASYNC);
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index f65fa3c..a6105d3 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -627,7 +627,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
 dev = usb_find_device(s-port, ep-faddr[idx]);
 uep = usb_ep_get(dev, pid, ep-type[idx]  0xf);
 usb_packet_setup(ep-packey[dir].p, pid, uep,
- (dev-addr  16) | (uep-nr  8) | pid, false);
+ (dev-addr  16) | (uep-nr  8) | pid, false, true);
 usb_packet_addbuf(ep-packey[dir].p, ep-buf[idx], len);
 ep-packey[dir].ep = ep;
 ep-packey[dir].dir = dir;
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 8741d0f..4c77600 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -810,9 +810,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 if (completion) {
 ret = ohci-usb_packet.result;
 } else {
+bool int_req = relative_frame_number == frame_count 
+   OHCI_BM(iso_td.flags, TD_DI) == 0;
 dev = ohci_find_device(ohci, OHCI_BM(ed-flags, ED_FA));
 ep = usb_ep_get(dev, pid, OHCI_BM(ed-flags, ED_EN));
-usb_packet_setup(ohci-usb_packet, pid, ep, addr, false);
+usb_packet_setup(ohci-usb_packet, pid, ep, addr, false, int_req);
 usb_packet_addbuf(ohci-usb_packet, ohci-usb_buf, len);
 ret = usb_handle_packet(dev, ohci-usb_packet);
 if (ret == USB_RET_ASYNC) {
@@ -1012,7 +1014,8 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 }
 dev = ohci_find_device(ohci, OHCI_BM(ed-flags, ED_FA));
 ep = usb_ep_get(dev, pid, OHCI_BM(ed-flags, ED_EN));
-usb_packet_setup(ohci-usb_packet, pid, ep, addr, !flag_r);
+usb_packet_setup(ohci-usb_packet, pid, ep, addr, !flag_r,
+ 

[Qemu-devel] [PATCH 06/22] ehci: Speed up the timer of raising int from the async schedule

2012-10-15 Thread Hans de Goede
Often the guest will queue up new packets in response to a packet, in the
async schedule with its IOC flag set, completing. By speeding up the
frame-timer, we notice these new packets earlier. This increases the
speed (MB/s) of a Linux guest reading from a USB mass storage device by a
factor of 1.15 on top of the Improve latency of interrupt delivery
speed-ups, both with and without input pipelining enabled.

I've not tested the speed-up of this patch without the
Improve latency of interrupt delivery patch.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-ehci.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index bbfa441..58e788b 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -443,6 +443,7 @@ struct EHCIState {
 
 uint64_t last_run_ns;
 uint32_t async_stepdown;
+bool int_req_by_async;
 };
 
 #define SET_LAST_RUN_CLOCK(s) \
@@ -1529,6 +1530,9 @@ static void ehci_execute_complete(EHCIQueue *q)
 
 if (q-qh.token  QTD_TOKEN_IOC) {
 ehci_raise_irq(q-ehci, USBSTS_INT);
+if (q-async) {
+q-ehci-int_req_by_async = true;
+}
 }
 }
 
@@ -2503,8 +2507,15 @@ static void ehci_frame_timer(void *opaque)
 }
 
 if (need_timer) {
-expire_time = t_now + (get_ticks_per_sec()
+/* If we've raised int, we speed up the timer, so that we quickly
+ * notice any new packets queued up in response */
+if (ehci-int_req_by_async  (ehci-usbsts  USBSTS_INT)) {
+expire_time = t_now + get_ticks_per_sec() / (FRAME_TIMER_FREQ * 2);
+ehci-int_req_by_async = false;
+} else {
+expire_time = t_now + (get_ticks_per_sec()
* (ehci-async_stepdown+1) / FRAME_TIMER_FREQ);
+}
 qemu_mod_timer(ehci-frame_timer, expire_time);
 }
 }
-- 
1.7.12.1




Re: [Qemu-devel] [RFC v1 0/7] IOMMU support

2012-10-15 Thread Avi Kivity
On 10/12/2012 04:36 AM, Benjamin Herrenschmidt wrote:
 On Thu, 2012-10-11 at 15:26 +0200, Avi Kivity wrote:
 These patches add IOMMU support to the memory core. IOMMUs can be added 
 anywhere in
 the memory hierarchy, and may be arranged in series.
 
 I haven't had a chance to review in details yet, but one thing I noticed
 is that you basically have a single read/write protection information
 for a translation.
 
 This is a loss of functionality to some extent (well, maybe not from the
 existing iommu layer but from what could be done by our HW) in that we
 have separate read and write permission bits.
 
 This is actually worth fixing I think. Catching incorrect reads from
 write-only regions is probably worth it in term of debugging drivers.
 

I do have an is_write parameter to translate, in fact I added it in
order to implement the spapr iommu.  Or do you mean something else?



-- 
error compiling committee.c: too many arguments to function



[Qemu-devel] [PATCH 17/22] usb-redir: Add support for 32 bits bulk packet length

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 configure | 2 +-
 hw/usb/redirect.c | 7 ++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 248b871..036c38a 100755
--- a/configure
+++ b/configure
@@ -2768,7 +2768,7 @@ fi
 
 # check for usbredirparser for usb network redirection support
 if test $usb_redir != no ; then
-if $pkg_config --atleast-version=0.5 libusbredirparser-0.5 /dev/null 21 
; then
+if $pkg_config --atleast-version=0.5.3 libusbredirparser-0.5 /dev/null 
21 ; then
 usb_redir=yes
 usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 
2/dev/null)
 usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2/dev/null)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 99e25d4..030522e 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -585,6 +585,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, 
USBPacket *p,
 bulk_packet.endpoint  = ep;
 bulk_packet.length= p-iov.size;
 bulk_packet.stream_id = 0;
+bulk_packet.length_high = p-iov.size  16;
+assert(bulk_packet.length_high == 0 ||
+   usbredirparser_peer_has_cap(dev-parser,
+   usb_redir_cap_32bits_bulk_length));
 
 if (ep  USB_DIR_IN) {
 usbredirparser_send_bulk_packet(dev-parser, p-id,
@@ -906,6 +910,7 @@ static void usbredir_create_parser(USBRedirDevice *dev)
 usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
 usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
 usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
+usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
 
 if (runstate_check(RUN_STATE_INMIGRATE)) {
 flags |= usbredirparser_fl_no_hello;
@@ -1479,7 +1484,7 @@ static void usbredir_bulk_packet(void *priv, uint64_t id,
 {
 USBRedirDevice *dev = priv;
 uint8_t ep = bulk_packet-endpoint;
-int len = bulk_packet-length;
+int len = (bulk_packet-length_high  16) | bulk_packet-length;
 USBPacket *p;
 
 DPRINTF(bulk-in status %d ep %02X len %d id %PRIu64\n,
-- 
1.7.12.1




[Qemu-devel] [PATCH 08/22] xhci: Add a xhci_ep_nuke_one_xfer helper function

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-xhci.c | 49 ++---
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index e0ca690..0d90578 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1081,6 +1081,35 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned 
int slotid,
 return CC_SUCCESS;
 }
 
+static int xhci_ep_nuke_one_xfer(XHCITransfer *t)
+{
+int killed = 0;
+
+if (t-running_async) {
+usb_cancel_packet(t-packet);
+t-running_async = 0;
+t-cancelled = 1;
+DPRINTF(xhci: cancelling transfer %d, waiting for it to 
complete...\n, i);
+killed = 1;
+}
+if (t-running_retry) {
+XHCIEPContext *epctx = t-xhci-slots[t-slotid-1].eps[t-epid-1];
+if (epctx) {
+epctx-retry = NULL;
+qemu_del_timer(epctx-kick_timer);
+}
+t-running_retry = 0;
+}
+if (t-trbs) {
+g_free(t-trbs);
+}
+
+t-trbs = NULL;
+t-trb_count = t-trb_alloced = 0;
+
+return killed;
+}
+
 static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned int slotid,
unsigned int epid)
 {
@@ -1102,25 +1131,7 @@ static int xhci_ep_nuke_xfers(XHCIState *xhci, unsigned 
int slotid,
 
 xferi = epctx-next_xfer;
 for (i = 0; i  TD_QUEUE; i++) {
-XHCITransfer *t = epctx-transfers[xferi];
-if (t-running_async) {
-usb_cancel_packet(t-packet);
-t-running_async = 0;
-t-cancelled = 1;
-DPRINTF(xhci: cancelling transfer %d, waiting for it to 
complete...\n, i);
-killed++;
-}
-if (t-running_retry) {
-t-running_retry = 0;
-epctx-retry = NULL;
-qemu_del_timer(epctx-kick_timer);
-}
-if (t-trbs) {
-g_free(t-trbs);
-}
-
-t-trbs = NULL;
-t-trb_count = t-trb_alloced = 0;
+killed += xhci_ep_nuke_one_xfer(epctx-transfers[xferi]);
 xferi = (xferi + 1) % TD_QUEUE;
 }
 return killed;
-- 
1.7.12.1




[Qemu-devel] [PATCH 10/22] usb: Add USB_RET_ADD_TO_QUEUE packet result code

2012-10-15 Thread Hans de Goede
This can be used by usb-device code which wishes to process an entire endpoint
queue at once, to do this the usb-device code returns USB_RET_ADD_TO_QUEUE
from its handle_data class method and defines a flush_ep_queue class method
to call when the hcd is done queuing up packets.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb.h  | 21 +++--
 hw/usb/bus.c  |  8 
 hw/usb/core.c |  4 
 hw/usb/hcd-ehci.c |  4 
 hw/usb/hcd-musb.c |  1 +
 hw/usb/hcd-ohci.c |  2 ++
 hw/usb/hcd-uhci.c | 16 +++-
 hw/usb/hcd-xhci.c |  6 ++
 8 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/hw/usb.h b/hw/usb.h
index 01dd423..435cd42 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -38,12 +38,13 @@
 #define USB_TOKEN_IN0x69 /* device - host */
 #define USB_TOKEN_OUT   0xe1 /* host - device */
 
-#define USB_RET_NODEV   (-1)
-#define USB_RET_NAK (-2)
-#define USB_RET_STALL   (-3)
-#define USB_RET_BABBLE  (-4)
-#define USB_RET_IOERROR (-5)
-#define USB_RET_ASYNC   (-6)
+#define USB_RET_NODEV (-1)
+#define USB_RET_NAK   (-2)
+#define USB_RET_STALL (-3)
+#define USB_RET_BABBLE(-4)
+#define USB_RET_IOERROR   (-5)
+#define USB_RET_ASYNC (-6)
+#define USB_RET_ADD_TO_QUEUE  (-7)
 
 #define USB_SPEED_LOW   0
 #define USB_SPEED_FULL  1
@@ -293,6 +294,12 @@ typedef struct USBDeviceClass {
 void (*set_interface)(USBDevice *dev, int interface,
   int alt_old, int alt_new);
 
+/*
+ * Called when the hcd is done queuing packets for an endpoint, only
+ * necessary for devices which can return USB_RET_ADD_TO_QUEUE.
+ */
+void (*flush_ep_queue)(USBDevice *dev, USBEndpoint *ep);
+
 const char *product_desc;
 const USBDesc *usb_desc;
 } USBDeviceClass;
@@ -507,6 +514,8 @@ int usb_device_handle_data(USBDevice *dev, USBPacket *p);
 void usb_device_set_interface(USBDevice *dev, int interface,
   int alt_old, int alt_new);
 
+void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep);
+
 const char *usb_device_get_product_desc(USBDevice *dev);
 
 const USBDesc *usb_device_get_usb_desc(USBDevice *dev);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index b649360..8066291 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -181,6 +181,14 @@ void usb_device_set_interface(USBDevice *dev, int 
interface,
 }
 }
 
+void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
+{
+USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);
+if (klass-flush_ep_queue) {
+klass-flush_ep_queue(dev, ep);
+}
+}
+
 static int usb_qdev_init(DeviceState *qdev)
 {
 USBDevice *dev = USB_DEVICE(qdev);
diff --git a/hw/usb/core.c b/hw/usb/core.c
index e2e31ca..014e3ac 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -393,6 +393,10 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p)
 if (ret == USB_RET_ASYNC) {
 usb_packet_set_state(p, USB_PACKET_ASYNC);
 QTAILQ_INSERT_TAIL(p-ep-queue, p, queue);
+} else if (ret == USB_RET_ADD_TO_QUEUE) {
+usb_packet_set_state(p, USB_PACKET_QUEUED);
+QTAILQ_INSERT_TAIL(p-ep-queue, p, queue);
+ret = USB_RET_ASYNC;
 } else {
 /*
  * When pipelining is enabled usb-devices must always return async,
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 79a9ad5..29365d9 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2070,6 +2070,7 @@ static int ehci_state_horizqh(EHCIQueue *q)
 
 static int ehci_fill_queue(EHCIPacket *p)
 {
+USBEndpoint *ep = p-packet.ep;
 EHCIQueue *q = p-queue;
 EHCIqtd qtd = p-qtd;
 uint32_t qtdaddr, start_addr = p-qtdaddr;
@@ -2105,6 +2106,9 @@ static int ehci_fill_queue(EHCIPacket *p)
 assert(p-usb_status == USB_RET_ASYNC);
 p-async = EHCI_ASYNC_INFLIGHT;
 }
+if (p-usb_status != USB_RET_PROCERR) {
+usb_device_flush_ep_queue(ep-dev, ep);
+}
 return p-usb_status;
 }
 
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index 0bb5c7b..4896d38 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -635,6 +635,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
 ret = usb_handle_packet(dev, ep-packey[dir].p);
 
 if (ret == USB_RET_ASYNC) {
+usb_device_flush_ep_queue(dev, uep);
 ep-status[dir] = len;
 return;
 }
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index c36184a..a3207f0 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -816,6 +816,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct 
ohci_ed *ed,
 usb_packet_addbuf(ohci-usb_packet, ohci-usb_buf, len);
 ret = usb_handle_packet(dev, ohci-usb_packet);
 if (ret == USB_RET_ASYNC) {
+usb_device_flush_ep_queue(dev, ep);
 return 1;
 }
 }
@@ -1018,6 +1019,7 @@ static int ohci_service_td(OHCIState *ohci, struct 
ohci_ed *ed)
 

[Qemu-devel] [PATCH 12/22] usb: Move short-not-ok handling to the core

2012-10-15 Thread Hans de Goede
After a short-not-ok packet ending short, we should not advance the queue.
Move enforcing this to the core, rather then handling it in the hcd code.

This may result in the queue now actually containing multiple input packets
(which would not happen before), and this requires special handling in
combination with pipelining, so disable pipleining for input endpoints
(for now).

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb.h|  4 +++-
 hw/usb/core.c   |  6 --
 hw/usb/hcd-ehci.c   |  9 -
 hw/usb/hcd-musb.c   |  2 +-
 hw/usb/hcd-ohci.c   |  4 ++--
 hw/usb/hcd-uhci.c   |  7 ---
 hw/usb/hcd-xhci.c   |  2 +-
 hw/usb/host-linux.c |  3 ++-
 hw/usb/redirect.c   | 18 --
 9 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/hw/usb.h b/hw/usb.h
index ead03c9..1fcf79c 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -351,6 +351,7 @@ struct USBPacket {
 USBEndpoint *ep;
 QEMUIOVector iov;
 uint64_t parameter; /* control transfers */
+bool short_not_ok;
 int result; /* transfer length or USB_RET_* status code */
 /* Internal use by the USB layer.  */
 USBPacketState state;
@@ -360,7 +361,8 @@ struct USBPacket {
 void usb_packet_init(USBPacket *p);
 void usb_packet_set_state(USBPacket *p, USBPacketState state);
 void usb_packet_check_state(USBPacket *p, USBPacketState expected);
-void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id);
+void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id,
+  bool short_not_ok);
 void usb_packet_addbuf(USBPacket *p, void *ptr, size_t len);
 int usb_packet_map(USBPacket *p, QEMUSGList *sgl);
 void usb_packet_unmap(USBPacket *p, QEMUSGList *sgl);
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 5a97a0e..f4a5ad2 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -423,7 +423,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
 assert(QTAILQ_FIRST(ep-queue) == p);
 assert(p-result != USB_RET_ASYNC  p-result != USB_RET_NAK);
 
-if (p-result  0) {
+if (p-result  0 || (p-short_not_ok  (p-result  p-iov.size))) {
 ep-halted = true;
 }
 usb_packet_set_state(p, USB_PACKET_COMPLETE);
@@ -532,7 +532,8 @@ void usb_packet_set_state(USBPacket *p, USBPacketState 
state)
 p-state = state;
 }
 
-void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id)
+void usb_packet_setup(USBPacket *p, int pid, USBEndpoint *ep, uint64_t id,
+  bool short_not_ok)
 {
 assert(!usb_packet_is_inflight(p));
 assert(p-iov.iov != NULL);
@@ -541,6 +542,7 @@ void usb_packet_setup(USBPacket *p, int pid, USBEndpoint 
*ep, uint64_t id)
 p-ep = ep;
 p-result = 0;
 p-parameter = 0;
+p-short_not_ok = short_not_ok;
 qemu_iovec_reset(p-iov);
 usb_packet_set_state(p, USB_PACKET_SETUP);
 }
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index e6f7642..4dfe0f3 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1550,6 +1550,7 @@ static int ehci_execute(EHCIPacket *p, const char *action)
 USBEndpoint *ep;
 int ret;
 int endp;
+bool spd;
 
 assert(p-async == EHCI_ASYNC_NONE ||
p-async == EHCI_ASYNC_INITIALIZED);
@@ -1589,7 +1590,8 @@ static int ehci_execute(EHCIPacket *p, const char *action)
 return USB_RET_PROCERR;
 }
 
-usb_packet_setup(p-packet, p-pid, ep, p-qtdaddr);
+spd = (p-pid == USB_TOKEN_IN  NLPTR_TBIT(p-qtd.altnext) == 0);
+usb_packet_setup(p-packet, p-pid, ep, p-qtdaddr, spd);
 usb_packet_map(p-packet, p-sgl);
 p-async = EHCI_ASYNC_INITIALIZED;
 }
@@ -1659,7 +1661,7 @@ static int ehci_process_itd(EHCIState *ehci,
 dev = ehci_find_device(ehci, devaddr);
 ep = usb_ep_get(dev, pid, endp);
 if (ep  ep-type == USB_ENDPOINT_XFER_ISOC) {
-usb_packet_setup(ehci-ipacket, pid, ep, addr);
+usb_packet_setup(ehci-ipacket, pid, ep, addr, false);
 usb_packet_map(ehci-ipacket, ehci-isgl);
 ret = usb_handle_packet(dev, ehci-ipacket);
 assert(ret != USB_RET_ASYNC);
@@ -2083,9 +2085,6 @@ static int ehci_fill_queue(EHCIPacket *p)
 uint32_t qtdaddr, start_addr = p-qtdaddr;
 
 for (;;) {
-if (NLPTR_TBIT(qtd.altnext) == 0) {
-break;
-}
 if (NLPTR_TBIT(qtd.next) != 0) {
 break;
 }
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index 4896d38..f65fa3c 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -627,7 +627,7 @@ static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
 dev = usb_find_device(s-port, ep-faddr[idx]);
 uep = usb_ep_get(dev, pid, ep-type[idx]  0xf);
 usb_packet_setup(ep-packey[dir].p, pid, uep,
- (dev-addr  16) | (uep-nr  8) | pid);
+ (dev-addr  16) | (uep-nr  8) | pid, false);
 usb_packet_addbuf(ep-packey[dir].p, ep-buf[idx], 

[Qemu-devel] [PATCH 21/22] usb-redir: Allow to attach USB 2.0 devices to 1.1 host controller

2012-10-15 Thread Hans de Goede
From: Jan Kiszka jan.kis...@siemens.com

This follows the logic of host-linux: If a 2.0 device has no ISO
endpoint and no interrupt endpoint with a packet size  64, we can
attach it also to an 1.1 host controller. In case the redir server does
not report endpoint sizes, play safe and remove the 1.1 compatibility as
well. Moreover, if we detect a conflicting change in the configuration
after the device was already attached, it will be disconnected
immediately.

HdG: Several small cleanups and fixes

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 30 +-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 26f501a..63b7010 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -106,6 +106,7 @@ struct USBRedirDevice {
 struct usb_redir_interface_info_header interface_info;
 struct usbredirfilter_rule *filter_rules;
 int filter_rules_count;
+int compatible_speedmask;
 };
 
 static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
@@ -974,6 +975,7 @@ static void usbredir_do_attach(void *opaque)
 }
 
 if (usb_device_attach(dev-dev) != 0) {
+WARNING(rejecting device due to speed mismatch\n);
 usbredir_reject_device(dev);
 }
 }
@@ -1094,6 +1096,9 @@ static int usbredir_initfn(USBDevice *udev)
 /* We'll do the attach once we receive the speed from the usb-host */
 udev-auto_attach = 0;
 
+/* Will be cleared during setup when we find conflicts */
+dev-compatible_speedmask = USB_SPEED_MASK_FULL;
+
 /* Let the backend know we are ready */
 qemu_chr_fe_open(dev-cs);
 qemu_chr_add_handlers(dev-cs, usbredir_chr_handlers, dev);
@@ -1237,6 +1242,7 @@ static void usbredir_device_connect(void *priv,
 case usb_redir_speed_low:
 speed = low speed;
 dev-dev.speed = USB_SPEED_LOW;
+dev-compatible_speedmask = ~USB_SPEED_MASK_FULL;
 break;
 case usb_redir_speed_full:
 speed = full speed;
@@ -1270,7 +1276,7 @@ static void usbredir_device_connect(void *priv,
  device_connect-device_class);
 }
 
-dev-dev.speedmask = (1  dev-dev.speed);
+dev-dev.speedmask = (1  dev-dev.speed) | dev-compatible_speedmask;
 dev-device_info = *device_connect;
 
 if (usbredir_check_filter(dev)) {
@@ -1310,6 +1316,7 @@ static void usbredir_device_disconnect(void *priv)
 dev-interface_info.interface_count = NO_INTERFACE_INFO;
 dev-dev.addr = 0;
 dev-dev.speed = 0;
+dev-compatible_speedmask = USB_SPEED_MASK_FULL;
 }
 
 static void usbredir_interface_info(void *priv,
@@ -1331,6 +1338,12 @@ static void usbredir_interface_info(void *priv,
 }
 }
 
+static void usbredir_mark_speed_incompatible(USBRedirDevice *dev, int speed)
+{
+dev-compatible_speedmask = ~(1  speed);
+dev-dev.speedmask = (1  dev-dev.speed) | dev-compatible_speedmask;
+}
+
 static void usbredir_set_pipeline(USBRedirDevice *dev, struct USBEndpoint *uep)
 {
 if (uep-type != USB_ENDPOINT_XFER_BULK) {
@@ -1379,7 +1392,14 @@ static void usbredir_ep_info(void *priv,
 case usb_redir_type_invalid:
 break;
 case usb_redir_type_iso:
+usbredir_mark_speed_incompatible(dev, USB_SPEED_FULL);
+/* Fall through */
 case usb_redir_type_interrupt:
+if (!usbredirparser_peer_has_cap(dev-parser,
+ usb_redir_cap_ep_info_max_packet_size) ||
+ep_info-max_packet_size[i]  64) {
+usbredir_mark_speed_incompatible(dev, USB_SPEED_FULL);
+}
 if (dev-endpoint[i].interval == 0) {
 ERROR(Received 0 interval for isoc or irq endpoint\n);
 usbredir_reject_device(dev);
@@ -1397,6 +1417,14 @@ static void usbredir_ep_info(void *priv,
 return;
 }
 }
+/* The new ep info may have caused a speed incompatibility, recheck */
+if (dev-dev.attached 
+!(dev-dev.port-speedmask  dev-dev.speedmask)) {
+ERROR(Device no longer matches speed after endpoint info change, 
+  disconnecting!\n);
+usbredir_reject_device(dev);
+return;
+}
 usbredir_setup_usb_eps(dev);
 }
 
-- 
1.7.12.1




Re: [Qemu-devel] [PATCH v2] chardev: add hotplug support.

2012-10-15 Thread Andreas Färber
Am 15.10.2012 08:51, schrieb Lei Li:
 On 10/12/2012 08:39 PM, Gerd Hoffmann wrote:
 +void qmp_chardev_del(const char *id, Error **errp)
 +{
 +CharDriverState *chr;
 +
 +chr = qemu_chr_find(id);
 +if (NULL == chr) {
 +error_setg(errp, Chardev '%s' not found\n, id);
 
 Maybe this should be replaced by QERR_ macros to keep
 compatibility since this one is listed in ErrorClass
 in the schema, like:
 
 error_set(errp, QERR_DEVICE_NOT_FOUND, id);

No, error_setg() is the new replacement, QERR_* is deprecated.

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] Silent filesystem/qcow2 corruptions with qemu-kvm-1.0 and 1.1.1

2012-10-15 Thread Kevin Wolf
Am 12.10.2012 10:53, schrieb Tiziano Müller:
 Am Freitag, den 12.10.2012, 10:33 +0200 schrieb Stefan Hajnoczi:
 On Thu, Oct 11, 2012 at 03:33:23PM +0200, Tiziano Müller wrote:
 Checking the image using `qemu-img check` then gives something like
 this:

 ERROR OFLAG_COPIED: offset=3bc3 refcount=1
 ERROR offset=c7e331: Cluster is not properly aligned; L2 entry
 corrupted.

 Is any other program accessing the qcow2 image on the host while the VM
 is running?
 
 For example, are you running qemu-img on the image while the VM is
 running?
 
 On some VMs we tried to extract filesystem snapshots at runtime:
 
   qemu-img convert -s snapshot-id original.qcow2 snapshot.qcow2
 
 (yes, that's not consistent, we're switching to external snapshots).
 But that should open the image read-only, right?

Yes, in theory that should be harmless and even produce a correct copy
of the snapshot.

 Other operations where the qemu-monitor-commands savevm and delvm. 
 
 Although: we created a new qcow2 and even in that the filesystem got
 corrupted without any of the above actions. So we're pretty confident
 that those operations are not the sole cause.

So no internal snapshots are involved at all with this new image? I'm
asking because in the past non-reproducible failures were reported with
snapshots, but I'm not aware of any case that didn't use snapshots.

Any other non-default feature that you used, like compression?

Kevin



[Qemu-devel] [PATCH 01/22] uhci: Properly unmap packets on cancel / invalid pid

2012-10-15 Thread Hans de Goede
Packets with an invalid pid, or which were cancelled have
usb_packet_map() called on them on init, but not usb_packet_unmap()
before being freed.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-uhci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index c2f08e3..671c712 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -236,6 +236,7 @@ static void uhci_async_cancel(UHCIAsync *async)
 trace_usb_uhci_packet_cancel(async-queue-token, async-td, async-done);
 if (!async-done)
 usb_cancel_packet(async-packet);
+usb_packet_unmap(async-packet, async-sgl);
 uhci_async_free(async);
 }
 
@@ -887,6 +888,7 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, 
UHCI_TD *td,
 
 default:
 /* invalid pid : frame interrupted */
+usb_packet_unmap(async-packet, async-sgl);
 uhci_async_free(async);
 s-status |= UHCI_STS_HCPERR;
 uhci_update_irq(s);
-- 
1.7.12.1




[Qemu-devel] [PATCH 03/22] ehci: Get rid of packet tbytes field

2012-10-15 Thread Hans de Goede
This field is used in some places to track the tbytes field of the token, but
in other places the field is used directly, use it directly everywhere for
consistency.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-ehci.c | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 3acd881a..6945992 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -362,7 +362,6 @@ struct EHCIPacket {
 USBPacket packet;
 QEMUSGList sgl;
 int pid;
-uint32_t tbytes;
 enum async_state async;
 int usb_status;
 };
@@ -1505,15 +1504,16 @@ static void ehci_execute_complete(EHCIQueue *q)
 }
 } else {
 // TODO check 4.12 for splits
+uint32_t tbytes = get_field(q-qh.token, QTD_TOKEN_TBYTES);
 
-if (p-tbytes  p-pid == USB_TOKEN_IN) {
-p-tbytes -= p-usb_status;
+if (tbytes  p-pid == USB_TOKEN_IN) {
+tbytes -= p-usb_status;
 } else {
-p-tbytes = 0;
+tbytes = 0;
 }
 
-DPRINTF(updating tbytes to %d\n, p-tbytes);
-set_field(q-qh.token, p-tbytes, QTD_TOKEN_TBYTES);
+DPRINTF(updating tbytes to %d\n, tbytes);
+set_field(q-qh.token, tbytes, QTD_TOKEN_TBYTES);
 }
 ehci_finish_transfer(q, p-usb_status);
 usb_packet_unmap(p-packet, p-sgl);
@@ -1544,8 +1544,7 @@ static int ehci_execute(EHCIPacket *p, const char *action)
 return USB_RET_PROCERR;
 }
 
-p-tbytes = (p-qtd.token  QTD_TOKEN_TBYTES_MASK)  QTD_TOKEN_TBYTES_SH;
-if (p-tbytes  BUFF_SIZE) {
+if (get_field(p-qtd.token, QTD_TOKEN_TBYTES)  BUFF_SIZE) {
 ehci_trace_guest_bug(p-queue-ehci,
  guest requested more bytes than allowed);
 return USB_RET_PROCERR;
@@ -1582,10 +1581,9 @@ static int ehci_execute(EHCIPacket *p, const char 
*action)
 
 trace_usb_ehci_packet_action(p-queue, p, action);
 ret = usb_handle_packet(p-queue-dev, p-packet);
-DPRINTF(submit: qh %x next %x qtd %x pid %x len %zd 
-(total %d) endp %x ret %d\n,
+DPRINTF(submit: qh %x next %x qtd %x pid %x len %zd endp %x ret %d\n,
 q-qhaddr, q-qh.next, q-qtdaddr, q-pid,
-q-packet.iov.size, q-tbytes, endp, ret);
+q-packet.iov.size, endp, ret);
 
 if (ret  BUFF_SIZE) {
 fprintf(stderr, ret from usb_handle_packet  BUFF_SIZE\n);
-- 
1.7.12.1




[Qemu-devel] [PATCH 02/22] uhci: Move checks to continue queuing to uhci_fill_queue()

2012-10-15 Thread Hans de Goede
Rather then having a special check to start queuing after the first packet,
and then another check for the other packets in uhci_fill_queue(), simply
check the previous packet beforehand in uhci_fill_queue()

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-uhci.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 671c712..600d095 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -991,7 +991,8 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
 UHCI_TD ptd;
 int ret;
 
-while (is_valid(plink)) {
+ptd.ctrl = td-ctrl;
+while (is_valid(plink)  !(ptd.ctrl  TD_CTRL_SPD)) {
 pci_dma_read(s-dev, plink  ~0xf, ptd, sizeof(ptd));
 le32_to_cpus(ptd.link);
 le32_to_cpus(ptd.ctrl);
@@ -1010,9 +1011,6 @@ static void uhci_fill_queue(UHCIState *s, UHCI_TD *td)
 }
 assert(ret == TD_RESULT_ASYNC_START);
 assert(int_mask == 0);
-if (ptd.ctrl  TD_CTRL_SPD) {
-break;
-}
 plink = ptd.link;
 }
 }
@@ -1110,9 +1108,7 @@ static void uhci_process_frame(UHCIState *s)
 
 case TD_RESULT_ASYNC_START:
 trace_usb_uhci_td_async(curr_qh  ~0xf, link  ~0xf);
-if (is_valid(td.link)  !(td.ctrl  TD_CTRL_SPD)) {
-uhci_fill_queue(s, td);
-}
+uhci_fill_queue(s, td);
 link = curr_qh ? qh.link : td.link;
 continue;
 
-- 
1.7.12.1




[Qemu-devel] [PATCH 19/22] usb-redir: Add an usbredir_setup_usb_eps() helper function

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 45 ++---
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index f715281..9e88779 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1346,17 +1346,35 @@ static void usbredir_set_pipeline(USBRedirDevice *dev, 
struct USBEndpoint *uep)
 }
 }
 
+static void usbredir_setup_usb_eps(USBRedirDevice *dev)
+{
+struct USBEndpoint *usb_ep;
+int i, pid;
+
+for (i = 0; i  MAX_ENDPOINTS; i++) {
+pid = (i  0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT;
+usb_ep = usb_ep_get(dev-dev, pid, i  0x0f);
+usb_ep-type = dev-endpoint[i].type;
+usb_ep-ifnum = dev-endpoint[i].interface;
+usb_ep-max_packet_size = dev-endpoint[i].max_packet_size;
+usbredir_set_pipeline(dev, usb_ep);
+}
+}
+
 static void usbredir_ep_info(void *priv,
 struct usb_redir_ep_info_header *ep_info)
 {
 USBRedirDevice *dev = priv;
-struct USBEndpoint *usb_ep;
 int i;
 
 for (i = 0; i  MAX_ENDPOINTS; i++) {
 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 (usbredirparser_peer_has_cap(dev-parser,
+ usb_redir_cap_ep_info_max_packet_size)) {
+dev-endpoint[i].max_packet_size = ep_info-max_packet_size[i];
+}
 switch (dev-endpoint[i].type) {
 case usb_redir_type_invalid:
 break;
@@ -1377,18 +1395,8 @@ static void usbredir_ep_info(void *priv,
 usbredir_device_disconnect(dev);
 return;
 }
-usb_ep = usb_ep_get(dev-dev,
-(i  0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT,
-i  0x0f);
-usb_ep-type = dev-endpoint[i].type;
-usb_ep-ifnum = dev-endpoint[i].interface;
-if (usbredirparser_peer_has_cap(dev-parser,
- usb_redir_cap_ep_info_max_packet_size)) {
-dev-endpoint[i].max_packet_size =
-usb_ep-max_packet_size = ep_info-max_packet_size[i];
-}
-usbredir_set_pipeline(dev, usb_ep);
 }
+usbredir_setup_usb_eps(dev);
 }
 
 static void usbredir_configuration_status(void *priv, uint64_t id,
@@ -1630,8 +1638,6 @@ static void usbredir_pre_save(void *priv)
 static int usbredir_post_load(void *priv, int version_id)
 {
 USBRedirDevice *dev = priv;
-struct USBEndpoint *usb_ep;
-int i;
 
 switch (dev-device_info.speed) {
 case usb_redir_speed_low:
@@ -1651,15 +1657,8 @@ static int usbredir_post_load(void *priv, int version_id)
 }
 dev-dev.speedmask = (1  dev-dev.speed);
 
-for (i = 0; i  MAX_ENDPOINTS; i++) {
-usb_ep = usb_ep_get(dev-dev,
-(i  0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT,
-i  0x0f);
-usb_ep-type = dev-endpoint[i].type;
-usb_ep-ifnum = dev-endpoint[i].interface;
-usb_ep-max_packet_size = dev-endpoint[i].max_packet_size;
-usbredir_set_pipeline(dev, usb_ep);
-}
+usbredir_setup_usb_eps(dev);
+
 return 0;
 }
 
-- 
1.7.12.1




[Qemu-devel] [PATCH 22/22] usb-redir: Allow redirecting super speed devices to high speed controllers

2012-10-15 Thread Hans de Goede
Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 23 +--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 63b7010..ae815b9 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1097,7 +1097,7 @@ static int usbredir_initfn(USBDevice *udev)
 udev-auto_attach = 0;
 
 /* Will be cleared during setup when we find conflicts */
-dev-compatible_speedmask = USB_SPEED_MASK_FULL;
+dev-compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH;
 
 /* Let the backend know we are ready */
 qemu_chr_fe_open(dev-cs);
@@ -1243,10 +1243,12 @@ static void usbredir_device_connect(void *priv,
 speed = low speed;
 dev-dev.speed = USB_SPEED_LOW;
 dev-compatible_speedmask = ~USB_SPEED_MASK_FULL;
+dev-compatible_speedmask = ~USB_SPEED_MASK_HIGH;
 break;
 case usb_redir_speed_full:
 speed = full speed;
 dev-dev.speed = USB_SPEED_FULL;
+dev-compatible_speedmask = ~USB_SPEED_MASK_HIGH;
 break;
 case usb_redir_speed_high:
 speed = high speed;
@@ -1316,7 +1318,7 @@ static void usbredir_device_disconnect(void *priv)
 dev-interface_info.interface_count = NO_INTERFACE_INFO;
 dev-dev.addr = 0;
 dev-dev.speed = 0;
-dev-compatible_speedmask = USB_SPEED_MASK_FULL;
+dev-compatible_speedmask = USB_SPEED_MASK_FULL | USB_SPEED_MASK_HIGH;
 }
 
 static void usbredir_interface_info(void *priv,
@@ -1393,6 +1395,7 @@ static void usbredir_ep_info(void *priv,
 break;
 case usb_redir_type_iso:
 usbredir_mark_speed_incompatible(dev, USB_SPEED_FULL);
+usbredir_mark_speed_incompatible(dev, USB_SPEED_HIGH);
 /* Fall through */
 case usb_redir_type_interrupt:
 if (!usbredirparser_peer_has_cap(dev-parser,
@@ -1400,6 +1403,11 @@ static void usbredir_ep_info(void *priv,
 ep_info-max_packet_size[i]  64) {
 usbredir_mark_speed_incompatible(dev, USB_SPEED_FULL);
 }
+if (!usbredirparser_peer_has_cap(dev-parser,
+ usb_redir_cap_ep_info_max_packet_size) ||
+ep_info-max_packet_size[i]  1024) {
+usbredir_mark_speed_incompatible(dev, USB_SPEED_HIGH);
+}
 if (dev-endpoint[i].interval == 0) {
 ERROR(Received 0 interval for isoc or irq endpoint\n);
 usbredir_reject_device(dev);
@@ -1530,6 +1538,17 @@ static void usbredir_control_packet(void *priv, uint64_t 
id,
 DPRINTF(ctrl-in status %d len %d id %PRIu64\n, control_packet-status,
 len, id);
 
+/* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices
+ * to work redirected to a not superspeed capable hcd */
+if (dev-dev.speed == USB_SPEED_SUPER 
+!((dev-dev.port-speedmask  USB_SPEED_MASK_SUPER)) 
+control_packet-requesttype == 0x80 
+control_packet-request == 6 
+control_packet-value == 0x100  control_packet-index == 0 
+data_len = 18  data[7] == 9) {
+data[7] = 64;
+}
+
 p = usbredir_find_packet_by_id(dev, 0, id);
 if (p) {
 len = usbredir_handle_status(dev, control_packet-status, len);
-- 
1.7.12.1




Re: [Qemu-devel] [PATCH 06/22] ehci: Speed up the timer of raising int from the async schedule

2012-10-15 Thread Gerd Hoffmann
On 10/15/12 12:38, Hans de Goede wrote:
 Often the guest will queue up new packets in response to a packet, in the
 async schedule with its IOC flag set, completing. By speeding up the
 frame-timer, we notice these new packets earlier. This increases the
 speed (MB/s) of a Linux guest reading from a USB mass storage device by a
 factor of 1.15 on top of the Improve latency of interrupt delivery
 speed-ups, both with and without input pipelining enabled.

Why not just set async_stepdown to 0?

cheers,
  Gerd




[Qemu-devel] [PATCH 15/22] combined-packet: Add a workaround for Linux usbfs + live migration

2012-10-15 Thread Hans de Goede
Older versions (anything but the latest) of Linux usbfs + libusb(x),
will submit larger (bulk) transfers split into multiple 16k submissions,
which means that rather then all tds getting linked into the queue in
one atomic operarion they get linked in a bunch at a time, which could
cause problems if:
1) We scan the queue while libusb is in the middle of submitting a split
   bulk transfer
2) While this bulk transfer is pending we migrate to another host.

The problem is that after 2, the new host will rescan the queue and
combine the packets in one large transfer, where as 1) has caused the
original host to see them as 2 transfers. This patch fixes this by stopping
combinging if we detect a 16k transfer with its int_req flag set.

This should not adversely effect performance for other cases as:
1) Linux never sets the interrupt flag on packets other then the last
2) Windows does set the in_req flag on each td, but will submit large
transfers in 20k tds thus never triggering the check

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/combined-packet.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/usb/combined-packet.c b/hw/usb/combined-packet.c
index b6fcb2c..d347324 100644
--- a/hw/usb/combined-packet.c
+++ b/hw/usb/combined-packet.c
@@ -120,7 +120,7 @@ void usb_ep_combine_input_packets(USBEndpoint *ep)
 USBPacket *p, *u, *next, *prev = NULL, *first = NULL;
 USBPort *port = ep-dev-port;
 USBDeviceClass *klass = USB_DEVICE_GET_CLASS(ep-dev);
-int ret;
+int ret, totalsize;
 
 assert(ep-pipeline);
 assert(ep-pid == USB_TOKEN_IN);
@@ -165,8 +165,11 @@ void usb_ep_combine_input_packets(USBEndpoint *ep)
 }
 
 /* Is this packet the last one of a (combined) transfer? */
+totalsize = (p-combined) ? p-combined-iov.size : p-iov.size;
 if ((p-iov.size % ep-max_packet_size) != 0 || !p-short_not_ok ||
-next == NULL) {
+next == NULL ||
+/* Work around for Linux usbfs bulk splitting + migration */
+(totalsize == 16348  p-int_req)) {
 ret = klass-handle_combined_data(ep-dev, first);
 assert(ret == USB_RET_ASYNC);
 if (first-combined) {
-- 
1.7.12.1




[Qemu-devel] [PATCH 04/22] ehci: Set int flag on a short input packet

2012-10-15 Thread Hans de Goede
According to 4.15.1.2 an interrupt must be raised when a short packet
is received. If we don't do this it may take a significant time for
the guest to notice a short trasnfer has completed, since only the last td
will have its IOC flag set, and a short transfer may complete in an earlier
packet.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/hcd-ehci.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 6945992..d9d4918 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1508,6 +1508,10 @@ static void ehci_execute_complete(EHCIQueue *q)
 
 if (tbytes  p-pid == USB_TOKEN_IN) {
 tbytes -= p-usb_status;
+if (tbytes) {
+/* 4.15.1.2 must raise int on a short input packet */
+ehci_raise_irq(q-ehci, USBSTS_INT);
+}
 } else {
 tbytes = 0;
 }
-- 
1.7.12.1




[Qemu-devel] [PATCH 16/22] usb-redir: When a packet contains data on a stall, ignore the stall

2012-10-15 Thread Hans de Goede
It is possbile for bulk packets to transfer some of the data and
to then stall. ATM our usb core allows us to return either data, or an
error, not both. For now return the data rather then the stall when this
happens, counting on further packets to detect the stall.
In the future we should fix the qemu usb core to handle packets
completing with some data and an error.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
 hw/usb/redirect.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 84b9705..99e25d4 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1152,6 +1152,10 @@ static int usbredir_handle_status(USBRedirDevice *dev,
 case usb_redir_success:
 return actual_len;
 case usb_redir_stall:
+if (actual_len  0) {
+WARNING(got both data and stall, returning data\n);
+return actual_len;
+}
 return USB_RET_STALL;
 case usb_redir_cancelled:
 /*
-- 
1.7.12.1




[Qemu-devel] Connecting virtio-9p-pci to a remote 9p server

2012-10-15 Thread Chris Webb
We're planning to implement shared filesystems for guests on our virtualized
hosting platform, stored on a central fileserver separate from the hosts.

Whilst we can mount the shares on each host and then use qemu's 9p
passthrough/proxy support to access the mountpoint, going via the host
kernel and vfs like this feels quite inefficient. We would be converting
back and forth between vfs and 9p models several times needlessly.

Instead, I'm wondering about the feasibility of connecting the 9p stream
directly from qemu's virtio-9p-pci device to a socket opened on a
9p-over-TCP export from the fileserver. Am I right in thinking that qemu's
-fsdev proxy gives me access to a file descriptor attached to the 9p stream
to/from the guest, or is the protocol between virtfs-proxy-helper and qemu
re-encoded within qemu first?

Secondly, assuming I can somehow get at the 9p streams directly (either with
an existing option or by adding a new one), I'd like to restrict guests to
the relevant user's subdirectory on the fileserver, and have been thinking
about doing this by filtering the 9p stream to restrict 'attach' operations.

Fortunately, 9p uses client-chosen fids rather than server filesystem inode
numbers which would immediately scupper any simple attempts to implement a
secure chroot proxy of this kind. Looking at the 9p2000.L protocol, it
doesn't look obviously difficult, but I've not really worked with 9p before,
and could well be missing security complications. (I'm not sure whether
there's risk of symlinks being interpreted server side rather than client
side, for example.)

I'd also be interested in any more general thoughts on this kind of thing.
If we're going to work on it, it would be nice for us to write something
that would be more widely useful to others rather than just create an
in-house hack.

Cheers,

Chris.



Re: [Qemu-devel] Silent filesystem/qcow2 corruptions with qemu-kvm-1.0 and 1.1.1

2012-10-15 Thread Tiziano Müller
Am Montag, den 15.10.2012, 13:11 +0200 schrieb Kevin Wolf:
 Am 12.10.2012 10:53, schrieb Tiziano Müller:
  Am Freitag, den 12.10.2012, 10:33 +0200 schrieb Stefan Hajnoczi:
  On Thu, Oct 11, 2012 at 03:33:23PM +0200, Tiziano Müller wrote:
  Checking the image using `qemu-img check` then gives something like
  this:
 
  ERROR OFLAG_COPIED: offset=3bc3 refcount=1
  ERROR offset=c7e331: Cluster is not properly aligned; L2 entry
  corrupted.
 
  Is any other program accessing the qcow2 image on the host while the VM
  is running?
  
  For example, are you running qemu-img on the image while the VM is
  running?
  
  On some VMs we tried to extract filesystem snapshots at runtime:
  
qemu-img convert -s snapshot-id original.qcow2 snapshot.qcow2
  
  (yes, that's not consistent, we're switching to external snapshots).
  But that should open the image read-only, right?
 
 Yes, in theory that should be harmless and even produce a correct copy
 of the snapshot.

Good to know, thanks.

 
  Other operations where the qemu-monitor-commands savevm and delvm. 
  
  Although: we created a new qcow2 and even in that the filesystem got
  corrupted without any of the above actions. So we're pretty confident
  that those operations are not the sole cause.
 
 So no internal snapshots are involved at all with this new image?

No. I just checked again: no internal snapshot are currently present nor
have been added/removed in the past.

  I'm
 asking because in the past non-reproducible failures were reported with
 snapshots, but I'm not aware of any case that didn't use snapshots.
 
 Any other non-default feature that you used, like compression?

No, we either create the qcows by hand using:
  qemu-img create -f qcow2 kvm-0XY_01.qcow2 30G

or (usually) using libvirt:
  virsh vol-create $pool $diskfile

where $diskfile points to a xml like this:

volume
  name${diskfilename}/name
  allocation0/allocation
  capacity unit=G${kvmsize}.qcow2/capacity
  target
format type='qcow2'/
permissions
  owner0/owner
  group3000/group
  mode0660/mode
/permissions
  /target
/volume

and $pool references a directory-based storage pool.

-- 
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.muel...@stepping-stone.ch




Re: [Qemu-devel] [PATCH v5] target-i386: initialize APIC at CPU level

2012-10-15 Thread Igor Mammedov
On Sun, 14 Oct 2012 06:09:56 +0200
Andreas Färber afaer...@suse.de wrote:

 Am 13.10.2012 22:35, schrieb Igor Mammedov:
  (L)APIC is a part of cpu [1] so move APIC initialization inside of
  x86_cpu object. Since cpu_model and override flags currently specify
  whether APIC should be created or not, APIC creationinitialization is
  moved into x86_cpu_apic_init() which is called from x86_cpu_realize().
  
  [1] - all x86 cpus have integrated APIC if we overlook existence of i486,
  and it's more convenient to model after majority of them.
  
  Signed-off-by: Igor Mammedov imamm...@redhat.com
  ---
v5: fix *-user target build, smp_cpus is defined for softmmu only
 
 I do not run into any build issue with v4. Is it a runtime issue?
 
 Andreas
 
I've run into this trying to build your latest CPUstate series with
following configure options:
  './configure' '--enable-debug'  
'--target-list=x86_64-softmmu,x86_64-linux-user'

Anyway it's better not to build in any APIC checks in user target since it
doesn't need it at all.

I'm sorry for not noticing error earlier at v4 build time.
Could you re-apply it, please?



[Qemu-devel] [PATCH v2 0/3] qemu-img: Add --backing-chain option to info command

2012-10-15 Thread Stefan Hajnoczi
This series adds the --backing-chain option for enumerating the backing file
chain.  Given the topmost image it will print qemu-img info information for
each image file in the chain.

Special care needs to be taken when image files form an infinite loop.  This is
very unusual, most like due to malicious image files.  Nevertheless, qemu-img
must be robust against invalid inputs so we explicit check for this.

Stefan Hajnoczi (3):
  qemu-img: Add --backing-chain option to info command
  qemu-img: Detect backing file chain infinite loops
  qemu-iotests: Add 041 backing file chain infinite loop test

 qemu-img.c   | 115 ++-
 tests/qemu-iotests/041   |  90 +
 tests/qemu-iotests/041.out   |  81 ++
 tests/qemu-iotests/common.rc |   9 
 tests/qemu-iotests/group |   1 +
 5 files changed, 274 insertions(+), 22 deletions(-)
 create mode 100755 tests/qemu-iotests/041
 create mode 100644 tests/qemu-iotests/041.out

-- 
1.7.11.7




[Qemu-devel] [PATCH v2 1/3] qemu-img: Add --backing-chain option to info command

2012-10-15 Thread Stefan Hajnoczi
The qemu-img info --backing-chain option enumerates the backing file
chain.  For example, for base.qcow2 - snap1.qcow2 - snap2.qcow2 the
output becomes:

  $ qemu-img info --backing-chain snap2.qcow2
  image: snap2.qcow2
  file format: qcow2
  virtual size: 100M (104857600 bytes)
  disk size: 196K
  cluster_size: 65536
  backing file: snap1.qcow2
  backing file format: qcow2

  image: snap1.qcow2
  file format: qcow2
  virtual size: 100M (104857600 bytes)
  disk size: 196K
  cluster_size: 65536
  backing file: base.qcow2
  backing file format: qcow2

  image: base.qcow2
  file format: qcow2
  virtual size: 100M (104857600 bytes)
  disk size: 136K
  cluster_size: 65536

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 qemu-img.c | 98 --
 1 file changed, 76 insertions(+), 22 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index f17f187..c717f3e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1249,7 +1249,10 @@ static void dump_human_image_info(ImageInfo *info)
 }
 }
 
-enum {OPTION_OUTPUT = 256};
+enum {
+OPTION_OUTPUT = 256,
+OPTION_BACKING_CHAIN = 257,
+};
 
 typedef enum OutputFormat {
 OFORMAT_JSON,
@@ -1260,7 +1263,9 @@ static int img_info(int argc, char **argv)
 {
 int c;
 OutputFormat output_format = OFORMAT_HUMAN;
-const char *filename, *fmt, *output;
+bool chain = false;
+const char *output;
+char *filename, *fmt;
 BlockDriverState *bs;
 ImageInfo *info;
 
@@ -1272,6 +1277,7 @@ static int img_info(int argc, char **argv)
 {help, no_argument, 0, 'h'},
 {format, required_argument, 0, 'f'},
 {output, required_argument, 0, OPTION_OUTPUT},
+{backing-chain, no_argument, 0, OPTION_BACKING_CHAIN},
 {0, 0, 0, 0}
 };
 c = getopt_long(argc, argv, f:h,
@@ -1285,17 +1291,20 @@ static int img_info(int argc, char **argv)
 help();
 break;
 case 'f':
-fmt = optarg;
+fmt = g_strdup(optarg);
 break;
 case OPTION_OUTPUT:
 output = optarg;
 break;
+case OPTION_BACKING_CHAIN:
+chain = true;
+break;
 }
 }
 if (optind = argc) {
 help();
 }
-filename = argv[optind++];
+filename = g_strdup(argv[optind++]);
 
 if (output  !strcmp(output, json)) {
 output_format = OFORMAT_JSON;
@@ -1303,31 +1312,76 @@ static int img_info(int argc, char **argv)
 output_format = OFORMAT_HUMAN;
 } else if (output) {
 error_report(--output must be used with human or json as argument.);
-return 1;
+goto err;
 }
 
-bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING, false);
-if (!bs) {
-return 1;
+if (chain  output_format == OFORMAT_JSON) {
+printf([\n);
 }
 
-info = g_new0(ImageInfo, 1);
-collect_image_info(bs, info, filename, fmt);
+do {
+bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
+   false);
+if (!bs) {
+goto err;
+}
 
-switch (output_format) {
-case OFORMAT_HUMAN:
-dump_human_image_info(info);
-dump_snapshots(bs);
-break;
-case OFORMAT_JSON:
-collect_snapshots(bs, info);
-dump_json_image_info(info);
-break;
-}
+info = g_new0(ImageInfo, 1);
+collect_image_info(bs, info, filename, fmt);
 
-qapi_free_ImageInfo(info);
-bdrv_delete(bs);
+switch (output_format) {
+case OFORMAT_HUMAN:
+dump_human_image_info(info);
+dump_snapshots(bs);
+break;
+case OFORMAT_JSON:
+collect_snapshots(bs, info);
+dump_json_image_info(info);
+break;
+}
+
+g_free(filename);
+g_free(fmt);
+filename = NULL;
+fmt = NULL;
+
+if (chain) {
+if (info-has_full_backing_filename) {
+filename = g_strdup(info-full_backing_filename);
+} else if (info-has_backing_filename) {
+filename = g_strdup(info-backing_filename);
+}
+
+if (filename  info-has_backing_filename_format) {
+fmt = g_strdup(info-backing_filename_format);
+}
+
+/* Print delimiters between items */
+if (filename) {
+switch (output_format) {
+case OFORMAT_HUMAN:
+printf(\n);
+break;
+case OFORMAT_JSON:
+printf(,\n);
+break;
+}
+}
+}
+
+qapi_free_ImageInfo(info);
+bdrv_delete(bs);
+} while (filename);
+
+if (chain  output_format == OFORMAT_JSON) {
+printf(]\n);
+}
 return 0;
+
+err:
+g_free(filename);
+g_free(fmt);
+ 

[Qemu-devel] [PATCH v2 3/3] qemu-iotests: Add 041 backing file chain infinite loop test

2012-10-15 Thread Stefan Hajnoczi
This new test verifies that qemu-img info --backing-chain safely aborts
when an image file has a backing file infinite loop.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 tests/qemu-iotests/041   | 90 
 tests/qemu-iotests/041.out   | 81 +++
 tests/qemu-iotests/common.rc |  9 +
 tests/qemu-iotests/group |  1 +
 4 files changed, 181 insertions(+)
 create mode 100755 tests/qemu-iotests/041
 create mode 100644 tests/qemu-iotests/041.out

diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
new file mode 100755
index 000..839255f
--- /dev/null
+++ b/tests/qemu-iotests/041
@@ -0,0 +1,90 @@
+#!/bin/bash
+#
+# Test that qemu-img info --backing-chain detects infinite loops
+#
+# Copyright (C) 2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/.
+#
+
+# creator
+owner=stefa...@redhat.com
+
+seq=`basename $0`
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap _cleanup; exit \$status 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# Any format supporting backing files
+_supported_fmt qcow qcow2 vmdk qed
+_supported_proto generic
+_supported_os Linux
+
+
+size=128M
+_make_test_img $size
+$QEMU_IMG rebase -u -b $TEST_IMG $TEST_IMG
+
+echo
+echo == backing file references self ==
+_img_info --backing-chain
+
+_make_test_img $size
+mv $TEST_IMG $TEST_IMG.base
+_make_test_img -b $TEST_IMG.base $size
+$QEMU_IMG rebase -u -b $TEST_IMG $TEST_IMG.base
+
+echo
+echo == parent references self ==
+_img_info --backing-chain
+
+_make_test_img $size
+mv $TEST_IMG $TEST_IMG.1.base
+_make_test_img -b $TEST_IMG.1.base $size
+mv $TEST_IMG $TEST_IMG.2.base
+_make_test_img -b $TEST_IMG.2.base $size
+mv $TEST_IMG $TEST_IMG.3.base
+_make_test_img -b $TEST_IMG.3.base $size
+$QEMU_IMG rebase -u -b $TEST_IMG.2.base $TEST_IMG.1.base
+
+echo
+echo == ancestor references another ancestor ==
+_img_info --backing-chain
+
+_make_test_img $size
+mv $TEST_IMG $TEST_IMG.1.base
+_make_test_img -b $TEST_IMG.1.base $size
+mv $TEST_IMG $TEST_IMG.2.base
+_make_test_img -b $TEST_IMG.2.base $size
+
+echo
+echo == finite chain of length 3 ==
+_img_info --backing-chain
+
+# success, all done
+echo *** done
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out
new file mode 100644
index 000..0c871b0
--- /dev/null
+++ b/tests/qemu-iotests/041.out
@@ -0,0 +1,81 @@
+QA output created by 041
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
+
+== backing file references self ==
+qemu-img: Aborting due to backing file chain infinite loop.
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file='TEST_DIR/t.IMGFMT.base' 
+
+== parent references self ==
+qemu-img: Aborting due to backing file chain infinite loop.
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.base
+
+image: TEST_DIR/t.IMGFMT.base
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file='TEST_DIR/t.IMGFMT.1.base' 
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file='TEST_DIR/t.IMGFMT.2.base' 
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file='TEST_DIR/t.IMGFMT.3.base' 
+
+== ancestor references another ancestor ==
+qemu-img: Aborting due to backing file chain infinite loop.
+image: TEST_DIR/t.IMGFMT
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.3.base
+
+image: TEST_DIR/t.IMGFMT.3.base
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.2.base
+
+image: TEST_DIR/t.IMGFMT.2.base
+file format: IMGFMT
+virtual size: 128M (134217728 bytes)
+cluster_size: 65536
+backing file: TEST_DIR/t.IMGFMT.1.base
+
+image: 

[Qemu-devel] [PATCH v2 2/3] qemu-img: Detect backing file chain infinite loops

2012-10-15 Thread Stefan Hajnoczi
A malicious or corruption image can contain an infinite loop of backing
files.  The qemu-img info --backing-chain command must not hang when
such files are encountered.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 qemu-img.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/qemu-img.c b/qemu-img.c
index c717f3e..60a5cc8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1259,6 +1259,11 @@ typedef enum OutputFormat {
 OFORMAT_HUMAN,
 } OutputFormat;
 
+static gboolean str_equal_func(gconstpointer a, gconstpointer b)
+{
+return strcmp(a, b) == 0;
+}
+
 static int img_info(int argc, char **argv)
 {
 int c;
@@ -1268,6 +1273,7 @@ static int img_info(int argc, char **argv)
 char *filename, *fmt;
 BlockDriverState *bs;
 ImageInfo *info;
+GHashTable *filenames;
 
 fmt = NULL;
 output = NULL;
@@ -1306,6 +1312,9 @@ static int img_info(int argc, char **argv)
 }
 filename = g_strdup(argv[optind++]);
 
+filenames = g_hash_table_new_full(g_str_hash, str_equal_func,
+  g_free, NULL);
+
 if (output  !strcmp(output, json)) {
 output_format = OFORMAT_JSON;
 } else if (output  !strcmp(output, human)) {
@@ -1320,6 +1329,12 @@ static int img_info(int argc, char **argv)
 }
 
 do {
+if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
+error_report(Aborting due to backing file chain infinite loop.);
+goto err;
+}
+g_hash_table_insert(filenames, g_strdup(filename), NULL);
+
 bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING,
false);
 if (!bs) {
@@ -1376,11 +1391,13 @@ static int img_info(int argc, char **argv)
 if (chain  output_format == OFORMAT_JSON) {
 printf(]\n);
 }
+g_hash_table_destroy(filenames);
 return 0;
 
 err:
 g_free(filename);
 g_free(fmt);
+g_hash_table_destroy(filenames);
 return 1;
 }
 
-- 
1.7.11.7




[Qemu-devel] delvm does not reduce the qcow2 file size

2012-10-15 Thread Kuniyasu Suzaki

Hello,

delvm is a command to delete a snapshot image in a qcow2 file.
However it does not reduce the qcow2 file size.

Is there any method to reduce the qcow2 file size when I delete a snapshot 
image?
should I convert the qcow2 file?

--
suzaki




[Qemu-devel] [PATCH] hw/qxl: guest bug on primary create with stride %4 != 0

2012-10-15 Thread Alon Levy
Due to usage of pixman for rendering on all spice surfaces we have
pixman's requirement that the stride be word aligned. A guest not
honoring that can crash spice and qemu with it due to failure to create
a surface (in spice-server). Avoid this early on in primary surface
creation and offscreen surface creation.

Recently windows guests got odd width support which triggers a non word
aligned primary surface in 16bit color depth. Off screen surfaces have
always been word aligned, but doesn't hurt to check them here too.

Signed-off-by: Alon Levy al...@redhat.com
---
 hw/qxl.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/qxl.c b/hw/qxl.c
index bd37a83..eaeee76 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -459,6 +459,12 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct 
QXLCommandExt *ext)
   qxl-ssd.num_surfaces);
 return 1;
 }
+if (cmd-type == QXL_SURFACE_CMD_CREATE 
+(cmd-u.surface_create.stride  0x03) != 0) {
+qxl_set_guest_bug(qxl, QXL_CMD_SURFACE stride = %d %% 4 != 0\n,
+  cmd-u.surface_create.stride);
+return 1;
+}
 qemu_mutex_lock(qxl-track_lock);
 if (cmd-type == QXL_SURFACE_CMD_CREATE) {
 qxl-guest_surfaces.cmds[id] = ext-cmd.data;
@@ -1382,6 +1388,12 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, 
int loadvm,
 trace_qxl_create_guest_primary_rest(qxl-id, sc-stride, sc-type,
 sc-flags);
 
+if ((surface.stride  0x3) != 0) {
+qxl_set_guest_bug(qxl, primary surface stride = %d %% 4 != 0,
+  surface.stride);
+return;
+}
+
 surface.mouse_mode = true;
 surface.group_id   = MEMSLOT_GROUP_GUEST;
 if (loadvm) {
-- 
1.7.12.1




Re: [Qemu-devel] [PATCH v5] target-i386: initialize APIC at CPU level

2012-10-15 Thread Andreas Färber
Am 15.10.2012 13:54, schrieb Igor Mammedov:
 On Sun, 14 Oct 2012 06:09:56 +0200
 Andreas Färber afaer...@suse.de wrote:
 
 Am 13.10.2012 22:35, schrieb Igor Mammedov:
 (L)APIC is a part of cpu [1] so move APIC initialization inside of
 x86_cpu object. Since cpu_model and override flags currently specify
 whether APIC should be created or not, APIC creationinitialization is
 moved into x86_cpu_apic_init() which is called from x86_cpu_realize().

 [1] - all x86 cpus have integrated APIC if we overlook existence of i486,
 and it's more convenient to model after majority of them.

 Signed-off-by: Igor Mammedov imamm...@redhat.com
 ---
   v5: fix *-user target build, smp_cpus is defined for softmmu only

 I do not run into any build issue with v4. Is it a runtime issue?

 Andreas

 I've run into this trying to build your latest CPUstate series with
 following configure options:
   './configure' '--enable-debug'  
 '--target-list=x86_64-softmmu,x86_64-linux-user'

--enable-debug was the missing puzzle piece, now I get the undefined
reference warning, too. :)

 Anyway it's better not to build in any APIC checks in user target since it
 doesn't need it at all.
 
 I'm sorry for not noticing error earlier at v4 build time.
 Could you re-apply it, please?

Sure, the patch itself is indeed better. Now that I've been able to
reproduce, I've exchanged v4 against v5 in on qom-cpu queue:
https://github.com/afaerber/qemu-cpu/commits/qom-cpu

Thanks for noticing,
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 06/22] ehci: Speed up the timer of raising int from the async schedule

2012-10-15 Thread Hans de Goede

Hi,

On 10/15/2012 01:17 PM, Gerd Hoffmann wrote:

On 10/15/12 12:38, Hans de Goede wrote:

Often the guest will queue up new packets in response to a packet, in the
async schedule with its IOC flag set, completing. By speeding up the
frame-timer, we notice these new packets earlier. This increases the
speed (MB/s) of a Linux guest reading from a USB mass storage device by a
factor of 1.15 on top of the Improve latency of interrupt delivery
speed-ups, both with and without input pipelining enabled.


Why not just set async_stepdown to 0?


We already do that whenever we run a package completion (it get sets when
we move to the executing stage). What this patch does is request the
frame timer to run again in 500 usecs instead of after 1 ms, thus making
us see and process async transfers faster when they are queued up in
response to just completed packages (which we've told the guest about with
the int interrupt). This makes the USB-bus / device idle time between
any 2 transfers of the 3 transfer involving USB storage BOT time shorter,
thereby speeding things up.

Regards,

Hans



Re: [Qemu-devel] [PATCH v5] target-i386: initialize APIC at CPU level

2012-10-15 Thread Igor Mammedov
On Mon, 15 Oct 2012 14:58:40 +0200
Andreas Färber afaer...@suse.de wrote:

 Am 15.10.2012 13:54, schrieb Igor Mammedov:
  On Sun, 14 Oct 2012 06:09:56 +0200
  Andreas Färber afaer...@suse.de wrote:
  
  Am 13.10.2012 22:35, schrieb Igor Mammedov:
  (L)APIC is a part of cpu [1] so move APIC initialization inside of
  x86_cpu object. Since cpu_model and override flags currently specify
  whether APIC should be created or not, APIC creationinitialization is
  moved into x86_cpu_apic_init() which is called from x86_cpu_realize().
 
  [1] - all x86 cpus have integrated APIC if we overlook existence of
  i486, and it's more convenient to model after majority of them.
 
  Signed-off-by: Igor Mammedov imamm...@redhat.com
  ---
v5: fix *-user target build, smp_cpus is defined for softmmu only
 
  I do not run into any build issue with v4. Is it a runtime issue?
 
  Andreas
 
  I've run into this trying to build your latest CPUstate series with
  following configure options:
'./configure' '--enable-debug'
  '--target-list=x86_64-softmmu,x86_64-linux-user'
 
 --enable-debug was the missing puzzle piece, now I get the undefined
 reference warning, too. :)
 
  Anyway it's better not to build in any APIC checks in user target since it
  doesn't need it at all.
  
  I'm sorry for not noticing error earlier at v4 build time.
  Could you re-apply it, please?
 
 Sure, the patch itself is indeed better. Now that I've been able to
 reproduce, I've exchanged v4 against v5 in on qom-cpu queue:
 https://github.com/afaerber/qemu-cpu/commits/qom-cpu
Thanks.

 
 Thanks for noticing,
 Andreas
 




Re: [Qemu-devel] [PATCH v4 24/26] qidl: add QAPI-based code generator

2012-10-15 Thread Paolo Bonzini
Il 15/10/2012 10:12, Paolo Bonzini ha scritto:
 Il 12/10/2012 23:11, Michael Roth ha scritto:
 +elif field['type'].startswith('enum '):
 +typename = 'int'
 
 Note that there is support for enum properties in qdev.  Please consider
 adding it, though it can be done as a follow-up.
 
 I'm going to play a bit with the series and convert 1 or 2 devices
 myself to see how it looks, then I'll give my acked-by.

Ok, so now I played with it a bit.  My main comments, which can all be
tackled as a follow-up, are:

- immutable/derived/broken/elsewhere (and the default, let's call it
serialized) are really five cases of the same QIDL property.  Perhaps
this could be enforced in the extended syntax like this:

#define q_immutable QIDL(serialize(immutable))
#define q_derived QIDL(serialize(derived))
#define q_broken QIDL(serialize(broken))
#define q_elsewhere QIDL(serialize(elsewhere))

I would also make it possible to explicitly specify the fifth state, if
only for symmetry.

I'm not sure what your plans are for q_derived vs. VMState.  If a field
X is set in pre_save hooks based on field Y, how should the fields be
set?  X is usually not up-to-date, so it should be q_derived.  But Y
cannot be serialized as is, so it should be q_elsewhere.  One of the
two is wrong, which one? :)

- q_properties are also always q_immutable.  I think this should be
enforced in the code generator.

- it would be _much_ better if you could automatically derive properties
information for embedded structs.  For example, Notifiers and qemu_irqs
are always q_immutable.  NotifierLists probably are always q_elsewhere,
because the owner of the notifiers should add themselves back.

In general, if struct X is QIDL_DECLAREd and only has q_immutable
fields, it can be taken as q_immutable.  Hence for example the base
class should not need any decoration; ISADevice will be seen as
q_immutable, but PCIDevice will be seen as serialized.  But even if a
struct is not QIDL_DECLAREd, it  should be possible to apply a tag to a
typedef, and have it always applied to the members.

Paolo



Re: [Qemu-devel] [PULL v3 00/23] Integrate DMA into the memory API

2012-10-15 Thread Avi Kivity
On 10/11/2012 11:01 PM, Anthony Liguori wrote:
 This conflicts with a recent pull from Stefano in xen-all.c.  The
 difference doesn't look that awful but since I don't have a xen test
 setup, I'm not confident in resolving it myself.
 
 Can you rebase and fixup?
 

Rebased tree in the same place:

  git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory/dma



-- 
error compiling committee.c: too many arguments to function



Re: [Qemu-devel] delvm does not reduce the qcow2 file size

2012-10-15 Thread Paolo Bonzini
Il 15/10/2012 11:33, Kuniyasu Suzaki ha scritto:
 Hello,
 
 delvm is a command to delete a snapshot image in a qcow2 file.
 However it does not reduce the qcow2 file size.

Note that the file will not grow when new allocations are performed in
the future.

QEMU should also convert the unused clusters to holes in the file
system, but it doesn't do that yet.

 Is there any method to reduce the qcow2 file size when I delete a snapshot 
 image?
 should I convert the qcow2 file?

I'm not sure what convert does if you have internal snapshots.

Paolo



Re: [Qemu-devel] [PATCH v3 21/22] qidl: qidl.h, definitions for qidl annotations

2012-10-15 Thread Paolo Bonzini
Il 05/10/2012 18:47, Michael Roth ha scritto:
 On Fri, Oct 05, 2012 at 05:53:09PM +0200, Paolo Bonzini wrote:
 Il 05/10/2012 17:41, Michael Roth ha scritto:
 On Fri, Oct 05, 2012 at 05:07:46PM +0200, Paolo Bonzini wrote:
 Il 04/10/2012 19:33, Michael Roth ha scritto:
 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
 ---
  qidl.h |  113 
 
  1 file changed, 113 insertions(+)
  create mode 100644 qidl.h

 diff --git a/qidl.h b/qidl.h
 new file mode 100644
 index 000..eae0202
 --- /dev/null
 +++ b/qidl.h
 @@ -0,0 +1,113 @@
 +/*
 + * QEMU IDL Macros/stubs
 + *
 + * See docs/qidl.txt for usage information.
 + *
 + * Copyright IBM, Corp. 2012
 + *
 + * Authors:
 + *  Michael Rothmdr...@linux.vnet.ibm.com
 + *
 + * This work is licensed under the terms of the GNU GPLv2 or later.
 + * See the COPYING file in the top-level directory.
 + *
 + */
 +
 +#ifndef QIDL_H
 +#define QIDL_H
 +
 +#include glib.h
 +#include qapi/qapi-visit-core.h
 +#include qemu/object.h
 +#include hw/qdev-properties.h
 +
 +#ifdef QIDL_GEN
 +
 +/* we pass the code through the preprocessor with QIDL_GEN defined to 
 parse
 + * structures as they'd appear after preprocessing, and use the following
 + * definitions mostly to re-insert the initial macros/annotations so they
 + * stick around for the parser to process
 + */
 +#define QIDL(...) QIDL(__VA_ARGS__)
 +#define QIDL_START(name, ...) QIDL_START(name, ##__VA_ARGS__)
 +
 +#define QIDL_VISIT_TYPE(name, v, s, f, e)
 +#define QIDL_SCHEMA_ADD_LINK(name, obj, path, errp)
 +#define QIDL_PROPERTIES(name)

 Ok, a few questions...

 Why do you need these to expand to nothing in the QIDL_GEN case?


 They don't need to, I was just trying to be explicit about what
 directives were relevant to the parser and which ones were relevant to
 the actually compiled code. It was more a development aid than
 anything else though, so I think we can drop the special handling and
 clean these up a bit.

 Yes, thanks!

 +#define QIDL_DECLARE(name, ...) \

 Can QIDL_DECLARE replace QIDL_ENABLED as the magic detection string for
 qidl compilation?


 In some cases the declarations will come via #include'd headers, so the
 only way to do that reliable is to run it through the preprocessor
 first, which is how things were done in v1. But running everything
 through cpp adds substantial overhead, and just because a QIDL-fied
 struct is included in a C file, it doesn't mean that the C file intends
 to use any qidl-generated code.

 Ok, I guess I need to see some example.  We can clean it up later if we
 find a more clever way to do things.
 
 This was the main example I hit (not yet rebased):
 
 https://github.com/mdroth/qemu/commit/d8ea7c7a882e2fcbd0a9b7ab9ea47a389f87d31b
 
 As part of that patch We add annotations to PCIDevice in pci.h, which then 
 gets
 pulled in from quite a few devices. So we end up with *.qidl.c files for 
 devices
 that don't expose a state property or even have a QIDL_DECLARE() directive.
 
 If we were to scan for QIDL_DECLARE() in advance of running it through
 the preprocessor, we'd address a lot of those case. But then we miss
 cases like this:
 
 https://github.com/mdroth/qemu/commit/2199f721daebd5c3961069bdd51de80a5b4fa827
 
 where, in pci.c, we use code generated from declarations in pci_internals.h 
 even
 though pci.c doesn't contain a QIDL_DECLARE()

Hmm, this opens another can of worms.  There is a substantial amount of
duplicated code between generated files.  For example,
visit_type_PCIDevice is found in all *.qidl.c files for PCI devices.
Worse, the same is true for the properties array.

Right now, QIDL_DECLARE is a no-op at code-generation time.  Could it be
a marker to generate code for that particular struct?  Then you would
put a normal

struct PCIDevice {
};

declaration in hw/pci.h, and a

QIDL_DECLARE(PCIDevice);

in hw/pci.c that would trigger creation of the visitor etc.  The code
generator can also prepare extern declarations for types that are used
but not defined, for example visit_type_PCIDevice in piix_pci.qidl.c.

Paolo



Re: [Qemu-devel] [PATCH v10 00/14] QEMU MIPS ASE DSP support

2012-10-15 Thread Andreas Färber
Am 15.10.2012 12:35, schrieb Jia Liu:
 ping~~ Aurelien
 
 Any more comment except the TODO one?

I briefly looked through 01-12 and nothing caught my eye.

Since you'll be resending anyway, could you rethink the subjects?
There's no directory target-mips-ase-dsp, just target-mips. Maybe
target-mips/dsp_helper: or target-mips: ASE DSP: or something?

Regards,
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 v3 1/9] serial: split serial.c

2012-10-15 Thread Anthony Liguori
Gerd Hoffmann kra...@redhat.com writes:

 Split serial.c into serial.c, serial.h and serial-isa.c.  While being at
 creating a serial.h header file move the serial prototypes from pc.h to
 the new serial.h.  The latter leads to s/pc.h/serial.h/ in tons of
 boards which just want the serial bits from pc.h

 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  hw/Makefile.objs |2 +-
  hw/alpha_dp264.c |1 +
  hw/kzm.c |2 +-
  hw/mips_fulong2e.c   |1 +
  hw/mips_jazz.c   |1 +
  hw/mips_malta.c  |1 +
  hw/mips_mipssim.c|2 +-
  hw/mips_r4k.c|1 +
  hw/musicpal.c|2 +-
  hw/omap_uart.c   |3 +-
  hw/openrisc_sim.c|3 +-
  hw/pc.c  |1 +
  hw/pc.h  |   27 -
  hw/petalogix_ml605_mmu.c |2 +-
  hw/ppc/e500.c|2 +-
  hw/ppc405_uc.c   |2 +-
  hw/ppc440_bamboo.c   |2 +-
  hw/ppc_prep.c|1 +
  hw/pxa2xx.c  |2 +-
  hw/serial-isa.c  |  130 +
  hw/serial.c  |  143 
 ++
  hw/serial.h  |   73 +++
  hw/sm501.c   |2 +-
  hw/sun4u.c   |1 +
  hw/virtex_ml507.c|2 +-
  hw/xtensa_lx60.c |3 +-
  26 files changed, 232 insertions(+), 180 deletions(-)
  create mode 100644 hw/serial-isa.c
  create mode 100644 hw/serial.h

 diff --git a/hw/Makefile.objs b/hw/Makefile.objs
 index 854faa9..16e7a1e 100644
 --- a/hw/Makefile.objs
 +++ b/hw/Makefile.objs
 @@ -20,7 +20,7 @@ common-obj-$(CONFIG_M48T59) += m48t59.o
  common-obj-$(CONFIG_ESCC) += escc.o
  common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
  
 -common-obj-$(CONFIG_SERIAL) += serial.o
 +common-obj-$(CONFIG_SERIAL) += serial.o serial-isa.o
  common-obj-$(CONFIG_PARALLEL) += parallel.o
  common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
  common-obj-$(CONFIG_PCSPK) += pcspk.o
 diff --git a/hw/alpha_dp264.c b/hw/alpha_dp264.c
 index 5ea04c7..8ce04e5 100644
 --- a/hw/alpha_dp264.c
 +++ b/hw/alpha_dp264.c
 @@ -15,6 +15,7 @@
  #include mc146818rtc.h
  #include ide.h
  #include i8254.h
 +#include serial.h
  
  #define MAX_IDE_BUS 2
  
 diff --git a/hw/kzm.c b/hw/kzm.c
 index 68cd1b4..1f3082b 100644
 --- a/hw/kzm.c
 +++ b/hw/kzm.c
 @@ -21,7 +21,7 @@
  #include net.h
  #include sysemu.h
  #include boards.h
 -#include pc.h /* for the FPGA UART that emulates a 16550 */
 +#include serial.h
  #include imx.h
  
  /* Memory map for Kzm Emulation Baseboard:
 diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
 index d4a8672..a3cb3ab 100644
 --- a/hw/mips_fulong2e.c
 +++ b/hw/mips_fulong2e.c
 @@ -20,6 +20,7 @@
  
  #include hw.h
  #include pc.h
 +#include serial.h
  #include fdc.h
  #include net.h
  #include boards.h
 diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
 index db927f1..d35cd54 100644
 --- a/hw/mips_jazz.c
 +++ b/hw/mips_jazz.c
 @@ -26,6 +26,7 @@
  #include mips.h
  #include mips_cpudevs.h
  #include pc.h
 +#include serial.h
  #include isa.h
  #include fdc.h
  #include sysemu.h
 diff --git a/hw/mips_malta.c b/hw/mips_malta.c
 index 632b466..8f73b1b 100644
 --- a/hw/mips_malta.c
 +++ b/hw/mips_malta.c
 @@ -24,6 +24,7 @@
  
  #include hw.h
  #include pc.h
 +#include serial.h
  #include fdc.h
  #include net.h
  #include boards.h
 diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
 index 830f635..0ee6756 100644
 --- a/hw/mips_mipssim.c
 +++ b/hw/mips_mipssim.c
 @@ -27,7 +27,7 @@
  #include hw.h
  #include mips.h
  #include mips_cpudevs.h
 -#include pc.h
 +#include serial.h
  #include isa.h
  #include net.h
  #include sysemu.h
 diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
 index 967a76e..b3be80b 100644
 --- a/hw/mips_r4k.c
 +++ b/hw/mips_r4k.c
 @@ -11,6 +11,7 @@
  #include mips.h
  #include mips_cpudevs.h
  #include pc.h
 +#include serial.h
  #include isa.h
  #include net.h
  #include sysemu.h
 diff --git a/hw/musicpal.c b/hw/musicpal.c
 index f305e21..346fe41 100644
 --- a/hw/musicpal.c
 +++ b/hw/musicpal.c
 @@ -15,7 +15,7 @@
  #include net.h
  #include sysemu.h
  #include boards.h
 -#include pc.h
 +#include serial.h
  #include qemu-timer.h
  #include ptimer.h
  #include block.h
 diff --git a/hw/omap_uart.c b/hw/omap_uart.c
 index 167d5c4..1c16a54 100644
 --- a/hw/omap_uart.c
 +++ b/hw/omap_uart.c
 @@ -20,8 +20,7 @@
  #include qemu-char.h
  #include hw.h
  #include omap.h
 -/* We use pc-style serial ports.  */
 -#include pc.h
 +#include serial.h
  #include exec-memory.h
  
  /* UARTs */
 diff --git a/hw/openrisc_sim.c b/hw/openrisc_sim.c
 index 55e97f0..e484613 100644
 --- a/hw/openrisc_sim.c
 +++ b/hw/openrisc_sim.c
 @@ -21,7 +21,8 @@
  #include hw.h
  #include boards.h
  #include elf.h
 -#include pc.h
 +#include serial.h
 +#include net.h
  #include loader.h
  #include exec-memory.h
  #include sysemu.h
 diff --git a/hw/pc.c b/hw/pc.c
 index 

Re: [Qemu-devel] [PATCH 2/8] console: add unregister_displaychangelistener

2012-10-15 Thread Andreas Färber
Am 15.10.2012 11:51, schrieb Gerd Hoffmann:
 Also change the way the gui_timer is initialized: each time a
 displaychangelistener is registered or unregistered we'll check
 whenever we need a timer (due to dpy_refresh callback being present)

whether

 and if so setup a timer, otherwise zap it.  This way the gui timer works
 correctly with displaychangelisteners coming and going.
 
 Signed-off-by: Gerd Hoffmann kra...@redhat.com

Logic looks okay to me.

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 v3 4/9] serial: add 2x + 4x pci variant

2012-10-15 Thread Anthony Liguori
Gerd Hoffmann kra...@redhat.com writes:

 Add multiport serial card implementation, with two variants,
 one featuring two and one featuring four ports.

 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  docs/qemupciserial.inf |2 +
  hw/serial-pci.c|  157 
 
  2 files changed, 159 insertions(+), 0 deletions(-)

 diff --git a/docs/qemupciserial.inf b/docs/qemupciserial.inf
 index c7cea99..3474310 100644
 --- a/docs/qemupciserial.inf
 +++ b/docs/qemupciserial.inf
 @@ -11,6 +11,8 @@
  ; (Com+Lpt) from the list.  Click Have a disk.  Select this file.
  ; Procedure may vary a bit depending on the windows version.
  
 +; FIXME: This file covers the single port version only.
 +
  [Version]
  Signature=$CHICAGO$
  Class=Ports
 diff --git a/hw/serial-pci.c b/hw/serial-pci.c
 index 17247a8..c89e8b0 100644
 --- a/hw/serial-pci.c
 +++ b/hw/serial-pci.c
 @@ -28,6 +28,14 @@
   *pci region 0 is a io bar, 8 bytes long, with the 16550 uart mapped to 
 it.
   *interrupt is wired to pin A.
   *
 + * pci-serial-4x spec:
 + *pci region 0 is a io bar, with four 16550 uarts mapped after each 
 other,
 + *the first at offset 0, second at 8, third at 16 and fourth at 24.
 + *interrupt is wired to pin A.
 + *
 + * pci-serial-2x spec:
 + *same as pci-serial-4x but with two uarts only.
 + *

I know I neglected to respond to your previous note in this thread, but
I'd prefer this be made a file in docs/.

That way, you can look in docs and discover all of the QEMU-invented
devices.  Having to troll through hw/*.c to find which new devices were
added is a bit painful.

This is important for people looking to implement guest support for
QEMU.

Regards,

Anthony Liguori

   * [root@fedora ~]# lspci -vnse
   * 00:0e.0 0700: 1b36:0002 (rev 01) (prog-if 00 [8250])
   * Subsystem: 1af4:1100
 @@ -40,11 +48,23 @@
  #include serial.h
  #include pci.h
  
 +#define PCI_SERIAL_MAX_PORTS 4
 +
  typedef struct PCISerialState {
  PCIDevice dev;
  SerialState state;
  } PCISerialState;
  
 +typedef struct PCIMultiSerialState {
 +PCIDevicedev;
 +MemoryRegion iobar;
 +uint32_t ports;
 +char *name[PCI_SERIAL_MAX_PORTS];
 +SerialState  state[PCI_SERIAL_MAX_PORTS];
 +uint32_t level[PCI_SERIAL_MAX_PORTS];
 +qemu_irq *irqs;
 +} PCIMultiSerialState;
 +
  static int serial_pci_init(PCIDevice *dev)
  {
  PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
 @@ -61,6 +81,56 @@ static int serial_pci_init(PCIDevice *dev)
  return 0;
  }
  
 +static void multi_serial_irq_mux(void *opaque, int n, int level)
 +{
 +PCIMultiSerialState *pci = opaque;
 +int i, pending = 0;
 +
 +pci-level[n] = level;
 +for (i = 0; i  pci-ports; i++) {
 +if (pci-level[i]) {
 +pending = 1;
 +}
 +}
 +qemu_set_irq(pci-dev.irq[0], pending);
 +}
 +
 +static int multi_serial_pci_init(PCIDevice *dev)
 +{
 +PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
 +PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
 +SerialState *s;
 +int i;
 +
 +switch (pc-device_id) {
 +case 0x0003:
 +pci-ports = 2;
 +break;
 +case 0x0004:
 +pci-ports = 4;
 +break;
 +}
 +assert(pci-ports  0);
 +assert(pci-ports = PCI_SERIAL_MAX_PORTS);
 +
 +pci-dev.config[PCI_INTERRUPT_PIN] = 0x01;
 +memory_region_init(pci-iobar, multiserial, 8 * pci-ports);
 +pci_register_bar(pci-dev, 0, PCI_BASE_ADDRESS_SPACE_IO, pci-iobar);
 +pci-irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci,
 +   pci-ports);
 +
 +for (i = 0; i  pci-ports; i++) {
 +s = pci-state + i;
 +s-baudbase = 115200;
 +serial_init_core(s);
 +s-irq = pci-irqs[i];
 +pci-name[i] = g_strdup_printf(uart #%d, i+1);
 +memory_region_init_io(s-io, serial_io_ops, s, pci-name[i], 8);
 +memory_region_add_subregion(pci-iobar, 8 * i, s-io);
 +}
 +return 0;
 +}
 +
  static void serial_pci_exit(PCIDevice *dev)
  {
  PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev);
 @@ -70,6 +140,22 @@ static void serial_pci_exit(PCIDevice *dev)
  memory_region_destroy(s-io);
  }
  
 +static void multi_serial_pci_exit(PCIDevice *dev)
 +{
 +PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev);
 +SerialState *s;
 +int i;
 +
 +for (i = 0; i  pci-ports; i++) {
 +s = pci-state + i;
 +serial_exit_core(s);
 +memory_region_destroy(s-io);
 +g_free(pci-name[i]);
 +}
 +memory_region_destroy(pci-iobar);
 +qemu_free_irqs(pci-irqs);
 +}
 +
  static const VMStateDescription vmstate_pci_serial = {
  .name = pci-serial,
  .version_id = 1,
 @@ -81,11 +167,38 @@ static const VMStateDescription vmstate_pci_serial = {
  }
  };
  
 +static const VMStateDescription vmstate_pci_multi_serial = {
 +.name 

Re: [Qemu-devel] [PATCH v3 9/9] chardev: add hotplug support.

2012-10-15 Thread Anthony Liguori
Gerd Hoffmann kra...@redhat.com writes:

 This patch adds chardev_add and chardev_del monitor commands.

 They work simliar to the netdev_{add,del} commands.  The hmp version of
 chardev_add accepts like the -chardev command line option does.  The qmp
 version expects the arguments being passed as named parameters.

 chardev_del just takes an id argument and zaps the chardev specified.

 Signed-off-by: Gerd Hoffmann kra...@redhat.com
 ---
  hmp-commands.hx  |   32 
  hmp.c|   23 
  hmp.h|2 +
  qapi-schema.json |   39 ++
  qemu-char.c  |   44 ++
  qemu-char.h  |1 +
  qmp-commands.hx  |   61 
 ++
  7 files changed, 202 insertions(+), 0 deletions(-)

 diff --git a/hmp-commands.hx b/hmp-commands.hx
 index e0b537d..48504d1 100644
 --- a/hmp-commands.hx
 +++ b/hmp-commands.hx
 @@ -1404,6 +1404,38 @@ passed since 1970, i.e. unix epoch.
  ETEXI
  
  {
 +.name   = chardev_add,
 +.args_type  = args:s,
 +.params = args,
 +.help   = add chardev,
 +.mhandler.cmd = hmp_chardev_add,
 +},

Should be chardev-add at this point.

 +
 +STEXI
 +@item chardev_add args
 +@findex chardev_add
 +
 +chardev_add accepts the same parameters as the -chardev command line switch.
 +
 +ETEXI
 +
 +{
 +.name   = chardev_del,
 +.args_type  = id:s,
 +.params = id,
 +.help   = del chardev,
 +.mhandler.cmd = hmp_chardev_del,
 +},
 +
 +STEXI
 +@item chardev_del id
 +@findex chardev_del
 +
 +Removes the chardev @var{id}.
 +
 +ETEXI
 +
 +{
  .name   = info,
  .args_type  = item:s?,
  .params = [subcommand],
 diff --git a/hmp.c b/hmp.c
 index 70bdec2..96bb900 100644
 --- a/hmp.c
 +++ b/hmp.c
 @@ -1209,3 +1209,26 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict)
  qmp_screendump(filename, err);
  hmp_handle_error(mon, err);
  }
 +
 +void hmp_chardev_add(Monitor *mon, const QDict *qdict)
 +{
 +const char *args = qdict_get_str(qdict, args);
 +Error *err = NULL;
 +QemuOpts *opts;
 +
 +opts = qemu_opts_parse(qemu_find_opts(chardev), args, 1);
 +if (opts == NULL) {
 +error_setg(err, Parsing chardev args failed\n);
 +} else {
 +qemu_chr_new_from_opts(opts, NULL, err);
 +}
 +hmp_handle_error(mon, err);
 +}
 +
 +void hmp_chardev_del(Monitor *mon, const QDict *qdict)
 +{
 +Error *err = NULL;
 +qmp_chardev_del(qdict_get_str(qdict, id),
 +err);
 +hmp_handle_error(mon, err);
 +}
 diff --git a/hmp.h b/hmp.h
 index 71ea384..080afaa 100644
 --- a/hmp.h
 +++ b/hmp.h
 @@ -75,5 +75,7 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
  void hmp_closefd(Monitor *mon, const QDict *qdict);
  void hmp_send_key(Monitor *mon, const QDict *qdict);
  void hmp_screen_dump(Monitor *mon, const QDict *qdict);
 +void hmp_chardev_add(Monitor *mon, const QDict *qdict);
 +void hmp_chardev_del(Monitor *mon, const QDict *qdict);
  
  #endif
 diff --git a/qapi-schema.json b/qapi-schema.json
 index f9dbdae..550e4c7 100644
 --- a/qapi-schema.json
 +++ b/qapi-schema.json
 @@ -2796,3 +2796,42 @@
  # Since: 0.14.0
  ##
  { 'command': 'screendump', 'data': {'filename': 'str'} }
 +
 +##
 +# @chardev_add:
 +#
 +# Add a chardev
 +#
 +# @id: the chardev's ID, must be unique
 +# @backend: the chardev backend: file, socket, ...
 +# @path: file / device / unix socket path
 +# @name: spice channel name
 +# @host: host name
 +# @port: port number
 +# @server: create socket in server mode
 +# @wait: wait for connect
 +# @ipv4: force ipv4-only
 +# @ipv6: force ipv6-only
 +# @telnet: telnet negotiation

If we're documenting all of the options, then we probably should specify
them in the schema.  It's a little more cumbersome with QemuOpts, but it
makes the schema more correct wrt the implementation.

Regards,

Anthony Liguori

 +#
 +# Returns: Nothing on success
 +#
 +# Since: 1.3.0
 +##
 +{ 'command': 'chardev_add', 'data': {'id'  : 'str',
 + 'backend' : 'str',
 + '*props'  : '**' },
 +  'gen': 'no' }
 +
 +##
 +# @chardev_del:
 +#
 +# Remove a chardev
 +#
 +# @id: the chardev's ID, must exist and not be in use
 +#
 +# Returns: Nothing on success
 +#
 +# Since: 1.3.0
 +##
 +{ 'command': 'chardev_del', 'data': {'id': 'str'} }
 diff --git a/qemu-char.c b/qemu-char.c
 index be4ec61..dae3e3c 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -2911,3 +2911,47 @@ CharDriverState *qemu_char_get_next_serial(void)
  return serial_hds[next_serial++];
  }
  
 +int qmp_chardev_add(Monitor *mon, const QDict *qdict, QObject **ret)
 +{
 +Error *err = NULL;
 +QemuOptsList *opts_list;
 +QemuOpts *opts;
 +
 +opts_list = qemu_find_opts_err(chardev, err);
 +if 

Re: [Qemu-devel] delvm does not reduce the qcow2 file size

2012-10-15 Thread Kevin Wolf
Am 15.10.2012 15:25, schrieb Paolo Bonzini:
 Il 15/10/2012 11:33, Kuniyasu Suzaki ha scritto:
 Hello,

 delvm is a command to delete a snapshot image in a qcow2 file.
 However it does not reduce the qcow2 file size.
 
 Note that the file will not grow when new allocations are performed in
 the future.
 
 QEMU should also convert the unused clusters to holes in the file
 system, but it doesn't do that yet.
 
 Is there any method to reduce the qcow2 file size when I delete a snapshot 
 image?
 should I convert the qcow2 file?
 
 I'm not sure what convert does if you have internal snapshots.

It loses the snapshots.

Kevin



Re: [Qemu-devel] Connecting virtio-9p-pci to a remote 9p server

2012-10-15 Thread Troy Benjegerdes
On Mon, Oct 15, 2012 at 12:36:08PM +0100, Chris Webb wrote:
 We're planning to implement shared filesystems for guests on our virtualized
 hosting platform, stored on a central fileserver separate from the hosts.
 
 Whilst we can mount the shares on each host and then use qemu's 9p
 passthrough/proxy support to access the mountpoint, going via the host
 kernel and vfs like this feels quite inefficient. We would be converting
 back and forth between vfs and 9p models several times needlessly.
 
 Instead, I'm wondering about the feasibility of connecting the 9p stream
 directly from qemu's virtio-9p-pci device to a socket opened on a
 9p-over-TCP export from the fileserver. Am I right in thinking that qemu's
 -fsdev proxy gives me access to a file descriptor attached to the 9p stream
 to/from the guest, or is the protocol between virtfs-proxy-helper and qemu
 re-encoded within qemu first?
 
 Secondly, assuming I can somehow get at the 9p streams directly (either with
 an existing option or by adding a new one), I'd like to restrict guests to
 the relevant user's subdirectory on the fileserver, and have been thinking
 about doing this by filtering the 9p stream to restrict 'attach' operations.
 
 Fortunately, 9p uses client-chosen fids rather than server filesystem inode
 numbers which would immediately scupper any simple attempts to implement a
 secure chroot proxy of this kind. Looking at the 9p2000.L protocol, it
 doesn't look obviously difficult, but I've not really worked with 9p before,
 and could well be missing security complications. (I'm not sure whether
 there's risk of symlinks being interpreted server side rather than client
 side, for example.)
 
 I'd also be interested in any more general thoughts on this kind of thing.
 If we're going to work on it, it would be nice for us to write something
 that would be more widely useful to others rather than just create an
 in-house hack.
 
 Cheers,
 
 Chris.
 

If scalability and security are long-term goals, I'd suggest you take a look
at OpenAFS (openafs.org). There are other complications, in that you start 
getting into stuff like how to authenticate your users to the filesystem, but
imho, it's a PITA to switch and get used to this model, but once you do, you
don't have to worry about if you've got some complicated (and one-off) security
filtering configured right.

I've been playing with booting debian kernels  initrds directly from AFS as
the root filesystem ( http://bitspjoule.org/hg/initramfs-tools ). What's nice
(and also a PITA) is that normally the VM client cannot modify the root
filesystem, so I know there's no magic configuration on some VM disk image,
but if I wanted to make a change to multiple VMs, I could authenticate to 
AFS as administrator on one of the nodes, make the change, and then restart
the daemons on all the other VMs to load the new change.

The other (potential) advantage of AFS in a virtualized environment is client
side caching, so instead of VM disk image for the OS, and worrying about
backing it up, you just use that disk image as the client-side cache local to
the VM host machine. The actual authoritative data is stored on the AFS server,
so if you have it cached locally, you never have to hit the network, and if the
disk the cache is on dies, you just restart the VM on a different disk. (If 
you wanted to go overboard, you could modify the client-caching code to go
back to the server if the cache gets a read error)

I can't say that AFS has really *solved* all the hard problems with this, but
there is at least some history on how to effectively deal with them. With what
you are describing with 9p in a production environment, I think you'll end up
re-discovering all the hard problems and have to invent new 9p-specific ways
of dealing with them, and you'll end up with the same complexity as AFS.

- Troy



Re: [Qemu-devel] fixing qemu-0.1X endless loop in qcow2_alloc_cluster_offset

2012-10-15 Thread Andreas Färber
Am 15.10.2012 11:13, schrieb Kevin Wolf:
 Am 12.10.2012 17:52, schrieb Andreas Färber:
 Am 12.06.2012 15:44, schrieb Kevin Wolf:
 Am 12.06.2012 15:33, schrieb Andreas Färber:
 Am 14.05.2012 14:20, schrieb Kevin Wolf:
 Am 13.05.2012 10:03, schrieb Zhouyi Zhou:
   sometimes, qemu/kvm-0.1x will hang in endless loop in 
 qcow2_alloc_cluster_offset.

 The patch looks reasonable to me. Note however that while it fixes the
 hang, it still causes cluster leaks. I'm not sure if someone is
 interested in picking these up for old stable releases. Andreas, I think
 you were going to take 0.15? The first version that doesn't have the
 problem is 1.0.

 It's fixed as a side effect of the block layer conversion to
 coroutines. Not exactly the kind of patches you'd want to cherry-pick
 for stable-0.15.

 The better fix for 0.15 could be to backport the new behaviour of
 coroutine based requests with bdrv_aio_cancel:

 static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
 {
 qemu_aio_flush();
 }

 Using that as the implementation for qcow2_aio_cancel should be safe and
 fix this problem.

 [...] stable-0.15 does not have coroutines, so I don't
 understand what exactly you're suggesting as alternative here: Backport
 the whole coroutine feature including coroutine function above? Or just
 call qemu_aio_flush() in place of what? This is old qcow2_aio_cancel():
 
 No, that was qcow2_aio_flush. ;-)

Ugh, what a copy-and-paste error... ;-)

 What I'm suggesting (not even compile tested!) is:
 
 Signed-off-by: Kevin Wolf kw...@redhat.com
 
 diff --git a/block/qcow2.c b/block/qcow2.c
 index 48e1b95..d665675 100644
 --- a/block/qcow2.c
 +++ b/block/qcow2.c
 @@ -388,10 +388,7 @@ typedef struct QCowAIOCB {
 
  static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
  {
 -QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
 -if (acb-hd_aiocb)
 -bdrv_aio_cancel(acb-hd_aiocb);
 -qemu_aio_release(acb);
 +qemu_aio_flush();
  }
 
  static AIOPool qcow2_aio_pool = {

Compiles fine. Is there a particular test case to invoke this code path?

Does this attempt to fix the cluster leaks you mentioned as well, or
just the cluster allocation endless loop?

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] fixing qemu-0.1X endless loop in qcow2_alloc_cluster_offset

2012-10-15 Thread Kevin Wolf
Am 15.10.2012 16:28, schrieb Andreas Färber:
 What I'm suggesting (not even compile tested!) is:

 Signed-off-by: Kevin Wolf kw...@redhat.com

 diff --git a/block/qcow2.c b/block/qcow2.c
 index 48e1b95..d665675 100644
 --- a/block/qcow2.c
 +++ b/block/qcow2.c
 @@ -388,10 +388,7 @@ typedef struct QCowAIOCB {

  static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
  {
 -QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
 -if (acb-hd_aiocb)
 -bdrv_aio_cancel(acb-hd_aiocb);
 -qemu_aio_release(acb);
 +qemu_aio_flush();
  }

  static AIOPool qcow2_aio_pool = {
 
 Compiles fine. Is there a particular test case to invoke this code path?

As far as I know, the common way to get this were IDE resets. However,
I'm not sure what you need to do with a Linux guest if you want it to
reset the IDE controller...

 Does this attempt to fix the cluster leaks you mentioned as well, or
 just the cluster allocation endless loop?

Instead of cancelling the in-flight requests it waits for their
completion, so in the end we should be in an consistent state without
cluster leaks.

Kevin



Re: [Qemu-devel] [PATCH v3 22/22] qidl: unit tests and build infrastructure

2012-10-15 Thread Michael Roth
On Mon, Oct 15, 2012 at 10:52:37AM +0200, Kevin Wolf wrote:
 Am 12.10.2012 23:39, schrieb Michael Roth:
  On Fri, Oct 05, 2012 at 10:24:30AM +0200, Paolo Bonzini wrote:
  Il 04/10/2012 19:33, Michael Roth ha scritto:
  +
  +%.qidl.c: %.c $(SRC_PATH)/qidl.h $(addprefix 
  $(SRC_PATH)/scripts/,lexer.py qidl.py qidl_parser.py qapi.py 
  qapi_visit.py)
  + $(call rm -f $(*D)/qidl-generated/$(*F).qidl.c)
  + $(if $(strip $(shell grep QIDL_ENABLE() $ 1/dev/null  echo 
  true)), \
  +   $(call quiet-command, \
  + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -E -c -DQIDL_GEN $ 
  | \
  + $(PYTHON) $(SRC_PATH)/scripts/qidl.py \
  + --output-filepath=$(*D)/qidl-generated/$(*F).qidl.c || [ $$? -eq 
  2 ], \
  + qidl PP $(*D)/$(*F).c),)
  +%.o: %.c %.qidl.c
  + $(if $(strip $(shell test -f $(*D)/qidl-generated/$(*F).qidl.c  echo 
  true)), \
  +   $(call quiet-command, \
  + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
  + -DQIDL_ENABLED -include $ -o $@ 
  $(*D)/qidl-generated/$(*F).qidl.c, \
  + qidl CC $@), \
  +   $(call quiet-command, \
  + $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
  +   -o $@ $,  CC$@))
 
 
  Because the .qidl.c files are not created for files without a QIDL_ENABLE()
  directive, all those files will be grepped on every invocation of the 
  makefile.
 
  It is better to define the list of QIDL_ENABLEd files in an auxiliary 
  makefile
  like this (untested):
  
  Thanks for the suggestion / example.
  
  FYI, I tried to get this working but didn't manage to get it in for v4. 
  Everything
  seems to be falling back to the non-qidl %o: target, and I haven't had time 
  to
  debug it.
  
  FWIW, it doesn't seem to be a major factor performance-wise. Current build
  times on my laptop are (for all-target builds):
  
  QIDL v4:
   real8m35.383s
   user31m1.844s
   sys 1m33.998s
  
  upstream:
   real8m28.181s
   user30m44.983s
   sys 1m29.926s
 
 Isn't the more interesting case that I only touched block/qcow2.c and
 run make to update my binaries? I haven't really looked at the code, but
 Paolo's comment suggests that even in this case a lot of files would be
 grepped, and I think that losing a few seconds in such cases would
 really hurt.

True, that's the more interesting case and I missed that point in
my response (had actually thought Paolo was driving at making
qemu-idl-files.mak a top-level target to avoid re-grepping on each
--target-list entry's build)

But Paolo posted some clarification in the v4 comments for this patch
on why this isn't the case for individual compilation units. The re-grep
would only occur for cases where the .c file changes, or something else
that might affect the output of the code generators changed
(scripts/(qidl|qapi)*, qidl.h, etc.). So in your example only
block/qcow2.c would be re-grepped.

 
 Kevin
 



Re: [Qemu-devel] [libvirt] Problems using netdev_del+netdev_add w/o corresponding device_del+device_add

2012-10-15 Thread Laine Stump
On 10/15/2012 05:25 AM, Daniel P. Berrange wrote:
 On Mon, Oct 15, 2012 at 10:30:07AM +0200, Stefan Hajnoczi wrote:
 On Sat, Oct 13, 2012 at 04:47:14PM -0400, Laine Stump wrote:
 Here is the sequence sent to disconnect only the host side, then
 reconnect it with a new tap device. (although the fd is the same, this
 is because the old tap device had already been closed, so the number is
 just being used - the same thing happens when doing sequential full
 detach/attach cycles, and they all work with no problems):


 168.750  0x7f8e2c90
 {execute:netdev_del,arguments:{id:hostnet0},id:libvirt-30}
 168.762  0x7f8e2c90 {return: {}, id: libvirt-30}
 168.800  0x7f8e2c90
 {execute:getfd,arguments:{fdname:fd-net0},id:libvirt-31}
 (fd=27)
 168.801  0x7f8e2c90 {return: {}, id: libvirt-31}
 168.801  0x7f8e2c90
 {execute:netdev_add,arguments:{type:tap,fd:fd-net0,id:hostnet0},id:libvirt-32}
 168.802  0x7f8e2c90 {return: {}, id: libvirt-32}
 168.802  0x7f8e2c90
 {execute:set_link,arguments:{name:net0,up:true},id:libvirt-33}
 168.803  0x7f8e2c90 {return: {}, id: libvirt-33}

 After this sequence is done, everything about the network device
 *appears* normal on both the guest and host (at least the things I know
 to look at), but no traffic from the host shows up in a tcpdump of the
 interface on the guest, and no traffic from the guest shows up in a
 tcpdump of the tap device on the host.
 What you are trying to do isn't possible today.

Well, at least it's good to know that I should stop trying to make it
work :-)

Actually, it's a bit disconcerting that 1) the act of creating a guest
device is split into two commands, implying that they don't necessarily
have a hardwired a--b relationship although that is the case, and that
2) netdev_add even returns success when you use it in this way. Although
hindsight is 20/20 and all that, if both a and b are required, and must
always be in the same order, wouldn't it have made more sense for the
two steps to be a single command? I suppose this is a byproduct of the
monitor commands being a direct reflection ot the commandline options.
(At the very least, though, I think netdev_add should report an error if
the device name alias it uses is already in use by a device.)


 The device associates with the netdev during initialization only - there
 is no command to associate at a later point in time.  That is why your
 example works only when the device is deleted together with the netdev.

 It is certainly possible to implement a command to switch netdevs

At this point yes, it would be better to have a new command rather than
to make netdev_add work in the way I've attempted - this way there would
be a new command whose presence libvirt could use to decide whether or
not to support this functionality.

  but
 I'm curious what the use case is.  Is this necessary just because QEMU
 doesn't provide a way to modify the existing netdev or because you
 really want to switch to a completely different netdev?
 We have end users who want to be able to dynamically change the guest'
 networking attachment, without restarting/hotplugging devices in the
 guest[1]. If it is just a case of changing from one bridge, to another
 bridge we can do that just by moving the TAP Device from one to another.
 This doesn't work if we want to support more general changes in config.
 eg from a macvtap setup to a TAP setup, or vica-verca.

Beyond that, I haven't determined it conclusively yet, but it so far
looks to me like a macvtap device can only be linked to a physdev when
it is created - there is no netlink message to re-link it to a different
physdev (this is based on my naive examination of the relevant kernel
source). So if you want to change the attach point for a macvtap-type
connection, you again need to discard the old macvtap device and create
a new one, implying that you need to do a new netdev_add.




  1   2   >