Re: [Qemu-devel] [PATCH 2/3] Compile vl.c once

2010-05-04 Thread TeLeMan
This patch breaks cpu list(-cpu ?).

--
SUN OF A BEACH



On Fri, Apr 16, 2010 at 03:08, Blue Swirl blauwir...@gmail.com wrote:
 Since kvm.h can be used in files compiled once,
 we can partially revert
 b33612d03540fda7fa67485f1c20395beb7a2bf0.

 Signed-off-by: Blue Swirl blauwir...@gmail.com
 ---
  Makefile.objs   |    2 +-
  Makefile.target |    2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

 diff --git a/Makefile.objs b/Makefile.objs
 index ab1af88..c0fe5e2 100644
 --- a/Makefile.objs
 +++ b/Makefile.objs
 @@ -128,7 +128,7 @@ user-obj-y += cutils.o cache-utils.o
  # libhw

  hw-obj-y =
 -hw-obj-y += loader.o
 +hw-obj-y += vl.o loader.o
  hw-obj-y += virtio.o virtio-console.o
  hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o
  hw-obj-y += watchdog.o
 diff --git a/Makefile.target b/Makefile.target
 index 34ceed6..3bd4b86 100644
 --- a/Makefile.target
 +++ b/Makefile.target
 @@ -162,7 +162,7 @@ endif #CONFIG_BSD_USER
  # System emulator target
  ifdef CONFIG_SOFTMMU

 -obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o vl.o balloon.o
 +obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
  # virtio has to be here due to weird dependency between PCI and virtio-net.
  # need to fix this properly
  obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
 --
 1.6.2.4







Re: [Qemu-devel] Re: [PATCH] virtio-spec: document block CMD and FLUSH

2010-05-04 Thread Stefan Hajnoczi
A userspace barrier API would be very useful instead of doing fsync when
only ordering is required. I'd like to follow that discussion too.

Stefan

On 4 May 2010 05:39, Rusty Russell ru...@rustcorp.com.au wrote:

On Fri, 19 Feb 2010 08:52:20 am Michael S. Tsirkin wrote:
 I took a stub at documenting CMD and FLU...
ISTR Christoph had withdrawn some patches in this area, and was waiting
for him to resubmit?

I've given up on figuring out the block device.  What seem to me to be sane
semantics along the lines of memory barriers are foreign to disk people:
they
want (and depend on) flushing everywhere.

For example, tdb transactions do not require a flush, they only require what
I would call a barrier: that prior data be written out before any future
data.
Surely that would be more efficient in general than a flush!  In fact, TDB
wants only writes to *that file* (and metadata) written out first; it has no
ordering issues with other I/O on the same device.

A generic I/O interface would allow you to specify this request depends on
these
outstanding requests and leave it at that.  It might have some sync flush
command for dumb applications and OSes.  The userspace API might be not be
as
precise and only allow such a barrier against all prior writes on this fd.

ISTR someone mentioning a desire for such an API years ago, so CC'ing the
usual I/O suspects...

Cheers,
Rusty.


[Qemu-devel] [PATCH v4 1/5] char: Let writers know how much data was written in case of errors

2010-05-04 Thread Amit Shah
On writing errors, we just returned -1 even if some bytes were already
written out. Ensure we return the number of bytes written before we
return the error (on a subsequent call to qemu_chr_write()).

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 qemu-char.c |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index ac65a1c..bc76000 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -522,8 +522,13 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
 while (len  0) {
 ret = write(fd, buf, len);
 if (ret  0) {
-if (errno != EINTR  errno != EAGAIN)
-return -1;
+if (errno != EINTR  errno != EAGAIN) {
+if (len1 - len) {
+return len1 - len;
+} else {
+return -1;
+}
+}
 } else if (ret == 0) {
 break;
 } else {
-- 
1.6.2.5





[Qemu-devel] [PATCH v4 3/5] char: unix/tcp: Add a non-blocking write handler

2010-05-04 Thread Amit Shah
Add a non-blocking write handler that can return with -EAGAIN to the
caller and also callback when the socket becomes writable.

Non-blocking writes are only enabled for sockets that are opened in
non-blocking mode and only for callers that have registered a callback
handler for resuming writes.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 qemu-char.c |   50 ++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 1cae1d2..476bb4e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2117,11 +2117,60 @@ static void tcp_chr_read(void *opaque)
 }
 }
 
+static void tcp_chr_write_unblocked(void *opaque)
+{
+CharDriverState *chr = opaque;
+TCPCharDriver *s = chr-opaque;
+
+assert(chr-write_blocked  chr-chr_write_unblocked);
+
+chr-write_blocked = false;
+qemu_set_fd_handler2(s-fd, tcp_chr_read_poll, tcp_chr_read, NULL, chr);
+chr-chr_write_unblocked(chr-handler_opaque);
+}
+
+static ssize_t tcp_chr_write_nb(CharDriverState *chr, const uint8_t *buf,
+size_t len)
+{
+TCPCharDriver *s = chr-opaque;
+ssize_t ret;
+
+if (!s-connected) {
+/* XXX: indicate an error? */
+return len;
+}
+
+ret = send_all(s-fd, buf, len, true);
+if (ret == -EAGAIN) {
+chr-write_blocked = true;
+qemu_set_fd_handler2(s-fd, tcp_chr_read_poll,
+ tcp_chr_read, tcp_chr_write_unblocked, chr);
+}
+return ret;
+}
+
 static void tcp_chr_connect(void *opaque)
 {
 CharDriverState *chr = opaque;
 TCPCharDriver *s = chr-opaque;
+IOHandler *write_cb;
+int flags;
+bool nonblock;
+
+flags = fcntl(s-fd, F_GETFL);
+if (flags == -1) {
+flags = 0;
+}
+nonblock = flags  O_NONBLOCK;
+
+write_cb = NULL;
+chr-nonblock = false;
+if (nonblock  chr-chr_write_unblocked) {
+write_cb = chr-chr_write_unblocked;
+chr-nonblock = true;
+}
 
+chr-write_blocked = false;
 s-connected = 1;
 qemu_set_fd_handler2(s-fd, tcp_chr_read_poll,
  tcp_chr_read, NULL, chr);
@@ -2254,6 +2303,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts 
*opts)
 
 chr-opaque = s;
 chr-chr_write = tcp_chr_write;
+chr-chr_write_nb = tcp_chr_write_nb;
 chr-chr_close = tcp_chr_close;
 chr-get_msgfd = tcp_get_msgfd;
 
-- 
1.6.2.5





[Qemu-devel] [PATCH v4 4/5] virtio-console: Factor out common init between console and generic ports

2010-05-04 Thread Amit Shah
The initialisation for generic ports and console ports is similar.
Factor out the parts that are the same in a different function that can
be called from each of the initfns.

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

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 2bccdd0..1552f47 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -58,24 +58,28 @@ static void chr_event(void *opaque, int event)
 }
 }
 
-/* Virtio Console Ports */
-static int virtconsole_initfn(VirtIOSerialDevice *dev)
+static int generic_port_init(VirtConsole *vcon, VirtIOSerialDevice *dev)
 {
-VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
-VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
-port-info = dev-info;
-
-port-is_console = true;
+vcon-port.info = dev-info;
 
 if (vcon-chr) {
 qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read,
   NULL, chr_event, vcon);
-port-info-have_data = flush_buf;
+vcon-port.info-have_data = flush_buf;
 }
 return 0;
 }
 
+/* Virtio Console Ports */
+static int virtconsole_initfn(VirtIOSerialDevice *dev)
+{
+VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
+VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+port-is_console = true;
+return generic_port_init(vcon, dev);
+}
+
 static int virtconsole_exitfn(VirtIOSerialDevice *dev)
 {
 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
@@ -115,14 +119,7 @@ static int virtserialport_initfn(VirtIOSerialDevice *dev)
 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-port-info = dev-info;
-
-if (vcon-chr) {
-qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read,
-  NULL, chr_event, vcon);
-port-info-have_data = flush_buf;
-}
-return 0;
+return generic_port_init(vcon, dev);
 }
 
 static VirtIOSerialPortInfo virtserialport_info = {
-- 
1.6.2.5





[Qemu-devel] [PATCH v4 2/5] char: Add qemu_chr_write_nb() for nonblocking writes

2010-05-04 Thread Amit Shah
For char devices whose backing files are open in non-blocking mode,
non-blocking writes can now be made using qemu_chr_write_nb().

For non-blocking chardevs, we can return -EAGAIN to callers of
qemu_chr_write_nb(). When the backend is ready to accept more data,
we can let the caller know via a callback.

-EAGAIN is returned only when the backend's file is non-blocking
and a callback is registered by the caller when invoking
qemu_chr_add_handlers().

In case a backend doesn't support non-blocking writes,
qemu_chr_write_nb() fallsback to qemu_chr_write().

Update all callers of qemu chardevs to not register any callback
handler for non-blocked writes.

Individual callers can update their code to add a callback handler,
register the handler at the time of calling qemu_chr_add_handlers()
and call qemu_chr_write_nb() instead of qemu_chr_write() if they wish
to receive -EAGAIN notifications.

No backend currently supports non-blocking writes.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 gdbstub.c|2 +-
 hw/debugcon.c|2 +-
 hw/escc.c|3 ++-
 hw/etraxfs_ser.c |4 ++--
 hw/mcf_uart.c|2 +-
 hw/pl011.c   |2 +-
 hw/pxa2xx.c  |2 +-
 hw/serial.c  |2 +-
 hw/sh_serial.c   |2 +-
 hw/syborg_serial.c   |3 ++-
 hw/usb-serial.c  |2 +-
 hw/virtio-console.c  |8 
 hw/xen_console.c |7 ---
 hw/xilinx_uartlite.c |5 +++--
 monitor.c|4 ++--
 net/slirp.c  |2 +-
 net/socket.c |4 ++--
 qemu-char.c  |   35 +++
 qemu-char.h  |9 +
 qemu_socket.h|3 ++-
 20 files changed, 68 insertions(+), 35 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 93c4850..d6e5b23 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2650,7 +2650,7 @@ int gdbserver_start(const char *device)
 if (!chr)
 return -1;
 
-qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
+qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive, NULL,
   gdb_chr_event, NULL);
 }
 
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 5ee6821..4fa9189 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
 exit(1);
 }
 
-qemu_chr_add_handlers(s-chr, NULL, NULL, NULL, s);
+qemu_chr_add_handlers(s-chr, NULL, NULL, NULL, NULL, s);
 }
 
 static int debugcon_isa_initfn(ISADevice *dev)
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..94d1ba7 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -904,7 +904,8 @@ static int escc_init1(SysBusDevice *dev)
 s-chn[i].clock = s-frequency / 2;
 if (s-chn[i].chr) {
 qemu_chr_add_handlers(s-chn[i].chr, serial_can_receive,
-  serial_receive1, serial_event, s-chn[i]);
+  serial_receive1, NULL, serial_event,
+  s-chn[i]);
 }
 }
 s-chn[0].otherchn = s-chn[1];
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index e1f9615..5e592c9 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -176,8 +176,8 @@ static int etraxfs_ser_init(SysBusDevice *dev)
 s-chr = qdev_init_chardev(dev-qdev);
 if (s-chr)
 qemu_chr_add_handlers(s-chr,
-  serial_can_receive, serial_receive,
-  serial_event, s);
+  serial_can_receive, serial_receive, NULL,
+  serial_event, s);
 return 0;
 }
 
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index d16bac7..5cea623 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -277,7 +277,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
 s-irq = irq;
 if (chr) {
 qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
-  mcf_uart_event, s);
+  NULL, mcf_uart_event, s);
 }
 mcf_uart_reset(s);
 return s;
diff --git a/hw/pl011.c b/hw/pl011.c
index 81de91e..73ae086 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -304,7 +304,7 @@ static int pl011_init(SysBusDevice *dev, const unsigned 
char *id)
 s-flags = 0x90;
 if (s-chr) {
 qemu_chr_add_handlers(s-chr, pl011_can_receive, pl011_receive,
-  pl011_event, s);
+  NULL, pl011_event, s);
 }
 register_savevm(pl011_uart, -1, 1, pl011_save, pl011_load, s);
 return 0;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index 9095386..04dbda4 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2012,7 +2012,7 @@ static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t 
base,
 
 if (chr)
 qemu_chr_add_handlers(chr, pxa2xx_fir_is_empty,
-pxa2xx_fir_rx, pxa2xx_fir_event, s);
+  pxa2xx_fir_rx, NULL, pxa2xx_fir_event, s);
 
 

[Qemu-devel] [PATCH v4 5/5] virtio-console: Throttle virtio-serial-bus if we can't consume any more guest data

2010-05-04 Thread Amit Shah
If the char device we're connected to is overwhelmed with data and it
can't accept any more, signal to the virtio-serial-bus to stop sending
us more data till we tell otherwise.

If the current buffer being processed hasn't been completely written out
to the char device, we have to keep it around and re-try sending it
since the virtio-serial-bus code assumes we consume the entire buffer.

Allow the chardev backends to return -EAGAIN; we're ready with a
callback handler that will flush the remainder of the buffer.

Also register with savevm so that we save/restore such a buffer across
migration.

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

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 1552f47..035ef94 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -13,18 +13,92 @@
 #include qemu-char.h
 #include virtio-serial.h
 
+typedef struct Buffer {
+uint8_t *buf;
+size_t rem_len;
+size_t offset;
+} Buffer;
+
 typedef struct VirtConsole {
 VirtIOSerialPort port;
 CharDriverState *chr;
+Buffer *unflushed_buf;
 } VirtConsole;
 
+static void add_unflushed_buf(VirtConsole *vcon, const uint8_t *buf, size_t 
len)
+{
+vcon-unflushed_buf = qemu_malloc(sizeof(Buffer));
+vcon-unflushed_buf-buf = qemu_malloc(len);
+
+memcpy(vcon-unflushed_buf-buf, buf, len);
+vcon-unflushed_buf-rem_len = len;
+vcon-unflushed_buf-offset = 0;
+}
+
+static void free_unflushed_buf(VirtConsole *vcon)
+{
+if (vcon-unflushed_buf) {
+qemu_free(vcon-unflushed_buf-buf);
+qemu_free(vcon-unflushed_buf);
+vcon-unflushed_buf = NULL;
+}
+}
+
+static int buffered_write_to_chardev(VirtConsole *vcon, const uint8_t *buf,
+ size_t len)
+{
+size_t written;
+ssize_t ret;
+
+written = 0;
+do {
+ret = qemu_chr_write_nb(vcon-chr, buf + written, len - written);
+if (ret  0) {
+if (vcon-unflushed_buf) {
+vcon-unflushed_buf-offset += written;
+vcon-unflushed_buf-rem_len -= written;
+} else {
+virtio_serial_throttle_port(vcon-port, true);
+add_unflushed_buf(vcon, buf + written, len - written);
+}
+
+return -EAGAIN;
+}
+
+written += ret;
+} while (written != len);
+
+return 0;
+}
+
+/* Callback function called when the chardev can accept more data */
+static void chr_write_unblocked(void *opaque)
+{
+VirtConsole *vcon = opaque;
+
+if (vcon-unflushed_buf) {
+int ret;
+
+ret = buffered_write_to_chardev(vcon, vcon-unflushed_buf-buf
+  + vcon-unflushed_buf-offset,
+vcon-unflushed_buf-rem_len);
+if (ret  0) {
+return;
+}
+free_unflushed_buf(vcon);
+}
+virtio_serial_throttle_port(vcon-port, false);
+}
 
 /* Callback function that's called when the guest sends us data */
 static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
 {
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-qemu_chr_write(vcon-chr, buf, len);
+/* If a previous write was incomplete, we should've been throttled. */
+assert(!vcon-unflushed_buf);
+
+buffered_write_to_chardev(vcon, buf, len);
 }
 
 /* Readiness of the guest to accept data on a port */
@@ -48,25 +122,69 @@ static void chr_event(void *opaque, int event)
 VirtConsole *vcon = opaque;
 
 switch (event) {
-case CHR_EVENT_OPENED: {
+case CHR_EVENT_OPENED:
 virtio_serial_open(vcon-port);
 break;
-}
+
 case CHR_EVENT_CLOSED:
+if (vcon-unflushed_buf) {
+free_unflushed_buf(vcon);
+}
 virtio_serial_close(vcon-port);
 break;
 }
 }
 
+static void virtio_console_port_save(QEMUFile *f, void *opaque)
+{
+VirtConsole *vcon = opaque;
+uint32_t have_buffer;
+
+have_buffer = vcon-unflushed_buf ? true : false;
+
+qemu_put_be32s(f, have_buffer);
+if (have_buffer) {
+qemu_put_be64s(f, vcon-unflushed_buf-rem_len);
+qemu_put_buffer(f, vcon-unflushed_buf-buf
+   + vcon-unflushed_buf-offset,
+vcon-unflushed_buf-rem_len);
+}
+}
+
+static int virtio_console_port_load(QEMUFile *f, void *opaque, int version_id)
+{
+VirtConsole *vcon = opaque;
+uint32_t have_buffer;
+
+if (version_id  1) {
+return -EINVAL;
+}
+
+qemu_get_be32s(f, have_buffer);
+if (have_buffer) {
+vcon-unflushed_buf = qemu_mallocz(sizeof(Buffer));
+
+qemu_get_be64s(f, vcon-unflushed_buf-rem_len);
+vcon-unflushed_buf-buf = qemu_malloc(vcon-unflushed_buf-rem_len);
+vcon-unflushed_buf-offset = 0;
+
+qemu_get_buffer(f, 

[Qemu-devel] [PATCH v4 0/5] char: non-blocking writes, virtio-console flow control

2010-05-04 Thread Amit Shah
Hello,

This series lets interested callers ask for an -EAGAIN return from the
chardev backends (only unix and tcp sockets as of now) to implement
their own flow control.

A new call, qemu_chr_write_nb() is added, that will fallback to
qemu_chr_write() if the backend file isn't non-blocking or if no
callback was supplied.

Support for other backend types is easy to add and will be done in
later patches.

Amit Shah (5):
  char: Let writers know how much data was written in case of errors
  char: Add qemu_chr_write_nb() for nonblocking writes
  char: unix/tcp: Add a non-blocking write handler
  virtio-console: Factor out common init between console and generic
ports
  virtio-console: Throttle virtio-serial-bus if we can't consume any
more guest data

 gdbstub.c|2 +-
 hw/debugcon.c|2 +-
 hw/escc.c|3 +-
 hw/etraxfs_ser.c |4 +-
 hw/mcf_uart.c|2 +-
 hw/pl011.c   |2 +-
 hw/pxa2xx.c  |2 +-
 hw/serial.c  |2 +-
 hw/sh_serial.c   |2 +-
 hw/syborg_serial.c   |3 +-
 hw/usb-serial.c  |2 +-
 hw/virtio-console.c  |  156 +++---
 hw/xen_console.c |7 +-
 hw/xilinx_uartlite.c |5 +-
 monitor.c|4 +-
 net/slirp.c  |2 +-
 net/socket.c |4 +-
 qemu-char.c  |   94 +++---
 qemu-char.h  |9 +++
 qemu_socket.h|3 +-
 20 files changed, 257 insertions(+), 53 deletions(-)





[Qemu-devel] Re: [PATCH v4 3/5] char: unix/tcp: Add a non-blocking write handler

2010-05-04 Thread Gerd Hoffmann

On 05/04/10 09:17, Amit Shah wrote:

Add a non-blocking write handler that can return with -EAGAIN to the
caller and also callback when the socket becomes writable.

Non-blocking writes are only enabled for sockets that are opened in
non-blocking mode and only for callers that have registered a callback
handler for resuming writes.


The logic will be pretty much the same for all filehandle-based backends 
on unix.  So maybe create some helper functions, so implementing 
$backend_chr_write_unblocked can be done with just three lines of code?


cheers,
  Gerd





[Qemu-devel] Re: [PATCH v4 3/5] char: unix/tcp: Add a non-blocking write handler

2010-05-04 Thread Gerd Hoffmann

On 05/04/10 09:56, Amit Shah wrote:

The logic will be pretty much the same for all filehandle-based backends
on unix.  So maybe create some helper functions, so implementing
$backend_chr_write_unblocked can be done with just three lines of code?


Yes, that's the next step. Let's push this for now and do that in a
later patch series?


Fine with me.

cheers,
  Gerd





Re: [Qemu-devel] [PATCH v4 1/4] Modify DIRTY_FLAG value and introduce DIRTY_IDX to use as indexes of bit-based phys_ram_dirty.

2010-05-04 Thread Yoshiaki Tamura
Sure.  Submitted as v5.

Thanks,

Yoshi

2010/5/4 Anthony Liguori anth...@codemonkey.ws:
 Hi Yoshi,

 Could you rebase this series and resubmit?  It conflicts with the latest
 HEAD.

 Regards,

 Anthony Liguori

 On 04/19/2010 10:40 PM, Yoshiaki Tamura wrote:

 Replaces byte-based phys_ram_dirty bitmap with four (MASTER, VGA, CODE,
 MIGRATION) bit-based phys_ram_dirty bitmap.  On allocation, it sets all
 bits in
 the bitmap.  It uses ffs() to convert DIRTY_FLAG to DIRTY_IDX.

 Modifies wrapper functions for byte-based phys_ram_dirty bitmap to
 bit-based
 phys_ram_dirty bitmap.  MASTER works as a buffer, and upon get_diry() or
 get_dirty_flags(), it calls cpu_physical_memory_sync_master() to update
 VGA and
 MIGRATION.

 Signed-off-by: Yoshiaki Tamuratamura.yoshi...@lab.ntt.co.jp
 ---
  cpu-all.h     |  127
 -
  exec.c        |   15 +--
  qemu-common.h |    3 +
  3 files changed, 121 insertions(+), 24 deletions(-)

 diff --git a/cpu-all.h b/cpu-all.h
 index f8bfa66..b6a2d91 100644
 --- a/cpu-all.h
 +++ b/cpu-all.h
 @@ -37,6 +37,9 @@

  #include softfloat.h

 +/* to use ffs in flag_to_idx() */
 +#includestrings.h
 +
  #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
  #define BSWAP_NEEDED
  #endif
 @@ -853,7 +856,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState
 *env, target_ulong addr);
  /* memory API */

  extern int phys_ram_fd;
 -extern uint8_t *phys_ram_dirty;
  extern ram_addr_t ram_size;
  extern ram_addr_t last_ram_offset;

 @@ -878,50 +880,137 @@ extern int mem_prealloc;
  /* Set if TLB entry is an IO callback.  */
  #define TLB_MMIO        (1  5)

 -#define VGA_DIRTY_FLAG       0x01
 -#define CODE_DIRTY_FLAG      0x02
 -#define MIGRATION_DIRTY_FLAG 0x08
 +/* Use DIRTY_IDX as indexes of bit-based phys_ram_dirty. */
 +#define MASTER_DIRTY_IDX    0
 +#define VGA_DIRTY_IDX       1
 +#define CODE_DIRTY_IDX      2
 +#define MIGRATION_DIRTY_IDX 3
 +#define NUM_DIRTY_IDX       4
 +
 +#define MASTER_DIRTY_FLAG    (1  MASTER_DIRTY_IDX)
 +#define VGA_DIRTY_FLAG       (1  VGA_DIRTY_IDX)
 +#define CODE_DIRTY_FLAG      (1  CODE_DIRTY_IDX)
 +#define MIGRATION_DIRTY_FLAG (1  MIGRATION_DIRTY_IDX)
 +
 +extern unsigned long *phys_ram_dirty[NUM_DIRTY_IDX];
 +
 +static inline int dirty_flag_to_idx(int flag)
 +{
 +    return ffs(flag) - 1;
 +}
 +
 +static inline int dirty_idx_to_flag(int idx)
 +{
 +    return 1  idx;
 +}

  /* read dirty bit (return 0 or 1) */
  static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
  {
 -    return phys_ram_dirty[addr  TARGET_PAGE_BITS] == 0xff;
 +    unsigned long mask;
 +    ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
 +    int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
 +
 +    mask = 1UL  offset;
 +    return (phys_ram_dirty[MASTER_DIRTY_IDX][index]  mask) == mask;
 +}
 +
 +static inline void cpu_physical_memory_sync_master(ram_addr_t index)
 +{
 +    if (phys_ram_dirty[MASTER_DIRTY_IDX][index]) {
 +        phys_ram_dirty[VGA_DIRTY_IDX][index]
 +            |=  phys_ram_dirty[MASTER_DIRTY_IDX][index];
 +        phys_ram_dirty[MIGRATION_DIRTY_IDX][index]
 +            |=  phys_ram_dirty[MASTER_DIRTY_IDX][index];
 +        phys_ram_dirty[MASTER_DIRTY_IDX][index] = 0UL;
 +    }
  }

  static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
  {
 -    return phys_ram_dirty[addr  TARGET_PAGE_BITS];
 +     unsigned long mask;
 +     ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
 +     int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
 +     int ret = 0, i;
 +
 +     mask = 1UL  offset;
 +     cpu_physical_memory_sync_master(index);
 +
 +     for (i = VGA_DIRTY_IDX; i= MIGRATION_DIRTY_IDX; i++) {
 +         if (phys_ram_dirty[i][index]  mask) {
 +             ret |= dirty_idx_to_flag(i);
 +         }
 +     }
 +
 +     return ret;
 +}
 +
 +static inline int cpu_physical_memory_get_dirty_idx(ram_addr_t addr,
 +                                                    int dirty_idx)
 +{
 +    unsigned long mask;
 +    ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
 +    int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
 +
 +    mask = 1UL  offset;
 +    cpu_physical_memory_sync_master(index);
 +    return (phys_ram_dirty[dirty_idx][index]  mask) == mask;
  }

  static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
                                                  int dirty_flags)
  {
 -    return phys_ram_dirty[addr  TARGET_PAGE_BITS]  dirty_flags;
 +    return cpu_physical_memory_get_dirty_idx(addr,
 +
 dirty_flag_to_idx(dirty_flags));
  }

  static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
  {
 -    phys_ram_dirty[addr  TARGET_PAGE_BITS] = 0xff;
 +    unsigned long mask;
 +    ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
 +    int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
 +
 +    mask = 1UL  offset;
 +    

[Qemu-devel] Re: [PATCH] virtio-spec: document block CMD and FLUSH

2010-05-04 Thread Avi Kivity

On 05/04/2010 07:38 AM, Rusty Russell wrote:

On Fri, 19 Feb 2010 08:52:20 am Michael S. Tsirkin wrote:
   

I took a stub at documenting CMD and FLUSH request types in virtio
block.  Christoph, could you look over this please?

I note that the interface seems full of warts to me,
this might be a first step to cleaning them.
 

ISTR Christoph had withdrawn some patches in this area, and was waiting
for him to resubmit?

I've given up on figuring out the block device.  What seem to me to be sane
semantics along the lines of memory barriers are foreign to disk people: they
want (and depend on) flushing everywhere.

For example, tdb transactions do not require a flush, they only require what
I would call a barrier: that prior data be written out before any future data.
Surely that would be more efficient in general than a flush!  In fact, TDB
wants only writes to *that file* (and metadata) written out first; it has no
ordering issues with other I/O on the same device.
   


I think that's SCSI ordered tags.


A generic I/O interface would allow you to specify this request depends on 
these
outstanding requests and leave it at that.  It might have some sync flush
command for dumb applications and OSes.  The userspace API might be not be as
precise and only allow such a barrier against all prior writes on this fd.
   


Depends on all previous requests, and will commit before all following 
requests.  ie a full barrier.



ISTR someone mentioning a desire for such an API years ago, so CC'ing the
usual I/O suspects...
   


I'd love to see TCQ exposed to user space.

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





Re: [Qemu-devel] Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread Kevin Wolf
Am 03.05.2010 23:26, schrieb Peter Lieven:
 Hi Qemu/KVM Devel Team,
 
 i'm using qemu-kvm 0.12.3 with latest Kernel 2.6.33.3.
 As backend we use open-iSCSI with dm-multipath.
 
 Multipath is configured to queue i/o if no path is available.
 
 If we create a failure on all paths, qemu starts to consume 100%
 CPU due to i/o waits which is ok so far.
 
 1 odd thing: The Monitor Interface is not responding any more ...
 
 What es a really blocker is that KVM crashes with:
 kvm: /usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507: bmdma_active_if: 
 Assertion `bmdma-unit != (uint8_t)-1' failed.
 
 after the multipath has reestablisched at least one path.

Can you get a stack backtrace with gdb?

 Any ideas? I remember this was working with earlier kernel/kvm/qemu 
 versions.

If it works in the same setup with an older qemu version, bisecting
might help.

Kevin




Re: [Qemu-devel] Re: [PATCH] Revert PCI: Convert pci_device_hot_add() to QObject

2010-05-04 Thread Markus Armbruster
Anthony Liguori anth...@codemonkey.ws writes:

 On 05/03/2010 04:29 AM, Markus Armbruster wrote:
[...]
 Why am I proposing to remove pci_add from QMP before its replacement is
 ready?  I want it out sooner rather than later, because it isn't fully
 functional (errors and drive_add are missing), and we do not plan to
 complete the job.  In other words, it's not really usable over QMP now,
 and it's not what we want for QMP anyway.  Since we don't want it to be
 used over QMP, we should take it out, not leave it around as a trap for
 the uninitiated.

 Anyway, I'll respin with a more verbose commit message, and I'll throw
 in the buddy patch Revert monitor: Convert do_pci_device_hot_remove()
 to QObject.


 Does libvirt not use pci_add with QMP?

Re QMP in general: libvirt has code for QMP, but it is disabled.  It'll
get enabled as soon as a usable QMP ships, which we all expect for the
next release.

Re pci_add over QMP, git://libvirt.org/libvirt.git has:

commit efd4ee7871a631a9293e94d58fc4384c162388a7
Author: Daniel P. Berrange berra...@redhat.com
Date:   Wed Apr 14 15:23:38 2010 +0100

Remove code from JSON monitor for commands that won't be ported

The QEMU developers have stated that they will not be porting
the commands 'pci_add', 'pci_del', 'usb_add', 'usb_del' to the
JSON mode monitor, since they're obsoleted by 'device_add'
and 'device_del'. libvirt has (untested) code that would have
supported those commands in theory, but since we already use
device_add/del where available, there's no need to keep the
legacy stuff anymore.

The text mode monitor keeps support for all commands for sake
of historical compatability.

* src/qemu/qemu_monitor_json.c: Remove 'pci_add', 'pci_del',
  'usb_add', 'usb_del' commands

Does this answer your question?




[Qemu-devel] Re: [PATCH] virtio-spec: document block CMD and FLUSH

2010-05-04 Thread Jens Axboe
On Tue, May 04 2010, Rusty Russell wrote:
 On Fri, 19 Feb 2010 08:52:20 am Michael S. Tsirkin wrote:
  I took a stub at documenting CMD and FLUSH request types in virtio
  block.  Christoph, could you look over this please?
  
  I note that the interface seems full of warts to me,
  this might be a first step to cleaning them.
 
 ISTR Christoph had withdrawn some patches in this area, and was waiting
 for him to resubmit?
 
 I've given up on figuring out the block device.  What seem to me to be sane
 semantics along the lines of memory barriers are foreign to disk people: they
 want (and depend on) flushing everywhere.
 
 For example, tdb transactions do not require a flush, they only require what
 I would call a barrier: that prior data be written out before any future data.
 Surely that would be more efficient in general than a flush!  In fact, TDB
 wants only writes to *that file* (and metadata) written out first; it has no
 ordering issues with other I/O on the same device.
 
 A generic I/O interface would allow you to specify this request depends on 
 these
 outstanding requests and leave it at that.  It might have some sync flush
 command for dumb applications and OSes.  The userspace API might be not be as
 precise and only allow such a barrier against all prior writes on this fd.
 
 ISTR someone mentioning a desire for such an API years ago, so CC'ing the
 usual I/O suspects...

It would be nice to have a more fuller API for this, but the reality is
that only the flush approach is really workable. Even just strict
ordering of requests could only be supported on SCSI, and even there the
kernel still lacks proper guarantees on error handling to prevent
reordering there.

-- 
Jens Axboe





[Qemu-devel] [PATCH v5 4/4] Use cpu_physical_memory_get_dirty_range() to check multiple dirty pages.

2010-05-04 Thread Yoshiaki Tamura
Modifies ram_save_block() and ram_save_remaining() to use
cpu_physical_memory_get_dirty_range() to check multiple dirty and non-dirty
pages at once.

Signed-off-by: Yoshiaki Tamura tamura.yoshi...@lab.ntt.co.jp
Signed-off-by: OHMURA Kei ohmura@lab.ntt.co.jp
---
 arch_init.c |   54 +-
 1 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/arch_init.c b/arch_init.c
index cfc03ea..245a082 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -108,31 +108,37 @@ static int ram_save_block(QEMUFile *f)
 static ram_addr_t current_addr = 0;
 ram_addr_t saved_addr = current_addr;
 ram_addr_t addr = 0;
-int found = 0;
+ram_addr_t dirty_rams[HOST_LONG_BITS];
+int i, found = 0;
 
 while (addr  last_ram_offset) {
-if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) 
{
+if ((found = cpu_physical_memory_get_dirty_range(
+ current_addr, last_ram_offset, dirty_rams, HOST_LONG_BITS,
+ MIGRATION_DIRTY_FLAG))) {
 uint8_t *p;
 
-cpu_physical_memory_reset_dirty(current_addr,
-current_addr + TARGET_PAGE_SIZE,
-MIGRATION_DIRTY_FLAG);
+for (i = 0; i  found; i++) {
+ram_addr_t page_addr = dirty_rams[i];
+cpu_physical_memory_reset_dirty(page_addr,
+page_addr + TARGET_PAGE_SIZE,
+MIGRATION_DIRTY_FLAG);
 
-p = qemu_get_ram_ptr(current_addr);
+p = qemu_get_ram_ptr(page_addr);
 
-if (is_dup_page(p, *p)) {
-qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
-qemu_put_byte(f, *p);
-} else {
-qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
-qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+if (is_dup_page(p, *p)) {
+qemu_put_be64(f, page_addr | RAM_SAVE_FLAG_COMPRESS);
+qemu_put_byte(f, *p);
+} else {
+qemu_put_be64(f, page_addr | RAM_SAVE_FLAG_PAGE);
+qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+}
 }
 
-found = 1;
 break;
+} else {
+addr += dirty_rams[0];
+current_addr = (saved_addr + addr) % last_ram_offset;
 }
-addr += TARGET_PAGE_SIZE;
-current_addr = (saved_addr + addr) % last_ram_offset;
 }
 
 return found;
@@ -142,12 +148,18 @@ static uint64_t bytes_transferred;
 
 static ram_addr_t ram_save_remaining(void)
 {
-ram_addr_t addr;
+ram_addr_t addr = 0;
 ram_addr_t count = 0;
+ram_addr_t dirty_rams[HOST_LONG_BITS];
+int found = 0;
 
-for (addr = 0; addr  last_ram_offset; addr += TARGET_PAGE_SIZE) {
-if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
-count++;
+while (addr  last_ram_offset) {
+if ((found = cpu_physical_memory_get_dirty_range(addr, last_ram_offset,
+dirty_rams, HOST_LONG_BITS, MIGRATION_DIRTY_FLAG))) {
+count += found;
+addr = dirty_rams[found - 1] + TARGET_PAGE_SIZE;
+} else {
+addr += dirty_rams[0];
 }
 }
 
-- 
1.7.0.31.g1df487





[Qemu-devel] [PATCH v5 1/4] Modify DIRTY_FLAG value and introduce DIRTY_IDX to use as indexes of bit-based phys_ram_dirty.

2010-05-04 Thread Yoshiaki Tamura
Replaces byte-based phys_ram_dirty bitmap with four (MASTER, VGA, CODE,
MIGRATION) bit-based phys_ram_dirty bitmap.  On allocation, it sets all bits in
the bitmap.  It uses ffs() to convert DIRTY_FLAG to DIRTY_IDX.

Modifies wrapper functions for byte-based phys_ram_dirty bitmap to bit-based
phys_ram_dirty bitmap.  MASTER works as a buffer, and upon get_diry() or
get_dirty_flags(), it calls cpu_physical_memory_sync_master() to update VGA and
MIGRATION.

Signed-off-by: Yoshiaki Tamura tamura.yoshi...@lab.ntt.co.jp
---
 cpu-all.h |  128 -
 exec.c|   15 --
 qemu-common.h |3 +
 3 files changed, 121 insertions(+), 25 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index 7b1594c..d21ecbc 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -37,6 +37,9 @@
 
 #include softfloat.h
 
+/* to use ffs in flag_to_idx() */
+#include strings.h
+
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 #define BSWAP_NEEDED
 #endif
@@ -853,7 +856,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, 
target_ulong addr);
 /* memory API */
 
 extern int phys_ram_fd;
-extern uint8_t *phys_ram_dirty;
 extern ram_addr_t ram_size;
 extern ram_addr_t last_ram_offset;
 
@@ -878,51 +880,137 @@ extern int mem_prealloc;
 /* Set if TLB entry is an IO callback.  */
 #define TLB_MMIO(1  5)
 
-#define VGA_DIRTY_FLAG   0x01
-#define CODE_DIRTY_FLAG  0x02
-#define MIGRATION_DIRTY_FLAG 0x08
+/* Use DIRTY_IDX as indexes of bit-based phys_ram_dirty. */
+#define MASTER_DIRTY_IDX0
+#define VGA_DIRTY_IDX   1
+#define CODE_DIRTY_IDX  2
+#define MIGRATION_DIRTY_IDX 3
+#define NUM_DIRTY_IDX   4
+
+#define MASTER_DIRTY_FLAG(1  MASTER_DIRTY_IDX)
+#define VGA_DIRTY_FLAG   (1  VGA_DIRTY_IDX)
+#define CODE_DIRTY_FLAG  (1  CODE_DIRTY_IDX)
+#define MIGRATION_DIRTY_FLAG (1  MIGRATION_DIRTY_IDX)
+
+extern unsigned long *phys_ram_dirty[NUM_DIRTY_IDX];
+
+static inline int dirty_flag_to_idx(int flag)
+{
+return ffs(flag) - 1;
+}
+
+static inline int dirty_idx_to_flag(int idx)
+{
+return 1  idx;
+}
 
 /* read dirty bit (return 0 or 1) */
 static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
 {
-return phys_ram_dirty[addr  TARGET_PAGE_BITS] == 0xff;
+unsigned long mask;
+ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+ 
+mask = 1UL  offset;
+return (phys_ram_dirty[MASTER_DIRTY_IDX][index]  mask) == mask;
+}
+
+static inline void cpu_physical_memory_sync_master(ram_addr_t index)
+{
+if (phys_ram_dirty[MASTER_DIRTY_IDX][index]) {
+phys_ram_dirty[VGA_DIRTY_IDX][index]
+|=  phys_ram_dirty[MASTER_DIRTY_IDX][index];
+phys_ram_dirty[MIGRATION_DIRTY_IDX][index]
+|=  phys_ram_dirty[MASTER_DIRTY_IDX][index];
+phys_ram_dirty[MASTER_DIRTY_IDX][index] = 0UL;
+}
 }
 
 static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
 {
-return phys_ram_dirty[addr  TARGET_PAGE_BITS];
+ unsigned long mask;
+ ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+ int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+ int ret = 0, i;
+ 
+ mask = 1UL  offset;
+ cpu_physical_memory_sync_master(index);
+
+ for (i = VGA_DIRTY_IDX; i = MIGRATION_DIRTY_IDX; i++) {
+ if (phys_ram_dirty[i][index]  mask) {
+ ret |= dirty_idx_to_flag(i);
+ }
+ }
+ 
+ return ret;
+}
+
+static inline int cpu_physical_memory_get_dirty_idx(ram_addr_t addr,
+int dirty_idx)
+{
+unsigned long mask;
+ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+
+mask = 1UL  offset;
+cpu_physical_memory_sync_master(index);
+return (phys_ram_dirty[dirty_idx][index]  mask) == mask;
 }
 
 static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
 int dirty_flags)
 {
-return phys_ram_dirty[addr  TARGET_PAGE_BITS]  dirty_flags;
+return cpu_physical_memory_get_dirty_idx(addr,
+ dirty_flag_to_idx(dirty_flags));
 }
 
 static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
 {
-phys_ram_dirty[addr  TARGET_PAGE_BITS] = 0xff;
+unsigned long mask;
+ram_addr_t index = (addr  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+int offset = (addr  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+
+mask = 1UL  offset;
+phys_ram_dirty[MASTER_DIRTY_IDX][index] |= mask;
 }
 
-static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
-  int dirty_flags)
+static inline void cpu_physical_memory_set_dirty_range(ram_addr_t addr,
+   unsigned long mask)
 {
-return 

Re: [Qemu-devel] [PATCH 3/3] qemu-nbd: Improve error reporting

2010-05-04 Thread Kevin Wolf
Am 03.05.2010 19:01, schrieb Anthony Liguori:
 On 03/29/2010 06:03 AM, Kevin Wolf wrote:
 Am 28.03.2010 19:07, schrieb Ryota Ozaki:

 - use err(3) instead of errx(3) if errno is available
to report why failed
 - let fail prior to daemon(3) if opening a nbd file
is likely to fail after daemonizing to avoid silent
failure exit
 - add missing 'ret = 1' when unix_socket_outgoing failed

 Signed-off-by: Ryota Ozakiozaki.ry...@gmail.com
  
 Acked-by: Kevin Wolfkw...@redhat.com

 
 Are you going to pull this into the block branch?

There was a v2 of this patch yesterday, which I did apply to the block
branch.

Kevin




Re: [Qemu-devel] Re: [PATCH] Revert PCI: Convert pci_device_hot_add() to QObject

2010-05-04 Thread Daniel P. Berrange
On Mon, May 03, 2010 at 11:59:55AM -0500, Anthony Liguori wrote:
 On 05/03/2010 04:29 AM, Markus Armbruster wrote:
 Why am I proposing to remove pci_add from QMP before its replacement is
 ready?  I want it out sooner rather than later, because it isn't fully
 functional (errors and drive_add are missing), and we do not plan to
 complete the job.  In other words, it's not really usable over QMP now,
 and it's not what we want for QMP anyway.  Since we don't want it to be
 used over QMP, we should take it out, not leave it around as a trap for
 the uninitiated.
 
 Anyway, I'll respin with a more verbose commit message, and I'll throw
 in the buddy patch Revert monitor: Convert do_pci_device_hot_remove()
 to QObject.

 
 Does libvirt not use pci_add with QMP?

As of QEMU 0.12, libvirt uses -device syntax for everything.

As of QEMU 0.13, libvirt will use QMP for everything (if compiled with
the libyajl JSON library - otherwise text mode only).

When -device is in use, we use device_add exclusively. Therefore,
we will have no need for pci_add  friends when using QMP.


Regards,
Daniel
-- 
|: Red Hat, Engineering, London-o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org-o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




[Qemu-devel] [PATCH v5 2/4] Introduce cpu_physical_memory_get_dirty_range().

2010-05-04 Thread Yoshiaki Tamura
It checks the first row and puts dirty addr in the array.  If the first row is
empty, it skips to the first non-dirty row or the end addr, and put the length
in the first entry of the array.

Signed-off-by: Yoshiaki Tamura tamura.yoshi...@lab.ntt.co.jp
Signed-off-by: OHMURA Kei ohmura@lab.ntt.co.jp
---
 cpu-all.h |4 +++
 exec.c|   67 +
 2 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index d21ecbc..6d7a7fd 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -1013,6 +1013,10 @@ static inline void 
cpu_physical_memory_mask_dirty_range(ram_addr_t start,
  }
 }
 
+int cpu_physical_memory_get_dirty_range(ram_addr_t start, ram_addr_t end, 
+ram_addr_t *dirty_rams, int length,
+int dirty_flags);
+
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
  int dirty_flags);
 void cpu_tlb_update_dirty(CPUState *env);
diff --git a/exec.c b/exec.c
index 6b4b1b3..3107487 100644
--- a/exec.c
+++ b/exec.c
@@ -2045,6 +2045,73 @@ static inline void tlb_reset_dirty_range(CPUTLBEntry 
*tlb_entry,
 }
 }
 
+/* It checks the first row and puts dirty addrs in the array.
+   If the first row is empty, it skips to the first non-dirty row
+   or the end addr, and put the length in the first entry of the array. */
+int cpu_physical_memory_get_dirty_range(ram_addr_t start, ram_addr_t end, 
+ram_addr_t *dirty_rams, int length,
+int dirty_flag)
+{
+unsigned long p = 0, page_number;
+ram_addr_t addr;
+ram_addr_t s_idx = (start  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+ram_addr_t e_idx = (end  TARGET_PAGE_BITS) / HOST_LONG_BITS;
+int i, j, offset, dirty_idx = dirty_flag_to_idx(dirty_flag);
+
+/* mask bits before the start addr */
+offset = (start  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+cpu_physical_memory_sync_master(s_idx);
+p |= phys_ram_dirty[dirty_idx][s_idx]  ~((1UL  offset) - 1);
+
+if (s_idx == e_idx) {
+/* mask bits after the end addr */
+offset = (end  TARGET_PAGE_BITS)  (HOST_LONG_BITS - 1);
+p = (1UL  offset) - 1;
+}
+
+if (p == 0) {
+/* when the row is empty */
+ram_addr_t skip;
+if (s_idx == e_idx) {
+skip = end;
+   } else {
+/* skip empty rows */
+while (s_idx  e_idx) {
+s_idx++;
+cpu_physical_memory_sync_master(s_idx);
+
+if (phys_ram_dirty[dirty_idx][s_idx] != 0) {
+break;
+}
+}
+skip = (s_idx * HOST_LONG_BITS * TARGET_PAGE_SIZE);
+}
+dirty_rams[0] = skip - start;
+i = 0;
+
+} else if (p == ~0UL) {
+/* when the row is fully dirtied */
+addr = start;
+for (i = 0; i  length; i++) {
+dirty_rams[i] = addr;
+addr += TARGET_PAGE_SIZE;
+}
+} else {
+/* when the row is partially dirtied */
+i = 0;
+do {
+j = ffsl(p) - 1;
+p = ~(1UL  j);
+page_number = s_idx * HOST_LONG_BITS + j;
+addr = page_number * TARGET_PAGE_SIZE;
+dirty_rams[i] = addr;
+i++;
+} while (p != 0  i  length);
+}
+
+return i;
+}
+
 /* Note: start and end must be within the same ram block.  */
 void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
  int dirty_flags)
-- 
1.7.0.31.g1df487





[Qemu-devel] Re: apparent key mapping error for usb keyboard

2010-05-04 Thread Avi Kivity

On 04/27/2010 12:46 PM, Michael Tokarev wrote:

I've a debian bugreport that claims to have a fix
for apparently wrong keymap for usb keyboard.  I
noticed this before with ps/2 keyboard too, the
sympthoms were that e.g windows keys were not
working in guests, but later on that has been
fixed.  But with `-usbdevice keyboard', i.e. with
usb keyboard, it still does not work.  See
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=578846
for details and for the proposed patch which
fixes the mentioned issue.  Here's the patch itself:

--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -399,3 +399,3 @@
 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

I'm not sure if it's right fix however.  Hence I'm
asking for opinions here.  If it's a right way to go,
it should probably be applied to -stable too.


I've no idea, but the correct place to ask is qemu-devel (copied).

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





[Qemu-devel] Re: [PATCH] virtio-spec: document block CMD and FLUSH

2010-05-04 Thread Christoph Hellwig
On Tue, May 04, 2010 at 02:08:24PM +0930, Rusty Russell wrote:
 On Fri, 19 Feb 2010 08:52:20 am Michael S. Tsirkin wrote:
  I took a stub at documenting CMD and FLUSH request types in virtio
  block.  Christoph, could you look over this please?
  
  I note that the interface seems full of warts to me,
  this might be a first step to cleaning them.
 
 ISTR Christoph had withdrawn some patches in this area, and was waiting
 for him to resubmit?

Any patches I've withdrawn in this area are withdrawn for good.  But
what I really need to do is to review Michaels spec updates, sorry.

UI'll get back to it today.





[Qemu-devel] Re: [PATCH v4 2/5] char: Add qemu_chr_write_nb() for nonblocking writes

2010-05-04 Thread Gerd Hoffmann

  Hi,


-static int unix_write(int fd, const uint8_t *buf, int len1)
+static int unix_write(int fd, const uint8_t *buf, int len1, bool nonblock)
  {
  int ret, len;

@@ -522,6 +537,9 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
  while (len  0) {
  ret = write(fd, buf, len);
  if (ret  0) {
+if (errno == EAGAIN  nonblock) {
+return -EAGAIN;
+}


You've just re-introduced the bug you've fixed in patch 1/5 ...

cheers,
  Gerd




[Qemu-devel] [PATCH v5 3/4] Use cpu_physical_memory_set_dirty_range() to update phys_ram_dirty.

2010-05-04 Thread Yoshiaki Tamura
Modifies kvm_physical_sync_dirty_bitmap to use
cpu_physical_memory_set_dirty_range() to update the row of the bit-based
phys_ram_dirty bitmap at once.

Signed-off-by: OHMURA Kei ohmura@lab.ntt.co.jp
Signed-off-by: Yoshiaki Tamura tamura.yoshi...@lab.ntt.co.jp
---
 kvm-all.c |   24 +---
 1 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 6962b2b..5f8f1ec 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -290,8 +290,8 @@ static int kvm_get_dirty_pages_log_range(unsigned long 
start_addr,
  unsigned long offset,
  unsigned long mem_size)
 {
-unsigned int i, j;
-unsigned long page_number, addr, addr1, c;
+unsigned int i;
+unsigned long page_number, addr, addr1;
 ram_addr_t ram_addr;
 unsigned int len = ((mem_size / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) /
 HOST_LONG_BITS;
@@ -302,23 +302,17 @@ static int kvm_get_dirty_pages_log_range(unsigned long 
start_addr,
  */
 for (i = 0; i  len; i++) {
 if (bitmap[i] != 0) {
-c = leul_to_cpu(bitmap[i]);
-do {
-j = ffsl(c) - 1;
-c = ~(1ul  j);
-page_number = i * HOST_LONG_BITS + j;
-addr1 = page_number * TARGET_PAGE_SIZE;
-addr = offset + addr1;
-ram_addr = cpu_get_physical_page_desc(addr);
-cpu_physical_memory_set_dirty(ram_addr);
-} while (c != 0);
+page_number = i * HOST_LONG_BITS;
+addr1 = page_number * TARGET_PAGE_SIZE;
+addr = offset + addr1;
+ram_addr = cpu_get_physical_page_desc(addr);
+cpu_physical_memory_set_dirty_range(ram_addr,
+leul_to_cpu(bitmap[i]));
 }
 }
 return 0;
 }
 
-#define ALIGN(x, y)  (((x)+(y)-1)  ~((y)-1))
-
 /**
  * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
  * This function updates qemu's dirty bitmap using 
cpu_physical_memory_set_dirty().
@@ -343,7 +337,7 @@ static int 
kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
 break;
 }
 
-size = ALIGN(((mem-memory_size)  TARGET_PAGE_BITS), HOST_LONG_BITS) 
/ 8;
+size = BITMAP_SIZE(mem-memory_size);
 if (!d.dirty_bitmap) {
 d.dirty_bitmap = qemu_malloc(size);
 } else if (size  allocated_size) {
-- 
1.7.0.31.g1df487





[Qemu-devel] simple block driver cleanups

2010-05-04 Thread Christoph Hellwig
This series cleans up the simple read-only block drivers to use the
qemu block device API to access their backing devices, making the code
simpler and usable over nbd/curl.  I've not touched dmg yet as it's even
more bitrot than usual and deserves it's own series.




[Qemu-devel] [PATCH 1/6] bochs: use pread

2010-05-04 Thread Christoph Hellwig
Use pread instead of lseek + read in preparation of using the qemu
block API.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/bochs.c
===
--- qemu-kevin.orig/block/bochs.c   2010-05-03 12:58:53.419012621 +0200
+++ qemu-kevin/block/bochs.c2010-05-03 12:59:13.873005360 +0200
@@ -125,7 +125,7 @@ static int bochs_open(BlockDriverState *
 
 s-fd = fd;
 
-if (read(fd, bochs, sizeof(bochs)) != sizeof(bochs)) {
+if (pread(fd, bochs, sizeof(bochs), 0) != sizeof(bochs)) {
 goto fail;
 }
 
@@ -144,14 +144,10 @@ static int bochs_open(BlockDriverState *
   bs-total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
 }
 
-if (lseek(s-fd, le32_to_cpu(bochs.header), SEEK_SET) == (off_t)-1) {
-goto fail;
-}
-
 s-catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
 s-catalog_bitmap = qemu_malloc(s-catalog_size * 4);
-if (read(s-fd, s-catalog_bitmap, s-catalog_size * 4) !=
-   s-catalog_size * 4)
+if (pread(s-fd, s-catalog_bitmap, s-catalog_size * 4,
+  le32_to_cpu(bochs.header)) != s-catalog_size * 4)
goto fail;
 for (i = 0; i  s-catalog_size; i++)
le32_to_cpus(s-catalog_bitmap[i]);
@@ -169,54 +165,35 @@ static int bochs_open(BlockDriverState *
 return -1;
 }
 
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
+static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
 {
 BDRVBochsState *s = bs-opaque;
 int64_t offset = sector_num * 512;
-int64_t extent_index, extent_offset, bitmap_offset, block_offset;
+int64_t extent_index, extent_offset, bitmap_offset;
 char bitmap_entry;
 
 // seek to sector
 extent_index = offset / s-extent_size;
 extent_offset = (offset % s-extent_size) / 512;
 
-if (s-catalog_bitmap[extent_index] == 0x)
-{
-// fprintf(stderr, page not allocated [%x - %x:%x]\n,
-// sector_num, extent_index, extent_offset);
-   return -1; // not allocated
+if (s-catalog_bitmap[extent_index] == 0x) {
+   return -1; /* not allocated */
 }
 
 bitmap_offset = s-data_offset + (512 * s-catalog_bitmap[extent_index] *
(s-extent_blocks + s-bitmap_blocks));
-block_offset = bitmap_offset + (512 * (s-bitmap_blocks + extent_offset));
 
-//fprintf(stderr, sect: %x [ext i: %x o: %x] - %x bitmap: %x block: 
%x\n,
-// sector_num, extent_index, extent_offset,
-// le32_to_cpu(s-catalog_bitmap[extent_index]),
-// bitmap_offset, block_offset);
-
-// read in bitmap for current extent
-if (lseek(s-fd, bitmap_offset + (extent_offset / 8), SEEK_SET) ==
-(off_t)-1) {
+/* read in bitmap for current extent */
+if (pread(s-fd, bitmap_entry, 1, bitmap_offset + (extent_offset / 8))
+!= 1) {
 return -1;
 }
 
-if (read(s-fd, bitmap_entry, 1) != 1)
-return -1;
-
-if (!((bitmap_entry  (extent_offset % 8))  1))
-{
-// fprintf(stderr, sector (%x) in bitmap not allocated\n,
-// sector_num);
-   return -1; // not allocated
+if (!((bitmap_entry  (extent_offset % 8))  1)) {
+   return -1; /* not allocated */
 }
 
-if (lseek(s-fd, block_offset, SEEK_SET) == (off_t)-1) {
-return -1;
-}
-
-return 0;
+return bitmap_offset + (512 * (s-bitmap_blocks + extent_offset));
 }
 
 static int bochs_read(BlockDriverState *bs, int64_t sector_num,
@@ -226,13 +203,13 @@ static int bochs_read(BlockDriverState *
 int ret;
 
 while (nb_sectors  0) {
-   if (!seek_to_sector(bs, sector_num))
-   {
-   ret = read(s-fd, buf, 512);
-   if (ret != 512)
-   return -1;
-   }
-   else
+int64_t block_offset = seek_to_sector(bs, sector_num);
+if (block_offset = 0) {
+ret = pread(s-fd, buf, 512, block_offset);
+if (ret != 512) {
+return -1;
+}
+} else
 memset(buf, 0, 512);
 nb_sectors--;
 sector_num++;




[Qemu-devel] [PATCH 2/6] bochs: use qemu block API

2010-05-04 Thread Christoph Hellwig
Use bdrv_pwrite to access the backing device instead of pread, and
convert the driver to implementing the bdrv_open method which gives
it an already opened BlockDriverState for the underlying device.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/bochs.c
===
--- qemu-kevin.orig/block/bochs.c   2010-05-03 12:42:19.385274599 +0200
+++ qemu-kevin/block/bochs.c2010-05-03 12:48:54.434007033 +0200
@@ -80,8 +80,6 @@ struct bochs_header {
 };
 
 typedef struct BDRVBochsState {
-int fd;
-
 uint32_t *catalog_bitmap;
 int catalog_size;
 
@@ -109,23 +107,16 @@ static int bochs_probe(const uint8_t *bu
 return 0;
 }
 
-static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
+static int bochs_open(BlockDriverState *bs, int flags)
 {
 BDRVBochsState *s = bs-opaque;
-int fd, i;
+int i;
 struct bochs_header bochs;
 struct bochs_header_v1 header_v1;
 
-fd = open(filename, O_RDONLY | O_BINARY);
-if (fd  0) {
-return -1;
-}
-
 bs-read_only = 1; // no write support yet
 
-s-fd = fd;
-
-if (pread(fd, bochs, sizeof(bochs), 0) != sizeof(bochs)) {
+if (bdrv_pread(bs-file, 0, bochs, sizeof(bochs)) != sizeof(bochs)) {
 goto fail;
 }
 
@@ -146,8 +137,8 @@ static int bochs_open(BlockDriverState *
 
 s-catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
 s-catalog_bitmap = qemu_malloc(s-catalog_size * 4);
-if (pread(s-fd, s-catalog_bitmap, s-catalog_size * 4,
-  le32_to_cpu(bochs.header)) != s-catalog_size * 4)
+if (bdrv_pread(bs-file, le32_to_cpu(bochs.header), s-catalog_bitmap,
+   s-catalog_size * 4) != s-catalog_size * 4)
goto fail;
 for (i = 0; i  s-catalog_size; i++)
le32_to_cpus(s-catalog_bitmap[i]);
@@ -161,7 +152,6 @@ static int bochs_open(BlockDriverState *
 
 return 0;
  fail:
-close(fd);
 return -1;
 }
 
@@ -184,8 +174,8 @@ static int64_t seek_to_sector(BlockDrive
(s-extent_blocks + s-bitmap_blocks));
 
 /* read in bitmap for current extent */
-if (pread(s-fd, bitmap_entry, 1, bitmap_offset + (extent_offset / 8))
-!= 1) {
+if (bdrv_pread(bs-file, bitmap_offset + (extent_offset / 8),
+   bitmap_entry, 1) != 1) {
 return -1;
 }
 
@@ -199,13 +189,12 @@ static int64_t seek_to_sector(BlockDrive
 static int bochs_read(BlockDriverState *bs, int64_t sector_num,
 uint8_t *buf, int nb_sectors)
 {
-BDRVBochsState *s = bs-opaque;
 int ret;
 
 while (nb_sectors  0) {
 int64_t block_offset = seek_to_sector(bs, sector_num);
 if (block_offset = 0) {
-ret = pread(s-fd, buf, 512, block_offset);
+ret = bdrv_pread(bs-file, block_offset, buf, 512);
 if (ret != 512) {
 return -1;
 }
@@ -222,14 +211,13 @@ static void bochs_close(BlockDriverState
 {
 BDRVBochsState *s = bs-opaque;
 qemu_free(s-catalog_bitmap);
-close(s-fd);
 }
 
 static BlockDriver bdrv_bochs = {
 .format_name   = bochs,
 .instance_size = sizeof(BDRVBochsState),
 .bdrv_probe= bochs_probe,
-.bdrv_file_open= bochs_open,
+.bdrv_open = bochs_open,
 .bdrv_read = bochs_read,
 .bdrv_close= bochs_close,
 };




[Qemu-devel] [PATCH 3/6] cloop: use pread

2010-05-04 Thread Christoph Hellwig
Use pread instead of lseek + read in preparation of using the qemu
block API.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/cloop.c
===
--- qemu-kevin.orig/block/cloop.c   2010-05-03 13:01:09.035025542 +0200
+++ qemu-kevin/block/cloop.c2010-05-03 13:01:57.918284307 +0200
@@ -62,23 +62,22 @@ static int cloop_open(BlockDriverState *
 bs-read_only = 1;
 
 /* read header */
-if(lseek(s-fd,128,SEEK_SET)0) {
-cloop_close:
-   close(s-fd);
-   return -1;
+if (pread(s-fd, s-block_size, 4, 128)  4) {
+goto cloop_close;
 }
-if(read(s-fd,s-block_size,4)4)
-   goto cloop_close;
-s-block_size=be32_to_cpu(s-block_size);
-if(read(s-fd,s-n_blocks,4)4)
-   goto cloop_close;
-s-n_blocks=be32_to_cpu(s-n_blocks);
+s-block_size = be32_to_cpu(s-block_size);
+
+if (pread(s-fd, s-n_blocks, 4, 128 + 4)  4) {
+goto cloop_close;
+}
+s-n_blocks = be32_to_cpu(s-n_blocks);
 
 /* read offsets */
-offsets_size=s-n_blocks*sizeof(uint64_t);
-s-offsets=(uint64_t*)qemu_malloc(offsets_size);
-if(read(s-fd,s-offsets,offsets_size)offsets_size)
+offsets_size = s-n_blocks * sizeof(uint64_t);
+s-offsets = qemu_malloc(offsets_size);
+if (pread(s-fd, s-offsets, offsets_size, 128 + 4 + 4)  offsets_size) {
goto cloop_close;
+}
 for(i=0;is-n_blocks;i++) {
s-offsets[i]=be64_to_cpu(s-offsets[i]);
if(i0) {
@@ -98,6 +97,10 @@ cloop_close:
 s-sectors_per_block = s-block_size/512;
 bs-total_sectors = s-n_blocks*s-sectors_per_block;
 return 0;
+
+cloop_close:
+close(s-fd);
+return -1;
 }
 
 static inline int cloop_read_block(BDRVCloopState *s,int block_num)
@@ -106,8 +109,7 @@ static inline int cloop_read_block(BDRVC
int ret;
 uint32_t bytes = s-offsets[block_num+1]-s-offsets[block_num];
 
-   lseek(s-fd, s-offsets[block_num], SEEK_SET);
-ret = read(s-fd, s-compressed_block, bytes);
+ret = pread(s-fd, s-compressed_block, bytes, s-offsets[block_num]);
 if (ret != bytes)
 return -1;
 




[Qemu-devel] [PATCH 4/6] cloop: use qemu block API

2010-05-04 Thread Christoph Hellwig
Use bdrv_pwrite to access the backing device instead of pread, and
convert the driver to implementing the bdrv_open method which gives
it an already opened BlockDriverState for the underlying device.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/cloop.c
===
--- qemu-kevin.orig/block/cloop.c   2010-05-03 13:01:57.918284307 +0200
+++ qemu-kevin/block/cloop.c2010-05-03 13:02:27.836318598 +0200
@@ -27,7 +27,6 @@
 #include zlib.h
 
 typedef struct BDRVCloopState {
-int fd;
 uint32_t block_size;
 uint32_t n_blocks;
 uint64_t* offsets;
@@ -51,23 +50,20 @@ static int cloop_probe(const uint8_t *bu
 return 0;
 }
 
-static int cloop_open(BlockDriverState *bs, const char *filename, int flags)
+static int cloop_open(BlockDriverState *bs, int flags)
 {
 BDRVCloopState *s = bs-opaque;
 uint32_t offsets_size,max_compressed_block_size=1,i;
 
-s-fd = open(filename, O_RDONLY | O_BINARY);
-if (s-fd  0)
-return -errno;
 bs-read_only = 1;
 
 /* read header */
-if (pread(s-fd, s-block_size, 4, 128)  4) {
+if (bdrv_pread(bs-file, 128, s-block_size, 4)  4) {
 goto cloop_close;
 }
 s-block_size = be32_to_cpu(s-block_size);
 
-if (pread(s-fd, s-n_blocks, 4, 128 + 4)  4) {
+if (bdrv_pread(bs-file, 128 + 4, s-n_blocks, 4)  4) {
 goto cloop_close;
 }
 s-n_blocks = be32_to_cpu(s-n_blocks);
@@ -75,7 +71,8 @@ static int cloop_open(BlockDriverState *
 /* read offsets */
 offsets_size = s-n_blocks * sizeof(uint64_t);
 s-offsets = qemu_malloc(offsets_size);
-if (pread(s-fd, s-offsets, offsets_size, 128 + 4 + 4)  offsets_size) {
+if (bdrv_pread(bs-file, 128 + 4 + 4, s-offsets, offsets_size) 
+offsets_size) {
goto cloop_close;
 }
 for(i=0;is-n_blocks;i++) {
@@ -99,17 +96,19 @@ static int cloop_open(BlockDriverState *
 return 0;
 
 cloop_close:
-close(s-fd);
 return -1;
 }
 
-static inline int cloop_read_block(BDRVCloopState *s,int block_num)
+static inline int cloop_read_block(BlockDriverState *bs, int block_num)
 {
+BDRVCloopState *s = bs-opaque;
+
 if(s-current_block != block_num) {
int ret;
 uint32_t bytes = s-offsets[block_num+1]-s-offsets[block_num];
 
-ret = pread(s-fd, s-compressed_block, bytes, s-offsets[block_num]);
+ret = bdrv_pread(bs-file, s-offsets[block_num], s-compressed_block,
+ bytes);
 if (ret != bytes)
 return -1;
 
@@ -138,7 +137,7 @@ static int cloop_read(BlockDriverState *
 for(i=0;inb_sectors;i++) {
uint32_t sector_offset_in_block=((sector_num+i)%s-sectors_per_block),
block_num=(sector_num+i)/s-sectors_per_block;
-   if(cloop_read_block(s, block_num) != 0)
+   if(cloop_read_block(bs, block_num) != 0)
return -1;
memcpy(buf+i*512,s-uncompressed_block+sector_offset_in_block*512,512);
 }
@@ -148,7 +147,6 @@ static int cloop_read(BlockDriverState *
 static void cloop_close(BlockDriverState *bs)
 {
 BDRVCloopState *s = bs-opaque;
-close(s-fd);
 if(s-n_blocks0)
free(s-offsets);
 free(s-compressed_block);
@@ -160,7 +158,7 @@ static BlockDriver bdrv_cloop = {
 .format_name   = cloop,
 .instance_size = sizeof(BDRVCloopState),
 .bdrv_probe= cloop_probe,
-.bdrv_file_open= cloop_open,
+.bdrv_open = cloop_open,
 .bdrv_read = cloop_read,
 .bdrv_close= cloop_close,
 };




[Qemu-devel] [PATCH 5/6] parallels: use pread

2010-05-04 Thread Christoph Hellwig
Use pread instead of lseek + read in preparation of using the qemu
block API.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/parallels.c
===
--- qemu-kevin.orig/block/parallels.c   2010-05-03 13:00:09.711253925 +0200
+++ qemu-kevin/block/parallels.c2010-05-03 13:04:15.686033993 +0200
@@ -83,7 +83,7 @@ static int parallels_open(BlockDriverSta
 
 s-fd = fd;
 
-if (read(fd, ph, sizeof(ph)) != sizeof(ph))
+if (pread(fd, ph, sizeof(ph), 0) != sizeof(ph))
 goto fail;
 
 if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
@@ -93,14 +93,11 @@ static int parallels_open(BlockDriverSta
 
 bs-total_sectors = le32_to_cpu(ph.nb_sectors);
 
-if (lseek(s-fd, 64, SEEK_SET) != 64)
-   goto fail;
-
 s-tracks = le32_to_cpu(ph.tracks);
 
 s-catalog_size = le32_to_cpu(ph.catalog_entries);
 s-catalog_bitmap = qemu_malloc(s-catalog_size * 4);
-if (read(s-fd, s-catalog_bitmap, s-catalog_size * 4) !=
+if (pread(s-fd, s-catalog_bitmap, s-catalog_size * 4, 64) !=
s-catalog_size * 4)
goto fail;
 for (i = 0; i  s-catalog_size; i++)
@@ -114,28 +111,18 @@ fail:
 return -1;
 }
 
-static inline int seek_to_sector(BlockDriverState *bs, int64_t sector_num)
+static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num)
 {
 BDRVParallelsState *s = bs-opaque;
 uint32_t index, offset;
-uint64_t position;
 
 index = sector_num / s-tracks;
 offset = sector_num % s-tracks;
 
-// not allocated
+/* not allocated */
 if ((index  s-catalog_size) || (s-catalog_bitmap[index] == 0))
return -1;
-
-position = (uint64_t)(s-catalog_bitmap[index] + offset) * 512;
-
-//fprintf(stderr, sector: %llx index=%x offset=%x pointer=%x 
position=%x\n,
-// sector_num, index, offset, s-catalog_bitmap[index], position);
-
-if (lseek(s-fd, position, SEEK_SET) != position)
-   return -1;
-
-return 0;
+return (uint64_t)(s-catalog_bitmap[index] + offset) * 512;
 }
 
 static int parallels_read(BlockDriverState *bs, int64_t sector_num,
@@ -144,11 +131,13 @@ static int parallels_read(BlockDriverSta
 BDRVParallelsState *s = bs-opaque;
 
 while (nb_sectors  0) {
-   if (!seek_to_sector(bs, sector_num)) {
-   if (read(s-fd, buf, 512) != 512)
-   return -1;
-   } else
+uint64_t position = seek_to_sector(bs, sector_num);
+if (position = 0) {
+if (pread(s-fd, buf, 512, position) != 512)
+return -1;
+} else {
 memset(buf, 0, 512);
+}
 nb_sectors--;
 sector_num++;
 buf += 512;




[Qemu-devel] [PATCH 6/6] parallels: use qemu block API

2010-05-04 Thread Christoph Hellwig
Use bdrv_pwrite to access the backing device instead of pread, and
convert the driver to implementing the bdrv_open method which gives
it an already opened BlockDriverState for the underlying device.

Signed-off-by: Christoph Hellwig h...@lst.de

Index: qemu-kevin/block/parallels.c
===
--- qemu-kevin.orig/block/parallels.c   2010-05-03 13:04:37.494261748 +0200
+++ qemu-kevin/block/parallels.c2010-05-03 13:05:55.781255810 +0200
@@ -46,7 +46,6 @@ struct parallels_header {
 } __attribute__((packed));
 
 typedef struct BDRVParallelsState {
-int fd;
 
 uint32_t *catalog_bitmap;
 int catalog_size;
@@ -68,22 +67,15 @@ static int parallels_probe(const uint8_t
 return 0;
 }
 
-static int parallels_open(BlockDriverState *bs, const char *filename, int 
flags)
+static int parallels_open(BlockDriverState *bs, int flags)
 {
 BDRVParallelsState *s = bs-opaque;
-int fd, i;
+int i;
 struct parallels_header ph;
 
-fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
-if (fd  0) {
-return -1;
-}
-
 bs-read_only = 1; // no write support yet
 
-s-fd = fd;
-
-if (pread(fd, ph, sizeof(ph), 0) != sizeof(ph))
+if (bdrv_pread(bs-file, 0, ph, sizeof(ph)) != sizeof(ph))
 goto fail;
 
 if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
@@ -97,7 +89,7 @@ static int parallels_open(BlockDriverSta
 
 s-catalog_size = le32_to_cpu(ph.catalog_entries);
 s-catalog_bitmap = qemu_malloc(s-catalog_size * 4);
-if (pread(s-fd, s-catalog_bitmap, s-catalog_size * 4, 64) !=
+if (bdrv_pread(bs-file, 64, s-catalog_bitmap, s-catalog_size * 4) !=
s-catalog_size * 4)
goto fail;
 for (i = 0; i  s-catalog_size; i++)
@@ -107,7 +99,6 @@ static int parallels_open(BlockDriverSta
 fail:
 if (s-catalog_bitmap)
qemu_free(s-catalog_bitmap);
-close(fd);
 return -1;
 }
 
@@ -128,12 +119,10 @@ static int64_t seek_to_sector(BlockDrive
 static int parallels_read(BlockDriverState *bs, int64_t sector_num,
 uint8_t *buf, int nb_sectors)
 {
-BDRVParallelsState *s = bs-opaque;
-
 while (nb_sectors  0) {
 uint64_t position = seek_to_sector(bs, sector_num);
 if (position = 0) {
-if (pread(s-fd, buf, 512, position) != 512)
+if (bdrv_pread(bs-file, position, buf, 512) != 512)
 return -1;
 } else {
 memset(buf, 0, 512);
@@ -149,14 +138,13 @@ static void parallels_close(BlockDriverS
 {
 BDRVParallelsState *s = bs-opaque;
 qemu_free(s-catalog_bitmap);
-close(s-fd);
 }
 
 static BlockDriver bdrv_parallels = {
 .format_name   = parallels,
 .instance_size = sizeof(BDRVParallelsState),
 .bdrv_probe= parallels_probe,
-.bdrv_file_open= parallels_open,
+.bdrv_open = parallels_open,
 .bdrv_read = parallels_read,
 .bdrv_close= parallels_close,
 };




[Qemu-devel] [PATCH v5 1/6] virtio-console: Factor out common init between console and generic ports

2010-05-04 Thread Amit Shah
The initialisation for generic ports and console ports is similar.
Factor out the parts that are the same in a different function that can
be called from each of the initfns.

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

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index caea11f..d7fe68b 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -58,24 +58,28 @@ static void chr_event(void *opaque, int event)
 }
 }
 
-/* Virtio Console Ports */
-static int virtconsole_initfn(VirtIOSerialDevice *dev)
+static int generic_port_init(VirtConsole *vcon, VirtIOSerialDevice *dev)
 {
-VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
-VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
-
-port-info = dev-info;
-
-port-is_console = true;
+vcon-port.info = dev-info;
 
 if (vcon-chr) {
 qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read, chr_event,
   vcon);
-port-info-have_data = flush_buf;
+vcon-port.info-have_data = flush_buf;
 }
 return 0;
 }
 
+/* Virtio Console Ports */
+static int virtconsole_initfn(VirtIOSerialDevice *dev)
+{
+VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
+VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
+
+port-is_console = true;
+return generic_port_init(vcon, dev);
+}
+
 static int virtconsole_exitfn(VirtIOSerialDevice *dev)
 {
 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
@@ -115,14 +119,7 @@ static int virtserialport_initfn(VirtIOSerialDevice *dev)
 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, dev-qdev);
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-port-info = dev-info;
-
-if (vcon-chr) {
-qemu_chr_add_handlers(vcon-chr, chr_can_read, chr_read, chr_event,
-  vcon);
-port-info-have_data = flush_buf;
-}
-return 0;
+return generic_port_init(vcon, dev);
 }
 
 static VirtIOSerialPortInfo virtserialport_info = {
-- 
1.6.2.5





[Qemu-devel] [PATCH v5 0/6] char: non-blocking writes, virtio-console flow control

2010-05-04 Thread Amit Shah
Hello,

This series lets interested callers ask for an -EAGAIN return from the
chardev backends (only unix and tcp sockets as of now) to implement
their own flow control.

A new call, qemu_chr_write_nb() is added, that will fallback to
qemu_chr_write() if the backend file isn't non-blocking or if no
callback was supplied.

Support for other backend types is easy to add and will be done in
later patches.

v5:
- Fix bug pointed out by Gerd
- Convert to using a struct for passing on handlers to
  qemu_chr_add_handlers() instead of passing each one
  individually. Simplifies patches. (Inspired by Juan's comment)
- Re-arranged patches

Amit Shah (6):
  virtio-console: Factor out common init between console and generic
ports
  char: Add a QemuChrHandlers struct to initialise chardev handlers
  char: Let writers know how much data was written in case of errors
  char: Add qemu_chr_write_nb() for nonblocking writes
  char: unix/tcp: Add a non-blocking write handler
  virtio-console: Throttle virtio-serial-bus if we can't consume any
more guest data

 gdbstub.c|9 ++-
 hw/debugcon.c|2 +-
 hw/escc.c|9 ++-
 hw/etraxfs_ser.c |   13 +++-
 hw/mcf_uart.c|9 ++-
 hw/pl011.c   |9 ++-
 hw/pxa2xx.c  |   13 +++-
 hw/serial.c  |9 ++-
 hw/sh_serial.c   |   12 +++-
 hw/syborg_serial.c   |9 ++-
 hw/usb-serial.c  |9 ++-
 hw/virtio-console.c  |  162 +++--
 hw/xen_console.c |   16 --
 hw/xilinx_uartlite.c |   11 +++-
 monitor.c|   19 +-
 net/slirp.c  |8 ++-
 net/socket.c |4 +-
 qemu-char.c  |  119 +++--
 qemu-char.h  |   20 +-
 qemu_socket.h|3 +-
 20 files changed, 381 insertions(+), 84 deletions(-)





[Qemu-devel] [PATCH v5 3/6] char: Let writers know how much data was written in case of errors

2010-05-04 Thread Amit Shah
On writing errors, we just returned -1 even if some bytes were already
written out. Ensure we return the number of bytes written before we
return the error (on a subsequent call to qemu_chr_write()).

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 qemu-char.c |9 -
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 65cb3f5..97f2ef6 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -507,6 +507,9 @@ int send_all(int fd, const void *buf, int len1)
 while (len  0) {
 ret = send(fd, buf, len, 0);
 if (ret  0) {
+if (len1 - len) {
+return len1 - len;
+}
 errno = WSAGetLastError();
 if (errno != WSAEWOULDBLOCK) {
 return -1;
@@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
 while (len  0) {
 ret = write(fd, buf, len);
 if (ret  0) {
-if (errno != EINTR  errno != EAGAIN)
+if (len1 - len) {
+return len1 - len;
+}
+if (errno != EINTR  errno != EAGAIN) {
 return -1;
+}
 } else if (ret == 0) {
 break;
 } else {
-- 
1.6.2.5





[Qemu-devel] [PATCH v5 4/6] char: Add qemu_chr_write_nb() for nonblocking writes

2010-05-04 Thread Amit Shah
For char devices whose backing files are open in non-blocking mode,
non-blocking writes can now be made using qemu_chr_write_nb().

For non-blocking chardevs, we can return -EAGAIN to callers of
qemu_chr_write_nb(). When the backend is ready to accept more data,
we can let the caller know via a callback.

-EAGAIN is returned only when the backend's file is non-blocking
and a callback is registered by the caller when invoking
qemu_chr_add_handlers().

In case a backend doesn't support non-blocking writes,
qemu_chr_write_nb() invokes qemu_chr_write().

Individual callers can update their code to add a callback handler,
call qemu_chr_write_nb() instead of qemu_chr_write() if they wish to
receive -EAGAIN notifications.

No backend currently supports non-blocking writes.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 net/socket.c  |4 ++--
 qemu-char.c   |   31 ---
 qemu-char.h   |8 
 qemu_socket.h |3 ++-
 4 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index 1c4e153..8a401e6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -56,8 +56,8 @@ static ssize_t net_socket_receive(VLANClientState *nc, const 
uint8_t *buf, size_
 uint32_t len;
 len = htonl(size);
 
-send_all(s-fd, (const uint8_t *)len, sizeof(len));
-return send_all(s-fd, buf, size);
+send_all(s-fd, (const uint8_t *)len, sizeof(len), false);
+return send_all(s-fd, buf, size, false);
 }
 
 static ssize_t net_socket_receive_dgram(VLANClientState *nc, const uint8_t 
*buf, size_t size)
diff --git a/qemu-char.c b/qemu-char.c
index 97f2ef6..d383c8f 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -145,6 +145,16 @@ int qemu_chr_write(CharDriverState *s, const uint8_t *buf, 
int len)
 return s-chr_write(s, buf, len);
 }
 
+ssize_t qemu_chr_write_nb(CharDriverState *s, const uint8_t *buf, size_t len)
+{
+if (!s-nonblock) {
+/* Fallback to blocking write if no callback registered */
+return qemu_chr_write(s, buf, len);
+}
+
+return s-chr_write_nb(s, buf, len);
+}
+
 int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
 {
 if (!s-chr_ioctl)
@@ -203,11 +213,15 @@ void qemu_chr_add_handlers(CharDriverState *s,
 }
 s-chr_can_read = handlers-fd_can_read;
 s-chr_read = handlers-fd_read;
+s-chr_write_unblocked = handlers-fd_write_unblocked;
 s-chr_event = handlers-fd_event;
 s-handler_opaque = opaque;
 if (s-chr_update_read_handler)
 s-chr_update_read_handler(s);
 
+/* We'll set this at connect-time */
+s-nonblock = false;
+
 /* We're connecting to an already opened device, so let's make sure we
also get the open event */
 if (s-opened) {
@@ -499,7 +513,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState 
*drv)
 
 
 #ifdef _WIN32
-int send_all(int fd, const void *buf, int len1)
+int send_all(int fd, const void *buf, int len1, bool nonblock)
 {
 int ret, len;
 
@@ -526,7 +540,7 @@ int send_all(int fd, const void *buf, int len1)
 
 #else
 
-static int unix_write(int fd, const uint8_t *buf, int len1)
+static int unix_write(int fd, const uint8_t *buf, int len1, bool nonblock)
 {
 int ret, len;
 
@@ -537,6 +551,9 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
 if (len1 - len) {
 return len1 - len;
 }
+if (errno == EAGAIN  nonblock) {
+return -EAGAIN;
+}
 if (errno != EINTR  errno != EAGAIN) {
 return -1;
 }
@@ -550,9 +567,9 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
 return len1 - len;
 }
 
-int send_all(int fd, const void *buf, int len1)
+int send_all(int fd, const void *buf, int len1, bool nonblock)
 {
-return unix_write(fd, buf, len1);
+return unix_write(fd, buf, len1, nonblock);
 }
 #endif /* !_WIN32 */
 
@@ -569,7 +586,7 @@ static int stdio_nb_clients = 0;
 static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
 {
 FDCharDriver *s = chr-opaque;
-return send_all(s-fd_out, buf, len);
+return send_all(s-fd_out, buf, len, false);
 }
 
 static int fd_chr_read_poll(void *opaque)
@@ -881,7 +898,7 @@ static int pty_chr_write(CharDriverState *chr, const 
uint8_t *buf, int len)
 pty_chr_update_read_handler(chr);
 return 0;
 }
-return send_all(s-fd, buf, len);
+return send_all(s-fd, buf, len, false);
 }
 
 static int pty_chr_read_poll(void *opaque)
@@ -1946,7 +1963,7 @@ static int tcp_chr_write(CharDriverState *chr, const 
uint8_t *buf, int len)
 {
 TCPCharDriver *s = chr-opaque;
 if (s-connected) {
-return send_all(s-fd, buf, len);
+return send_all(s-fd, buf, len, false);
 } else {
 /* XXX: indicate an error ? */
 return len;
diff --git a/qemu-char.h b/qemu-char.h
index 6ff490b..7b10b2b 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -1,6 +1,8 @@
 #ifndef QEMU_CHAR_H
 #define 

[Qemu-devel] [PATCH v5 2/6] char: Add a QemuChrHandlers struct to initialise chardev handlers

2010-05-04 Thread Amit Shah
Instead of passing each handler in the qemu_add_handlers() function,
create a struct of handlers that can be passed to the function instead.

Signed-off-by: Amit Shah amit.s...@redhat.com
---
 gdbstub.c|9 +++--
 hw/debugcon.c|2 +-
 hw/escc.c|9 +++--
 hw/etraxfs_ser.c |   13 +
 hw/mcf_uart.c|9 +++--
 hw/pl011.c   |9 +++--
 hw/pxa2xx.c  |   13 +
 hw/serial.c  |9 +++--
 hw/sh_serial.c   |   12 +---
 hw/syborg_serial.c   |9 +++--
 hw/usb-serial.c  |9 +++--
 hw/virtio-console.c  |9 +++--
 hw/xen_console.c |   16 +++-
 hw/xilinx_uartlite.c |   11 +--
 monitor.c|   19 +++
 net/slirp.c  |8 ++--
 qemu-char.c  |   27 ++-
 qemu-char.h  |   12 
 18 files changed, 151 insertions(+), 54 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 93c4850..7b981ce 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2621,6 +2621,12 @@ static void gdb_sigterm_handler(int signal)
 }
 #endif
 
+static QemuChrHandlers gdb_handlers = {
+.fd_can_read = gdb_chr_can_receive,
+.fd_read = gdb_chr_receive,
+.fd_event = gdb_chr_event,
+};
+
 int gdbserver_start(const char *device)
 {
 GDBState *s;
@@ -2650,8 +2656,7 @@ int gdbserver_start(const char *device)
 if (!chr)
 return -1;
 
-qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
-  gdb_chr_event, NULL);
+qemu_chr_add_handlers(chr, gdb_handlers, NULL);
 }
 
 s = gdbserver_state;
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 5ee6821..e79a595 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -73,7 +73,7 @@ static void debugcon_init_core(DebugconState *s)
 exit(1);
 }
 
-qemu_chr_add_handlers(s-chr, NULL, NULL, NULL, s);
+qemu_chr_add_handlers(s-chr, NULL, s);
 }
 
 static int debugcon_isa_initfn(ISADevice *dev)
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..1978bf7 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -890,6 +890,12 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, 
qemu_irq irq,
 sysbus_mmio_map(s, 0, base);
 }
 
+static QemuChrHandlers serial_handlers = {
+.fd_can_read = serial_can_receive,
+.fd_read = serial_receive1,
+.fd_event = serial_event,
+};
+
 static int escc_init1(SysBusDevice *dev)
 {
 SerialState *s = FROM_SYSBUS(SerialState, dev);
@@ -903,8 +909,7 @@ static int escc_init1(SysBusDevice *dev)
 s-chn[i].chn = 1 - i;
 s-chn[i].clock = s-frequency / 2;
 if (s-chn[i].chr) {
-qemu_chr_add_handlers(s-chn[i].chr, serial_can_receive,
-  serial_receive1, serial_event, s-chn[i]);
+qemu_chr_add_handlers(s-chn[i].chr, serial_handlers, s-chn[i]);
 }
 }
 s-chn[0].otherchn = s-chn[1];
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index e1f9615..e22f770 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -161,6 +161,12 @@ static void serial_event(void *opaque, int event)
 
 }
 
+static QemuChrHandlers serial_handlers = {
+.fd_can_read = serial_can_receive,
+.fd_read = serial_receive,
+.fd_event = serial_event,
+};
+
 static int etraxfs_ser_init(SysBusDevice *dev)
 {
 struct etrax_serial *s = FROM_SYSBUS(typeof (*s), dev);
@@ -174,10 +180,9 @@ static int etraxfs_ser_init(SysBusDevice *dev)
 ser_regs = cpu_register_io_memory(ser_read, ser_write, s);
 sysbus_init_mmio(dev, R_MAX * 4, ser_regs);
 s-chr = qdev_init_chardev(dev-qdev);
-if (s-chr)
-qemu_chr_add_handlers(s-chr,
-  serial_can_receive, serial_receive,
-  serial_event, s);
+if (s-chr) {
+qemu_chr_add_handlers(s-chr, serial_handlers, s);
+}
 return 0;
 }
 
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index d16bac7..301b901 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -268,6 +268,12 @@ static void mcf_uart_receive(void *opaque, const uint8_t 
*buf, int size)
 mcf_uart_push_byte(s, buf[0]);
 }
 
+static QemuChrHandlers mcf_uart_handlers = {
+.fd_can_read = mcf_uart_can_receive,
+.fd_read = mcf_uart_receive,
+.fd_event = mcf_uart_event,
+};
+
 void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
 {
 mcf_uart_state *s;
@@ -276,8 +282,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
 s-chr = chr;
 s-irq = irq;
 if (chr) {
-qemu_chr_add_handlers(chr, mcf_uart_can_receive, mcf_uart_receive,
-  mcf_uart_event, s);
+qemu_chr_add_handlers(chr, mcf_uart_handlers, s);
 }
 mcf_uart_reset(s);
 return s;
diff --git a/hw/pl011.c b/hw/pl011.c
index 81de91e..8e5356e 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -286,6 +286,12 @@ static int pl011_load(QEMUFile *f, void *opaque, int 
version_id)
 return 0;
 }

[Qemu-devel] [PATCH v5 6/6] virtio-console: Throttle virtio-serial-bus if we can't consume any more guest data

2010-05-04 Thread Amit Shah
If the char device we're connected to is overwhelmed with data and it
can't accept any more, signal to the virtio-serial-bus to stop sending
us more data till we tell otherwise.

If the current buffer being processed hasn't been completely written out
to the char device, we have to keep it around and re-try sending it
since the virtio-serial-bus code assumes we consume the entire buffer.

Allow the chardev backends to return -EAGAIN; we're ready with a
callback handler that will flush the remainder of the buffer.

Also register with savevm so that we save/restore such a buffer across
migration.

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

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 749ed59..7eb6aa1 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -13,18 +13,92 @@
 #include qemu-char.h
 #include virtio-serial.h
 
+typedef struct Buffer {
+uint8_t *buf;
+size_t rem_len;
+size_t offset;
+} Buffer;
+
 typedef struct VirtConsole {
 VirtIOSerialPort port;
 CharDriverState *chr;
+Buffer *unflushed_buf;
 } VirtConsole;
 
+static void add_unflushed_buf(VirtConsole *vcon, const uint8_t *buf, size_t 
len)
+{
+vcon-unflushed_buf = qemu_malloc(sizeof(Buffer));
+vcon-unflushed_buf-buf = qemu_malloc(len);
+
+memcpy(vcon-unflushed_buf-buf, buf, len);
+vcon-unflushed_buf-rem_len = len;
+vcon-unflushed_buf-offset = 0;
+}
+
+static void free_unflushed_buf(VirtConsole *vcon)
+{
+if (vcon-unflushed_buf) {
+qemu_free(vcon-unflushed_buf-buf);
+qemu_free(vcon-unflushed_buf);
+vcon-unflushed_buf = NULL;
+}
+}
+
+static int buffered_write_to_chardev(VirtConsole *vcon, const uint8_t *buf,
+ size_t len)
+{
+size_t written;
+ssize_t ret;
+
+written = 0;
+do {
+ret = qemu_chr_write_nb(vcon-chr, buf + written, len - written);
+if (ret  0) {
+if (vcon-unflushed_buf) {
+vcon-unflushed_buf-offset += written;
+vcon-unflushed_buf-rem_len -= written;
+} else {
+virtio_serial_throttle_port(vcon-port, true);
+add_unflushed_buf(vcon, buf + written, len - written);
+}
+
+return -EAGAIN;
+}
+
+written += ret;
+} while (written != len);
+
+return 0;
+}
+
+/* Callback function called when the chardev can accept more data */
+static void chr_write_unblocked(void *opaque)
+{
+VirtConsole *vcon = opaque;
+
+if (vcon-unflushed_buf) {
+int ret;
+
+ret = buffered_write_to_chardev(vcon, vcon-unflushed_buf-buf
+  + vcon-unflushed_buf-offset,
+vcon-unflushed_buf-rem_len);
+if (ret  0) {
+return;
+}
+free_unflushed_buf(vcon);
+}
+virtio_serial_throttle_port(vcon-port, false);
+}
 
 /* Callback function that's called when the guest sends us data */
 static void flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
 {
 VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-qemu_chr_write(vcon-chr, buf, len);
+/* If a previous write was incomplete, we should've been throttled. */
+assert(!vcon-unflushed_buf);
+
+buffered_write_to_chardev(vcon, buf, len);
 }
 
 /* Readiness of the guest to accept data on a port */
@@ -48,19 +122,62 @@ static void chr_event(void *opaque, int event)
 VirtConsole *vcon = opaque;
 
 switch (event) {
-case CHR_EVENT_OPENED: {
+case CHR_EVENT_OPENED:
 virtio_serial_open(vcon-port);
 break;
-}
+
 case CHR_EVENT_CLOSED:
+if (vcon-unflushed_buf) {
+free_unflushed_buf(vcon);
+}
 virtio_serial_close(vcon-port);
 break;
 }
 }
 
+static void virtio_console_port_save(QEMUFile *f, void *opaque)
+{
+VirtConsole *vcon = opaque;
+uint32_t have_buffer;
+
+have_buffer = vcon-unflushed_buf ? true : false;
+
+qemu_put_be32s(f, have_buffer);
+if (have_buffer) {
+qemu_put_be64s(f, vcon-unflushed_buf-rem_len);
+qemu_put_buffer(f, vcon-unflushed_buf-buf
+   + vcon-unflushed_buf-offset,
+vcon-unflushed_buf-rem_len);
+}
+}
+
+static int virtio_console_port_load(QEMUFile *f, void *opaque, int version_id)
+{
+VirtConsole *vcon = opaque;
+uint32_t have_buffer;
+
+if (version_id  1) {
+return -EINVAL;
+}
+
+qemu_get_be32s(f, have_buffer);
+if (have_buffer) {
+vcon-unflushed_buf = qemu_mallocz(sizeof(Buffer));
+
+qemu_get_be64s(f, vcon-unflushed_buf-rem_len);
+vcon-unflushed_buf-buf = qemu_malloc(vcon-unflushed_buf-rem_len);
+vcon-unflushed_buf-offset = 0;
+
+qemu_get_buffer(f, 

[Qemu-devel] [PATCH] iov: Move from hw/ to topdir

2010-05-04 Thread Amit Shah
The iov functions can be useful to other code as well.

Signed-off-by: Amit Shah amit.s...@redhat.com
CC: Christoph Hellwig h...@lst.de
---
 hw/iov.c = iov.c |0
 hw/iov.h = iov.h |0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename hw/iov.c = iov.c (100%)
 rename hw/iov.h = iov.h (100%)

diff --git a/hw/iov.c b/iov.c
similarity index 100%
rename from hw/iov.c
rename to iov.c
diff --git a/hw/iov.h b/iov.h
similarity index 100%
rename from hw/iov.h
rename to iov.h
-- 
1.6.2.5





[Qemu-devel] [PATCH 3/4] doc: Heading for monitor command cpu got lost, restore it

2010-05-04 Thread Markus Armbruster
Broken in commit 2313086a.

Signed-off-by: Markus Armbruster arm...@redhat.com
---
 qemu-monitor.hx |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index bf47ae0..220ed9c 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -611,6 +611,8 @@ ETEXI
 },
 
 STEXI
+...@item cpu @var{index}
+...@findex cpu
 Set the default CPU.
 ETEXI
 
-- 
1.6.6.1





[Qemu-devel] [PATCH 1/4] doc: Fix host forwarding monitor command documentation

2010-05-04 Thread Markus Armbruster
Commit f3546deb replaced host_net_redir by hostfwd_add,
hostfwd_remove, but neglected to update documentation.

Signed-off-by: Markus Armbruster arm...@redhat.com
---
 qemu-monitor.hx |   13 ++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5ea5748..21aeb6b 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -953,7 +953,14 @@ ETEXI
 .help   = redirect TCP or UDP connections from host to guest 
(requires -net user),
 .mhandler.cmd = net_slirp_hostfwd_add,
 },
+#endif
+STEXI
+...@item hostfwd_add
+...@findex hostfwd_add
+Redirect TCP or UDP connections from host to guest (requires -net user).
+ETEXI
 
+#ifdef CONFIG_SLIRP
 {
 .name   = hostfwd_remove,
 .args_type  = arg1:s,arg2:s?,arg3:s?,
@@ -964,9 +971,9 @@ ETEXI
 
 #endif
 STEXI
-...@item host_net_redir
-...@findex host_net_redir
-Redirect TCP or UDP connections from host to guest (requires -net user).
+...@item hostfwd_remove
+...@findex hostfwd_remove
+Remove host-to-guest TCP or UDP redirection.
 ETEXI
 
 {
-- 
1.6.6.1





[Qemu-devel] [PATCH 2/4] doc: Fix acl monitor command documentation

2010-05-04 Thread Markus Armbruster
Commit 15dfcd45 added acl_add and acl_reset, but fat-fingered their
documentation to read acl_allow and acl_remove.

Signed-off-by: Markus Armbruster arm...@redhat.com
---
 qemu-monitor.hx |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 21aeb6b..bf47ae0 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -1063,8 +1063,8 @@ ETEXI
 },
 
 STEXI
-...@item acl_allow @var{aclname} @var{match} @code{allow|deny} [...@var{index}]
-...@findex acl_allow
+...@item acl_add @var{aclname} @var{match} @code{allow|deny} [...@var{index}]
+...@findex acl_add
 Add a match rule to the access control list, allowing or denying access.
 The match will normally be an exact username or x509 distinguished name,
 but can optionally include wildcard globs. eg @code{*@@EXAMPLE.COM} to
@@ -1096,7 +1096,8 @@ ETEXI
 },
 
 STEXI
-...@item acl_remove @var{aclname}
+...@item acl_reset @var{aclname}
+...@findex acl_reset
 Remove all matches from the access control list, and set the default
 policy back to @code{deny}.
 ETEXI
-- 
1.6.6.1





[Qemu-devel] [PATCH 0/4] doc: Monitor command documentation fixes

2010-05-04 Thread Markus Armbruster
Markus Armbruster (4):
  doc: Fix host forwarding monitor command documentation
  doc: Fix acl monitor command documentation
  doc: Heading for monitor command cpu got lost, restore it
  doc: Clean up monitor command function index

 qemu-monitor.hx |   26 +-
 1 files changed, 17 insertions(+), 9 deletions(-)





Re: [Qemu-devel] [PATCH 1/6] bochs: use pread

2010-05-04 Thread Roy Tam
2010/5/4 Christoph Hellwig h...@lst.de:
 Use pread instead of lseek + read in preparation of using the qemu
 block API.


IIRC there is no pread in MinGW.




[Qemu-devel] Re: [PATCH v5 3/6] char: Let writers know how much data was written in case of errors

2010-05-04 Thread Gerd Hoffmann

@@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
  while (len  0) {
  ret = write(fd, buf, len);
  if (ret  0) {
-if (errno != EINTR  errno != EAGAIN)
+if (len1 - len) {
+return len1 - len;
+}
+if (errno != EINTR  errno != EAGAIN) {
  return -1;
+}


This makes unix_write pass -EINTR up to the caller which it didn't before.

cheers,
  Gerd





[Qemu-devel] [PATCH v5 0/4] Introduce bit-based phys_ram_dirty, and bit-based dirty page checker.

2010-05-04 Thread Yoshiaki Tamura
The dirty and non-dirty pages are checked one by one.  When most of the memory
is not dirty, checking the dirty and non-dirty pages by multiple page size
should be much faster than checking them one by one.  We introduced bit-based
phys_ram_dirty for VGA, CODE, MIGRATION, MASTER, and
cpu_physical_memory_get_dirty_range() for this purpose.

The following numbers show the speed up of bit-based phys_ram_dirty.  The speed
up grows when the number of rows, whose contents are 0, gets larger.

Test Environment:
CPU: 4x Intel Xeon Quad Core 2.66GHz
Mem size: 96GB

Host OS: CentOS (kernel 2.6.33)
Guest OS: Debian/GNU Linux lenny (kernel 2.6.26)
Guest Mem size: 512MB

Conditions of experiments are as follows:
Cond1: Guest OS periodically makes the 256MB continuous dirty pages.
Cond2: Guest OS periodically makes the 256MB dirty pages and non-dirty pages
in turn.
Cond3: Guest OS read 1GB file, which is bigger than memory.
Cond4: Guest OS write 1GB file, which is bigger than memory.

Experimental results:
Cond1: 5 ??? 83 times speed up
Cond2: 5 ??? 52 times speed up
Cond3: 5 ??? 132 times speed up
Cond4: 5 ??? 57 times speed up

Changes from v4 to v5 are:
- Rebased to HEAD (2b644fd0e737407133c88054ba498e772ce01f27)
- Use BITMAP_SIZE() in kvm_physical_sync_dirty_bitmap() (3/4)

Changes from v3 to v4 are:

- Merged {1,2,3}/6 to compile correctly.
- Fix setting bits after phys_ram_dirty allocation.
- renamed DIRTY_FLAG and DIRTY_IDX converter function.

Changes from v2 to v3 are:

- Change FLAGS value to (1,2,4,8), and add IDX (0,1,2,3)
- Use ffs to convert FLAGS to IDX.
- Add a helper function which takes IDX.
- Change the behavior of MASTER as a buffer.
- Change dirty bitmap access to a loop.
- Add brace after if ()

Yoshiaki Tamura (4):
  Modify DIRTY_FLAG value and introduce DIRTY_IDX to use as indexes of
bit-based phys_ram_dirty.
  Introduce cpu_physical_memory_get_dirty_range().
  Use cpu_physical_memory_set_dirty_range() to update phys_ram_dirty.
  Use cpu_physical_memory_get_dirty_range() to check multiple dirty
pages.

 arch_init.c   |   54 ++-
 cpu-all.h |  132 -
 exec.c|   82 +--
 kvm-all.c |   24 --
 qemu-common.h |3 +
 5 files changed, 234 insertions(+), 61 deletions(-)





[Qemu-devel] Re: [PATCH v5 3/6] char: Let writers know how much data was written in case of errors

2010-05-04 Thread Amit Shah
On (Tue) May 04 2010 [13:24:58], Gerd Hoffmann wrote:
 @@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int 
 len1)
   while (len  0) {
   ret = write(fd, buf, len);
   if (ret  0) {
 -if (errno != EINTR  errno != EAGAIN)
 +if (len1 - len) {
 +return len1 - len;
 +}
 +if (errno != EINTR  errno != EAGAIN) {
   return -1;
 +}

 This makes unix_write pass -EINTR up to the caller which it didn't before.

Only on partial writes. Should be OK, no?

Amit




Re: [Qemu-devel] [PATCH 1/6] bochs: use pread

2010-05-04 Thread Christoph Hellwig
On Tue, May 04, 2010 at 07:20:22PM +0800, Roy Tam wrote:
 2010/5/4 Christoph Hellwig h...@lst.de:
  Use pread instead of lseek + read in preparation of using the qemu
  block API.
 
 
 IIRC there is no pread in MinGW.

It gets replaced in the next patch anyway.




Re: [Qemu-devel] Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread Peter Lieven

hi kevin,

i set a breakpint at bmdma_active_if. the first 2 breaks encountered 
when the last path in the multipath

failed, but the assertion was not true.
when i kicked one path back in the breakpoint was reached again, this 
time leading to an assert.

the stacktrace is from the point shortly before.

hope this helps.

br,
peter
--

(gdb) b bmdma_active_if
Breakpoint 2 at 0x43f2e0: file 
/usr/src/qemu-kvm-0.12.3/hw/ide/internal.h, line 507.

(gdb) c
Continuing.
[Switching to Thread 0x7f7b3300d950 (LWP 21171)]

Breakpoint 2, bmdma_active_if (bmdma=0xe31fd8) at 
/usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507

507assert(bmdma-unit != (uint8_t)-1);
(gdb) c
Continuing.

Breakpoint 2, bmdma_active_if (bmdma=0xe31fd8) at 
/usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507

507assert(bmdma-unit != (uint8_t)-1);
(gdb) c
Continuing.

Breakpoint 2, bmdma_active_if (bmdma=0xe31fd8) at 
/usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507

507assert(bmdma-unit != (uint8_t)-1);
(gdb) bt full
#0  bmdma_active_if (bmdma=0xe31fd8) at 
/usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507

   __PRETTY_FUNCTION__ = bmdma_active_if
#1  0x0043f6ba in ide_read_dma_cb (opaque=0xe31fd8, ret=0) at 
/usr/src/qemu-kvm-0.12.3/hw/ide/core.c:554

   bm = (BMDMAState *) 0xe31fd8
   s = (IDEState *) 0xe17940
   n = 0
   sector_num = 0
#2  0x0058730c in dma_bdrv_cb (opaque=0xe17940, ret=0) at 
/usr/src/qemu-kvm-0.12.3/dma-helpers.c:94

   dbs = (DMAAIOCB *) 0xe17940
   cur_addr = 0
   cur_len = 0
   mem = (void *) 0x0
#3  0x0049e510 in qemu_laio_process_completion (s=0xe119c0, 
laiocb=0xe179c0) at linux-aio.c:68

   ret = 0
#4  0x0049e611 in qemu_laio_enqueue_completed (s=0xe119c0, 
laiocb=0xe179c0) at linux-aio.c:107

No locals.
#5  0x0049e787 in qemu_laio_completion_cb (opaque=0xe119c0) at 
linux-aio.c:144

   iocb = (struct iocb *) 0xe179f0
   laiocb = (struct qemu_laiocb *) 0xe179c0
   val = 1
   ret = 8
   nevents = 1
   i = 0
   events = {{data = 0x0, obj = 0xe179f0, res = 4096, res2 = 0}, {data 
= 0x0, obj = 0x0, res = 0, res2 = 0} repeats 46 times, {data = 0x0, 
obj = 0x0, res = 0,
   res2 = 4365191}, {data = 0x429abf, obj = 0x7f7b3300c410, res = 
4614129721674825936, res2 = 14777248}, {data = 0x300018, obj = 
0x7f7b3300c4c0, res = 140167113393152,
   res2 = 47259417504}, {data = 0xe17740, obj = 0xa3300c4e0, res = 
140167113393184, res2 = 0}, {data = 0xe17740, obj = 0x0, res = 0, res2 = 
17}, {data = 0x7f7b3300ccf0,
   obj = 0x92, res = 32, res2 = 168}, {data = 0x7f7b33797a00, obj = 
0x801000, res = 0, res2 = 140167141433408}, {data = 0x7f7b34496e00, obj 
= 0x7f7b33797a00,
   res = 140167113393392, res2 = 8392704}, {data = 0x0, obj = 
0x7f7b34aca040, res = 140167134932480, res2 = 140167118209654}, {data = 
0x7f7b3300d950, obj = 0x42603d, res = 0,
   res2 = 42949672960}, {data = 0x7f7b3300c510, obj = 0xe17ba0, res = 
14776128, res2 = 43805361568}, {data = 0x7f7b3300ced0, obj = 0x42797e, 
res = 0, res2 = 14777248}, {
   data = 0x174, obj = 0x0, res = 373, res2 = 0}, {data = 0x176, obj = 
0x0, res = 3221225601, res2 = 0}, {data = 0x4008ae89c083, obj = 0x0, 
res = 209379655938, res2 = 0}, {
   data = 0x7f7bc084, obj = 0x0, res = 3221225602, res2 = 0}, {data 
= 0x7f7b0012, obj = 0x0, res = 17, res2 = 0}, {data = 0x0, obj = 
0x11, res = 140167113395840,
   res2 = 146}, {data = 0x20, obj = 0xa8, res = 140167121304064, res2 = 
8392704}, {data = 0x0, obj = 0x7f7b34aca040, res = 140167134932480, res2 
= 140167121304064}, {
   data = 0x7f7b3300c680, obj = 0x801000, res = 0, res2 = 
140167141433408}, {data = 0x7f7b34496e00, obj = 0x7f7b334a4276, res = 
140167113398608, res2 = 4350013}, {data = 0x0,
   obj = 0xa, res = 140167113393824, res2 = 14777248}, {data = 
0xe2c010, obj = 0xa3300c730, res = 140167113396320, res2 = 4356478}, 
{data = 0x0, obj = 0xe17ba0,
   res = 372, res2 = 0}, {data = 0x175, obj = 0x0, res = 374, res2 = 
0}, {data = 0xc081, obj = 0x0, res = 3221225603, res2 = 0}, {data = 
0xc102, obj = 0x0,
   res = 3221225604, res2 = 0}, {data = 0xc082, obj = 0x0, res = 
18, res2 = 0}, {data = 0x11, obj = 0x0, res = 0, res2 = 0}, {data = 0x0, 
obj = 0x0, res = 0, res2 = 0}, {
   data = 0x0, obj = 0x0, res = 0, res2 = 0}, {data = 0x0, obj = 0x0, 
res = 0, res2 = 0}, {data = 0x0, obj = 0x0, res = 0, res2 = 0}, {data = 
0x0, obj = 0x0, res = 0,
   res2 = 140167139245116}, {data = 0x0, obj = 0x7f7b34abe118, res = 9, 
res2 = 13}, {data = 0x25bf5fc6, obj = 0x7f7b348b40f0, res = 
140167117719264, res2 = 6}, {
   data = 0x96fd7f, obj = 0x7f7b3300c850, res = 140167113394680, res2 = 
140167117724520}, {data = 0x0, obj = 0x7f7b34abe168, res = 
140167141388288, res2 = 4206037}, {
   data = 0x7f7b3343a210, obj = 0x402058, res = 21474836480, res2 = 
4294968102}, {data = 0x0, obj = 0x7f7b34ac8358, res = 140167113394736, 
res2 = 140167113394680}, {
   data = 0x25bf5fc6, obj = 0x7f7b3300c9e0, res = 0, res2 = 
140167139246910}, {data = 0x0, obj = 0x7f7b34abe168, res 

[Qemu-devel] [PATCH] vnc: set the right prefered encoding

2010-05-04 Thread Corentin Chary
From RFB specs: The order of the encoding types given in this
message is a hint by the client as to its preference (the first
encoding specified being most preferred)

Signed-off-by: Corentin Chary corenti...@iksaif.net
---
 vnc.c |   14 ++
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/vnc.c b/vnc.c
index 5241a6a..2d05d8f 100644
--- a/vnc.c
+++ b/vnc.c
@@ -1594,7 +1594,7 @@ static void set_encodings(VncState *vs, int32_t 
*encodings, size_t n_encodings)
 
 vnc_zlib_init(vs);
 vs-features = 0;
-vs-vnc_encoding = 0;
+vs-vnc_encoding = -1;
 vs-tight_compression = 9;
 vs-tight_quality = 9;
 vs-absolute = -1;
@@ -1603,18 +1603,24 @@ static void set_encodings(VncState *vs, int32_t 
*encodings, size_t n_encodings)
 enc = encodings[i];
 switch (enc) {
 case VNC_ENCODING_RAW:
-vs-vnc_encoding = enc;
+if (vs-vnc_encoding != -1) {
+vs-vnc_encoding = enc;
+}
 break;
 case VNC_ENCODING_COPYRECT:
 vs-features |= VNC_FEATURE_COPYRECT_MASK;
 break;
 case VNC_ENCODING_HEXTILE:
 vs-features |= VNC_FEATURE_HEXTILE_MASK;
-vs-vnc_encoding = enc;
+if (vs-vnc_encoding != -1) {
+vs-vnc_encoding = enc;
+}
 break;
 case VNC_ENCODING_ZLIB:
 vs-features |= VNC_FEATURE_ZLIB_MASK;
-vs-vnc_encoding = enc;
+if (vs-vnc_encoding != -1) {
+vs-vnc_encoding = enc;
+}
 break;
 case VNC_ENCODING_DESKTOPRESIZE:
 vs-features |= VNC_FEATURE_RESIZE_MASK;
-- 
1.7.0.2





[Qemu-devel] Re: [PATCH v4 3/5] char: unix/tcp: Add a non-blocking write handler

2010-05-04 Thread Amit Shah
On (Tue) May 04 2010 [09:43:04], Gerd Hoffmann wrote:
 On 05/04/10 09:17, Amit Shah wrote:
 Add a non-blocking write handler that can return with -EAGAIN to the
 caller and also callback when the socket becomes writable.

 Non-blocking writes are only enabled for sockets that are opened in
 non-blocking mode and only for callers that have registered a callback
 handler for resuming writes.

 The logic will be pretty much the same for all filehandle-based backends  
 on unix.  So maybe create some helper functions, so implementing  
 $backend_chr_write_unblocked can be done with just three lines of code?

Yes, that's the next step. Let's push this for now and do that in a
later patch series?

Amit




[Qemu-devel] [PATCH 4/5] lsi: Adjust some register reset values

2010-05-04 Thread Jan Kiszka
According to the LSI spec, the reset value of dcmd, dstat, and ctest2
were wrong, and sdid as well as ssid require zero initialization. There
are surely more discrepancies, this is just another increment.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 hw/lsi53c895a.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 61de23e..f088d06 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -298,8 +298,8 @@ static void lsi_soft_reset(LSIState *s)
 memset(s-scratch, 0, sizeof(s-scratch));
 s-istat0 = 0;
 s-istat1 = 0;
-s-dcmd = 0;
-s-dstat = 0;
+s-dcmd = 0x40;
+s-dstat = LSI_DSTAT_DFE;
 s-dien = 0;
 s-sist0 = 0;
 s-sist1 = 0;
@@ -308,7 +308,7 @@ static void lsi_soft_reset(LSIState *s)
 s-mbox0 = 0;
 s-mbox1 = 0;
 s-dfifo = 0;
-s-ctest2 = 0;
+s-ctest2 = LSI_CTEST2_DACK;
 s-ctest3 = 0;
 s-ctest4 = 0;
 s-ctest5 = 0;
@@ -327,6 +327,8 @@ static void lsi_soft_reset(LSIState *s)
 s-scid = 7;
 s-sxfer = 0;
 s-socl = 0;
+s-sdid = 0;
+s-ssid = 0;
 s-stest1 = 0;
 s-stest2 = 0;
 s-stest3 = 0;
-- 
1.6.0.2





[Qemu-devel] [PATCH 0/5] scsi: More reset and hotplug fixes

2010-05-04 Thread Jan Kiszka
This series finally stabilizes system reset during ongoing SCSI I/O
here. The first patch is a repost, the others include missing reset
related bits that mostly concern the LSI controller. And the last patch
addresses a disk hotplugging issue: The LSI used to keep pointers to the
selected device, pointer that can become invalid it the device is
removed in the middle of ongoing I/O.

Jan Kiszka (5):
  SCSI: Add disk reset handler
  scsi-disk: Clear aiocb on read completion
  lsi: Purge message queue on reset
  lsi: Adjust some register reset values
  lsi: Handle removal of selected devices

 hw/lsi53c895a.c |   70 +++---
 hw/scsi-disk.c  |   37 ++--
 2 files changed, 74 insertions(+), 33 deletions(-)





[Qemu-devel] [PATCH 5/5] lsi: Handle removal of selected devices

2010-05-04 Thread Jan Kiszka
We must not store references to selected devices as they may be
hot-removed. Instead, look up the device based on its tag right before
using it. If the device disappeared, throw an interrupt and disconnect.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 hw/lsi53c895a.c |   60 ++
 1 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index f088d06..9d3c44d 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -175,7 +175,6 @@ do { fprintf(stderr, lsi_scsi: error:  fmt , ## 
__VA_ARGS__);} while (0)
 
 typedef struct lsi_request {
 uint32_t tag;
-SCSIDevice *dev;
 uint32_t dma_len;
 uint8_t *dma_buf;
 uint32_t pending;
@@ -202,7 +201,6 @@ typedef struct {
  * 3 if a DMA operation is in progress.  */
 int waiting;
 SCSIBus bus;
-SCSIDevice *select_dev;
 int current_lun;
 /* The tag is a combination of the device ID and the SCSI tag.  */
 uint32_t select_tag;
@@ -518,11 +516,25 @@ static void lsi_resume_script(LSIState *s)
 }
 }
 
+static void lsi_disconnect(LSIState *s)
+{
+s-scntl1 = ~LSI_SCNTL1_CON;
+s-sstat1 = ~PHASE_MASK;
+}
+
+static void lsi_bad_selection(LSIState *s, uint32_t id)
+{
+DPRINTF(Selected absent target %d\n, id);
+lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
+lsi_disconnect(s);
+}
+
 /* Initiate a SCSI layer data transfer.  */
 static void lsi_do_dma(LSIState *s, int out)
 {
-uint32_t count;
+uint32_t count, id;
 target_phys_addr_t addr;
+SCSIDevice *dev;
 
 assert(s-current);
 if (!s-current-dma_len) {
@@ -531,6 +543,13 @@ static void lsi_do_dma(LSIState *s, int out)
 return;
 }
 
+id = s-current-tag  8;
+dev = s-bus.devs[id];
+if (!dev) {
+lsi_bad_selection(s, id);
+return;
+}
+
 count = s-dbc;
 if (count  s-current-dma_len)
 count = s-current-dma_len;
@@ -550,8 +569,7 @@ static void lsi_do_dma(LSIState *s, int out)
 s-dbc -= count;
 
 if (s-current-dma_buf == NULL) {
-s-current-dma_buf = s-current-dev-info-get_buf(s-current-dev,
- s-current-tag);
+s-current-dma_buf = dev-info-get_buf(dev, s-current-tag);
 }
 
 /* ??? Set SFBR to first data byte.  */
@@ -565,10 +583,10 @@ static void lsi_do_dma(LSIState *s, int out)
 s-current-dma_buf = NULL;
 if (out) {
 /* Write the data.  */
-s-current-dev-info-write_data(s-current-dev, 
s-current-tag);
+dev-info-write_data(dev, s-current-tag);
 } else {
 /* Request any remaining data.  */
-s-current-dev-info-read_data(s-current-dev, s-current-tag);
+dev-info-read_data(dev, s-current-tag);
 }
 } else {
 s-current-dma_buf += count;
@@ -715,7 +733,9 @@ static void lsi_command_complete(SCSIBus *bus, int reason, 
uint32_t tag,
 
 static void lsi_do_command(LSIState *s)
 {
+SCSIDevice *dev;
 uint8_t buf[16];
+uint32_t id;
 int n;
 
 DPRINTF(Send command len=%d\n, s-dbc);
@@ -725,19 +745,24 @@ static void lsi_do_command(LSIState *s)
 s-sfbr = buf[0];
 s-command_complete = 0;
 
+id = s-select_tag  8;
+dev = s-bus.devs[id];
+if (!dev) {
+lsi_bad_selection(s, id);
+return;
+}
+
 assert(s-current == NULL);
 s-current = qemu_mallocz(sizeof(lsi_request));
 s-current-tag = s-select_tag;
-s-current-dev = s-select_dev;
 
-n = s-current-dev-info-send_command(s-current-dev, s-current-tag, 
buf,
-s-current_lun);
+n = dev-info-send_command(dev, s-current-tag, buf, s-current_lun);
 if (n  0) {
 lsi_set_phase(s, PHASE_DI);
-s-current-dev-info-read_data(s-current-dev, s-current-tag);
+dev-info-read_data(dev, s-current-tag);
 } else if (n  0) {
 lsi_set_phase(s, PHASE_DO);
-s-current-dev-info-write_data(s-current-dev, s-current-tag);
+dev-info-write_data(dev, s-current-tag);
 }
 
 if (!s-command_complete) {
@@ -771,12 +796,6 @@ static void lsi_do_status(LSIState *s)
 lsi_add_msg_byte(s, 0); /* COMMAND COMPLETE */
 }
 
-static void lsi_disconnect(LSIState *s)
-{
-s-scntl1 = ~LSI_SCNTL1_CON;
-s-sstat1 = ~PHASE_MASK;
-}
-
 static void lsi_do_msgin(LSIState *s)
 {
 int len;
@@ -1092,9 +,7 @@ again:
 s-sstat0 |= LSI_SSTAT0_WOA;
 s-scntl1 = ~LSI_SCNTL1_IARB;
 if (id = LSI_MAX_DEVS || !s-bus.devs[id]) {
-DPRINTF(Selected absent target %d\n, id);
-lsi_script_scsi_interrupt(s, 0, LSI_SIST1_STO);
-lsi_disconnect(s);
+lsi_bad_selection(s, id);
 break;
 }
 DPRINTF(Selected target %d%s\n,
@@ -1102,7 +1119,6 @@ again:
 /* 

[Qemu-devel] [PATCH 3/5] lsi: Purge message queue on reset

2010-05-04 Thread Jan Kiszka
Declare the input message queue empty and initialize the related state
machine properly on controller reset. This fixes unrecoverable errors
when the controller was reset during ongoing requests.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 hw/lsi53c895a.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 85eea15..61de23e 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -288,6 +288,8 @@ static void lsi_soft_reset(LSIState *s)
 DPRINTF(Reset\n);
 s-carry = 0;
 
+s-msg_action = 0;
+s-msg_len = 0;
 s-waiting = 0;
 s-dsa = 0;
 s-dnad = 0;
-- 
1.6.0.2





[Qemu-devel] [PATCH 1/5] SCSI: Add disk reset handler

2010-05-04 Thread Jan Kiszka
Ensure that pending requests of an SCSI disk are purged on system reset
and also restore max_lba. The latter is no only present in the reset
handler as that one is called after init as well.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 hw/scsi-disk.c |   35 +++
 1 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 77cb1da..b8d805f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1010,22 +1010,45 @@ static int32_t scsi_send_command(SCSIDevice *d, 
uint32_t tag,
 }
 }
 
-static void scsi_destroy(SCSIDevice *dev)
+static void scsi_disk_purge_requests(SCSIDiskState *s)
 {
-SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 SCSIDiskReq *r;
 
 while (!QTAILQ_EMPTY(s-qdev.requests)) {
 r = DO_UPCAST(SCSIDiskReq, req, QTAILQ_FIRST(s-qdev.requests));
+if (r-req.aiocb) {
+bdrv_aio_cancel(r-req.aiocb);
+}
 scsi_remove_request(r);
 }
+}
+
+static void scsi_disk_reset(DeviceState *dev)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
+uint64_t nb_sectors;
+
+scsi_disk_purge_requests(s);
+
+bdrv_get_geometry(s-bs, nb_sectors);
+nb_sectors /= s-cluster_size;
+if (nb_sectors) {
+nb_sectors--;
+}
+s-max_lba = nb_sectors;
+}
+
+static void scsi_destroy(SCSIDevice *dev)
+{
+SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+
+scsi_disk_purge_requests(s);
 drive_uninit(s-qdev.conf.dinfo);
 }
 
 static int scsi_disk_initfn(SCSIDevice *dev)
 {
 SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
-uint64_t nb_sectors;
 
 if (!s-qdev.conf.dinfo || !s-qdev.conf.dinfo-bdrv) {
 error_report(scsi-disk: drive property not set);
@@ -1046,11 +1069,6 @@ static int scsi_disk_initfn(SCSIDevice *dev)
 s-cluster_size = s-qdev.blocksize / 512;
 
 s-qdev.type = TYPE_DISK;
-bdrv_get_geometry(s-bs, nb_sectors);
-nb_sectors /= s-cluster_size;
-if (nb_sectors)
-nb_sectors--;
-s-max_lba = nb_sectors;
 qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
 return 0;
 }
@@ -1059,6 +1077,7 @@ static SCSIDeviceInfo scsi_disk_info = {
 .qdev.name= scsi-disk,
 .qdev.desc= virtual scsi disk or cdrom,
 .qdev.size= sizeof(SCSIDiskState),
+.qdev.reset   = scsi_disk_reset,
 .init = scsi_disk_initfn,
 .destroy  = scsi_destroy,
 .send_command = scsi_send_command,
-- 
1.6.0.2





[Qemu-devel] [PATCH 2/5] scsi-disk: Clear aiocb on read completion

2010-05-04 Thread Jan Kiszka
Once the I/O completion callback returned, aiocb will be released by the
controller. So we have to clear the reference not only in
scsi_write_complete, but also in scsi_read_complete. Otherwise we risk
inconsistencies when a reset hits us before the related request is
released.

Signed-off-by: Jan Kiszka jan.kis...@siemens.com
---
 hw/scsi-disk.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index b8d805f..4d20919 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -125,6 +125,8 @@ static void scsi_read_complete(void * opaque, int ret)
 {
 SCSIDiskReq *r = (SCSIDiskReq *)opaque;
 
+r-req.aiocb = NULL;
+
 if (ret) {
 DPRINTF(IO error\n);
 r-req.bus-complete(r-req.bus, SCSI_REASON_DATA, r-req.tag, 0);
-- 
1.6.0.2





Re: [Qemu-devel] Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread Kevin Wolf
Am 04.05.2010 13:38, schrieb Peter Lieven:
 hi kevin,
 
 i set a breakpint at bmdma_active_if. the first 2 breaks encountered 
 when the last path in the multipath
 failed, but the assertion was not true.
 when i kicked one path back in the breakpoint was reached again, this 
 time leading to an assert.
 the stacktrace is from the point shortly before.
 
 hope this helps.

Hm, looks like there's something wrong with cancelling requests -
bdrv_aio_cancel might decide that it completes a request (and
consequently calls the callback for it) whereas the IDE emulation
decides that it's done with the request before calling bdrv_aio_cancel.

I haven't looked in much detail what this could break, but does
something like this help?

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 0757528..3cd55e3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2838,10 +2838,6 @@ static void ide_dma_restart(IDEState *s, int is_read)
 void ide_dma_cancel(BMDMAState *bm)
 {
 if (bm-status  BM_STATUS_DMAING) {
-bm-status = ~BM_STATUS_DMAING;
-/* cancel DMA request */
-bm-unit = -1;
-bm-dma_cb = NULL;
 if (bm-aiocb) {
 #ifdef DEBUG_AIO
 printf(aio_cancel\n);
@@ -2849,6 +2845,10 @@ void ide_dma_cancel(BMDMAState *bm)
 bdrv_aio_cancel(bm-aiocb);
 bm-aiocb = NULL;
 }
+bm-status = ~BM_STATUS_DMAING;
+/* cancel DMA request */
+bm-unit = -1;
+bm-dma_cb = NULL;
 }
 }

Kevin




Re: [Qemu-devel] simple block driver cleanups

2010-05-04 Thread Kevin Wolf
Am 04.05.2010 12:43, schrieb Christoph Hellwig:
 This series cleans up the simple read-only block drivers to use the
 qemu block device API to access their backing devices, making the code
 simpler and usable over nbd/curl.  I've not touched dmg yet as it's even
 more bitrot than usual and deserves it's own series.

Have you already added something to qemu-iotests locally to test this or
did you test manually?

Kevin




[Qemu-devel] [patch uq/master 5/9] kvm: synchronize state from cpu context

2010-05-04 Thread Marcelo Tosatti
From: Jan Kiszka jan.kis...@siemens.com

It is not safe to retrieve the KVM internal state of a given cpu
while its potentially modifying it.

Queue the request to run on cpu context, similarly to qemu-kvm.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/kvm-all.c
===
--- qemu.orig/kvm-all.c
+++ qemu/kvm-all.c
@@ -796,14 +796,22 @@ void kvm_flush_coalesced_mmio_buffer(voi
 #endif
 }
 
-void kvm_cpu_synchronize_state(CPUState *env)
+static void do_kvm_cpu_synchronize_state(void *_env)
 {
+CPUState *env = _env;
+
 if (!env-kvm_vcpu_dirty) {
 kvm_arch_get_registers(env);
 env-kvm_vcpu_dirty = 1;
 }
 }
 
+void kvm_cpu_synchronize_state(CPUState *env)
+{
+if (!env-kvm_vcpu_dirty)
+run_on_cpu(env, do_kvm_cpu_synchronize_state, env);
+}
+
 void kvm_cpu_synchronize_post_reset(CPUState *env)
 {
 kvm_arch_put_registers(env, KVM_PUT_RESET_STATE);






[Qemu-devel] [patch uq/master 4/9] port qemu-kvm's on_vcpu code

2010-05-04 Thread Marcelo Tosatti
run_on_cpu allows to execute work on a given CPUState context.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h
+++ qemu/cpu-all.h
@@ -818,6 +818,7 @@ void cpu_watchpoint_remove_all(CPUState 
 
 void cpu_single_step(CPUState *env, int enabled);
 void cpu_reset(CPUState *s);
+void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
 
 #define CPU_LOG_TB_OUT_ASM (1  0)
 #define CPU_LOG_TB_IN_ASM  (1  1)
Index: qemu/cpu-defs.h
===
--- qemu.orig/cpu-defs.h
+++ qemu/cpu-defs.h
@@ -132,6 +132,7 @@ typedef struct icount_decr_u16 {
 
 struct kvm_run;
 struct KVMState;
+struct qemu_work_item;
 
 typedef struct CPUBreakpoint {
 target_ulong pc;
@@ -204,6 +205,7 @@ typedef struct CPUWatchpoint {
 uint32_t created;   \
 struct QemuThread *thread;  \
 struct QemuCond *halt_cond; \
+struct qemu_work_item *queued_work_first, *queued_work_last;\
 const char *cpu_model_str;  \
 struct KVMState *kvm_state; \
 struct kvm_run *kvm_run;\
Index: qemu/cpus.c
===
--- qemu.orig/cpus.c
+++ qemu/cpus.c
@@ -115,6 +115,8 @@ static int cpu_has_work(CPUState *env)
 {
 if (env-stop)
 return 1;
+if (env-queued_work_first)
+return 1;
 if (env-stopped || !vm_running)
 return 0;
 if (!env-halted)
@@ -252,6 +254,11 @@ int qemu_cpu_self(void *env)
 return 1;
 }
 
+void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
+{
+func(data);
+}
+
 void resume_all_vcpus(void)
 {
 }
@@ -304,6 +311,7 @@ static QemuCond qemu_cpu_cond;
 /* system init */
 static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
+static QemuCond qemu_work_cond;
 
 static void tcg_block_io_signals(void);
 static void kvm_block_io_signals(CPUState *env);
@@ -334,6 +342,50 @@ void qemu_main_loop_start(void)
 qemu_cond_broadcast(qemu_system_cond);
 }
 
+void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
+{
+struct qemu_work_item wi;
+
+if (qemu_cpu_self(env)) {
+func(data);
+return;
+}
+
+wi.func = func;
+wi.data = data;
+if (!env-queued_work_first)
+env-queued_work_first = wi;
+else
+env-queued_work_last-next = wi;
+env-queued_work_last = wi;
+wi.next = NULL;
+wi.done = false;
+
+qemu_cpu_kick(env);
+while (!wi.done) {
+CPUState *self_env = cpu_single_env;
+
+qemu_cond_wait(qemu_work_cond, qemu_global_mutex);
+cpu_single_env = self_env;
+}
+}
+
+static void flush_queued_work(CPUState *env)
+{
+struct qemu_work_item *wi;
+
+if (!env-queued_work_first)
+return;
+
+while ((wi = env-queued_work_first)) {
+env-queued_work_first = wi-next;
+wi-func(wi-data);
+wi-done = true;
+}
+env-queued_work_last = NULL;
+qemu_cond_broadcast(qemu_work_cond);
+}
+
 static void qemu_wait_io_event_common(CPUState *env)
 {
 if (env-stop) {
@@ -341,6 +393,7 @@ static void qemu_wait_io_event_common(CP
 env-stopped = 1;
 qemu_cond_signal(qemu_pause_cond);
 }
+flush_queued_work(env);
 }
 
 static void qemu_wait_io_event(CPUState *env)
Index: qemu/qemu-common.h
===
--- qemu.orig/qemu-common.h
+++ qemu/qemu-common.h
@@ -249,6 +249,14 @@ void qemu_notify_event(void);
 void qemu_cpu_kick(void *env);
 int qemu_cpu_self(void *env);
 
+/* work queue */
+struct qemu_work_item {
+struct qemu_work_item *next;
+void (*func)(void *data);
+void *data;
+int done;
+};
+
 #ifdef CONFIG_USER_ONLY
 #define qemu_init_vcpu(env) do { } while (0)
 #else






[Qemu-devel] [patch uq/master 7/9] move stop/stopped CPU_COMMON fields after area zeroed by reset

2010-05-04 Thread Marcelo Tosatti
cpu_reset zeroes CPUState upto breakpoints member. Contents of
stop/stopped should not be zeroed on cpu_reset.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/cpu-defs.h
===
--- qemu.orig/cpu-defs.h
+++ qemu/cpu-defs.h
@@ -159,8 +159,6 @@ typedef struct CPUWatchpoint {
 target_ulong mem_io_vaddr; /* target virtual addr at which the  \
  memory was accessed */ \
 uint32_t halted; /* Nonzero if the CPU is in suspend state */   \
-uint32_t stop;   /* Stop request */ \
-uint32_t stopped; /* Artificially stopped */\
 uint32_t interrupt_request; \
 volatile sig_atomic_t exit_request; \
 CPU_COMMON_TLB  \
@@ -203,6 +201,8 @@ typedef struct CPUWatchpoint {
 void *opaque;   \
 \
 uint32_t created;   \
+uint32_t stop;   /* Stop request */ \
+uint32_t stopped; /* Artificially stopped */\
 struct QemuThread *thread;  \
 struct QemuCond *halt_cond; \
 struct qemu_work_item *queued_work_first, *queued_work_last;\






[Qemu-devel] [patch uq/master 6/9] add cpu_is_stopped helper

2010-05-04 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/cpu-all.h
===
--- qemu.orig/cpu-all.h
+++ qemu/cpu-all.h
@@ -818,6 +818,7 @@ void cpu_watchpoint_remove_all(CPUState 
 
 void cpu_single_step(CPUState *env, int enabled);
 void cpu_reset(CPUState *s);
+int cpu_is_stopped(CPUState *env);
 void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
 
 #define CPU_LOG_TB_OUT_ASM (1  0)
Index: qemu/cpus.c
===
--- qemu.orig/cpus.c
+++ qemu/cpus.c
@@ -91,6 +91,11 @@ void cpu_synchronize_all_post_init(void)
 }
 }
 
+int cpu_is_stopped(CPUState *env)
+{
+return !vm_running || env-stopped;
+}
+
 static void do_vm_stop(int reason)
 {
 if (vm_running) {






[Qemu-devel] [patch uq/master 9/9] kvm: enable smp 1

2010-05-04 Thread Marcelo Tosatti
Process INIT/SIPI requests and enable -smp  1.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/kvm-all.c
===
--- qemu.orig/kvm-all.c
+++ qemu/kvm-all.c
@@ -593,11 +593,6 @@ int kvm_init(int smp_cpus)
 int ret;
 int i;
 
-if (smp_cpus  1) {
-fprintf(stderr, No SMP KVM support, use '-smp 1'\n);
-return -EINVAL;
-}
-
 s = qemu_mallocz(sizeof(KVMState));
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
@@ -840,6 +835,11 @@ int kvm_cpu_exec(CPUState *env)
 }
 #endif
 
+if (kvm_arch_process_irqchip_events(env)) {
+ret = 0;
+break;
+}
+
 if (env-kvm_vcpu_dirty) {
 kvm_arch_put_registers(env, KVM_PUT_RUNTIME_STATE);
 env-kvm_vcpu_dirty = 0;
Index: qemu/kvm.h
===
--- qemu.orig/kvm.h
+++ qemu/kvm.h
@@ -90,6 +90,8 @@ int kvm_arch_handle_exit(CPUState *env, 
 
 int kvm_arch_pre_run(CPUState *env, struct kvm_run *run);
 
+int kvm_arch_process_irqchip_events(CPUState *env);
+
 int kvm_arch_get_registers(CPUState *env);
 
 /* state subset only touched by the VCPU itself during runtime */
Index: qemu/target-i386/kvm.c
===
--- qemu.orig/target-i386/kvm.c
+++ qemu/target-i386/kvm.c
@@ -1073,6 +1073,22 @@ int kvm_arch_post_run(CPUState *env, str
 return 0;
 }
 
+int kvm_arch_process_irqchip_events(CPUState *env)
+{
+if (env-interrupt_request  CPU_INTERRUPT_INIT) {
+kvm_cpu_synchronize_state(env);
+do_cpu_init(env);
+env-exception_index = EXCP_HALTED;
+}
+
+if (env-interrupt_request  CPU_INTERRUPT_SIPI) {
+kvm_cpu_synchronize_state(env);
+do_cpu_sipi(env);
+}
+
+return env-halted;
+}
+
 static int kvm_handle_halt(CPUState *env)
 {
 if (!((env-interrupt_request  CPU_INTERRUPT_HARD) 
Index: qemu/target-ppc/kvm.c
===
--- qemu.orig/target-ppc/kvm.c
+++ qemu/target-ppc/kvm.c
@@ -224,6 +224,11 @@ int kvm_arch_post_run(CPUState *env, str
 return 0;
 }
 
+int kvm_arch_process_irqchip_events(CPUState *env)
+{
+return 0;
+}
+
 static int kvmppc_handle_halt(CPUState *env)
 {
 if (!(env-interrupt_request  CPU_INTERRUPT_HARD)  (msr_ee)) {
Index: qemu/target-s390x/kvm.c
===
--- qemu.orig/target-s390x/kvm.c
+++ qemu/target-s390x/kvm.c
@@ -175,6 +175,11 @@ int kvm_arch_post_run(CPUState *env, str
 return 0;
 }
 
+int kvm_arch_process_irqchip_events(CPUState *env)
+{
+return 0;
+}
+
 static void kvm_s390_interrupt_internal(CPUState *env, int type, uint32_t parm,
 uint64_t parm64, int vm)
 {






[Qemu-devel] Re: qemu-user[armel/mips] and debian-rootfs

2010-05-04 Thread Kenneth Johansson


On Mon, 2010-05-03 at 21:30 +0200, Kenneth Johansson wrote:
 I'm trying to setup a debian root that I can chroot into for armel and
 mips from an ubuntu 9.10 x86_64.
 
 While I have it working for armel on a specific qemu the mips target is
 more problematic. 
 
 first both fail for qemu newer than
 6173d56bdcb53389c54e803873e6bf8f87836a4f.
 
 doing /sbin/ldconfig. I get bad address
 
 
 now on to mips. during installation of debian I get the following error,
 
 /bin/tar: ./postinst: Cannot utime: Level 2 not synchronized

after discovering QEMU_STRACE. not sure why tar thinks it got EL2NSYNC
in errno.


15978 execve(/bin/tar,{tar,xf,-,NULL})15977 
fcntl64(0,0x300,0x0001) = 0
15976 exit_group(0)
15977 fstat64(0,0x4007e0e8) = 0
15977 mmap(NULL,256,0x300,0x208,-1,0) = 0x4225d000
15977 _llseek(0,0,0,1074258344,1,0) = -1 errno=29 (Illegal seek)
15977 read(0,0x43e570,16384) = 1959
15977 read(0,0x43ed17,12288) = 0
15977 _llseek(0,0,0,1074258408,1,0) = -1 errno=29 (Illegal seek)
15978 brk(NULL) = 0x0047a000
15978 uname(0x4007f240) = 0
15978 access(/etc/ld.so.nohwcap,F_OK) = -1 errno=2 (No such file or directory)
15978 mmap(NULL,1048576,0x300,0x208,-1,0) = 0x42081000
15978 access(/etc/ld.so.preload,0x400) = -1 errno=2 (No such file or 
directory)
15977 write(1,0x4007e43c,4096) = 4096
15977 write(1,0x4007e43c,4096) = 4096
15978 open(/etc/ld.so.cache,O_RDONLY) = 4
15978 fstat64(67108864,0x4007ee28) = 0
15978 mmap(NULL,-1358102528,0x100,0x200,67108864,0)15977  = 0x42082000
read(0,0x43e570,16384) = 0
15978 close(4) = 0
15977 write(1,0x4007e43c,2048) = 2048
15977 close(1) = 0
15978 access(/etc/ld.so.nohwcap,F_OK) = -1 errno=2 (No such file or directory)
15978 open(/lib/librt.so.1,O_RDONLY) = 4
15978 read(4,0x4007ef78,512) = 512
15978 lseek(4,744,0,1074262308,0,0) = 744
15978 read(4,0x4007eed0,32) = 32
15978 fstat64(67108864,0x4007ee40) = 0
15977 exit_group(0)
15978 mmap(NULL,-1602092800,0x500,0x220,67108864,0) = 0x42083000
15978 mprotect(0x4208b000,15728640,PROT_NONE) = 0
15978 mmap(0x4209a000,2097152,0x300,0x1220,67108864,0x70) = 
0x4209a000
15978 close(4) = 0
15978 access(/etc/ld.so.nohwcap,F_OK) = -1 errno=2 (No such file or directory)
15978 open(/lib/libc.so.6,O_RDONLY) = 4
15978 read(4,0x4007ef60,512) = 512
15978 lseek(4,760,0,1074262316,0,0) = 760
15978 read(4,0x4007eeb8,32) = 32
15978 fstat64(67108864,0x4007ee28) = 0
15978 mmap(NULL,1048576,0x300,0x208,-1,0) = 0x4209c000
15978 mmap(NULL,1089345280,0x500,0x220,67108864,0) = 0x4209d000
15978 mprotect(0x421ff000,15728640,PROT_NONE) = 0
15978 mmap(0x4220e000,11534336,0x300,0x1220,67108864,0x101600) = 
0x4220e000
15978 mmap(0x42219000,1076756480,0x300,0x1208,-1,0) = 0x42219000
15978 close(4) = 0
15978 access(/etc/ld.so.nohwcap,F_OK) = -1 errno=2 (No such file or directory)
15978 open(/lib/libpthread.so.0,O_RDONLY) = 4
15978 read(4,0x4007eeb0,512) = 512
15978 lseek(4,744,0,1074262108,0,0) = 744
15978 read(4,0x4007ee08,32) = 32
15978 fstat64(67108864,0x4007ed78) = 0
15978 mmap(NULL,-1599929856,0x500,0x220,67108864,0) = 0x4221c000
15978 mprotect(0x42233000,256,PROT_NONE) = 0
15978 mmap(0x42243000,2097152,0x300,0x1220,67108864,0x700100) = 
0x42243000
15978 mmap(0x42245000,-1609367552,0x300,0x1208,-1,0) = 0x42245000
15978 close(4) = 0
15978 mmap(NULL,1048576,0x300,0x208,-1,0) = 0x42247000
15978 set_thread_area(1109714064,1109685392,65536,1109685392,0,0) = 0
15978 open(/dev/urandom,O_RDONLY) = 4
15978 read(4,0x4007f3e1,3) = 3
15978 close(4) = 0
15978 mprotect(0x42243000,1048576,0x100) = 0
15978 mprotect(0x4220e000,9437184,0x100) = 0
15978 mprotect(0x4209a000,1048576,0x100) = 0
15978 mprotect(0x400b2000,1048576,0x100) = 0
15978 munmap(0x42082000,-1358102528) = 0
15978 set_tid_address(1109684328,1109714064,1074264284,1074264284,0,0) = 15978
15978 set_robust_list(1109684336,12,1074264284,0,0,0) = -1 errno=89 (Function 
not implemented)
15978 futex(0x4007f758,-2130706432,16777216,0x0001,NULL,0) = 0
15978 futex(0x4007f758,-1996423168,16777216,NULL,NULL,0) = -1 errno=89 
(Function not implemented)
15978 rt_sigaction(32,1074263784,0,16,0,0) = 0
15978 rt_sigaction(33,1074263784,0,16,0,0) = -1 errno=22 (Invalid argument)
15978 rt_sigprocmask(2,1074263920,0,16,0,0) = 0
15978 getrlimit(3,1074263904,0,0,0,0) = 0
15978 clock_gettime(0,4688892,1074264284,0,0,0) = 0
15978 brk(NULL) = 0x0047a000
15978 brk(0x0049b000) = 0x0049b000
15978 open(/usr/lib/locale/locale-archive,O_RDONLY|O_LARGEFILE) = -1 errno=2 
(No such file or directory)
15978 open(/usr/share/locale/locale.alias,O_RDONLY) = -1 errno=2 (No such 
file or directory)
15978 open(/usr/lib/locale/en_US.UTF-8/LC_IDENTIFICATION,O_RDONLY) = -1 
errno=2 (No such file or directory)
15978 open(/usr/lib/locale/en_US.utf8/LC_IDENTIFICATION,O_RDONLY) = -1 
errno=2 (No such file or directory)
15978 open(/usr/lib/locale/en_US/LC_IDENTIFICATION,O_RDONLY) = -1 errno=2 (No 
such file or directory)
15978 

[Qemu-devel] Re: [PATCH v5 3/6] char: Let writers know how much data was written in case of errors

2010-05-04 Thread Gerd Hoffmann

On 05/04/10 13:31, Amit Shah wrote:

On (Tue) May 04 2010 [13:24:58], Gerd Hoffmann wrote:

@@ -531,8 +534,12 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
   while (len   0) {
   ret = write(fd, buf, len);
   if (ret   0) {
-if (errno != EINTR   errno != EAGAIN)
+if (len1 - len) {
+return len1 - len;
+}
+if (errno != EINTR   errno != EAGAIN) {
   return -1;
+}


This makes unix_write pass -EINTR up to the caller which it didn't before.


Only on partial writes. Should be OK, no?


No.  Callers which never saw partial writes due to write() syscall being 
interrupted by some signal start seeing them now.


cheers,
  Gerd





[Qemu-devel] [PATCH] vnc: make sure to send pointer type change event on SetEncodings

2010-05-04 Thread Anthony Liguori
Commit 37c34d9d5d87ea9d51760310c8863b82cb8c055a introduced a regression when
using relative mouse mode with a client that understands the PointerTypeChange
pseudo-encoding.

Reported-by: Marcelo Tosatti mtosa...@redhat.com
Reported-by: Gerhard Wiesinger li...@wiesinger.com
Signed-off-by: Anthony Liguori aligu...@us.ibm.com
---
 vnc.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/vnc.c b/vnc.c
index 5241a6a..b1a3fdb 100644
--- a/vnc.c
+++ b/vnc.c
@@ -1642,6 +1642,8 @@ static void set_encodings(VncState *vs, int32_t 
*encodings, size_t n_encodings)
 break;
 }
 }
+
+check_pointer_type_change(vs-mouse_mode_notifier);
 }
 
 static void set_pixel_conversion(VncState *vs)
-- 
1.6.5.2





[Qemu-devel] [patch uq/master 0/9] enable smp 1 and related fixes

2010-05-04 Thread Marcelo Tosatti





Re: [Qemu-devel] Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread Peter Lieven

hi kevin,

you did it *g*

looks promising. applied this patched and was not able to reproduce yet :-)

secure way to reproduce was to shut down all multipath paths, then 
initiate i/o
in the vm (e.g. start an application). of course, everything hangs at 
this point.


after reenabling one path, vm crashed. now it seems to behave correctly and
just report an DMA timeout and continues normally afterwards.

can you imagine of any way preventing the vm to consume 100% cpu in
that waiting state?
my current approach is to run all vms with nice 1, which helped to keep the
machine responsible if all vms (in my test case 64 on a box) have hanging
i/o at the same time.

br,
peter



Kevin Wolf wrote:

Am 04.05.2010 13:38, schrieb Peter Lieven:
  

hi kevin,

i set a breakpint at bmdma_active_if. the first 2 breaks encountered 
when the last path in the multipath

failed, but the assertion was not true.
when i kicked one path back in the breakpoint was reached again, this 
time leading to an assert.

the stacktrace is from the point shortly before.

hope this helps.



Hm, looks like there's something wrong with cancelling requests -
bdrv_aio_cancel might decide that it completes a request (and
consequently calls the callback for it) whereas the IDE emulation
decides that it's done with the request before calling bdrv_aio_cancel.

I haven't looked in much detail what this could break, but does
something like this help?

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 0757528..3cd55e3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2838,10 +2838,6 @@ static void ide_dma_restart(IDEState *s, int is_read)
 void ide_dma_cancel(BMDMAState *bm)
 {
 if (bm-status  BM_STATUS_DMAING) {
-bm-status = ~BM_STATUS_DMAING;
-/* cancel DMA request */
-bm-unit = -1;
-bm-dma_cb = NULL;
 if (bm-aiocb) {
 #ifdef DEBUG_AIO
 printf(aio_cancel\n);
@@ -2849,6 +2845,10 @@ void ide_dma_cancel(BMDMAState *bm)
 bdrv_aio_cancel(bm-aiocb);
 bm-aiocb = NULL;
 }
+bm-status = ~BM_STATUS_DMAING;
+/* cancel DMA request */
+bm-unit = -1;
+bm-dma_cb = NULL;
 }
 }

Kevin

  






Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Anthony Liguori

On 04/20/2010 11:56 AM, Alexander Graf wrote:

Virtio-Console can only process one character at a time. Using it on S390
gave me strage lags where I got the character I pressed before when
pressing one. So I typed in abc and only received a, then pressed d
but the guest received b and so on.

While the stdio driver calls a poll function that just processes on its
queue in case virtio-console can't take multiple characters at once, the
muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only gets
active when the guest can not receive any more characters. In that case
it polls again after a while to check if the guest is now receiving input.

This patch fixes input when using -nographic on s390 for me.
   


I think this is really a kvm issue.  I assume it's because s390 idles in 
the kernel so you never drop to userspace to repoll the descriptor.


A timer is a hacky solution.  You really need to use an io thread to 
solve this and then you need to switch away from qemu_set_fd_handler2 to 
qemu_set_fd_handler() and make sure that the later breaks select 
whenever it's invoked.


Regards,

Anthony Liguori


---

Please consider for stable.
---
  qemu-char.c |   10 ++
  1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ce9df3a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -235,6 +235,7 @@ typedef struct {
  IOEventHandler *chr_event[MAX_MUX];
  void *ext_opaque[MAX_MUX];
  CharDriverState *drv;
+QEMUTimer *accept_timer;
  int focus;
  int mux_cnt;
  int term_got_escape;
@@ -396,6 +397,13 @@ static void mux_chr_accept_input(CharDriverState *chr)
  d-chr_read[m](d-ext_opaque[m],
 d-buffer[m][d-cons[m]++  MUX_BUFFER_MASK], 1);
  }
+
+/* We're still not able to sync producer and consumer, so let's wait a bit
+   and try again by then. */
+if (d-prod[m] != d-cons[m]) {
+qemu_mod_timer(d-accept_timer, qemu_get_clock(vm_clock)
++ (int64_t)10);
+}
  }

  static int mux_chr_can_read(void *opaque)
@@ -478,6 +486,8 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState 
*drv)
  chr-opaque = d;
  d-drv = drv;
  d-focus = -1;
+d-accept_timer = qemu_new_timer(vm_clock,
+ (QEMUTimerCB*)mux_chr_accept_input, chr);
  chr-chr_write = mux_chr_write;
  chr-chr_update_read_handler = mux_chr_update_read_handler;
  chr-chr_accept_input = mux_chr_accept_input;
   






Re: [Qemu-devel] [PATCH] hw: better i440 emulation

2010-05-04 Thread Anthony Liguori

On 04/20/2010 01:48 PM, Bernhard M. Wiedemann wrote:

updated version of an old patch
http://xenon.stanford.edu/~eswierk/misc/qemu-linuxbios/qemu-piix-ram-size.patch
that together with
http://www.mail-archive.com/linuxb...@linuxbios.org/msg02390.html
(which is already in coreboot trunk) allows coreboot to autodetect the amount 
of RAM within qemu/kvm from a register in i440 northbridge.

The message on the old patch states:
Unfortunately the current version of qemu does not set these
registers, but I have patched qemu so that it emulates the i440 more
faithfully in this regard.

Signed-off-by: Bernhard M. Wiedemannqemudev...@lsmod.de
   


Applied.  Thanks.

Regards,

Anthony Liguori





[Qemu-devel] [patch uq/master 3/9] standardize on qemu_cpu_kick for signalling cpu thread(s)

2010-05-04 Thread Marcelo Tosatti
Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/cpus.c
===
--- qemu.orig/cpus.c
+++ qemu/cpus.c
@@ -454,8 +454,7 @@ void qemu_cpu_kick(void *_env)
 {
 CPUState *env = _env;
 qemu_cond_broadcast(env-halt_cond);
-if (kvm_enabled())
-qemu_thread_signal(env-thread, SIG_IPI);
+qemu_thread_signal(env-thread, SIG_IPI);
 }
 
 int qemu_cpu_self(void *_env)
@@ -583,7 +582,6 @@ void pause_all_vcpus(void)
 
 while (penv) {
 penv-stop = 1;
-qemu_thread_signal(penv-thread, SIG_IPI);
 qemu_cpu_kick(penv);
 penv = (CPUState *)penv-next_cpu;
 }
@@ -592,7 +590,7 @@ void pause_all_vcpus(void)
 qemu_cond_timedwait(qemu_pause_cond, qemu_global_mutex, 100);
 penv = first_cpu;
 while (penv) {
-qemu_thread_signal(penv-thread, SIG_IPI);
+qemu_cpu_kick(penv);
 penv = (CPUState *)penv-next_cpu;
 }
 }
@@ -605,7 +603,6 @@ void resume_all_vcpus(void)
 while (penv) {
 penv-stop = 0;
 penv-stopped = 0;
-qemu_thread_signal(penv-thread, SIG_IPI);
 qemu_cpu_kick(penv);
 penv = (CPUState *)penv-next_cpu;
 }






[Qemu-devel] [patch uq/master 1/9] kvm: set cpu_single_env around KVM_RUN ioctl

2010-05-04 Thread Marcelo Tosatti
Zero cpu_single_env before leaving global lock protection, and
restore on return.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/kvm-all.c
===
--- qemu.orig/kvm-all.c
+++ qemu/kvm-all.c
@@ -846,9 +846,11 @@ int kvm_cpu_exec(CPUState *env)
 }
 
 kvm_arch_pre_run(env, run);
+cpu_single_env = NULL;
 qemu_mutex_unlock_iothread();
 ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
 qemu_mutex_lock_iothread();
+cpu_single_env = env;
 kvm_arch_post_run(env, run);
 
 if (ret == -EINTR || ret == -EAGAIN) {






[Qemu-devel] [patch uq/master 2/9] make SIG_IPI to tcg vcpu thread reliable

2010-05-04 Thread Marcelo Tosatti
Store tcg loop exit request on a global variable, and transfer it to
per-CPUState exit_request after assignment of cpu_single_env.

This makes exit request signal from robust. Drop the timedlock hack.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/cpu-exec.c
===
--- qemu.orig/cpu-exec.c
+++ qemu/cpu-exec.c  
@@ -213,6 +213,8 @@ static void cpu_handle_debug_exception(C
 
 /* main execution loop */
 
+volatile sig_atomic_t exit_request;
+
 int cpu_exec(CPUState *env1)
 {
 volatile host_reg_t saved_env_reg;
@@ -234,6 +236,11 @@ int cpu_exec(CPUState *env1)
 asm();
 env = env1;
 
+if (exit_request) {
+env-exit_request = 1;
+exit_request = 0;
+}
+
 #if defined(TARGET_I386)
 if (!kvm_enabled()) {
 /* put eflags in CPU temporary format */
Index: qemu/cpus.c
===
--- qemu.orig/cpus.c
+++ qemu/cpus.c
@@ -472,6 +472,7 @@ static void cpu_signal(int sig)
 {
 if (cpu_single_env)
 cpu_exit(cpu_single_env);
+exit_request = 1;
 }
 
 static void tcg_block_io_signals(void)
@@ -542,26 +543,20 @@ static void unblock_io_signals(void)
 pthread_sigmask(SIG_BLOCK, set, NULL);
 }
 
-static void qemu_signal_lock(unsigned int msecs)
-{
-qemu_mutex_lock(qemu_fair_mutex);
-
-while (qemu_mutex_trylock(qemu_global_mutex)) {
-qemu_thread_signal(tcg_cpu_thread, SIG_IPI);
-if (!qemu_mutex_timedlock(qemu_global_mutex, msecs))
-break;
-}
-qemu_mutex_unlock(qemu_fair_mutex);
-}
-
 void qemu_mutex_lock_iothread(void)
 {
 if (kvm_enabled()) {
 qemu_mutex_lock(qemu_fair_mutex);
 qemu_mutex_lock(qemu_global_mutex);
 qemu_mutex_unlock(qemu_fair_mutex);
-} else
-qemu_signal_lock(100);
+} else {
+qemu_mutex_lock(qemu_fair_mutex);
+if (qemu_mutex_trylock(qemu_global_mutex)) {
+qemu_thread_signal(tcg_cpu_thread, SIG_IPI);
+qemu_mutex_lock(qemu_global_mutex);
+}
+qemu_mutex_unlock(qemu_fair_mutex);
+}
 }
 
 void qemu_mutex_unlock_iothread(void)
Index: qemu/exec-all.h
===
--- qemu.orig/exec-all.h
+++ qemu/exec-all.h
@@ -339,4 +339,7 @@ CPUDebugExcpHandler *cpu_set_debug_excp_
 /* vl.c */
 extern int singlestep;
 
+/* cpu-exec.c */
+extern volatile sig_atomic_t exit_request;
+
 #endif






[Qemu-devel] [patch uq/master 8/9] kvm: validate context for kvm cpu get/put operations

2010-05-04 Thread Marcelo Tosatti
From: Jan Kiszka jan.kis...@siemens.com

Validate that KVM vcpu state is only read/written from cpu thread itself
or that cpu is stopped.

Signed-off-by: Marcelo Tosatti mtosa...@redhat.com

Index: qemu/target-i386/kvm.c
===
--- qemu.orig/target-i386/kvm.c
+++ qemu/target-i386/kvm.c
@@ -949,6 +949,8 @@ int kvm_arch_put_registers(CPUState *env
 {
 int ret;
 
+assert(cpu_is_stopped(env) || qemu_cpu_self(env));
+
 ret = kvm_getput_regs(env, 1);
 if (ret  0)
 return ret;
@@ -991,6 +993,8 @@ int kvm_arch_get_registers(CPUState *env
 {
 int ret;
 
+assert(cpu_is_stopped(env) || qemu_cpu_self(env));
+
 ret = kvm_getput_regs(env, 0);
 if (ret  0)
 return ret;






Re: [Qemu-devel] [PATCH 1/2] qemu-error: Introduce get_errno_name()

2010-05-04 Thread Anthony Liguori

On 05/04/2010 08:56 AM, Luiz Capitulino wrote:

On Mon, 03 May 2010 08:16:35 -0500
Anthony Liguorianth...@codemonkey.ws  wrote:

   

On 05/03/2010 08:06 AM, Markus Armbruster wrote:
 

Luiz Capitulinolcapitul...@redhat.com   writes:


   

We need to expose errno in QMP, for three reasons:

1. Some error handling functions print errno codes to the user,
   while it's debatable whether this is good or not from a user
   perspective, sometimes it's the best we can do because it's
   what system calls and libraries return

2. Some events (eg. BLOCK_IO_ERROR) will be made even more
   complete with errno information

3. It's very good for debugging

So, we need a way to expose those codes in QMP. We can't just use
the codes themselfs because they may vary between systems.

The best solution I can think of is to return the string
representation of the name. For example, EIO becomes EIO.

This is what get_errno_name() does.

Signed-off-by: Luiz Capitulinolcapitul...@redhat.com
---
   qemu-error.c |   85 
++
   qemu-error.h |1 +
   2 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/qemu-error.c b/qemu-error.c
index 5a35e7c..7035417 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -207,3 +207,88 @@ void error_report(const char *fmt, ...)
   va_end(ap);
   error_printf(\n);
   }
+
+/*
+ * Probably only useful for QMP
+ */
+const char *get_errno_name(int err)
+{
+switch (abs(err)) {
+case EPERM:
+return EPERM;
+case ENOENT:
+return ENOENT;

 

[...]

   

+case EDOM:
+return EDOM;
+case ERANGE:
+return ERANGE;
+case ENOMEDIUM:
+return ENOMEDIUM;
+case ENOTSUP:
+return ENOTSUP;
+default:
+return unknown;

 

How did you choose the codes to implement?  POSIX has many more...
   

  I just ran an awk script on the linux's base errno header file, my
idea is just to have the common names, anything 'new' will hit the
default clause and we can add it later.

   

Let me say another way why I think this is a bad path to go down.

In generally, we could never just pass errno through down.  Different
host platforms are going to generate different errno values so we really
need to filter and send reliable errno values so that clients don't have
to have special code for when they're on Linux vs. AIX vs. Solaris.
 

  Sorry for the potential stupid question, but what would a 'reliable'
errno be? Or, what's an unreliable errno?

  We're not sending plain integers to the clients, so the only problem
I can see is if different unices return different errnos for the
same error. Is that the problem you're seeing?
   


Different types of platforms return different errno values for the same 
error type.


As an example, on Linux, connect() returns EINPROGRESS when you set the 
socket non-blocking.  On Windows, it returns EWOULDBLOCK.


If you just pass through errno, then all QMP clients are going to have 
to know the different between QEMU on Windows and Linux and handle the 
errnos appropriately.



If we're white listing errno values, we should be able to trivially
convert errnos to QError types via a table just like you have above.
 

  Having a direct errno -  QError mapping doesn't seem good for the
current use cases.

  For example, do_savevm() (not merged yet) has a StateVmSaveFailed
error which also has a 'reason' member, which would look like this
on the wire:

{ 'class': 'StateVmSaveFailed', 'data': { 'reason': EIO } }

  So, the QError class says what has failed and the errno part says
why it has failed.

  I'd be happy to implement a different solution that satisfies this
basic requirement.
   


We need to map errnos to some QMP defined error type.  However, as I've 
said before, reason is usually an indicator that an error is bad.


A better error would be:

{ 'class': 'SocketIOError': 'data' : { 'source': 'migration' }}

Or something like that.  You don't want to have command and then 
CommandFailed as the error.  You want the errors to be the 'reason's for 
the commands failure.


Regards,

Anthony Liguori




Re: [Qemu-devel] Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread Kevin Wolf
Am 04.05.2010 15:42, schrieb Peter Lieven:
 hi kevin,
 
 you did it *g*
 
 looks promising. applied this patched and was not able to reproduce yet :-)
 
 secure way to reproduce was to shut down all multipath paths, then 
 initiate i/o
 in the vm (e.g. start an application). of course, everything hangs at 
 this point.
 
 after reenabling one path, vm crashed. now it seems to behave correctly and
 just report an DMA timeout and continues normally afterwards.

Great, I'm going to submit it as a proper patch then.

Christoph, by now I'm pretty sure it's right, but can you have another
look if this is correct, anyway?

 can you imagine of any way preventing the vm to consume 100% cpu in
 that waiting state?
 my current approach is to run all vms with nice 1, which helped to keep the
 machine responsible if all vms (in my test case 64 on a box) have hanging
 i/o at the same time.

I don't have anything particular in mind, but you could just attach gdb
and get another backtrace while it consumes 100% CPU (you'll need to use
thread apply all bt to catch everything). Then we should see where
it's hanging.

Kevin




Re: [Qemu-devel] [PATCH 1/2] qemu-error: Introduce get_errno_name()

2010-05-04 Thread Luiz Capitulino
On Mon, 03 May 2010 08:16:35 -0500
Anthony Liguori anth...@codemonkey.ws wrote:

 On 05/03/2010 08:06 AM, Markus Armbruster wrote:
  Luiz Capitulinolcapitul...@redhat.com  writes:
 
 
  We need to expose errno in QMP, for three reasons:
 
 1. Some error handling functions print errno codes to the user,
while it's debatable whether this is good or not from a user
perspective, sometimes it's the best we can do because it's
what system calls and libraries return
 
 2. Some events (eg. BLOCK_IO_ERROR) will be made even more
complete with errno information
 
 3. It's very good for debugging
 
  So, we need a way to expose those codes in QMP. We can't just use
  the codes themselfs because they may vary between systems.
 
  The best solution I can think of is to return the string
  representation of the name. For example, EIO becomes EIO.
 
  This is what get_errno_name() does.
 
  Signed-off-by: Luiz Capitulinolcapitul...@redhat.com
  ---
qemu-error.c |   85 
  ++
qemu-error.h |1 +
2 files changed, 86 insertions(+), 0 deletions(-)
 
  diff --git a/qemu-error.c b/qemu-error.c
  index 5a35e7c..7035417 100644
  --- a/qemu-error.c
  +++ b/qemu-error.c
  @@ -207,3 +207,88 @@ void error_report(const char *fmt, ...)
va_end(ap);
error_printf(\n);
}
  +
  +/*
  + * Probably only useful for QMP
  + */
  +const char *get_errno_name(int err)
  +{
  +switch (abs(err)) {
  +case EPERM:
  +return EPERM;
  +case ENOENT:
  +return ENOENT;
   
  [...]
 
  +case EDOM:
  +return EDOM;
  +case ERANGE:
  +return ERANGE;
  +case ENOMEDIUM:
  +return ENOMEDIUM;
  +case ENOTSUP:
  +return ENOTSUP;
  +default:
  +return unknown;
   
  How did you choose the codes to implement?  POSIX has many more...

 I just ran an awk script on the linux's base errno header file, my
idea is just to have the common names, anything 'new' will hit the
default clause and we can add it later.

 Let me say another way why I think this is a bad path to go down.
 
 In generally, we could never just pass errno through down.  Different 
 host platforms are going to generate different errno values so we really 
 need to filter and send reliable errno values so that clients don't have 
 to have special code for when they're on Linux vs. AIX vs. Solaris.

 Sorry for the potential stupid question, but what would a 'reliable'
errno be? Or, what's an unreliable errno?

 We're not sending plain integers to the clients, so the only problem
I can see is if different unices return different errnos for the
same error. Is that the problem you're seeing?

 If we're white listing errno values, we should be able to trivially 
 convert errnos to QError types via a table just like you have above.

 Having a direct errno - QError mapping doesn't seem good for the
current use cases.

 For example, do_savevm() (not merged yet) has a StateVmSaveFailed
error which also has a 'reason' member, which would look like this
on the wire:

{ 'class': 'StateVmSaveFailed', 'data': { 'reason': EIO } }

 So, the QError class says what has failed and the errno part says
why it has failed.

 I'd be happy to implement a different solution that satisfies this
basic requirement.




[Qemu-devel] KVM call minutes for May 4

2010-05-04 Thread Chris Wright

KVM Forum topic ideas
- mgmt interface (qemud)
- working breakout sessions are welcome at the Forum

stable tree
- have a volunteer (thanks Justin)
- Anthony will write up proposal which is basically
  - bug fixes actively proposed for stable tree
  - stable maintainer collects and applies
  - periodically release and re-sync w/ main tree

0.12.4?
- RSN...will tag and push shortly




Re: [Qemu-devel] [PATCH] vnc: split encoding in specific files

2010-05-04 Thread Anthony Liguori

On 05/04/2010 03:12 AM, Kevin Wolf wrote:

Am 03.05.2010 19:15, schrieb Anthony Liguori:
   

On 05/03/2010 07:31 AM, Corentin Chary wrote:
 

This will allow to implement new encodings (tight, zrle, ..)
in a cleaner way. This may hurt performances, because some
functions like vnc_convert_pixel are not static anymore, but
should not be a problem with gcc 4.5 and the new -flto.

Signed-off-by: Corentin Charycorenti...@iksaif.net

   

Applied.  Thanks.

It's probably time to make a vnc directory too.
 

Or maybe one for all of the interfaces we currently have in the root
directory? So it would include not only VNC, but also SDL and curses.
   


Makes sense.

Regards,

Anthony Liguori


Kevin



   






[Qemu-devel] Re: QEMU: current user mode breakage

2010-05-04 Thread Riku Voipio
On Fri, Apr 30, 2010 at 11:43:43AM +0200, Martin Mohring wrote:
 not sure how to handle the situation. But since the commit of the new
 memory allocator for QEMU user mode, my test suites show it is broken.

The 0 sized write patch still isn't applied upstream. Is that the issue
(eg visible by ldconfig.real not working) for you, or is everything broken
even with that patch applied?

Just run ltp tests without any noticable regressions on debian/armel/sid.
No performance slowdown was observerd either.




Re: [Qemu-devel] [PATCH] document boot option to -drive parameter

2010-05-04 Thread Anthony Liguori

On 04/16/2010 12:11 PM, Bruce Rogers wrote:

The boot option is missing from the documentation for the -drive parameter.

If there is a better way to descibe it, I'm all ears.

Signed-off-by: Bruce Rogersbrog...@novell.com

diff --git a/qemu-options.hx b/qemu-options.hx
index f4b3bfe..f0f9a7c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -159,6 +159,8 @@ an untrusted format header.
  This option specifies the serial number to assign to the device.
  @item ad...@var{addr}
  Specify the controller's PCI address (if=virtio only).
+...@item bo...@var{boot}
+...@var{boot} is on or off and allows for booting from non-traditional 
interfaces, such as virtio.
  @end table

  By default, writethrough caching is used for all block device.  This means 
that
   


This is only in qemu-kvm.git.

Regards,

Anthony Liguori





   






Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Alexander Graf



Am 04.05.2010 um 15:44 schrieb Anthony Liguori anth...@codemonkey.ws:


On 04/20/2010 11:56 AM, Alexander Graf wrote:
Virtio-Console can only process one character at a time. Using it  
on S390

gave me strage lags where I got the character I pressed before when
pressing one. So I typed in abc and only received a, then  
pressed d

but the guest received b and so on.

While the stdio driver calls a poll function that just processes on  
its
queue in case virtio-console can't take multiple characters at  
once, the

muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only  
gets
active when the guest can not receive any more characters. In that  
case
it polls again after a while to check if the guest is now receiving  
input.


This patch fixes input when using -nographic on s390 for me.



I think this is really a kvm issue.  I assume it's because s390  
idles in the kernel so you never drop to userspace to repoll the  
descriptor.


There is no polling for the muxer. That's why it never knows when  
virtio-console can receive again.


This patch basically adfs timer based polling for that exact case.


Alex



A timer is a hacky solution.  You really need to use an io thread to  
solve this and then you need to switch away from  
qemu_set_fd_handler2 to qemu_set_fd_handler() and make sure that the  
later breaks select whenever it's invoked.


Regards,

Anthony Liguori


---

Please consider for stable.
---
 qemu-char.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ce9df3a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -235,6 +235,7 @@ typedef struct {
 IOEventHandler *chr_event[MAX_MUX];
 void *ext_opaque[MAX_MUX];
 CharDriverState *drv;
+QEMUTimer *accept_timer;
 int focus;
 int mux_cnt;
 int term_got_escape;
@@ -396,6 +397,13 @@ static void mux_chr_accept_input 
(CharDriverState *chr)

 d-chr_read[m](d-ext_opaque[m],
d-buffer[m][d-cons[m]++   
MUX_BUFFER_MASK], 1);

 }
+
+/* We're still not able to sync producer and consumer, so  
let's wait a bit

+   and try again by then. */
+if (d-prod[m] != d-cons[m]) {
+qemu_mod_timer(d-accept_timer, qemu_get_clock(vm_clock)
++ (int64_t)10);
+}
 }

 static int mux_chr_can_read(void *opaque)
@@ -478,6 +486,8 @@ static CharDriverState *qemu_chr_open_mux 
(CharDriverState *drv)

 chr-opaque = d;
 d-drv = drv;
 d-focus = -1;
+d-accept_timer = qemu_new_timer(vm_clock,
+ (QEMUTimerCB*) 
mux_chr_accept_input, chr);

 chr-chr_write = mux_chr_write;
 chr-chr_update_read_handler = mux_chr_update_read_handler;
 chr-chr_accept_input = mux_chr_accept_input;








Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Anthony Liguori

On 05/04/2010 09:30 AM, Alexander Graf wrote:



Am 04.05.2010 um 15:44 schrieb Anthony Liguori anth...@codemonkey.ws:


On 04/20/2010 11:56 AM, Alexander Graf wrote:
Virtio-Console can only process one character at a time. Using it on 
S390

gave me strage lags where I got the character I pressed before when
pressing one. So I typed in abc and only received a, then 
pressed d

but the guest received b and so on.

While the stdio driver calls a poll function that just processes on its
queue in case virtio-console can't take multiple characters at once, 
the

muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only gets
active when the guest can not receive any more characters. In that case
it polls again after a while to check if the guest is now receiving 
input.


This patch fixes input when using -nographic on s390 for me.



I think this is really a kvm issue.  I assume it's because s390 idles 
in the kernel so you never drop to userspace to repoll the descriptor.


There is no polling for the muxer. That's why it never knows when 
virtio-console can receive again.


Maybe I'm missing something simple, but it looks to me like the muxer is 
polling.  mux_chr_can_read() is going to eventually poll the muxed 
devices to figure this out.


If the root of the problem is that mux_chr_can_read() isn't being 
invoked for a prolonged period of time, the real issue is the problem I 
described.


Regards,

Anthony Liguori


This patch basically adfs timer based polling for that exact case.


Alex



A timer is a hacky solution.  You really need to use an io thread to 
solve this and then you need to switch away from qemu_set_fd_handler2 
to qemu_set_fd_handler() and make sure that the later breaks select 
whenever it's invoked.


Regards,

Anthony Liguori


---

Please consider for stable.
---
 qemu-char.c |   10 ++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ce9df3a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -235,6 +235,7 @@ typedef struct {
 IOEventHandler *chr_event[MAX_MUX];
 void *ext_opaque[MAX_MUX];
 CharDriverState *drv;
+QEMUTimer *accept_timer;
 int focus;
 int mux_cnt;
 int term_got_escape;
@@ -396,6 +397,13 @@ static void 
mux_chr_accept_input(CharDriverState *chr)

 d-chr_read[m](d-ext_opaque[m],
d-buffer[m][d-cons[m]++  MUX_BUFFER_MASK], 1);
 }
+
+/* We're still not able to sync producer and consumer, so let's 
wait a bit

+   and try again by then. */
+if (d-prod[m] != d-cons[m]) {
+qemu_mod_timer(d-accept_timer, qemu_get_clock(vm_clock)
++ (int64_t)10);
+}
 }

 static int mux_chr_can_read(void *opaque)
@@ -478,6 +486,8 @@ static CharDriverState 
*qemu_chr_open_mux(CharDriverState *drv)

 chr-opaque = d;
 d-drv = drv;
 d-focus = -1;
+d-accept_timer = qemu_new_timer(vm_clock,
+ 
(QEMUTimerCB*)mux_chr_accept_input, chr);

 chr-chr_write = mux_chr_write;
 chr-chr_update_read_handler = mux_chr_update_read_handler;
 chr-chr_accept_input = mux_chr_accept_input;









[Qemu-devel] Re: Qemu-KVM 0.12.3 and Multipath - Assertion

2010-05-04 Thread André Weidemann

Hi Peter,
On 03.05.2010 23:26, Peter Lieven wrote:


Hi Qemu/KVM Devel Team,

i'm using qemu-kvm 0.12.3 with latest Kernel 2.6.33.3.
As backend we use open-iSCSI with dm-multipath.

Multipath is configured to queue i/o if no path is available.

If we create a failure on all paths, qemu starts to consume 100%
CPU due to i/o waits which is ok so far.

1 odd thing: The Monitor Interface is not responding any more ...

What es a really blocker is that KVM crashes with:
kvm: /usr/src/qemu-kvm-0.12.3/hw/ide/internal.h:507: bmdma_active_if:
Assertion `bmdma-unit != (uint8_t)-1' failed.

after the multipath has reestablisched at least one path.

Any ideas? I remember this was working with earlier kernel/kvm/qemu
versions.



I have the same issue on my machine, although I am using local storage 
(LVM or a physical disk) to write my data to.
I reported the Assertion failed on March 17th to the list. Marcello 
and Avi had asked some question back then, but I don't know if they have 
come up with a fix for it.


Regards
 André




[Qemu-devel] Patch to improve handling of server sockets

2010-05-04 Thread Reinhard Max

Hi,

I am maintaining the tightvnc package for openSUSE and was recently 
confronted with an alleged vnc problem with QWMU that turned out to be 
a shortcoming in QEMU's code for handling TCP server sockets, which is 
used by the vnc and char modules.


The problem occurs when the address to listen on is given as a name 
which resolves to multiple IP addresses the most prominent example 
being localhost resolving to 127.0.0.1 and ::1 .


The existing code stopped walking the list of addresses returned by 
getaddrinfo() as soon as one socket was successfully opened and bound. 
The result was that a qemu instance started with -vnc localhost:42 
only listened on ::1, wasn't reachable through 127.0.0.1. The fact 
that the code set the IPV6_V6ONLY socket option didn't help, because 
that option only works when the socket gets bound to the IPv6 wildcard 
address (::), but is useless for explicit address bindings.


The attached patch against QEMU 0.11.0 extends inet_listen() to create 
sockets for as many addresses from the address list as possible and 
adapts its callers and their data structures to deal with a linked 
list of socket FDs rather than a single file descriptor.


So far I've only done some testing with the -vnc option. More testing 
is needed in the qemu-char area and for the parts of the code that get 
triggered from QEMU's Monitor.



Please review and comment.


cu
Reinhard

P.S. Please keep me in Cc when replying.Index: qemu-char.c
===
--- qemu-char.c.orig
+++ qemu-char.c
@@ -1831,7 +1831,8 @@ return_err:
 /* TCP Net console */
 
 typedef struct {
-int fd, listen_fd;
+int fd;
+FdList *listen_fds;
 int connected;
 int max_size;
 int do_telnetopt;
@@ -1983,6 +1984,7 @@ static void tcp_chr_read(void *opaque)
 TCPCharDriver *s = chr-opaque;
 uint8_t buf[1024];
 int len, size;
+FdList *fdl;
 
 if (!s-connected || s-max_size = 0)
 return;
@@ -1993,10 +1995,9 @@ static void tcp_chr_read(void *opaque)
 if (size == 0) {
 /* connection closed */
 s-connected = 0;
-if (s-listen_fd = 0) {
-qemu_set_fd_handler(s-listen_fd, tcp_chr_accept, NULL, chr);
-}
-qemu_set_fd_handler(s-fd, NULL, NULL, NULL);
+	for (fdl = s-listen_fds; fdl != NULL; fdl = fdl-next)
+qemu_set_fd_handler(fdl-fd, tcp_chr_accept, NULL, fdl);
+	qemu_set_fd_handler(s-fd, NULL, NULL, NULL);
 closesocket(s-fd);
 s-fd = -1;
 } else if (size  0) {
@@ -2045,7 +2046,8 @@ static void socket_set_nodelay(int fd)
 
 static void tcp_chr_accept(void *opaque)
 {
-CharDriverState *chr = opaque;
+FdList *fdl = opaque;
+CharDriverState *chr = fdl-opaque;
 TCPCharDriver *s = chr-opaque;
 struct sockaddr_in saddr;
 #ifndef _WIN32
@@ -2066,7 +2068,7 @@ static void tcp_chr_accept(void *opaque)
 	len = sizeof(saddr);
 	addr = (struct sockaddr *)saddr;
 	}
-fd = accept(s-listen_fd, addr, len);
+fd = accept(fdl-fd, addr, len);
 if (fd  0  errno != EINTR) {
 return;
 } else if (fd = 0) {
@@ -2079,20 +2081,24 @@ static void tcp_chr_accept(void *opaque)
 if (s-do_nodelay)
 socket_set_nodelay(fd);
 s-fd = fd;
-qemu_set_fd_handler(s-listen_fd, NULL, NULL, NULL);
+for (fdl = s-listen_fds; fdl != NULL; fdl = fdl-next)
+	qemu_set_fd_handler(fdl-fd, NULL, NULL, NULL);
 tcp_chr_connect(chr);
 }
 
 static void tcp_chr_close(CharDriverState *chr)
 {
 TCPCharDriver *s = chr-opaque;
+FdList *fdl, *fdtmp;
 if (s-fd = 0) {
 qemu_set_fd_handler(s-fd, NULL, NULL, NULL);
 closesocket(s-fd);
 }
-if (s-listen_fd = 0) {
-qemu_set_fd_handler(s-listen_fd, NULL, NULL, NULL);
-closesocket(s-listen_fd);
+for (fdl = s-listen_fds; fdl != NULL; fdl = fdtmp) {
+	fdtmp = fdl-next;
+qemu_set_fd_handler(fdl-fd, NULL, NULL, NULL);
+closesocket(fdl-fd);
+	free(fdl);
 }
 qemu_free(s);
 }
@@ -2108,6 +2114,7 @@ static CharDriverState *qemu_chr_open_tc
 int is_waitconnect = 1;
 int do_nodelay = 0;
 const char *ptr;
+FdList *sockets = NULL, *fdl, *fdtmp;
 
 ptr = host_str;
 while((ptr = strchr(ptr,','))) {
@@ -2155,11 +2162,18 @@ static CharDriverState *qemu_chr_open_tc
 } else {
 if (is_listen) {
 fd = inet_listen(host_str, chr-filename + offset, 256 - offset,
- SOCK_STREAM, 0);
+ SOCK_STREAM, 0, sockets);
 } else {
 fd = inet_connect(host_str, SOCK_STREAM);
 }
 }
+
+if (sockets == NULL) {
+	sockets = malloc(sizeof(*sockets));
+	sockets-next = NULL;
+	sockets-fd = fd;
+}
+
 if (fd  0)
 goto fail;
 
@@ -2168,7 +2182,7 @@ static CharDriverState *qemu_chr_open_tc
 
 s-connected = 0;
 s-fd = -1;
-s-listen_fd = -1;
+s-listen_fds = NULL;
 s-msgfd = 

Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Alexander Graf


Am 04.05.2010 um 16:34 schrieb Anthony Liguori anth...@codemonkey.ws:


On 05/04/2010 09:30 AM, Alexander Graf wrote:



Am 04.05.2010 um 15:44 schrieb Anthony Liguori  
anth...@codemonkey.ws:



On 04/20/2010 11:56 AM, Alexander Graf wrote:
Virtio-Console can only process one character at a time. Using it  
on S390
gave me strage lags where I got the character I pressed before  
when
pressing one. So I typed in abc and only received a, then  
pressed d

but the guest received b and so on.

While the stdio driver calls a poll function that just processes  
on its
queue in case virtio-console can't take multiple characters at  
once, the

muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that  
only gets
active when the guest can not receive any more characters. In  
that case
it polls again after a while to check if the guest is now  
receiving input.


This patch fixes input when using -nographic on s390 for me.



I think this is really a kvm issue.  I assume it's because s390  
idles in the kernel so you never drop to userspace to repoll the  
descriptor.


There is no polling for the muxer. That's why it never knows when  
virtio-console can receive again.


Maybe I'm missing something simple, but it looks to me like the  
muxer is polling.  mux_chr_can_read() is going to eventually poll  
the muxed devices to figure this out.


If the root of the problem is that mux_chr_can_read() isn't being  
invoked for a prolonged period of time, the real issue is the  
problem I described.


The problem is that the select list of fds includes the stdio fd, so  
that gets notified and is coupled with virtio-console, but there's  
nothing passing that on to mux and I don't think it'd be clever to  
expose internal data to the muxer to tell it about the backend fds.


Alex



Regards,

Anthony Liguori


This patch basically adfs timer based polling for that exact case.


Alex



A timer is a hacky solution.  You really need to use an io thread  
to solve this and then you need to switch away from  
qemu_set_fd_handler2 to qemu_set_fd_handler() and make sure that  
the later breaks select whenever it's invoked.


Regards,

Anthony Liguori


---

Please consider for stable.
---
qemu-char.c |   10 ++
1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 05df971..ce9df3a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -235,6 +235,7 @@ typedef struct {
IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX];
CharDriverState *drv;
+QEMUTimer *accept_timer;
int focus;
int mux_cnt;
int term_got_escape;
@@ -396,6 +397,13 @@ static void mux_chr_accept_input 
(CharDriverState *chr)

d-chr_read[m](d-ext_opaque[m],
d-buffer[m][d-cons[m]++  MUX_BUFFER_MASK], 1);
}
+
+/* We're still not able to sync producer and consumer, so  
let's wait a bit

+   and try again by then. */
+if (d-prod[m] != d-cons[m]) {
+qemu_mod_timer(d-accept_timer, qemu_get_clock(vm_clock)
++ (int64_t)10);
+}
}

static int mux_chr_can_read(void *opaque)
@@ -478,6 +486,8 @@ static CharDriverState *qemu_chr_open_mux 
(CharDriverState *drv)

chr-opaque = d;
d-drv = drv;
d-focus = -1;
+d-accept_timer = qemu_new_timer(vm_clock,
+ (QEMUTimerCB*) 
mux_chr_accept_input, chr);

chr-chr_write = mux_chr_write;
chr-chr_update_read_handler = mux_chr_update_read_handler;
chr-chr_accept_input = mux_chr_accept_input;










Re: [Qemu-devel] Patch to improve handling of server sockets

2010-05-04 Thread Anthony Liguori

On 05/04/2010 08:49 AM, Reinhard Max wrote:

Hi,

I am maintaining the tightvnc package for openSUSE and was recently 
confronted with an alleged vnc problem with QWMU that turned out to be 
a shortcoming in QEMU's code for handling TCP server sockets, which is 
used by the vnc and char modules.


The problem occurs when the address to listen on is given as a name 
which resolves to multiple IP addresses the most prominent example 
being localhost resolving to 127.0.0.1 and ::1 .


The existing code stopped walking the list of addresses returned by 
getaddrinfo() as soon as one socket was successfully opened and bound. 
The result was that a qemu instance started with -vnc localhost:42 
only listened on ::1, wasn't reachable through 127.0.0.1. The fact 
that the code set the IPV6_V6ONLY socket option didn't help, because 
that option only works when the socket gets bound to the IPv6 wildcard 
address (::), but is useless for explicit address bindings.


The attached patch against QEMU 0.11.0 extends inet_listen() to create 
sockets for as many addresses from the address list as possible and 
adapts its callers and their data structures to deal with a linked 
list of socket FDs rather than a single file descriptor.


So far I've only done some testing with the -vnc option. More testing 
is needed in the qemu-char area and for the parts of the code that get 
triggered from QEMU's Monitor.


0.11.0 is pretty old.  Please update your patch against the latest git.

But that said, I'm not sure we're doing the wrong thing right now.  
Gerd, what do you think about this behavior?


Regards,

Anthony Liguori



Please review and comment.


cu
Reinhard

P.S. Please keep me in Cc when replying.






Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Anthony Liguori

On 05/04/2010 11:01 AM, Alexander Graf wrote:


Am 04.05.2010 um 16:34 schrieb Anthony Liguori anth...@codemonkey.ws:


On 05/04/2010 09:30 AM, Alexander Graf wrote:



Am 04.05.2010 um 15:44 schrieb Anthony Liguori anth...@codemonkey.ws:


On 04/20/2010 11:56 AM, Alexander Graf wrote:
Virtio-Console can only process one character at a time. Using it 
on S390

gave me strage lags where I got the character I pressed before when
pressing one. So I typed in abc and only received a, then 
pressed d

but the guest received b and so on.

While the stdio driver calls a poll function that just processes 
on its
queue in case virtio-console can't take multiple characters at 
once, the

muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only 
gets
active when the guest can not receive any more characters. In that 
case
it polls again after a while to check if the guest is now 
receiving input.


This patch fixes input when using -nographic on s390 for me.



I think this is really a kvm issue.  I assume it's because s390 
idles in the kernel so you never drop to userspace to repoll the 
descriptor.


There is no polling for the muxer. That's why it never knows when 
virtio-console can receive again.


Maybe I'm missing something simple, but it looks to me like the muxer 
is polling.  mux_chr_can_read() is going to eventually poll the muxed 
devices to figure this out.


If the root of the problem is that mux_chr_can_read() isn't being 
invoked for a prolonged period of time, the real issue is the problem 
I described.


The problem is that the select list of fds includes the stdio fd, so 
that gets notified and is coupled with virtio-console, but there's 
nothing passing that on to mux and I don't think it'd be clever to 
expose internal data to the muxer to tell it about the backend fds.


When stdio is readable, it should invoke qemu_chr_read() with the read 
data which in turn ought to invoke mux_chr_read().


I'm not sure I understand what signalling is missing.  Jan, does the 
problem Alex describes ring a bell?  I seem to recall you saying that 
mux was still fundamentally broken but ought to work most of the time...


Regards,

Anthony Liguori


Alex






Re: [Qemu-devel] [PATCH] [RESEND] Make char muxer more robust wrt small FIFOs

2010-05-04 Thread Jan Kiszka
Anthony Liguori wrote:
 On 05/04/2010 11:01 AM, Alexander Graf wrote:
 Am 04.05.2010 um 16:34 schrieb Anthony Liguori anth...@codemonkey.ws:

 On 05/04/2010 09:30 AM, Alexander Graf wrote:

 Am 04.05.2010 um 15:44 schrieb Anthony Liguori anth...@codemonkey.ws:

 On 04/20/2010 11:56 AM, Alexander Graf wrote:
 Virtio-Console can only process one character at a time. Using it 
 on S390
 gave me strage lags where I got the character I pressed before when
 pressing one. So I typed in abc and only received a, then 
 pressed d
 but the guest received b and so on.

 While the stdio driver calls a poll function that just processes 
 on its
 queue in case virtio-console can't take multiple characters at 
 once, the
 muxer does not have such callbacks, so it can't empty its queue.

 To work around that limitation, I introduced a new timer that only 
 gets
 active when the guest can not receive any more characters. In that 
 case
 it polls again after a while to check if the guest is now 
 receiving input.

 This patch fixes input when using -nographic on s390 for me.

 I think this is really a kvm issue.  I assume it's because s390 
 idles in the kernel so you never drop to userspace to repoll the 
 descriptor.
 There is no polling for the muxer. That's why it never knows when 
 virtio-console can receive again.
 Maybe I'm missing something simple, but it looks to me like the muxer 
 is polling.  mux_chr_can_read() is going to eventually poll the muxed 
 devices to figure this out.

 If the root of the problem is that mux_chr_can_read() isn't being 
 invoked for a prolonged period of time, the real issue is the problem 
 I described.
 The problem is that the select list of fds includes the stdio fd, so 
 that gets notified and is coupled with virtio-console, but there's 
 nothing passing that on to mux and I don't think it'd be clever to 
 expose internal data to the muxer to tell it about the backend fds.
 
 When stdio is readable, it should invoke qemu_chr_read() with the read 
 data which in turn ought to invoke mux_chr_read().
 
 I'm not sure I understand what signalling is missing.  Jan, does the 
 problem Alex describes ring a bell?  I seem to recall you saying that 
 mux was still fundamentally broken but ought to work most of the time...

That problem was (and still is) that the muxer needs to accept
characters even if the active front-end device is not in order to filter
out control sequences. Once its queue is full, it will start dropping
those the active device would not if directly connected. Could only be
solved via some peek service on pending front-end data.

I think Alex' problem can be addressed by registering
qemu_set_fd_handler2(..., backend-read_poll, mux_chr_read, ...). That
means the backend has to tell us about its read poll handler (if any).

Jan

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




[Qemu-devel] [PATCH 2/5] Add hwheel to monitor mouse_move

2010-05-04 Thread Brad Jorsch
Adds a parameter to the monitor's mouse_move command to specify the
hwheel delta.

Signed-off-by: Brad Jorsch ano...@users.sourceforge.net
---
 monitor.c   |8 ++--
 qemu-monitor.hx |4 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/monitor.c b/monitor.c
index 520d48d..baff2cf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1832,16 +1832,20 @@ static int mouse_button_state;
 
 static void do_mouse_move(Monitor *mon, const QDict *qdict)
 {
-int dx, dy, dz;
+int dx, dy, dz, dw;
 const char *dx_str = qdict_get_str(qdict, dx_str);
 const char *dy_str = qdict_get_str(qdict, dy_str);
 const char *dz_str = qdict_get_try_str(qdict, dz_str);
+const char *dw_str = qdict_get_try_str(qdict, dw_str);
 dx = strtol(dx_str, NULL, 0);
 dy = strtol(dy_str, NULL, 0);
 dz = 0;
+dw = 0;
 if (dz_str)
 dz = strtol(dz_str, NULL, 0);
-kbd_mouse_event(dx, dy, dz, 0, mouse_button_state);
+if (dw_str)
+dw = strtol(dw_str, NULL, 0);
+kbd_mouse_event(dx, dy, dz, dw, mouse_button_state);
 }
 
 static void do_mouse_button(Monitor *mon, const QDict *qdict)
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 5ea5748..00067ba 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -616,8 +616,8 @@ ETEXI
 
 {
 .name   = mouse_move,
-.args_type  = dx_str:s,dy_str:s,dz_str:s?,
-.params = dx dy [dz],
+.args_type  = dx_str:s,dy_str:s,dz_str:s?,dw_str:s?,
+.params = dx dy [dz [dw]],
 .help   = send mouse move events,
 .mhandler.cmd = do_mouse_move,
 },
-- 
1.7.1





[Qemu-devel] [PATCH 1/5] Add function parameters for hwheel

2010-05-04 Thread Brad Jorsch
Add a parameter for the hwheel delta to QEMUPutMouseEntry and
kbd_mouse_event, and adjust all users of those to match. At the moment,
all calls to kbd_mouse_event will pass 0 for the delta.

Signed-off-by: Brad Jorsch ano...@users.sourceforge.net
---
 cocoa.m |6 +++---
 console.h   |4 ++--
 hw/adb.c|3 ++-
 hw/ads7846.c|2 +-
 hw/escc.c   |3 ++-
 hw/msmouse.c|2 +-
 hw/ps2.c|4 ++--
 hw/syborg_pointer.c |2 +-
 hw/tsc2005.c|2 +-
 hw/tsc210x.c|2 +-
 hw/usb-hid.c|5 +++--
 hw/usb-wacom.c  |5 +++--
 hw/vmmouse.c|3 ++-
 hw/xenfb.c  |2 +-
 input.c |6 +++---
 monitor.c   |4 ++--
 sdl.c   |   10 ++
 vnc.c   |6 +++---
 18 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/cocoa.m b/cocoa.m
index 56c789a..c247833 100644
--- a/cocoa.m
+++ b/cocoa.m
@@ -47,9 +47,9 @@
 #define cgrect(nsrect) (*(CGRect *)(nsrect))
 #define COCOA_MOUSE_EVENT \
 if (isTabletEnabled) { \
-kbd_mouse_event((int)(p.x * 0x7FFF / (screen.width - 1)), 
(int)((screen.height - p.y) * 0x7FFF / (screen.height - 1)), 0, buttons); \
+kbd_mouse_event((int)(p.x * 0x7FFF / (screen.width - 1)), 
(int)((screen.height - p.y) * 0x7FFF / (screen.height - 1)), 0, 0, buttons); \
 } else if (isMouseGrabed) { \
-kbd_mouse_event((int)[event deltaX], (int)[event deltaY], 0, 
buttons); \
+kbd_mouse_event((int)[event deltaX], (int)[event deltaY], 0, 0, 
buttons); \
 } else { \
 [NSApp sendEvent:event]; \
 }
@@ -649,7 +649,7 @@ static int cocoa_keycode_to_qemu(int keycode)
 break;
 case NSScrollWheel:
 if (isTabletEnabled || isMouseGrabed) {
-kbd_mouse_event(0, 0, -[event deltaY], 0);
+kbd_mouse_event(0, 0, -[event deltaY], 0, 0);
 } else {
 [NSApp sendEvent:event];
 }
diff --git a/console.h b/console.h
index 6def115..7ec693d 100644
--- a/console.h
+++ b/console.h
@@ -21,7 +21,7 @@
 
 typedef void QEMUPutKBDEvent(void *opaque, int keycode);
 typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
-typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int 
buttons_state);
+typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int dw, 
int buttons_state);
 
 typedef struct QEMUPutMouseEntry {
 QEMUPutMouseEvent *qemu_put_mouse_event;
@@ -53,7 +53,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry);
 
 void kbd_put_keycode(int keycode);
 void kbd_put_ledstate(int ledstate);
-void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+void kbd_mouse_event(int dx, int dy, int dz, int dw, int buttons_state);
 
 /* Does the current mouse generate absolute events */
 int kbd_mouse_is_absolute(void);
diff --git a/hw/adb.c b/hw/adb.c
index 4fb7a62..88be567 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -318,7 +318,8 @@ typedef struct MouseState {
 } MouseState;
 
 static void adb_mouse_event(void *opaque,
-int dx1, int dy1, int dz1, int buttons_state)
+int dx1, int dy1, int dz1, int dw1,
+int buttons_state)
 {
 ADBDevice *d = opaque;
 MouseState *s = d-opaque;
diff --git a/hw/ads7846.c b/hw/ads7846.c
index 184b3dd..544db09 100644
--- a/hw/ads7846.c
+++ b/hw/ads7846.c
@@ -86,7 +86,7 @@ static uint32_t ads7846_transfer(SSISlave *dev, uint32_t 
value)
 }
 
 static void ads7846_ts_event(void *opaque,
-int x, int y, int z, int buttons_state)
+int x, int y, int z, int w, int buttons_state)
 {
 ADS7846State *s = opaque;
 
diff --git a/hw/escc.c b/hw/escc.c
index 6d2fd36..c7b420d 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -827,7 +827,8 @@ static void handle_kbd_command(ChannelState *s, int val)
 }
 
 static void sunmouse_event(void *opaque,
-   int dx, int dy, int dz, int buttons_state)
+   int dx, int dy, int dz, int dw,
+   int buttons_state)
 {
 ChannelState *s = opaque;
 int ch;
diff --git a/hw/msmouse.c b/hw/msmouse.c
index 05f893c..f1bfd0d 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -31,7 +31,7 @@
 #define MSMOUSE_HI2(n) (((n)  0xc0)  6)
 
 static void msmouse_event(void *opaque,
-  int dx, int dy, int dz, int buttons_state)
+  int dx, int dy, int dz, int dw, int buttons_state)
 {
 CharDriverState *chr = (CharDriverState *)opaque;
 
diff --git a/hw/ps2.c b/hw/ps2.c
index f0b206a..db5605d 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -330,7 +330,7 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
 }
 
 static void ps2_mouse_event(void *opaque,
-int dx, int dy, int dz, int buttons_state)
+

[Qemu-devel] [PATCH 3/5] Pass hwheel events from the front-ends

2010-05-04 Thread Brad Jorsch
SDL seems to report hwheel events as SDL_BUTTON_X1 and SDL_BUTTON_X2.
VNC I am guessing is similar, and online docs indicate that Cocoa
reports hwheel deltas in deltaX for NSScrollWheel.

Signed-off-by: Brad Jorsch ano...@users.sourceforge.net
---
 cocoa.m |2 +-
 sdl.c   |   12 ++--
 vnc.c   |   11 ---
 3 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/cocoa.m b/cocoa.m
index c247833..afc1b5f 100644
--- a/cocoa.m
+++ b/cocoa.m
@@ -649,7 +649,7 @@ static int cocoa_keycode_to_qemu(int keycode)
 break;
 case NSScrollWheel:
 if (isTabletEnabled || isMouseGrabed) {
-kbd_mouse_event(0, 0, -[event deltaY], 0, 0);
+kbd_mouse_event(0, 0, -[event deltaY], -[event deltaX], 0);
 } else {
 [NSApp sendEvent:event];
 }
diff --git a/sdl.c b/sdl.c
index 616a7eb..f6fabf1 100644
--- a/sdl.c
+++ b/sdl.c
@@ -700,8 +700,9 @@ static void sdl_refresh(DisplayState *ds)
 sdl_grab_start();
 }
 } else {
-int dz;
+int dz, dw;
 dz = 0;
+dw = 0;
 if (ev-type == SDL_MOUSEBUTTONDOWN) {
 buttonstate |= SDL_BUTTON(bev-button);
 } else {
@@ -714,7 +715,14 @@ static void sdl_refresh(DisplayState *ds)
 dz = 1;
 }
 #endif
-sdl_send_mouse_event(0, 0, dz, 0, bev-x, bev-y,
+#ifdef SDL_BUTTON_X1
+if (bev-button == SDL_BUTTON_X1  ev-type == 
SDL_MOUSEBUTTONDOWN) {
+dw = -1;
+} else if (bev-button == SDL_BUTTON_X2  ev-type == 
SDL_MOUSEBUTTONDOWN) {
+dw = 1;
+}
+#endif
+sdl_send_mouse_event(0, 0, dz, dw, bev-x, bev-y,
  buttonstate);
 }
 }
diff --git a/vnc.c b/vnc.c
index 332c14a..c193963 100644
--- a/vnc.c
+++ b/vnc.c
@@ -1275,6 +1275,7 @@ static void pointer_event(VncState *vs, int button_mask, 
int x, int y)
 {
 int buttons = 0;
 int dz = 0;
+int dw = 0;
 
 if (button_mask  0x01)
 buttons |= MOUSE_EVENT_LBUTTON;
@@ -1286,23 +1287,27 @@ static void pointer_event(VncState *vs, int 
button_mask, int x, int y)
 dz = -1;
 if (button_mask  0x10)
 dz = 1;
+if (button_mask  0x20)
+dw = -1;
+if (button_mask  0x40)
+dw = 1;
 
 if (vs-absolute) {
 kbd_mouse_event(ds_get_width(vs-ds)  1 ?
   x * 0x7FFF / (ds_get_width(vs-ds) - 1) : 0x4000,
 ds_get_height(vs-ds)  1 ?
   y * 0x7FFF / (ds_get_height(vs-ds) - 1) : 0x4000,
-dz, 0, buttons);
+dz, dw, buttons);
 } else if (vnc_has_feature(vs, VNC_FEATURE_POINTER_TYPE_CHANGE)) {
 x -= 0x7FFF;
 y -= 0x7FFF;
 
-kbd_mouse_event(x, y, dz, 0, buttons);
+kbd_mouse_event(x, y, dz, dw, buttons);
 } else {
 if (vs-last_x != -1)
 kbd_mouse_event(x - vs-last_x,
 y - vs-last_y,
-dz, 0, buttons);
+dz, dw, buttons);
 vs-last_x = x;
 vs-last_y = y;
 }
-- 
1.7.1





[Qemu-devel] [PATCH 4/5] Add a horizontal wheel to the USB mouse and tablet

2010-05-04 Thread Brad Jorsch
Adjust the USB report descriptors to indicate that the mouse and tablet
have horizontal wheels, and then report the delta when polled.

Signed-off-by: Brad Jorsch ano...@users.sourceforge.net
---
 hw/usb-hid.c |   44 
 1 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index deb4731..15cc2a1 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -44,7 +44,7 @@
 #define USB_KEYBOARD  3
 
 typedef struct USBMouseState {
-int dx, dy, dz, buttons_state;
+int dx, dy, dz, dw, buttons_state;
 int x, y;
 int mouse_grabbed;
 QEMUPutMouseEntry *eh_entry;
@@ -137,14 +137,14 @@ static const uint8_t qemu_mouse_config_descriptor[] = {
 0x00,/*  u8 country_code */
 0x01,/*  u8 num_descriptors */
 0x22,/*  u8 type; Report */
-52, 0,   /*  u16 len */
+67, 0,   /*  u16 len */
 
/* one endpoint (status change endpoint) */
0x07,   /*  u8  ep_bLength; */
0x05,   /*  u8  ep_bDescriptorType; Endpoint */
0x81,   /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
0x03,   /*  u8  ep_bmAttributes; Interrupt */
-   0x04, 0x00, /*  u16 ep_wMaxPacketSize; */
+   0x05, 0x00, /*  u16 ep_wMaxPacketSize; */
0x0a,   /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
 };
 
@@ -192,14 +192,14 @@ static const uint8_t qemu_tablet_config_descriptor[] = {
 0x00,/*  u8 country_code */
 0x01,/*  u8 num_descriptors */
 0x22,/*  u8 type; Report */
-74, 0,   /*  u16 len */
+93, 0,   /*  u16 len */
 
/* one endpoint (status change endpoint) */
0x07,   /*  u8  ep_bLength; */
0x05,   /*  u8  ep_bDescriptorType; Endpoint */
0x81,   /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
0x03,   /*  u8  ep_bmAttributes; Interrupt */
-   0x08, 0x00, /*  u16 ep_wMaxPacketSize; */
+   0x09, 0x00, /*  u16 ep_wMaxPacketSize; */
0x0a,   /*  u8  ep_bInterval; (255ms -- usb 2.0 spec) */
 };
 
@@ -284,6 +284,13 @@ static const uint8_t qemu_mouse_hid_report_descriptor[] = {
 0x75, 0x08,/* Report Size (8) */
 0x95, 0x03,/* Report Count (3) */
 0x81, 0x06,/* Input (Data, Variable, Relative) */
+0x05, 0x0c,/* Usage Page (Consumer Devices) */
+0x0a, 0x38, 0x02,  /* Usage (AC Pan) */
+0x15, 0x81,/* Logical Minimum (-0x7f) */
+0x25, 0x7f,/* Logical Maximum (0x7f) */
+0x75, 0x08,/* Report Size (8) */
+0x95, 0x01,/* Report Count (1) */
+0x81, 0x06,/* Input (Data, Variable, Relative) */
 0xc0,  /*   End Collection */
 0xc0,  /* End Collection */
 };
@@ -324,6 +331,15 @@ static const uint8_t qemu_tablet_hid_report_descriptor[] = 
{
 0x75, 0x08,/* Report Size (8) */
 0x95, 0x01,/* Report Count (1) */
 0x81, 0x06,/* Input (Data, Variable, Relative) */
+0x05, 0x0c,/* Usage Page (Consumer Devices) */
+0x0a, 0x38, 0x02,  /* Usage (AC Pan) */
+0x15, 0x81,/* Logical Minimum (-0x7f) */
+0x25, 0x7f,/* Logical Maximum (0x7f) */
+0x35, 0x00,/* Physical Minimum (same as logical) */
+0x45, 0x00,/* Physical Maximum (same as logical) */
+0x75, 0x08,/* Report Size (8) */
+0x95, 0x01,/* Report Count (1) */
+0x81, 0x06,/* Input (Data, Variable, Relative) */
 0xc0,  /*   End Collection */
 0xc0,  /* End Collection */
 };
@@ -423,6 +439,7 @@ static void usb_mouse_event(void *opaque,
 s-dx += dx1;
 s-dy += dy1;
 s-dz += dz1;
+s-dw += dw1;
 s-buttons_state = buttons_state;
 
 usb_hid_changed(hs);
@@ -437,6 +454,7 @@ static void usb_tablet_event(void *opaque,
 s-x = x;
 s-y = y;
 s-dz += dz;
+s-dw += dw;
 s-buttons_state = buttons_state;
 
 usb_hid_changed(hs);
@@ -508,7 +526,7 @@ static inline int int_clamp(int val, int vmin, int vmax)
 
 static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, int len)
 {
-int dx, dy, dz, b, l;
+int dx, dy, dz, dw, b, l;
 USBMouseState *s = hs-ptr;
 
 if (!s-mouse_grabbed) {
@@ -519,10 +537,12 @@ static int usb_mouse_poll(USBHIDState *hs, uint8_t *buf, 
int len)
 dx = int_clamp(s-dx, -127, 127);
 dy = int_clamp(s-dy, -127, 127);
 dz = int_clamp(s-dz, -127, 127);
+dw = int_clamp(s-dw, -127, 127);
 
 s-dx -= dx;
 s-dy -= dy;
 s-dz -= dz;
+s-dw -= dw;
 
 /* Appears we have to invert the wheel direction */
 dz = 0 - dz;
@@ -544,12 +564,15 @@ 

[Qemu-devel] [PATCH 5/5] Add a horizontal wheel to the exps/2 mouse

2010-05-04 Thread Brad Jorsch
Have the emulated mouse report horizontal wheel events when in exps/2
mode.

Signed-off-by: Brad Jorsch ano...@users.sourceforge.net
---
 hw/ps2.c |   56 +++-
 1 files changed, 43 insertions(+), 13 deletions(-)

diff --git a/hw/ps2.c b/hw/ps2.c
index db5605d..09e4365 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -105,7 +105,9 @@ typedef struct {
 int mouse_dx; /* current values, needed for 'poll' mode */
 int mouse_dy;
 int mouse_dz;
+int mouse_dw;
 uint8_t mouse_buttons;
+uint8_t mouse_buttons_changed;
 } PS2MouseState;
 
 /* Table to convert from PC scancodes to raw scancodes.  */
@@ -284,11 +286,12 @@ void ps2_keyboard_set_translation(void *opaque, int mode)
 static void ps2_mouse_send_packet(PS2MouseState *s)
 {
 unsigned int b;
-int dx1, dy1, dz1;
+int dx1, dy1, dz1, dw1;
 
 dx1 = s-mouse_dx;
 dy1 = s-mouse_dy;
 dz1 = s-mouse_dz;
+dw1 = s-mouse_dw;
 /* XXX: increase range to 8 bits ? */
 if (dx1  127)
 dx1 = 127;
@@ -299,12 +302,17 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
 else if (dy1  -127)
 dy1 = -127;
 b = 0x08 | ((dx1  0)  4) | ((dy1  0)  5) | (s-mouse_buttons  0x07);
+s-mouse_buttons_changed = ~0x07;
 ps2_queue(s-common, b);
 ps2_queue(s-common, dx1  0xff);
 ps2_queue(s-common, dy1  0xff);
 /* extra byte for IMPS/2 or IMEX */
 switch(s-mouse_type) {
 default:
+/* Just ignore the wheels if not supported */
+s-mouse_dz = 0;
+s-mouse_dw = 0;
+s-mouse_buttons_changed = 0x07;
 break;
 case 3:
 if (dz1  127)
@@ -312,13 +320,29 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
 else if (dz1  -127)
 dz1 = -127;
 ps2_queue(s-common, dz1  0xff);
+s-mouse_dz -= dz1;
+s-mouse_dw = 0;
+s-mouse_buttons_changed = 0x07;
 break;
 case 4:
-if (dz1  7)
-dz1 = 7;
-else if (dz1  -7)
-dz1 = -7;
-b = (dz1  0x0f) | ((s-mouse_buttons  0x18)  1);
+/* This matches what the Linux kernel expects for exps/2 in
+ * drivers/input/mouse/psmouse-base.c. */
+if (dw1 != 0) {
+if (dw1  31)
+dw1 = 31;
+else if (dw1  -31)
+dw1 = -31;
+b = (dw1  0x3f) | 0x40;
+s-mouse_dw -= dw1;
+} else {
+if (dz1  7)
+dz1 = 7;
+else if (dz1  -7)
+dz1 = -7;
+b = (dz1  0x0f) | ((s-mouse_buttons  0x18)  1);
+s-mouse_dz -= dz1;
+s-mouse_buttons_changed = 0x07;
+}
 ps2_queue(s-common, b);
 break;
 }
@@ -326,7 +350,6 @@ static void ps2_mouse_send_packet(PS2MouseState *s)
 /* update deltas */
 s-mouse_dx -= dx1;
 s-mouse_dy -= dy1;
-s-mouse_dz -= dz1;
 }
 
 static void ps2_mouse_event(void *opaque,
@@ -341,11 +364,13 @@ static void ps2_mouse_event(void *opaque,
 s-mouse_dx += dx;
 s-mouse_dy -= dy;
 s-mouse_dz += dz;
+s-mouse_dw -= dw;
+s-mouse_buttons_changed |= s-mouse_buttons ^ buttons_state;
+s-mouse_buttons = buttons_state;
 /* XXX: SDL sometimes generates nul events: we delete them */
 if (s-mouse_dx == 0  s-mouse_dy == 0  s-mouse_dz == 0 
-s-mouse_buttons == buttons_state)
+s-mouse_dw == 0  s-mouse_buttons_changed == 0)
return;
-s-mouse_buttons = buttons_state;
 
 if (!(s-mouse_status  MOUSE_STATUS_REMOTE) 
 (s-common.queue.count  (PS2_QUEUE_SIZE - 16))) {
@@ -353,7 +378,8 @@ static void ps2_mouse_event(void *opaque,
 /* if not remote, send event. Multiple events are sent if
too big deltas */
 ps2_mouse_send_packet(s);
-if (s-mouse_dx == 0  s-mouse_dy == 0  s-mouse_dz == 0)
+if (s-mouse_dx == 0  s-mouse_dy == 0  s-mouse_dz == 0 
+s-mouse_dw == 0  s-mouse_buttons_changed == 0)
 break;
 }
 }
@@ -525,7 +551,9 @@ static void ps2_mouse_reset(void *opaque)
 s-mouse_dx = 0;
 s-mouse_dy = 0;
 s-mouse_dz = 0;
+s-mouse_dw = 0;
 s-mouse_buttons = 0;
+s-mouse_buttons_changed = 0;
 }
 
 static const VMStateDescription vmstate_ps2_common = {
@@ -569,9 +597,9 @@ static const VMStateDescription vmstate_ps2_keyboard = {
 
 static const VMStateDescription vmstate_ps2_mouse = {
 .name = ps2mouse,
-.version_id = 2,
-.minimum_version_id = 2,
-.minimum_version_id_old = 2,
+.version_id = 3,
+.minimum_version_id = 3,
+.minimum_version_id_old = 3,
 .fields  = (VMStateField []) {
 VMSTATE_STRUCT(common, PS2MouseState, 0, vmstate_ps2_common, PS2State),
 VMSTATE_UINT8(mouse_status, PS2MouseState),
@@ -583,7 +611,9 @@ static const VMStateDescription vmstate_ps2_mouse = {
 VMSTATE_INT32(mouse_dx, PS2MouseState),
 

[Qemu-devel] [RFC] [PATCH 0/5] Add horizontal wheel support to mice, where possible

2010-05-04 Thread Brad Jorsch
The emulated mice should emulate a horizontal wheel when possible. This
patch series does that for the USB mouse and tablet and the ExPS/2
mouse. As far as I can tell the vmmouse protocol doesn't handle a
horizontal wheel, and I have no idea if emulating a wheel might make
sense for any of the other mouse types.

I've tested this using the SDL interface and an Ububtu 10.04 cd image;
xev reports the correct events for all three devices, and a gedit window
with sufficient text to create scrollbars scrolls correctly with both
mice (didn't test the tablet). More testing would be good.

See also Debian bug #579968.[1]

[1] http://bugs.debian.org/579968