Re: [Qemu-devel] [PATCHv5 05/12] qxl: add io_port_to_string

2011-07-15 Thread Gerd Hoffmann

  Hi,


+switch (io_port) {
+case QXL_IO_NOTIFY_CMD:
+return "QXL_IO_NOTIFY_CMD";


Wasn't the plan to make this an array?

cheers,
  Gerd




Re: [Qemu-devel] [RFC] New thread for the VM migration

2011-07-15 Thread Paolo Bonzini

On 07/14/2011 06:07 PM, Avi Kivity wrote:


Maybe we can do this via a magic subsection whose contents are the
hotplug event.


What about making the device list just another "thing" that has to be 
migrated live, together with block and ram?


Paolo



Re: [Qemu-devel] [PATCHv5 09/12] qxl: async io support using new spice api

2011-07-15 Thread Gerd Hoffmann

  case QXL_IO_DESTROY_PRIMARY:
  if (val != 0) {
-qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
-break;
+qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
+  async);
+goto cancel_async;
+}
+dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
+   qxl_mode_to_string(d->mode));
+qxl_destroy_primary(d, async);
+#if SPICE_INTERFACE_QXL_MINOR>= 1
+if (d->mode == QXL_MODE_UNDEFINED&&  async == QXL_ASYNC) {
+dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
+qxl_mode_to_string(d->mode));
+qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
+goto cancel_async;
  }


Hmm?  Why this is needed?


  default:
  fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
  abort();
  }
+return;
+cancel_async:
+#if SPICE_INTERFACE_QXL_MINOR>= 1
+if (async) {
+qemu_mutex_lock(&d->async_lock);
+d->current_async = QXL_UNDEFINED_IO;
+qemu_mutex_unlock(&d->async_lock);


Add "qxl_send_events(d, QXL_INTERRUPT_IO_CMD)" here?


  typedef struct PCIQXLDevice {
  PCIDevice  pci;
  SimpleSpiceDisplay ssd;
@@ -30,6 +32,11 @@ typedef struct PCIQXLDevice {
  int32_tnum_memslots;
  int32_tnum_surfaces;

+#if SPICE_INTERFACE_QXL_MINOR>= 1
+uint32_t   current_async;
+QemuMutex  async_lock;
+#endif


No need to ifdef this.

cheers,
  Gerd



Re: [Qemu-devel] [PATCHv5 10/12] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support

2011-07-15 Thread Gerd Hoffmann

+#if SPICE_INTERFACE_QXL_MINOR>= 1
+case QXL_IO_FLUSH_RELEASE: {
+QXLReleaseRing *ring =&d->ram->release_ring;
+if (ring->prod - ring->cons + 1 == ring->num_items) {
+fprintf(stderr,
+"ERROR: no flush, full release ring [p%d,%dc]\n",
+ring->prod, ring->cons);
+}
+qxl_push_free_res(d, 1 /* flush */);
+dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
+qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+d->num_free_res, d->last_release);
+break;
+}
+case QXL_IO_FLUSH_SURFACES_ASYNC:
+dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+   val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+   d->num_free_res);
+qxl_spice_flush_surfaces_async(d);
+#endif
+break;


The last two lines should be swapped I guess.
Doesn't harm, but looks a bit odd ...

cheers,
  Gerd




Re: [Qemu-devel] [PATCHv5 11/12] qxl: bump pci rev

2011-07-15 Thread Gerd Hoffmann

+#if SPICE_INTERFACE_QXL_MINOR>= 1
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
+#else
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
+#endif


Does that actually build with old spice-protocol?  I don't think so ...

cheers,
  Gerd




Re: [Qemu-devel] [PATCHv5 09/12] qxl: async io support using new spice api

2011-07-15 Thread Gerd Hoffmann

On 07/14/11 21:13, Alon Levy wrote:

Some of the QXL port i/o commands are waiting for the spice server to
complete certain actions.  Add async versions for these commands, so we
don't block the vcpu while the spice server processses the command.
Instead the qxl device will raise an IRQ when done.

The async command processing relies on an added QXLInterface::async_complete
and added QXLWorker::*_async additions, in spice server qxl>= 3.1


Applying: qxl: async io support using new spice api
=== checkpatch complains ===
WARNING: labels should not be indented
#320: FILE: hw/qxl.c:1207:
+async_common:

total: 0 errors, 1 warnings, 574 lines checked

cheers,
  Gerd



Re: [Qemu-devel] [PATCHv5 12/12] qxl: use QXL_REVISION_*

2011-07-15 Thread Gerd Hoffmann

  Hi,


+#if SPICE_INTERFACE_QXL_MINOR>= 1
+qemu_mutex_init(&qxl->async_lock);
+qxl->current_async = QXL_UNDEFINED_IO;
+#endif


That surely belongs into another patch ...


+case QXL_REVISION_STABLE_V04: /* spice 0.4 -- qxl-1 */
+case QXL_REVISION_STABLE_V06: /* spice 0.6 -- qxl-2 */


I think we should just not use these defines for now.

In a year or so when the new bits are in widespread use we can raise the 
minimum required spice-server+spice-protocol versions, cleanup the ifdef 
mess and also use QXL_REVISION_STABLE_V04.


cheers,
  Gerd




Re: [Qemu-devel] [PATCHv5 05/12] qxl: add io_port_to_string

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 09:59:21AM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> >+switch (io_port) {
> >+case QXL_IO_NOTIFY_CMD:
> >+return "QXL_IO_NOTIFY_CMD";
> 
> Wasn't the plan to make this an array?
> 

yes. Somehow I sent the wrong patch. No idea how I managed to do that.

> cheers,
>   Gerd
> 



Re: [Qemu-devel] [PATCHv5 09/12] qxl: async io support using new spice api

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 10:19:27AM +0200, Gerd Hoffmann wrote:
> On 07/14/11 21:13, Alon Levy wrote:
> >Some of the QXL port i/o commands are waiting for the spice server to
> >complete certain actions.  Add async versions for these commands, so we
> >don't block the vcpu while the spice server processses the command.
> >Instead the qxl device will raise an IRQ when done.
> >
> >The async command processing relies on an added QXLInterface::async_complete
> >and added QXLWorker::*_async additions, in spice server qxl>= 3.1
> 
> Applying: qxl: async io support using new spice api
> === checkpatch complains ===
> WARNING: labels should not be indented
> #320: FILE: hw/qxl.c:1207:
> +async_common:
> 

thanks, my bad, did this after the checkpatch (obviously). I'll go add
it to the commit hook.

> total: 0 errors, 1 warnings, 574 lines checked
> 
> cheers,
>   Gerd



Re: [Qemu-devel] [PATCHv5 09/12] qxl: async io support using new spice api

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 10:12:14AM +0200, Gerd Hoffmann wrote:
> >  case QXL_IO_DESTROY_PRIMARY:
> >  if (val != 0) {
> >-qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
> >-break;
> >+qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",
> >+  async);
> >+goto cancel_async;
> >+}
> >+dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,
> >+   qxl_mode_to_string(d->mode));
> >+qxl_destroy_primary(d, async);
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+if (d->mode == QXL_MODE_UNDEFINED&&  async == QXL_ASYNC) {
> >+dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
> >+qxl_mode_to_string(d->mode));
> >+qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
> >+goto cancel_async;
> >  }
> 
> Hmm?  Why this is needed?
In this case we don't do any operation (i.e. qxl_destroy_primary is a nop,
it checkes d->mode == QXL_MODE_UNDEFINED too) so there will never be an 
async_complete,
so there will never be a qxl_send_events, so we need to send it now.

> 
> >  default:
> >  fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, 
> > io_port);
> >  abort();
> >  }
> >+return;
> >+cancel_async:
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+if (async) {
> >+qemu_mutex_lock(&d->async_lock);
> >+d->current_async = QXL_UNDEFINED_IO;
> >+qemu_mutex_unlock(&d->async_lock);
> 
> Add "qxl_send_events(d, QXL_INTERRUPT_IO_CMD)" here?

no, we want that wen the command is actually complete, on async_complete,
where it is already done.

> 
> >  typedef struct PCIQXLDevice {
> >  PCIDevice  pci;
> >  SimpleSpiceDisplay ssd;
> >@@ -30,6 +32,11 @@ typedef struct PCIQXLDevice {
> >  int32_tnum_memslots;
> >  int32_tnum_surfaces;
> >
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+uint32_t   current_async;
> >+QemuMutex  async_lock;
> >+#endif
> 
> No need to ifdef this.
> 

missed it.

> cheers,
>   Gerd



Re: [Qemu-devel] [PATCHv5 11/12] qxl: bump pci rev

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 10:20:08AM +0200, Gerd Hoffmann wrote:
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
> >+#else
> >+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
> >+#endif
> 
> Does that actually build with old spice-protocol?  I don't think so ...
> 

no, it won't. /me wonders how I did the compilations. I'll use 2 and 3.

> cheers,
>   Gerd
> 



Re: [Qemu-devel] [PATCHv5 10/12] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 10:15:26AM +0200, Gerd Hoffmann wrote:
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+case QXL_IO_FLUSH_RELEASE: {
> >+QXLReleaseRing *ring =&d->ram->release_ring;
> >+if (ring->prod - ring->cons + 1 == ring->num_items) {
> >+fprintf(stderr,
> >+"ERROR: no flush, full release ring [p%d,%dc]\n",
> >+ring->prod, ring->cons);
> >+}
> >+qxl_push_free_res(d, 1 /* flush */);
> >+dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
> >+qxl_mode_to_string(d->mode), d->guest_surfaces.count,
> >+d->num_free_res, d->last_release);
> >+break;
> >+}
> >+case QXL_IO_FLUSH_SURFACES_ASYNC:
> >+dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, 
> >res#=%d)\n",
> >+   val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
> >+   d->num_free_res);
> >+qxl_spice_flush_surfaces_async(d);
> >+#endif
> >+break;
> 
> The last two lines should be swapped I guess.
> Doesn't harm, but looks a bit odd ...

yep. thanks, will fix.

> 
> cheers,
>   Gerd
> 



Re: [Qemu-devel] [PATCHv5 12/12] qxl: use QXL_REVISION_*

2011-07-15 Thread Alon Levy
On Fri, Jul 15, 2011 at 10:23:39AM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> >+#if SPICE_INTERFACE_QXL_MINOR>= 1
> >+qemu_mutex_init(&qxl->async_lock);
> >+qxl->current_async = QXL_UNDEFINED_IO;
> >+#endif
> 
> That surely belongs into another patch ...

yes.

> 
> >+case QXL_REVISION_STABLE_V04: /* spice 0.4 -- qxl-1 */
> >+case QXL_REVISION_STABLE_V06: /* spice 0.6 -- qxl-2 */
> 
> I think we should just not use these defines for now.
> 
> In a year or so when the new bits are in widespread use we can raise
> the minimum required spice-server+spice-protocol versions, cleanup
> the ifdef mess and also use QXL_REVISION_STABLE_V04.
> 

ok. I'll drop this patch (at least the bits fitting the patch header).

> cheers,
>   Gerd
> 



Re: [Qemu-devel] [PATCH v5 06/10] trace-state: add "-trace events" argument to control initial state

2011-07-15 Thread Stefan Hajnoczi
On Tue, Jun 28, 2011 at 06:53:34PM +0200, Lluís wrote:
> diff --git a/docs/tracing.txt b/docs/tracing.txt
> index 017ff59..8f6e5c9 100644
> --- a/docs/tracing.txt
> +++ b/docs/tracing.txt
> @@ -129,6 +129,9 @@ This functionality is also provided through monitor 
> commands:
>  * trace-event NAME on|off
>Enable/disable a given trace event.
>  
> +The "-trace events=" command line argument can be used to enable the
> +events listed in  from the very beginning of the program.

Please document the syntax of the file: one event name per line.

> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -2394,17 +2394,29 @@ Normally QEMU loads a configuration file from 
> @var{sysconfdir}/qemu.conf and
>  option will prevent QEMU from loading these configuration files at startup.
>  ETEXI
>  DEF("trace", HAS_ARG, QEMU_OPTION_trace,
> -"-trace\n"
> -"Specify a trace file to log traces to\n",
> +"-trace [events=][,file=]\n"
> +"specify tracing options\n",
>  QEMU_ARCH_ALL)
>  STEXI
> -HXCOMM This line is not accurate, as the option is backend-specific but HX 
> does
> -HXCOMM not support conditional compilation of text.
> -@item -trace
> +HXCOMM This line is not accurate, as some sub-options are backend-specific 
> but
> +HXCOMM HX does not support conditional compilation of text.
> +@item -trace [events=@var{file}][,file=@var{file}]
>  @findex -trace
> -Specify a trace file to log output traces to.
> +
> +Specify tracing options.
> +
> +@table @option
> +@item events=@var{file}
> +Immediately enable events listed in @var{file}.
> +The file must contain one event name (as listed in the @var{trace-events} 
> file)
> +per line.
> +
> +This option is not available when using the @var{nop} tracing backend.
> +@item file=@var{file}

This option is only available when using the @var{simple} tracing
backend.

(nop, ust, dtrace, stderr don't support it)

Stefan



Re: [Qemu-devel] [PATCH v5 04/10] trace-state: separate trace event control and query routines from the simple backend

2011-07-15 Thread Stefan Hajnoczi
On Tue, Jun 28, 2011 at 06:53:21PM +0200, Lluís wrote:
> Move the 'st_print_trace_events' and 'st_change_trace_event_state' into
> backend-agnostic 'trace_print_events' and 'trace_event_set_state' 
> (respectively)
> in the "trace/control.c" file.

Renaming the functions makes sense but moving their implementations out
into control.c inside an #ifdef is not clean.  Why not keep their
implementations in simple.c?

Just renaming them to the generic name should be enough.  Let the linker
do the #ifdef (we only link in simple.o or we link in another trace
backend).  There's no need for control.c.

Stefan



Re: [Qemu-devel] [PATCH v5 00/10] trace-state: make the behaviour of "disable" consistent across all backends

2011-07-15 Thread Stefan Hajnoczi
On Tue, Jun 28, 2011 at 06:52:55PM +0200, Lluís wrote:
> This patch defines the "disable" trace event state to always use the "nop"
> backend.
> 
> As a side-effect, all events are now enabled (without "disable") by default, 
> as
> all backends (except "stderr") have programmatic support for dynamically
> (de)activating each trace event.
> 
> In order to make this true, the "simple" backend now has a "-trace
> events=" argument to let the user select which events must be enabled 
> from
> the very beginning.
> 
> NOTES:
> * Parsing of -trace arguments is not done in the OS-specific frontends.
> 
> Signed-off-by: Lluís Vilanova 
> ---
> 
> Changes in v5:
> 
> * Fix a variable name typo in configure.
> * Rebase on qemu.git/master (c24a9c6ef946ec1b5b280061d4f7b579aaac6707).
> 
> Changes in v4:
> 
> * Fix a couple of minor errors.
> 
> Changes in v3:
> 
> * Rebase on qemu.git/master (642cfd4d31241c0fc65c520cb1e703659af66236).
> * Remove already-merged patches.
> * Remove code styling patches.
> * Generalize programmatic interface for trace event state control.
> 
> Changes in v2:
> 
> * Documentation fixes.
> * Seggregate whitespace/indentation changes.
> * Minor code beautifications.
> * Make all -trace suboptions explicit.
> * Fix minor comments from Stefan.
> * Minor trace-events format fixes.
> * Integrate changes from Fabien.
> * Rebase on qemu.git/master (c8f930c0eeb696d638f4d4bf654e955fa44ff40f).
> 
> Lluís Vilanova (10):
>   trace: move backend-specific code into the trace/ directory
>   trace: avoid conditional code compilation during option parsing
>   trace: generalize the "property" concept in the trace-events file
>   trace-state: separate trace event control and query routines from the 
> simple backend
>   trace-state: always compile support for controlling and querying trace 
> event states
>   trace-state: add "-trace events" argument to control initial state
>   trace-state: always use the "nop" backend on events with the "disable" 
> keyword
>   trace-state: [simple] disable all trace points by default
>   trace-state: [stderr] add support for dynamically enabling/disabling 
> events
>   trace: enable all events
> 
> 
>  .gitignore|2 
>  Makefile  |1 
>  Makefile.objs |5 
>  configure |7 +
>  docs/tracing.txt  |   64 +++---
>  hmp-commands.hx   |9 +
>  monitor.c |   19 +-
>  qemu-config.c |7 -
>  qemu-options.hx   |   26 ++
>  scripts/tracetool |  116 +--
>  simpletrace.c |  355 -
>  simpletrace.h |   48 
>  trace-events  |  569 
> ++---
>  trace/control.c   |   66 ++
>  trace/control.h   |   16 +
>  trace/simple.c|  332 +++
>  trace/simple.h|   46 
>  trace/stderr.h|   11 +
>  vl.c  |   21 +-
>  19 files changed, 914 insertions(+), 806 deletions(-)
>  delete mode 100644 simpletrace.c
>  delete mode 100644 simpletrace.h
>  create mode 100644 trace/control.c
>  create mode 100644 trace/control.h
>  create mode 100644 trace/simple.c
>  create mode 100644 trace/simple.h
>  create mode 100644 trace/stderr.h

Nice!  Now both stderr and simple are unified in terms of user
interface.  -trace events= can be used to set the enabled trace
events on startup.

I did leave some comments, mainly #ifdef reduction.  But let's merge the
next version.

Stefan



Re: [Qemu-devel] [PATCH v5 01/10] trace: move backend-specific code into the trace/ directory

2011-07-15 Thread Stefan Hajnoczi
On Tue, Jun 28, 2011 at 06:53:01PM +0200, Lluís wrote:
> Signed-off-by: Lluís Vilanova 
> ---
>  .gitignore|2 
>  Makefile  |1 
>  Makefile.objs |4 -
>  scripts/tracetool |2 
>  simpletrace.c |  355 
> -
>  simpletrace.h |   48 ---
>  trace/simple.c|  355 
> +
>  trace/simple.h|   48 +++
>  vl.c  |2 
>  9 files changed, 410 insertions(+), 407 deletions(-)
>  delete mode 100644 simpletrace.c
>  delete mode 100644 simpletrace.h
>  create mode 100644 trace/simple.c
>  create mode 100644 trace/simple.h
> 
> diff --git a/.gitignore b/.gitignore
> index 08013fc..b1db525 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -2,6 +2,8 @@ config-devices.*
>  config-all-devices.*
>  config-host.*
>  config-target.*
> +trace/*.d
> +trace/*.o

These are not needed, the *.d and *.o rules already cover them.

>  trace.h
>  trace.c
>  trace-dtrace.h
> diff --git a/Makefile b/Makefile
> index b3ffbe2..fe01145 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -170,6 +170,7 @@ clean:
>   rm -Rf .libs
>   rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d 
> net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d
>   rm -f qemu-img-cmds.h
> + rm -f trace/*.o trace/*.d
>   rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
>   rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
>   rm -f trace-dtrace.h trace-dtrace.h-timestamp
> diff --git a/Makefile.objs b/Makefile.objs
> index cea15e4..9a67374 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -355,14 +355,14 @@ trace-dtrace.lo: trace-dtrace.dtrace
>   $(call quiet-command,libtool --mode=compile --tag=CC dtrace -o $@ -G -s 
> $<, "  lt GEN trace-dtrace.o")
>  endif
>  
> -simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
> +trace/simple.o: trace/simple.c $(GENERATED_HEADERS)
>  
>  ifeq ($(TRACE_BACKEND),dtrace)
>  trace-obj-y = trace-dtrace.o
>  else
>  trace-obj-y = trace.o
>  ifeq ($(TRACE_BACKEND),simple)
> -trace-obj-y += simpletrace.o
> +trace-obj-y += trace/simple.o

Once more files are added into trace/ it will be useful to use the
"nested" approach that the makefiles use elsewhere (e.g.
block-nested-y).  It avoids having to specify "trace/" for each object
file in the directory.

Stefan



Re: [Qemu-devel] [PATCH v5 02/10] trace: avoid conditional code compilation during option parsing

2011-07-15 Thread Stefan Hajnoczi
On Tue, Jun 28, 2011 at 06:53:08PM +0200, Lluís wrote:
> diff --git a/vl.c b/vl.c
> index b2f41fd..b766dc7 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2861,14 +2861,23 @@ int main(int argc, char **argv, char **envp)
>  }
>  xen_mode = XEN_ATTACH;
>  break;
> -#ifdef CONFIG_SIMPLE_TRACE
>  case QEMU_OPTION_trace:
>  opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
> -if (opts) {
> -trace_file = qemu_opt_get(opts, "file");
> +if (!opts) {
> +exit(1);
>  }
> -break;
> +#if defined(CONFIG_TRACE_NOP)
> +fprintf(stderr, "qemu: option \"-%s\" is not supported by 
> this tracing backend\n", popt->name);
> +exit(1);
>  #endif
> +trace_file = qemu_opt_get(opts, "file");
> +#if !defined(CONFIG_SIMPLE_TRACE)
> +if (trace_file) {
> +fprintf(stderr, "qemu: suboption \"-%s file\" is not 
> supported by this tracing backend\n", popt->name);
> +exit(1);
> +}
> +#endif

This doesn't account for other trace backends.  For example with dtrace
or ust the option would be compiled in and not rejected at runtime.

Instead of checking all possible trace backend CONFIG_* we could always
compile the -trace option in.  Specific backends can validate their
options (if used).  This approach will not reject unused options but
it's simple and doesn't use #ifdefs.

Stefan



Re: [Qemu-devel] [Bug 810588] [NEW] Unexpected crash of qemu-kvm with SCSI disk emulation.

2011-07-15 Thread Stefan Hajnoczi
On Thu, Jul 14, 2011 at 5:43 PM, Constantine Chernov
<810...@bugs.launchpad.net> wrote:
> Virual machine with MS windows 2003 installed on the virtual scsi disk 
> (-drive 
> file=/my/path/myimage.qcow2.img,boot=on,if=scsi,media=disk,bus=0,unit=1) 
> unexpectedly crashes without core dump. When the image is connected as an ide 
> disk (-hda )  vm flies normally.
> Qemu-kvm version: 0.12.5
> Os/distr.: Debian squeeze, x86_64

Please post your full QEMU command-line.

Did you enable core dumps before launch QEMU?  Do "ulimit -c
unlimited" in the same shell before running the QEMU command-line.

If it is exiting instead of crashing I suggest launching QEMU from gdb
and catching the exit:
1. Install qemu-kvm-dbg to get the debuginfo for useful backtraces
2. Start gdb with QEMU and its usual command-line arguments: gdb
--args qemu-kvm ...
3. Set breakpoints on exit(3) and abort(2):
b exit
b abort
4. Run the VM and reproduce the exit:
r
5. When it exits you will hopefully be at an exit/abort breakpoint and
can print the stack trace:
bt

Please post the backtrace so we have more information on how the exit happens.

Thanks,
Stefan



Re: [Qemu-devel] [PATCH] xen: introduce xen_change_state_handler

2011-07-15 Thread Stefano Stabellini
I have just realized that I wrote the reply to this email long ago but I
have never sent it, it was sitting in my Draft mbox.

On Thu, 30 Jun 2011, Alexander Graf wrote:
> On 06/29/2011 01:16 PM, stefano.stabell...@eu.citrix.com wrote:
> > From: Anthony PERARD
> >
> > Remove the call to xenstore_record_dm_state from xen_main_loop_prepare
> > that is HVM specific.
> > Add a new vm_change_state_handler shared between xen_pv and xen_hvm
> > machines to record the VM state to xenstore.
> >
> > Signed-off-by: Anthony PERARD
> > Signed-off-by: Stefano Stabellini
> > ---
> >   xen-all.c |   25 ++---
> >   1 files changed, 18 insertions(+), 7 deletions(-)
> >
> > diff --git a/xen-all.c b/xen-all.c
> > index 3fd04ef..e8da35f 100644
> > --- a/xen-all.c
> > +++ b/xen-all.c
> > @@ -797,12 +797,17 @@ void xenstore_store_pv_console_info(int i, 
> > CharDriverState *chr)
> >   }
> >   }
> >
> > -static void xenstore_record_dm_state(XenIOState *s, const char *state)
> > +static void xenstore_record_dm_state(struct xs_handle *xs, const char 
> > *state)
> >   {
> >   char path[50];
> >
> > +if (xs == NULL) {
> > +fprintf(stderr, "xenstore connection not initialized\n");
> > +exit(1);
> > +}
> 
> /studio/tmp/agraf/xen-all.c: In function ‘xenstore_record_dm_state’:
> /studio/tmp/agraf/xen-all.c:744: error: ‘xs’ undeclared (first use in 
> this function)
> /studio/tmp/agraf/xen-all.c:744: error: (Each undeclared identifier is 
> reported only once
> /studio/tmp/agraf/xen-all.c:744: error: for each function it appears in.)

I think you had some conflicts applying the patch, I'll post it again
rebased on your xen-next branch.

Re: [Qemu-devel] [PATCH v3] xen: implement unplug protocol in xen_platform

2011-07-15 Thread Stefano Stabellini
On Fri, 1 Jul 2011, Stefano Stabellini wrote:
> On Fri, 1 Jul 2011, Kevin Wolf wrote:
> > Am 30.06.2011 16:16, schrieb Stefano Stabellini:
> > > On Thu, 30 Jun 2011, Kevin Wolf wrote:
> > >>> +static int pci_piix3_xen_ide_unplug(DeviceState *dev)
> > >>> +{
> > >>> +PCIDevice *pci_dev;
> > >>> +PCIIDEState *pci_ide;
> > >>> +DriveInfo *di;
> > >>> +int i = 0;
> > >>> +
> > >>> +pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
> > >>> +pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev);
> > >>> +
> > >>> +for (; i < 3; i++) {
> > >>> +di = drive_get_by_index(IF_IDE, i);
> > >>> +if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) {
> > >>> +DeviceState *ds = bdrv_get_attached(di->bdrv);
> > >>> +if (ds) {
> > >>> +bdrv_detach(di->bdrv, ds);
> > >>> +}
> > >>> +bdrv_close(di->bdrv);
> > >>> +pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
> > >>
> > >> Have you tested if this is enough if the guest tries to continue using
> > >> the device? I don't know of any case where it's not sufficient, just
> > >> trying to make sure that it's really true in practice.
> > > 
> > > The purpose of this is to "hide" the disk from the guest. The unplug is
> > > supposed to happen *before* the guest enumerates the IDE disks; it is
> > > responsibility of the guest to make sure of it.
> > > I tested it with Linux PV on HVM drivers, and Linux doesn't see the
> > > emulated disk after the unplug, as it should be.
> > 
> > Yeah. What I meant is that we should make sure that a misbehaving guest,
> > which just keeps on playing with the IDE ports anyway, can't crash qemu.
> > A quick review suggests that it is the case, but testing it anyway would
> > be better.
> 
> I see what you mean: I tested it, a guest cannot crash Qemu.
> 

ping?



[Qemu-devel] [PATCH][REPOST] xen: introduce xen_change_state_handler

2011-07-15 Thread stefano.stabellini
From: Anthony PERARD 

Remove the call to xenstore_record_dm_state from xen_main_loop_prepare
that is HVM specific.
Add a new vm_change_state_handler shared between xen_pv and xen_hvm
machines to record the VM state to xenstore.

Signed-off-by: Anthony PERARD 
Signed-off-by: Stefano Stabellini 
---
 xen-all.c |   25 ++---
 1 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 8105c83..5fa92ae 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -797,12 +797,17 @@ void xenstore_store_pv_console_info(int i, 
CharDriverState *chr)
 }
 }
 
-static void xenstore_record_dm_state(XenIOState *s, const char *state)
+static void xenstore_record_dm_state(struct xs_handle *xs, const char *state)
 {
 char path[50];
 
+if (xs == NULL) {
+fprintf(stderr, "xenstore connection not initialized\n");
+exit(1);
+}
+
 snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", 
xen_domid);
-if (!xs_write(s->xenstore, XBT_NULL, path, state, strlen(state))) {
+if (!xs_write(xs, XBT_NULL, path, state, strlen(state))) {
 fprintf(stderr, "error recording dm state\n");
 exit(1);
 }
@@ -823,15 +828,20 @@ static void xen_main_loop_prepare(XenIOState *state)
 if (evtchn_fd != -1) {
 qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
 }
-
-/* record state running */
-xenstore_record_dm_state(state, "running");
 }
 
 
 /* Initialise Xen */
 
-static void xen_vm_change_state_handler(void *opaque, int running, int reason)
+static void xen_change_state_handler(void *opaque, int running, int reason)
+{
+if (running) {
+/* record state running */
+xenstore_record_dm_state(xenstore, "running");
+}
+}
+
+static void xen_hvm_change_state_handler(void *opaque, int running, int reason)
 {
 XenIOState *state = opaque;
 if (running) {
@@ -854,6 +864,7 @@ int xen_init(void)
 xen_be_printf(NULL, 0, "can't open xen interface\n");
 return -1;
 }
+qemu_add_vm_change_state_handler(xen_change_state_handler, NULL);
 
 return 0;
 }
@@ -915,7 +926,7 @@ int xen_hvm_init(void)
 xen_map_cache_init();
 xen_ram_init(ram_size);
 
-qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
+qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state);
 
 state->client = xen_cpu_phys_memory_client;
 QLIST_INIT(&state->physmap);
-- 
1.7.2.3




Re: [Qemu-devel] [PATCH v3] xen: implement unplug protocol in xen_platform

2011-07-15 Thread Kevin Wolf
Am 15.07.2011 12:34, schrieb Stefano Stabellini:
> On Fri, 1 Jul 2011, Stefano Stabellini wrote:
>> On Fri, 1 Jul 2011, Kevin Wolf wrote:
>>> Am 30.06.2011 16:16, schrieb Stefano Stabellini:
 On Thu, 30 Jun 2011, Kevin Wolf wrote:
>> +static int pci_piix3_xen_ide_unplug(DeviceState *dev)
>> +{
>> +PCIDevice *pci_dev;
>> +PCIIDEState *pci_ide;
>> +DriveInfo *di;
>> +int i = 0;
>> +
>> +pci_dev = DO_UPCAST(PCIDevice, qdev, dev);
>> +pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev);
>> +
>> +for (; i < 3; i++) {
>> +di = drive_get_by_index(IF_IDE, i);
>> +if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) {
>> +DeviceState *ds = bdrv_get_attached(di->bdrv);
>> +if (ds) {
>> +bdrv_detach(di->bdrv, ds);
>> +}
>> +bdrv_close(di->bdrv);
>> +pci_ide->bus[di->bus].ifs[di->unit].bs = NULL;
>
> Have you tested if this is enough if the guest tries to continue using
> the device? I don't know of any case where it's not sufficient, just
> trying to make sure that it's really true in practice.

 The purpose of this is to "hide" the disk from the guest. The unplug is
 supposed to happen *before* the guest enumerates the IDE disks; it is
 responsibility of the guest to make sure of it.
 I tested it with Linux PV on HVM drivers, and Linux doesn't see the
 emulated disk after the unplug, as it should be.
>>>
>>> Yeah. What I meant is that we should make sure that a misbehaving guest,
>>> which just keeps on playing with the IDE ports anyway, can't crash qemu.
>>> A quick review suggests that it is the case, but testing it anyway would
>>> be better.
>>
>> I see what you mean: I tested it, a guest cannot crash Qemu.
>>
> 
> ping?

I thought Alex had already merged it. I'm pretty sure that I stated
somewhere that the patch is okay for me now. In case I didn't:

Acked-by: Kevin Wolf 



Re: [Qemu-devel] [PATCHv5 09/12] qxl: async io support using new spice api

2011-07-15 Thread Gerd Hoffmann

  Hi,


+qxl_destroy_primary(d, async);
+#if SPICE_INTERFACE_QXL_MINOR>= 1
+if (d->mode == QXL_MODE_UNDEFINED&&   async == QXL_ASYNC) {
+dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",
+qxl_mode_to_string(d->mode));
+qxl_send_events(d, QXL_INTERRUPT_IO_CMD);
+goto cancel_async;
  }


Hmm?  Why this is needed?

In this case we don't do any operation (i.e. qxl_destroy_primary is a nop,
it checkes d->mode == QXL_MODE_UNDEFINED too) so there will never be an 
async_complete,
so there will never be a qxl_send_events, so we need to send it now.


Ok.  Maybe make qxl_destroy_primary return an error in case there is no 
primary to destroy, then catch this here?  Makes more clear what is 
going on here.





  default:
  fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
  abort();
  }
+return;
+cancel_async:
+#if SPICE_INTERFACE_QXL_MINOR>= 1
+if (async) {
+qemu_mutex_lock(&d->async_lock);
+d->current_async = QXL_UNDEFINED_IO;
+qemu_mutex_unlock(&d->async_lock);


Add "qxl_send_events(d, QXL_INTERRUPT_IO_CMD)" here?


no, we want that wen the command is actually complete, on async_complete,
where it is already done.


That is the cancel code path, i.e. the guest did a async request but we 
don't submit one to the spice-server because some sanity check failed, 
so we never get a complete callback.  Thats why I think we should raise 
the QXL_INTERRUPT_IO_CMD interrupt here instead.


cheers,
  Gerd




[Qemu-devel] [PATCH v6 01/11] spice: add worker wrapper functions.

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Add wrapper functions for all spice worker calls.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl-render.c|4 +-
 hw/qxl.c   |   32 +-
 ui/spice-display.c |   95 ---
 ui/spice-display.h |   22 
 4 files changed, 129 insertions(+), 24 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1316066..bef5f14 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
 update.bottom = qxl->guest_primary.surface.height;
 
 memset(dirty, 0, sizeof(dirty));
-qxl->ssd.worker->update_area(qxl->ssd.worker, 0, &update,
- dirty, ARRAY_SIZE(dirty), 1);
+qemu_spice_update_area(&qxl->ssd, 0, &update,
+   dirty, ARRAY_SIZE(dirty), 1);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 919ec91..545074d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -690,8 +690,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
 dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
 
-d->ssd.worker->reset_cursor(d->ssd.worker);
-d->ssd.worker->reset_image_cache(d->ssd.worker);
+qemu_spice_reset_cursor(&d->ssd);
+qemu_spice_reset_image_cache(&d->ssd);
 qxl_reset_surfaces(d);
 qxl_reset_memslots(d);
 
@@ -796,7 +796,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t 
slot_id, uint64_t delta)
__FUNCTION__, memslot.slot_id,
memslot.virt_start, memslot.virt_end);
 
-d->ssd.worker->add_memslot(d->ssd.worker, &memslot);
+qemu_spice_add_memslot(&d->ssd, &memslot);
 d->guest_slots[slot_id].ptr = (void*)memslot.virt_start;
 d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
 d->guest_slots[slot_id].delta = delta;
@@ -806,14 +806,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t 
slot_id, uint64_t delta)
 static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
 {
 dprint(d, 1, "%s: slot %d\n", __FUNCTION__, slot_id);
-d->ssd.worker->del_memslot(d->ssd.worker, MEMSLOT_GROUP_HOST, slot_id);
+qemu_spice_del_memslot(&d->ssd, MEMSLOT_GROUP_HOST, slot_id);
 d->guest_slots[slot_id].active = 0;
 }
 
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
-d->ssd.worker->reset_memslots(d->ssd.worker);
+qemu_spice_reset_memslots(&d->ssd);
 memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -821,7 +821,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
-d->ssd.worker->destroy_surfaces(d->ssd.worker);
+qemu_spice_destroy_surfaces(&d->ssd);
 memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -875,7 +875,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int 
loadvm)
 
 qxl->mode = QXL_MODE_NATIVE;
 qxl->cmdflags = 0;
-qxl->ssd.worker->create_primary_surface(qxl->ssd.worker, 0, &surface);
+qemu_spice_create_primary_surface(&qxl->ssd, 0, &surface);
 
 /* for local rendering */
 qxl_render_resize(qxl);
@@ -890,7 +890,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d)
 dprint(d, 1, "%s\n", __FUNCTION__);
 
 d->mode = QXL_MODE_UNDEFINED;
-d->ssd.worker->destroy_primary_surface(d->ssd.worker, 0);
+qemu_spice_destroy_primary_surface(&d->ssd, 0);
 }
 
 static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
@@ -962,15 +962,15 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_UPDATE_AREA:
 {
 QXLRect update = d->ram->update_area;
-d->ssd.worker->update_area(d->ssd.worker, d->ram->update_surface,
-   &update, NULL, 0, 0);
+qemu_spice_update_area(&d->ssd, d->ram->update_surface,
+   &update, NULL, 0, 0);
 break;
 }
 case QXL_IO_NOTIFY_CMD:
-d->ssd.worker->wakeup(d->ssd.worker);
+qemu_spice_wakeup(&d->ssd);
 break;
 case QXL_IO_NOTIFY_CURSOR:
-d->ssd.worker->wakeup(d->ssd.worker);
+qemu_spice_wakeup(&d->ssd);
 break;
 case QXL_IO_UPDATE_IRQ:
 qxl_set_irq(d);
@@ -984,7 +984,7 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 break;
 }
 d->oom_running = 1;
-d->ssd.worker->oom(d->ssd.worker);
+qemu_spice_oom(&d->ssd);
 d->oom_running = 0;
 break;
 case QXL_IO_SET_MODE:
@@ -1022,10 +1022,10 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_destroy_primary(d);
 break;
 case QXL_IO_DESTROY_SURFACE_WAIT:
-d->ssd.worker->destroy_surface_wait(d->ssd.worker, val);
+qemu_spice_destroy_surface_wait(&d->ssd, val);
 

[Qemu-devel] [PATCH v6 03/11] spice/qxl: move worker wrappers

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Move the wrapper functions which are used by qxl only to qxl.c.
Rename them from qemu_spice_* to qxl_spice_*.  Also pass in a
qxl state pointer instead of a SimpleSpiceDisplay pointer.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl-render.c|4 +-
 hw/qxl.c   |   67 ---
 hw/qxl.h   |   13 ++
 ui/spice-display.c |   46 ---
 ui/spice-display.h |   12 -
 5 files changed, 72 insertions(+), 70 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index bef5f14..60b822d 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl)
 update.bottom = qxl->guest_primary.surface.height;
 
 memset(dirty, 0, sizeof(dirty));
-qemu_spice_update_area(&qxl->ssd, 0, &update,
-   dirty, ARRAY_SIZE(dirty), 1);
+qxl_spice_update_area(qxl, 0, &update,
+  dirty, ARRAY_SIZE(dirty), 1);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 2d46814..29094a9 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,6 +125,53 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+
+void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
+   struct QXLRect *area, struct QXLRect *dirty_rects,
+   uint32_t num_dirty_rects,
+   uint32_t clear_dirty_region)
+{
+qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, 
dirty_rects,
+ num_dirty_rects, clear_dirty_region);
+}
+
+void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+{
+qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+}
+
+void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
+   uint32_t count)
+{
+qxl->ssd.worker->loadvm_commands(qxl->ssd.worker, ext, count);
+}
+
+void qxl_spice_oom(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->oom(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
+}
+
+void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
+}
+
+void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
+}
+
+
 static inline uint32_t msb_mask(uint32_t val)
 {
 uint32_t mask;
@@ -690,8 +737,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm)
 dprint(d, 1, "%s: start%s\n", __FUNCTION__,
loadvm ? " (loadvm)" : "");
 
-qemu_spice_reset_cursor(&d->ssd);
-qemu_spice_reset_image_cache(&d->ssd);
+qxl_spice_reset_cursor(d);
+qxl_spice_reset_image_cache(d);
 qxl_reset_surfaces(d);
 qxl_reset_memslots(d);
 
@@ -813,7 +860,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t 
slot_id)
 static void qxl_reset_memslots(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
-qemu_spice_reset_memslots(&d->ssd);
+qxl_spice_reset_memslots(d);
 memset(&d->guest_slots, 0, sizeof(d->guest_slots));
 }
 
@@ -821,7 +868,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 {
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
-qemu_spice_destroy_surfaces(&d->ssd);
+qxl_spice_destroy_surfaces(d);
 memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
@@ -962,8 +1009,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_UPDATE_AREA:
 {
 QXLRect update = d->ram->update_area;
-qemu_spice_update_area(&d->ssd, d->ram->update_surface,
-   &update, NULL, 0, 0);
+qxl_spice_update_area(d, d->ram->update_surface,
+  &update, NULL, 0, 0);
 break;
 }
 case QXL_IO_NOTIFY_CMD:
@@ -984,7 +1031,7 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 break;
 }
 d->oom_running = 1;
-qemu_spice_oom(&d->ssd);
+qxl_spice_oom(d);
 d->oom_running = 0;
 break;
 case QXL_IO_SET_MODE:
@@ -1022,10 +1069,10 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_destroy_primary(d);
 break;
 case QXL_IO_DESTROY_SURFACE_WAIT:
-qemu_spice_destroy_surface_wait(&d->ssd, val);
+qxl_spice_destroy_surface_wait(d, val);
 break;
 case QXL_IO_DESTROY_ALL_SURFACES:
-qemu_spice_destroy_surfaces(&d->ssd);
+qxl_spice_destroy_surfaces(d);
 break;
 default:
 fprintf(stderr,

[Qemu-devel] [PATCH v6 10/11] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3&S4 support

2011-07-15 Thread Alon Levy
Add two new IOs.
 QXL_IO_FLUSH_SURFACES - equivalent to update area for all surfaces, used
  to reduce vmexits from NumSurfaces to 1 on guest S3, S4 and resolution change 
(windows
  driver implementation is such that this is done on each of those occasions).
 QXL_IO_FLUSH_RELEASE - used to ensure anything on last_release is put on the 
release ring
  for the client to free.

Cc: Yonit Halperin 
Signed-off-by: Alon Levy 
---
 hw/qxl.c |   30 ++
 1 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 7c4c520..6d21171 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -185,6 +185,13 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice 
*qxl, uint32_t id,
 }
 }
 
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+static void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl)
+{
+qxl->ssd.worker->flush_surfaces_async(qxl->ssd.worker, 0);
+}
+#endif
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
 {
@@ -1190,6 +1197,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 goto async_common;
 case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:
 io_port = QXL_IO_DESTROY_ALL_SURFACES;
+goto async_common;
+case QXL_IO_FLUSH_SURFACES_ASYNC:
 async_common:
 async = QXL_ASYNC;
 qemu_mutex_lock(&d->async_lock);
@@ -1302,6 +1311,27 @@ async_common:
 }
 qxl_spice_destroy_surface_wait(d, val, async);
 break;
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+case QXL_IO_FLUSH_RELEASE: {
+QXLReleaseRing *ring = &d->ram->release_ring;
+if (ring->prod - ring->cons + 1 == ring->num_items) {
+fprintf(stderr,
+"ERROR: no flush, full release ring [p%d,%dc]\n",
+ring->prod, ring->cons);
+}
+qxl_push_free_res(d, 1 /* flush */);
+dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",
+qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+d->num_free_res, d->last_release);
+break;
+}
+case QXL_IO_FLUSH_SURFACES_ASYNC:
+dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+   val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
+   d->num_free_res);
+qxl_spice_flush_surfaces_async(d);
+break;
+#endif
 case QXL_IO_DESTROY_ALL_SURFACES:
 d->mode = QXL_MODE_UNDEFINED;
 qxl_spice_destroy_surfaces(d, async);
-- 
1.7.6




[Qemu-devel] [PATCH v6 05/11] qxl: add io_port_to_string

2011-07-15 Thread Alon Levy
Signed-off-by: Alon Levy 
---
 hw/qxl.c |   40 +++-
 1 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index e832d00..7d8b312 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -409,6 +409,43 @@ static const char *qxl_mode_to_string(int mode)
 return "INVALID";
 }
 
+static const char *io_port_to_string(uint32_t io_port)
+{
+if (io_port >= QXL_IO_RANGE_SIZE) {
+return "out of range";
+}
+static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {
+[QXL_IO_NOTIFY_CMD] = "QXL_IO_NOTIFY_CMD",
+[QXL_IO_NOTIFY_CURSOR]  = "QXL_IO_NOTIFY_CURSOR",
+[QXL_IO_UPDATE_AREA]= "QXL_IO_UPDATE_AREA",
+[QXL_IO_UPDATE_IRQ] = "QXL_IO_UPDATE_IRQ",
+[QXL_IO_NOTIFY_OOM] = "QXL_IO_NOTIFY_OOM",
+[QXL_IO_RESET]  = "QXL_IO_RESET",
+[QXL_IO_SET_MODE]   = "QXL_IO_SET_MODE",
+[QXL_IO_LOG]= "QXL_IO_LOG",
+[QXL_IO_MEMSLOT_ADD]= "QXL_IO_MEMSLOT_ADD",
+[QXL_IO_MEMSLOT_DEL]= "QXL_IO_MEMSLOT_DEL",
+[QXL_IO_DETACH_PRIMARY] = "QXL_IO_DETACH_PRIMARY",
+[QXL_IO_ATTACH_PRIMARY] = "QXL_IO_ATTACH_PRIMARY",
+[QXL_IO_CREATE_PRIMARY] = "QXL_IO_CREATE_PRIMARY",
+[QXL_IO_DESTROY_PRIMARY]= "QXL_IO_DESTROY_PRIMARY",
+[QXL_IO_DESTROY_SURFACE_WAIT]   = "QXL_IO_DESTROY_SURFACE_WAIT",
+[QXL_IO_DESTROY_ALL_SURFACES]   = "QXL_IO_DESTROY_ALL_SURFACES",
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+[QXL_IO_UPDATE_AREA_ASYNC]  = "QXL_IO_UPDATE_AREA_ASYNC",
+[QXL_IO_MEMSLOT_ADD_ASYNC]  = "QXL_IO_MEMSLOT_ADD_ASYNC",
+[QXL_IO_CREATE_PRIMARY_ASYNC]   = "QXL_IO_CREATE_PRIMARY_ASYNC",
+[QXL_IO_DESTROY_PRIMARY_ASYNC]  = "QXL_IO_DESTROY_PRIMARY_ASYNC",
+[QXL_IO_DESTROY_SURFACE_ASYNC]  = "QXL_IO_DESTROY_SURFACE_ASYNC",
+[QXL_IO_DESTROY_ALL_SURFACES_ASYNC]
+= "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",
+[QXL_IO_FLUSH_SURFACES_ASYNC]   = "QXL_IO_FLUSH_SURFACES_ASYNC",
+[QXL_IO_FLUSH_RELEASE]  = "QXL_IO_FLUSH_RELEASE",
+#endif
+};
+return io_port_to_string[io_port];
+}
+
 /* called from spice server thread context only */
 static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
 {
@@ -1011,7 +1048,8 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 default:
 if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
 break;
-dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, 
io_port);
+dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
+__func__, io_port, io_port_to_string(io_port));
 return;
 }
 
-- 
1.7.6




[Qemu-devel] [PATCH v6 00/11] async + suspend reworked

2011-07-15 Thread Alon Levy
v5->v6:
 really use array in io_port_to_string
 undo merged "async io support" to revision change
 remove QXL_REVISION_* defines usage
 move qxl_send_event to async_cancel
 fix async_cancel label per patchcheck

Alon Levy (5):
  qxl: add io_port_to_string
  qxl: make qxl_guest_bug take variable arguments
  qxl: only disallow specific io's in vga mode
  qxl: async io support using new spice api
  qxl: add QXL_IO_FLUSH_{SURFACES,RELEASE} for guest S3&S4 support

Gerd Hoffmann (6):
  spice: add worker wrapper functions.
  spice: add qemu_spice_display_init_common
  spice/qxl: move worker wrappers
  qxl: fix surface tracking & locking
  qxl: error handling fixes and cleanups.
  qxl: bump pci rev

 hw/qxl-render.c|4 +-
 hw/qxl.c   |  440 +---
 hw/qxl.h   |   34 -
 ui/spice-display.c |   93 ++--
 ui/spice-display.h |   28 
 5 files changed, 529 insertions(+), 70 deletions(-)

-- 
1.7.6




[Qemu-devel] [PATCH v6 09/11] qxl: async io support using new spice api

2011-07-15 Thread Alon Levy
Some of the QXL port i/o commands are waiting for the spice server to
complete certain actions.  Add async versions for these commands, so we
don't block the vcpu while the spice server processses the command.
Instead the qxl device will raise an IRQ when done.

The async command processing relies on an added QXLInterface::async_complete
and added QXLWorker::*_async additions, in spice server qxl >= 3.1

Signed-off-by: Gerd Hoffmann 
Signed-off-by: Alon Levy 
---
 hw/qxl-render.c|2 +-
 hw/qxl.c   |  240 
 hw/qxl.h   |   16 +++-
 ui/spice-display.c |   47 --
 ui/spice-display.h |   23 +-
 5 files changed, 274 insertions(+), 54 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 60b822d..643ff2d 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -125,7 +125,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
 
 memset(dirty, 0, sizeof(dirty));
 qxl_spice_update_area(qxl, 0, &update,
-  dirty, ARRAY_SIZE(dirty), 1);
+  dirty, ARRAY_SIZE(dirty), 1, QXL_SYNC);
 
 for (i = 0; i < ARRAY_SIZE(dirty); i++) {
 if (qemu_spice_rect_is_empty(dirty+i)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index b946942..7c4c520 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -120,7 +120,7 @@ static QXLMode qxl_modes[] = {
 static PCIQXLDevice *qxl0;
 
 static void qxl_send_events(PCIQXLDevice *d, uint32_t events);
-static void qxl_destroy_primary(PCIQXLDevice *d);
+static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async);
 static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
@@ -144,22 +144,47 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, 
...)
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
uint32_t num_dirty_rects,
-   uint32_t clear_dirty_region)
+   uint32_t clear_dirty_region,
+   qxl_async_io async)
 {
-qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area, 
dirty_rects,
- num_dirty_rects, clear_dirty_region);
+if (async == QXL_SYNC) {
+qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,
+dirty_rects, num_dirty_rects, clear_dirty_region);
+} else {
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+qxl->ssd.worker->update_area_async(qxl->ssd.worker, surface_id, area,
+   clear_dirty_region, 0);
+#else
+abort();
+#endif
+}
 }
 
-void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
+static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl,
+uint32_t id)
 {
 qemu_mutex_lock(&qxl->track_lock);
-PANIC_ON(id >= NUM_SURFACES);
-qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
 qxl->guest_surfaces.cmds[id] = 0;
 qxl->guest_surfaces.count--;
 qemu_mutex_unlock(&qxl->track_lock);
 }
 
+static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
+   qxl_async_io async)
+{
+if (async) {
+#if SPICE_INTERFACE_QXL_MINOR < 1
+abort();
+#else
+qxl->ssd.worker->destroy_surface_wait_async(qxl->ssd.worker, id,
+(uint64_t)id);
+#endif
+} else {
+qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+qxl_spice_destroy_surface_wait_complete(qxl, id);
+}
+}
+
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
uint32_t count)
 {
@@ -176,15 +201,28 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 qxl->ssd.worker->reset_memslots(qxl->ssd.worker);
 }
 
-void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
+static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
 {
 qemu_mutex_lock(&qxl->track_lock);
-qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
 memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
 qxl->guest_surfaces.count = 0;
 qemu_mutex_unlock(&qxl->track_lock);
 }
 
+static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
+{
+if (async) {
+#if SPICE_INTERFACE_QXL_MINOR < 1
+abort();
+#else
+qxl->ssd.worker->destroy_surfaces_async(qxl->ssd.worker, 0);
+#endif
+} else {
+qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+qxl_spice_destroy_surfaces_complete(qxl);
+}
+}
+
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
 {
 qxl->ssd.worker->reset_image_cache(qxl->ssd.worker);
@@ -689,6 +727,38 @@ static int interface_flush_resources(QXLInstance *sin)
 return ret;
 }
 
+static void q

[Qemu-devel] [PATCH v6 08/11] qxl: only disallow specific io's in vga mode

2011-07-15 Thread Alon Levy
Since the driver is still in operation even after moving to UNDEFINED, i.e.
by destroying primary in any way.

Signed-off-by: Alon Levy 
---
 hw/qxl.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index d645c87..b946942 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1061,8 +1061,9 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 case QXL_IO_LOG:
 break;
 default:
-if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT)
+if (d->mode != QXL_MODE_VGA) {
 break;
+}
 dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",
 __func__, io_port, io_port_to_string(io_port));
 return;
-- 
1.7.6




[Qemu-devel] [PATCH v6 04/11] qxl: fix surface tracking & locking

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Surface tracking needs proper locking since it is used from vcpu and spice
worker threads, add it.  Also reset the surface counter when zapping all
surfaces.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   13 -
 hw/qxl.h |2 ++
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 29094a9..e832d00 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -137,7 +137,12 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t 
surface_id,
 
 void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id)
 {
+qemu_mutex_lock(&qxl->track_lock);
+PANIC_ON(id >= NUM_SURFACES);
 qxl->ssd.worker->destroy_surface_wait(qxl->ssd.worker, id);
+qxl->guest_surfaces.cmds[id] = 0;
+qxl->guest_surfaces.count--;
+qemu_mutex_unlock(&qxl->track_lock);
 }
 
 void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext,
@@ -158,7 +163,11 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl)
 
 void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl)
 {
+qemu_mutex_lock(&qxl->track_lock);
 qxl->ssd.worker->destroy_surfaces(qxl->ssd.worker);
+memset(&qxl->guest_surfaces.cmds, 0, sizeof(qxl->guest_surfaces.cmds));
+qxl->guest_surfaces.count = 0;
+qemu_mutex_unlock(&qxl->track_lock);
 }
 
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
@@ -317,6 +326,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct 
QXLCommandExt *ext)
 QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
 uint32_t id = le32_to_cpu(cmd->surface_id);
 PANIC_ON(id >= NUM_SURFACES);
+qemu_mutex_lock(&qxl->track_lock);
 if (cmd->type == QXL_SURFACE_CMD_CREATE) {
 qxl->guest_surfaces.cmds[id] = ext->cmd.data;
 qxl->guest_surfaces.count++;
@@ -327,6 +337,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct 
QXLCommandExt *ext)
 qxl->guest_surfaces.cmds[id] = 0;
 qxl->guest_surfaces.count--;
 }
+qemu_mutex_unlock(&qxl->track_lock);
 break;
 }
 case QXL_CMD_CURSOR:
@@ -869,7 +880,6 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
 dprint(d, 1, "%s:\n", __FUNCTION__);
 d->mode = QXL_MODE_UNDEFINED;
 qxl_spice_destroy_surfaces(d);
-memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));
 }
 
 /* called from spice server thread context only */
@@ -1289,6 +1299,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 qxl->generation = 1;
 qxl->num_memslots = NUM_MEMSLOTS;
 qxl->num_surfaces = NUM_SURFACES;
+qemu_mutex_init(&qxl->track_lock);
 
 switch (qxl->revision) {
 case 1: /* spice 0.4 -- qxl-1 */
diff --git a/hw/qxl.h b/hw/qxl.h
index e62b9d0..5d0e85e 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -55,6 +55,8 @@ typedef struct PCIQXLDevice {
 } guest_surfaces;
 QXLPHYSICALguest_cursor;
 
+QemuMutex  track_lock;
+
 /* thread signaling */
 pthread_t  main;
 intpipe[2];
-- 
1.7.6




[Qemu-devel] [PATCH v6 11/11] qxl: bump pci rev

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Inform guest drivers about the new features I/O commands we have
now (async commands, S3 support) if building with newer spice, i.e.
if SPICE_INTERFACE_QXL_MINOR >= 1.

sneaked in some 81+ column line spliting.

Signed-off-by: Gerd Hoffmann 
Signed-off-by: Alon Levy 
---
 hw/qxl.c |   25 ++---
 hw/qxl.h |6 ++
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 6d21171..dcdd0df 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1572,9 +1572,14 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 pci_device_rev = QXL_REVISION_STABLE_V04;
 break;
 case 2: /* spice 0.6 -- qxl-2 */
-default:
 pci_device_rev = QXL_REVISION_STABLE_V06;
 break;
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+case 3: /* qxl-3 */
+#endif
+default:
+pci_device_rev = QXL_DEFAULT_REVISION;
+break;
 }
 
 pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
@@ -1836,9 +1841,12 @@ static PCIDeviceInfo qxl_info_primary = {
 .device_id= QXL_DEVICE_ID_STABLE,
 .class_id = PCI_CLASS_DISPLAY_VGA,
 .qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 
* 1024),
-DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 
1024),
-DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
+   QXL_DEFAULT_REVISION),
 DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
 DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
 DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
@@ -1857,9 +1865,12 @@ static PCIDeviceInfo qxl_info_secondary = {
 .device_id= QXL_DEVICE_ID_STABLE,
 .class_id = PCI_CLASS_DISPLAY_OTHER,
 .qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 
* 1024),
-DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 
1024),
-DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2),
+DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
+   64 * 1024 * 1024),
+DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
+   QXL_DEFAULT_REVISION),
 DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
 DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
 DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
diff --git a/hw/qxl.h b/hw/qxl.h
index 1046205..4bcf7e1 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -102,6 +102,12 @@ typedef struct PCIQXLDevice {
 }   \
 } while (0)
 
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
+#else
+#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V06
+#endif
+
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
 void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
-- 
1.7.6




[Qemu-devel] [PATCH v6 07/11] qxl: make qxl_guest_bug take variable arguments

2011-07-15 Thread Alon Levy
Signed-off-by: Alon Levy 
---
 hw/qxl.c |9 +++--
 hw/qxl.h |2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 68ce409..d645c87 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,13 +125,18 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
 {
 #if SPICE_INTERFACE_QXL_MINOR >= 1
 qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
 #endif
 if (qxl->guestdebug) {
-fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+va_list ap;
+va_start(ap, msg);
+fprintf(stderr, "qxl-%d: guest bug: ", qxl->id);
+vfprintf(stderr, msg, ap);
+fprintf(stderr, "\n");
+va_end(ap);
 }
 }
 
diff --git a/hw/qxl.h b/hw/qxl.h
index 5db9aae..32ca5a0 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -99,7 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
-void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.6




[Qemu-devel] [PATCH v6 02/11] spice: add qemu_spice_display_init_common

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Factor out SimpleSpiceDisplay initialization into
qemu_spice_display_init_common() and call it from
both qxl.c (for vga mode) and spice-display.c

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c   |7 +--
 ui/spice-display.c |   17 +++--
 ui/spice-display.h |1 +
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 545074d..2d46814 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1321,12 +1321,7 @@ static int qxl_init_primary(PCIDevice *dev)
 
 vga->ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
qxl_hw_screen_dump, qxl_hw_text_update, 
qxl);
-qxl->ssd.ds = vga->ds;
-qemu_mutex_init(&qxl->ssd.lock);
-qxl->ssd.mouse_x = -1;
-qxl->ssd.mouse_y = -1;
-qxl->ssd.bufsize = (16 * 1024 * 1024);
-qxl->ssd.buf = qemu_malloc(qxl->ssd.bufsize);
+qemu_spice_display_init_common(&qxl->ssd, vga->ds);
 
 qxl0 = qxl;
 register_displaychangelistener(vga->ds, &display_listener);
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 1e6a38f..93e25bf 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -286,6 +286,16 @@ void qemu_spice_vm_change_state_handler(void *opaque, int 
running, int reason)
 ssd->running = running;
 }
 
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
+{
+ssd->ds = ds;
+qemu_mutex_init(&ssd->lock);
+ssd->mouse_x = -1;
+ssd->mouse_y = -1;
+ssd->bufsize = (16 * 1024 * 1024);
+ssd->buf = qemu_malloc(ssd->bufsize);
+}
+
 /* display listener callbacks */
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
@@ -499,12 +509,7 @@ static DisplayChangeListener display_listener = {
 void qemu_spice_display_init(DisplayState *ds)
 {
 assert(sdpy.ds == NULL);
-sdpy.ds = ds;
-qemu_mutex_init(&sdpy.lock);
-sdpy.mouse_x = -1;
-sdpy.mouse_y = -1;
-sdpy.bufsize = (16 * 1024 * 1024);
-sdpy.buf = qemu_malloc(sdpy.bufsize);
+qemu_spice_display_init_common(&sdpy, ds);
 register_displaychangelistener(ds, &display_listener);
 
 sdpy.qxl.base.sif = &dpy_interface.base;
diff --git a/ui/spice-display.h b/ui/spice-display.h
index 5b06b11..eb7a573 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -75,6 +75,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd);
 void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd);
 void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason);
+void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds);
 
 void qemu_spice_display_update(SimpleSpiceDisplay *ssd,
int x, int y, int w, int h);
-- 
1.7.6




[Qemu-devel] [PATCH v6 06/11] qxl: error handling fixes and cleanups.

2011-07-15 Thread Alon Levy
From: Gerd Hoffmann 

Add qxl_guest_bug() function which is supposed to be called in case
sanity checks of guest requests fail.  It raises an error IRQ and
logs a message in case guest debugging is enabled.

Make PANIC_ON() abort instead of exit.  That macro should be used
for qemu bugs only, any guest-triggerable stuff should use the new
qxl_guest_bug() function instead.

Convert a few easy cases from PANIC_ON() to qxl_guest_bug() to
show intended usage.

Signed-off-by: Gerd Hoffmann 
---
 hw/qxl.c |   34 ++
 hw/qxl.h |3 ++-
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 7d8b312..68ce409 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -125,6 +125,16 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
 static void qxl_reset_surfaces(PCIQXLDevice *d);
 static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
 
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg)
+{
+#if SPICE_INTERFACE_QXL_MINOR >= 1
+qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
+#endif
+if (qxl->guestdebug) {
+fprintf(stderr, "qxl-%d: guest bug: %s\n", qxl->id, msg);
+}
+}
+
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
@@ -1097,22 +1107,38 @@ static void ioport_write(void *opaque, uint32_t addr, 
uint32_t val)
 qxl_hard_reset(d, 0);
 break;
 case QXL_IO_MEMSLOT_ADD:
-PANIC_ON(val >= NUM_MEMSLOTS);
-PANIC_ON(d->guest_slots[val].active);
+if (val >= NUM_MEMSLOTS) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");
+break;
+}
+if (d->guest_slots[val].active) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");
+break;
+}
 d->guest_slots[val].slot = d->ram->mem_slot;
 qxl_add_memslot(d, val, 0);
 break;
 case QXL_IO_MEMSLOT_DEL:
+if (val >= NUM_MEMSLOTS) {
+qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");
+break;
+}
 qxl_del_memslot(d, val);
 break;
 case QXL_IO_CREATE_PRIMARY:
-PANIC_ON(val != 0);
+if (val != 0) {
+qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY: val != 0");
+break;
+}
 dprint(d, 1, "QXL_IO_CREATE_PRIMARY\n");
 d->guest_primary.surface = d->ram->create_surface;
 qxl_create_guest_primary(d, 0);
 break;
 case QXL_IO_DESTROY_PRIMARY:
-PANIC_ON(val != 0);
+if (val != 0) {
+qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY: val != 0");
+break;
+}
 dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (%s)\n", 
qxl_mode_to_string(d->mode));
 qxl_destroy_primary(d);
 break;
diff --git a/hw/qxl.h b/hw/qxl.h
index 5d0e85e..5db9aae 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -86,7 +86,7 @@ typedef struct PCIQXLDevice {
 
 #define PANIC_ON(x) if ((x)) { \
 printf("%s: PANIC %s failed\n", __FUNCTION__, #x); \
-exit(-1);  \
+abort();   \
 }
 
 #define dprint(_qxl, _level, _fmt, ...) \
@@ -99,6 +99,7 @@ typedef struct PCIQXLDevice {
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
+void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg);
 
 void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,
struct QXLRect *area, struct QXLRect *dirty_rects,
-- 
1.7.6




[Qemu-devel] [PATCH 1/5] xen: Fix xen_enabled().

2011-07-15 Thread Anthony PERARD
Use the "host" CONFIG_ define instead of the "target" one.

Signed-off-by: Anthony PERARD 
---
 hw/xen.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/xen.h b/hw/xen.h
index e432705..43b95d6 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -24,7 +24,7 @@ extern int xen_allowed;
 
 static inline int xen_enabled(void)
 {
-#ifdef CONFIG_XEN
+#ifdef CONFIG_XEN_BACKEND
 return xen_allowed;
 #else
 return 0;
-- 
Anthony PERARD




[Qemu-devel] [PATCH 0/5] Enable QEMU to handle more than 2GB with Xen.

2011-07-15 Thread Anthony PERARD
Hi all,

Xen is not limited by the QEMU's virtual address space for the allocation of
the guest RAM. So even with a QEMU 32bits, a Xen guest can have more than 4 GB
of RAM.

With this serie, we will be able to run a guest with more than 4GB. The main
point is to change ram_addr_t from ulong to uin64 when QEMU is configure with
Xen. The second point is better register the memory in QEMU.

Regards,


Anthony PERARD (5):
  xen: Fix xen_enabled().
  exec.c: Use ram_addr_t in cpu_physical_memory_rw(...).
  cpu-common: Have a ram_addr_t of uint64 with Xen.
  xen: Fix the memory registration to reflect of what is done by Xen.
  vl.c: Check the asked ram_size later.

 cpu-common.h |8 
 exec.c   |   13 +++--
 hw/xen.h |2 +-
 vl.c |   14 --
 xen-all.c|   23 +++
 5 files changed, 39 insertions(+), 21 deletions(-)

-- 
Anthony PERARD




[Qemu-devel] [PATCH 2/5] exec.c: Use ram_addr_t in cpu_physical_memory_rw(...).

2011-07-15 Thread Anthony PERARD
As the variable pd and addr1 inside the function cpu_physical_memory_rw
are mean to handle a RAM address, they should be of the ram_addr_t type
instead of unsigned long.

Signed-off-by: Anthony PERARD 
---
 exec.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index c0673c2..4220d45 100644
--- a/exec.c
+++ b/exec.c
@@ -3858,7 +3858,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
 uint8_t *ptr;
 uint32_t val;
 target_phys_addr_t page;
-unsigned long pd;
+ram_addr_t pd;
 PhysPageDesc *p;
 
 while (len > 0) {
@@ -3898,7 +3898,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
 l = 1;
 }
 } else {
-unsigned long addr1;
+ram_addr_t addr1;
 addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
 /* RAM case */
 ptr = qemu_get_ram_ptr(addr1);
-- 
Anthony PERARD




[Qemu-devel] [PATCH 3/5] cpu-common: Have a ram_addr_t of uint64 with Xen.

2011-07-15 Thread Anthony PERARD
In Xen case, memory can be bigger than the host memory. that mean a
32bits host (and QEMU) should be able to handle a RAM address of 64bits.

Signed-off-by: Anthony PERARD 
---
 cpu-common.h |8 
 exec.c   |9 +
 xen-all.c|2 +-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/cpu-common.h b/cpu-common.h
index e4fcded..e1b40fe 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -27,7 +27,15 @@ enum device_endian {
 };
 
 /* address in the RAM (different from a physical address) */
+#ifndef CONFIG_XEN_BACKEND
 typedef unsigned long ram_addr_t;
+#  define RAM_ADDR_MAX ULONG_MAX
+#  define RAM_ADDR_FMT "%lx"
+#else
+typedef uint64_t ram_addr_t;
+#  define RAM_ADDR_MAX UINT64_MAX
+#  define RAM_ADDR_FMT "%" PRIx64
+#endif
 
 /* memory API */
 
diff --git a/exec.c b/exec.c
index 4220d45..b671cfd 100644
--- a/exec.c
+++ b/exec.c
@@ -2863,13 +2863,13 @@ static void *file_ram_alloc(RAMBlock *block,
 static ram_addr_t find_ram_offset(ram_addr_t size)
 {
 RAMBlock *block, *next_block;
-ram_addr_t offset = 0, mingap = ULONG_MAX;
+ram_addr_t offset = 0, mingap = RAM_ADDR_MAX;
 
 if (QLIST_EMPTY(&ram_list.blocks))
 return 0;
 
 QLIST_FOREACH(block, &ram_list.blocks, next) {
-ram_addr_t end, next = ULONG_MAX;
+ram_addr_t end, next = RAM_ADDR_MAX;
 
 end = block->offset + block->length;
 
@@ -3081,7 +3081,8 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
 #endif
 }
 if (area != vaddr) {
-fprintf(stderr, "Could not remap addr: %lx@%lx\n",
+fprintf(stderr, "Could not remap addr: "
+RAM_ADDR_FMT "@" RAM_ADDR_FMT "\n",
 length, addr);
 exit(1);
 }
@@ -4052,7 +4053,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
 target_phys_addr_t page;
 unsigned long pd;
 PhysPageDesc *p;
-ram_addr_t raddr = ULONG_MAX;
+ram_addr_t raddr = RAM_ADDR_MAX;
 ram_addr_t rlen;
 void *ret;
 
diff --git a/xen-all.c b/xen-all.c
index 8105c83..2c0a62d 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -184,7 +184,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
 }
 
 if (xc_domain_populate_physmap_exact(xen_xc, xen_domid, nr_pfn, 0, 0, 
pfn_list)) {
-hw_error("xen: failed to populate ram at %lx", ram_addr);
+hw_error("xen: failed to populate ram at " RAM_ADDR_FMT, ram_addr);
 }
 
 qemu_free(pfn_list);
-- 
Anthony PERARD




[Qemu-devel] [PATCH 5/5] vl.c: Check the asked ram_size later.

2011-07-15 Thread Anthony PERARD
As a Xen guest can have more than 2GB of RAM on a 32bit host, we move
the conditions after than we now if we run one Xen or not.

Signed-off-by: Anthony PERARD 
---
 vl.c |   14 --
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/vl.c b/vl.c
index fcd7395..c2efedf 100644
--- a/vl.c
+++ b/vl.c
@@ -2433,11 +2433,6 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 
-/* On 32-bit hosts, QEMU is limited by virtual address space */
-if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
-fprintf(stderr, "qemu: at most 2047 MB RAM can be 
simulated\n");
-exit(1);
-}
 if (value != (uint64_t)(ram_addr_t)value) {
 fprintf(stderr, "qemu: ram size too large\n");
 exit(1);
@@ -3091,8 +3086,15 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 
 /* init the memory */
-if (ram_size == 0)
+if (ram_size == 0) {
 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+} else if (!xen_enabled()) {
+/* On 32-bit hosts, QEMU is limited by virtual address space */
+if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
+fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
+exit(1);
+}
+}
 
 /* init the dynamic translator */
 cpu_exec_init_all(tb_size * 1024 * 1024);
-- 
Anthony PERARD




[Qemu-devel] [PATCH 4/5] xen: Fix the memory registration to reflect of what is done by Xen.

2011-07-15 Thread Anthony PERARD
A Xen guest memory is allocated by libxc. But this memory is not
allocated continuously, instead, it leaves the VGA IO memory space not
allocated, same for the MMIO space (at HVM_BELOW_4G_MMIO_START of size
HVM_BELOW_4G_MMIO_LENGTH).

So to reflect that, we do not register the physical memory for this two
holes. But we still keep only one RAMBlock for the all RAM as it is more
easier than have two separate blocks (1 above 4G). Also this prevent QEMU
from use the MMIO space for a ROM.

Signed-off-by: Anthony PERARD 
---
 xen-all.c |   21 ++---
 1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 2c0a62d..76d5c5c 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -144,6 +144,12 @@ static void xen_ram_init(ram_addr_t ram_size)
 new_block->host = NULL;
 new_block->offset = 0;
 new_block->length = ram_size;
+if (ram_size >= HVM_BELOW_4G_RAM_END) {
+/* Xen does not allocate the memory continuously, and keep a hole at
+ * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
+ */
+new_block->length += HVM_BELOW_4G_MMIO_LENGTH;
+}
 
 QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
 
@@ -152,20 +158,21 @@ static void xen_ram_init(ram_addr_t ram_size)
 memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
0xff, new_block->length >> TARGET_PAGE_BITS);
 
-if (ram_size >= 0xe000 ) {
-above_4g_mem_size = ram_size - 0xe000;
-below_4g_mem_size = 0xe000;
+if (ram_size >= HVM_BELOW_4G_RAM_END) {
+above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
+below_4g_mem_size = HVM_BELOW_4G_RAM_END;
 } else {
 below_4g_mem_size = ram_size;
 }
 
-cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
-#if TARGET_PHYS_ADDR_BITS > 32
+cpu_register_physical_memory(0, 0xa, 0);
+/* Skip of the VGA IO memory space */
+cpu_register_physical_memory(0xc, below_4g_mem_size - 0xc,
+ 0xc);
 if (above_4g_mem_size > 0) {
 cpu_register_physical_memory(0x1ULL, above_4g_mem_size,
- new_block->offset + below_4g_mem_size);
+ 0x1ULL);
 }
-#endif
 }
 
 void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
-- 
Anthony PERARD




Re: [Qemu-devel] [PATCH 2/5] exec.c: Use ram_addr_t in cpu_physical_memory_rw(...).

2011-07-15 Thread Paolo Bonzini

On 07/15/2011 04:32 PM, Anthony PERARD wrote:

As the variable pd and addr1 inside the function cpu_physical_memory_rw
are mean to handle a RAM address, they should be of the ram_addr_t type
instead of unsigned long.

Signed-off-by: Anthony PERARD
---
  exec.c |4 ++--
  1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/exec.c b/exec.c
index c0673c2..4220d45 100644
--- a/exec.c
+++ b/exec.c
@@ -3858,7 +3858,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
  uint8_t *ptr;
  uint32_t val;
  target_phys_addr_t page;
-unsigned long pd;
+ram_addr_t pd;
  PhysPageDesc *p;

  while (len>  0) {
@@ -3898,7 +3898,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, 
uint8_t *buf,
  l = 1;
  }
  } else {
-unsigned long addr1;
+ram_addr_t addr1;
  addr1 = (pd&  TARGET_PAGE_MASK) + (addr&  ~TARGET_PAGE_MASK);
  /* RAM case */
  ptr = qemu_get_ram_ptr(addr1);


Acked-by: Paolo Bonzini 

Paolo




Re: [Qemu-devel] [PATCH 1/5] xen: Fix xen_enabled().

2011-07-15 Thread Paolo Bonzini

On 07/15/2011 04:32 PM, Anthony PERARD wrote:

Use the "host" CONFIG_ define instead of the "target" one.

Signed-off-by: Anthony PERARD
---
  hw/xen.h |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/xen.h b/hw/xen.h
index e432705..43b95d6 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -24,7 +24,7 @@ extern int xen_allowed;

  static inline int xen_enabled(void)
  {
-#ifdef CONFIG_XEN
+#ifdef CONFIG_XEN_BACKEND
  return xen_allowed;
  #else
  return 0;


Acked-by: Paolo Bonzini 

Paolo




Re: [Qemu-devel] [PATCH 5/5] vl.c: Check the asked ram_size later.

2011-07-15 Thread Paolo Bonzini

On 07/15/2011 04:32 PM, Anthony PERARD wrote:

As a Xen guest can have more than 2GB of RAM on a 32bit host, we move
the conditions after than we now if we run one Xen or not.

Signed-off-by: Anthony PERARD
---
  vl.c |   14 --
  1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/vl.c b/vl.c
index fcd7395..c2efedf 100644
--- a/vl.c
+++ b/vl.c
@@ -2433,11 +2433,6 @@ int main(int argc, char **argv, char **envp)
  exit(1);
  }

-/* On 32-bit hosts, QEMU is limited by virtual address space */
-if (value>  (2047<<  20)&&  HOST_LONG_BITS == 32) {
-fprintf(stderr, "qemu: at most 2047 MB RAM can be 
simulated\n");
-exit(1);
-}
  if (value != (uint64_t)(ram_addr_t)value) {
  fprintf(stderr, "qemu: ram size too large\n");
  exit(1);
@@ -3091,8 +3086,15 @@ int main(int argc, char **argv, char **envp)
  exit(1);

  /* init the memory */
-if (ram_size == 0)
+if (ram_size == 0) {
  ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+} else if (!xen_enabled()) {
+/* On 32-bit hosts, QEMU is limited by virtual address space */
+if (ram_size>  (2047<<  20)&&  HOST_LONG_BITS == 32) {
+fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
+exit(1);
+}
+}

  /* init the dynamic translator */
  cpu_exec_init_all(tb_size * 1024 * 1024);


Acked-by: Paolo Bonzini 

Paolo



[Qemu-devel] [PATCH 00/12] bugfix and qdevify NAND and ONENAND devices

2011-07-15 Thread Peter Maydell
This patchseries is more goodies from the Meego tree. Specifically, various
bug fixes to hw/nand and hw/onenand, plus conversion of both to sysbus.

[An advance note on the next thing due to come out of the pipe: qdeving
nand and onenand allows us to move to qdevification of omap_gpmc, which
takes both of those (and other things) as 'downstream' devices. That
change will make it accept arbitrary SysBus devices as its 'downstream'
devices rather than the current setup of taking an opaque pointer and a
pair of resize/unmap function pointers. (There are also patches which add
NAND support so you can tell omap_gpmc "this is a NAND device" and it then
uses the nand_setpins/nand_getpins/nand_setio interface.) The rationale for
using SysBus there rather than defining some new kind of bus is that you
want to be able to plug any random thing into it; for instance the Overo
board has a lan9118 ethernet controller hanging off the GPMC. ]

A note on dependencies:
 * This patch depends on the omap gpio patchset (although more textually
   than seriously semantically)
 * the six nand patches and the six onenand patches are broadly independent
   of each other

Juha Riihimäki (9):
  hw/nand: Support large NAND devices
  hw/nand: Support devices wider than 8 bits
  hw/nand: Support multiple reads following READ STATUS
  hw/nand: qdevify
  onenand: Handle various ID fields separately
  onenand: Ignore zero writes to boot command space
  hw/onenand: program actions can only clear bits
  hw/sysbus: Add sysbus_mmio_unmap() for unmapping a region
  hw/onenand: qdevify

Peter Maydell (3):
  hw/nand: Pass block device state to init function
  hw/nand: Writing to NAND can only clear bits
  onenand: Pass BlockDriverState to init function

 hw/axis_dev88.c |8 +-
 hw/flash.h  |   19 ++--
 hw/nand.c   |  345 ---
 hw/nseries.c|   13 ++-
 hw/onenand.c|  373 +++
 hw/spitz.c  |6 +-
 hw/sysbus.c |   17 +++
 hw/sysbus.h |1 +
 hw/tc6393xb.c   |7 +-
 9 files changed, 561 insertions(+), 228 deletions(-)




Re: [Qemu-devel] [PATCH 4/5] xen: Fix the memory registration to reflect of what is done by Xen.

2011-07-15 Thread Paolo Bonzini

On 07/15/2011 04:32 PM, Anthony PERARD wrote:

A Xen guest memory is allocated by libxc. But this memory is not
allocated continuously, instead, it leaves the VGA IO memory space not
allocated, same for the MMIO space (at HVM_BELOW_4G_MMIO_START of size
HVM_BELOW_4G_MMIO_LENGTH).

So to reflect that, we do not register the physical memory for this two
holes. But we still keep only one RAMBlock for the all RAM as it is more
easier than have two separate blocks (1 above 4G). Also this prevent QEMU
from use the MMIO space for a ROM.

Signed-off-by: Anthony PERARD
---
  xen-all.c |   21 ++---
  1 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 2c0a62d..76d5c5c 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -144,6 +144,12 @@ static void xen_ram_init(ram_addr_t ram_size)
  new_block->host = NULL;
  new_block->offset = 0;
  new_block->length = ram_size;
+if (ram_size>= HVM_BELOW_4G_RAM_END) {
+/* Xen does not allocate the memory continuously, and keep a hole at
+ * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
+ */
+new_block->length += HVM_BELOW_4G_MMIO_LENGTH;
+}

  QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);

@@ -152,20 +158,21 @@ static void xen_ram_init(ram_addr_t ram_size)
  memset(ram_list.phys_dirty + (new_block->offset>>  TARGET_PAGE_BITS),
 0xff, new_block->length>>  TARGET_PAGE_BITS);

-if (ram_size>= 0xe000 ) {
-above_4g_mem_size = ram_size - 0xe000;
-below_4g_mem_size = 0xe000;
+if (ram_size>= HVM_BELOW_4G_RAM_END) {
+above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
+below_4g_mem_size = HVM_BELOW_4G_RAM_END;
  } else {
  below_4g_mem_size = ram_size;
  }

-cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
-#if TARGET_PHYS_ADDR_BITS>  32
+cpu_register_physical_memory(0, 0xa, 0);
+/* Skip of the VGA IO memory space */
+cpu_register_physical_memory(0xc, below_4g_mem_size - 0xc,
+ 0xc);
  if (above_4g_mem_size>  0) {
  cpu_register_physical_memory(0x1ULL, above_4g_mem_size,
- new_block->offset + below_4g_mem_size);
+ 0x1ULL);
  }
-#endif
  }

  void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)


Acked-by: Paolo Bonzini 

Paolo



[Qemu-devel] [PATCH 08/12] onenand: Handle various ID fields separately

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Handle the manufacturer, device and version IDs separately rather than
smooshing them all together into a single uint32_t. Note that the ID
registers are actually 16 bit, even though typically the top bits are 0
and the Read Identification Data command only returns the bottom 8 bits.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/flash.h   |3 ++-
 hw/nseries.c |5 +++--
 hw/onenand.c |   29 ++---
 3 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/hw/flash.h b/hw/flash.h
index 1aae43d..1064fd0 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -38,7 +38,8 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 /* onenand.c */
 void onenand_base_update(void *opaque, target_phys_addr_t new);
 void onenand_base_unmap(void *opaque);
-void *onenand_init(BlockDriverState *bdrv, uint32_t id,
+void *onenand_init(BlockDriverState *bdrv,
+   uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
int regshift, qemu_irq irq);
 void *onenand_raw_otp(void *opaque);
 
diff --git a/hw/nseries.c b/hw/nseries.c
index 4fef05d..9b8d338 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -167,8 +167,9 @@ static void n8x0_nand_setup(struct n800_s *s)
 DriveInfo *dinfo;
 
 dinfo = drive_get(IF_MTD, 0, 0);
-/* Either ec40xx or ec48xx are OK for the ID */
-s->nand = onenand_init(dinfo ? dinfo->bdrv : 0, 0xec4800, 1,
+/* Either 0x40 or 0x48 are OK for the device ID */
+s->nand = onenand_init(dinfo ? dinfo->bdrv : 0,
+   NAND_MFR_SAMSUNG, 0x48, 0, 1,
qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
 omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
  onenand_base_unmap, s->nand);
diff --git a/hw/onenand.c b/hw/onenand.c
index 3a19d7f..9f02736 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -31,7 +31,11 @@
 #define BLOCK_SHIFT(PAGE_SHIFT + 6)
 
 typedef struct {
-uint32_t id;
+struct {
+uint16_t man;
+uint16_t dev;
+uint16_t ver;
+} id;
 int shift;
 target_phys_addr_t base;
 qemu_irq intr;
@@ -453,12 +457,12 @@ static uint32_t onenand_read(void *opaque, 
target_phys_addr_t addr)
 return lduw_le_p(s->boot[0] + addr);
 
 case 0xf000:   /* Manufacturer ID */
-return (s->id >> 16) & 0xff;
+return s->id.man;
 case 0xf001:   /* Device ID */
-return (s->id >>  8) & 0xff;
-/* TODO: get the following values from a real chip!  */
+return s->id.dev;
 case 0xf002:   /* Version ID */
-return (s->id >>  0) & 0xff;
+return s->id.ver;
+/* TODO: get the following values from a real chip!  */
 case 0xf003:   /* Data Buffer size */
 return 1 << PAGE_SHIFT;
 case 0xf004:   /* Boot Buffer size */
@@ -541,8 +545,8 @@ static void onenand_write(void *opaque, target_phys_addr_t 
addr,
 
 case 0x0090:   /* Read Identification Data */
 memset(s->boot[0], 0, 3 << s->shift);
-s->boot[0][0 << s->shift] = (s->id >> 16) & 0xff;
-s->boot[0][1 << s->shift] = (s->id >>  8) & 0xff;
+s->boot[0][0 << s->shift] = s->id.man & 0xff;
+s->boot[0][1 << s->shift] = s->id.dev & 0xff;
 s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
 break;
 
@@ -615,21 +619,24 @@ static CPUWriteMemoryFunc * const onenand_writefn[] = {
 onenand_write,
 };
 
-void *onenand_init(BlockDriverState *bdrv, uint32_t id,
+void *onenand_init(BlockDriverState *bdrv,
+   uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
int regshift, qemu_irq irq)
 {
 OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
-uint32_t size = 1 << (24 + ((id >> 12) & 7));
+uint32_t size = 1 << (24 + ((dev_id >> 4) & 7));
 void *ram;
 
 s->shift = regshift;
 s->intr = irq;
 s->rdy = NULL;
-s->id = id;
+s->id.man = man_id;
+s->id.dev = dev_id;
+s->id.ver = ver_id;
 s->blocks = size >> BLOCK_SHIFT;
 s->secs = size >> 9;
 s->blockwp = qemu_malloc(s->blocks);
-s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
+s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
 s->iomemtype = cpu_register_io_memory(onenand_readfn,
 onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
 s->bdrv = bdrv;
-- 
1.7.1




[Qemu-devel] [PATCH 10/12] hw/onenand: program actions can only clear bits

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

The program actions onenand_prog_main() and onenand_prog_spare()
can only set bits.

This implies a rewrite of onenand_erase() to not use the program
functions, since erase does need to set bits.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/onenand.c |  135 +
 1 files changed, 106 insertions(+), 29 deletions(-)

diff --git a/hw/onenand.c b/hw/onenand.c
index 0edcfe2..981d23c 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -179,14 +179,39 @@ static inline int onenand_load_main(OneNANDState *s, int 
sec, int secn,
 static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
 void *src)
 {
-if (s->bdrv_cur)
-return bdrv_write(s->bdrv_cur, sec, src, secn) < 0;
-else if (sec + secn > s->secs_cur)
-return 1;
-
-memcpy(s->current + (sec << 9), src, secn << 9);
+int result = 0;
+
+if (secn > 0) {
+uint32_t size = (uint32_t)secn * 512;
+const uint8_t *sp = (const uint8_t *)src;
+uint8_t *dp = 0;
+if (s->bdrv_cur) {
+dp = qemu_malloc(size);
+if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) {
+result = 1;
+}
+} else {
+if (sec + secn > s->secs_cur) {
+result = 1;
+} else {
+dp = (uint8_t *)s->current + (sec << 9);
+}
+}
+if (!result) {
+uint32_t i;
+for (i = 0; i < size; i++) {
+dp[i] &= sp[i];
+}
+if (s->bdrv_cur) {
+result = bdrv_write(s->bdrv_cur, sec, dp, secn) < 0;
+}
+}
+if (dp && s->bdrv_cur) {
+qemu_free(dp);
+}
+}
 
-return 0;
+return result;
 }
 
 static inline int onenand_load_spare(OneNANDState *s, int sec, int secn,
@@ -209,35 +234,87 @@ static inline int onenand_load_spare(OneNANDState *s, int 
sec, int secn,
 static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 void *src)
 {
-uint8_t buf[512];
-
-if (s->bdrv_cur) {
-if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0)
-return 1;
-memcpy(buf + ((sec & 31) << 4), src, secn << 4);
-return bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0;
-} else if (sec + secn > s->secs_cur)
-return 1;
-
-memcpy(s->current + (s->secs_cur << 9) + (sec << 4), src, secn << 4);
- 
-return 0;
+int result = 0;
+if (secn > 0) {
+const uint8_t *sp = (const uint8_t *)src;
+uint8_t *dp = 0, *dpp = 0;
+if (s->bdrv_cur) {
+dp = qemu_malloc(512);
+if (!dp || bdrv_read(s->bdrv_cur,
+ s->secs_cur + (sec >> 5),
+ dp, 1) < 0) {
+result = 1;
+} else {
+dpp = dp + ((sec & 31) << 4);
+}
+} else {
+if (sec + secn > s->secs_cur) {
+result = 1;
+} else {
+dpp = s->current + (s->secs_cur << 9) + (sec << 4);
+}
+}
+if (!result) {
+uint32_t i;
+for (i = 0; i < (secn << 4); i++) {
+dpp[i] &= sp[i];
+}
+if (s->bdrv_cur) {
+result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
+dp, 1) < 0;
+}
+}
+if (dp) {
+qemu_free(dp);
+}
+}
+return result;
 }
 
 static inline int onenand_erase(OneNANDState *s, int sec, int num)
 {
-/* TODO: optimise */
-uint8_t buf[512];
-
-memset(buf, 0xff, sizeof(buf));
-for (; num > 0; num --, sec ++) {
-if (onenand_prog_main(s, sec, 1, buf))
-return 1;
-if (onenand_prog_spare(s, sec, 1, buf))
-return 1;
+uint8_t *blankbuf, *tmpbuf;
+blankbuf = qemu_malloc(512);
+if (!blankbuf) {
+return 1;
+}
+tmpbuf = qemu_malloc(512);
+if (!tmpbuf) {
+qemu_free(blankbuf);
+return 1;
+}
+memset(blankbuf, 0xff, 512);
+for (; num > 0; num--, sec++) {
+if (s->bdrv_cur) {
+int erasesec = s->secs_cur + (sec >> 5);
+if (bdrv_write(s->bdrv_cur, sec, blankbuf, 1)) {
+goto fail;
+}
+if (bdrv_read(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
+goto fail;
+}
+memcpy(tmpbuf + ((sec & 31) << 4), blankbuf, 1 << 4);
+if (bdrv_write(s->bdrv_cur, erasesec, tmpbuf, 1) < 0) {
+goto fail;
+}
+} else {
+if (sec + 1 > s->secs_cur) {
+goto f

[Qemu-devel] [PATCH 06/12] hw/nand: qdevify

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Qdevify the NAND device.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/axis_dev88.c |2 +-
 hw/flash.h  |   14 ++---
 hw/nand.c   |  164 +++
 hw/spitz.c  |2 +-
 hw/tc6393xb.c   |2 +-
 5 files changed, 102 insertions(+), 82 deletions(-)

diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index de1f5a5..e0a8c14 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -37,7 +37,7 @@
 
 struct nand_state_t
 {
-NANDFlashState *nand;
+DeviceState *nand;
 unsigned int rdy:1;
 unsigned int ale:1;
 unsigned int cle:1;
diff --git a/hw/flash.h b/hw/flash.h
index 132ad29..43260ce 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -18,15 +18,13 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, 
ram_addr_t off,
 int be);
 
 /* nand.c */
-typedef struct NANDFlashState NANDFlashState;
-NANDFlashState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
-void nand_done(NANDFlashState *s);
-void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
+DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
+void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
   uint8_t ce, uint8_t wp, uint8_t gnd);
-void nand_getpins(NANDFlashState *s, int *rb);
-void nand_setio(NANDFlashState *s, uint32_t value);
-uint32_t nand_getio(NANDFlashState *s);
-uint32_t nand_getbuswidth(NANDFlashState *s);
+void nand_getpins(DeviceState *dev, int *rb);
+void nand_setio(DeviceState *dev, uint32_t value);
+uint32_t nand_getio(DeviceState *dev);
+uint32_t nand_getbuswidth(DeviceState *dev);
 
 #define NAND_MFR_TOSHIBA   0x98
 #define NAND_MFR_SAMSUNG   0xec
diff --git a/hw/nand.c b/hw/nand.c
index d068eb6..2f5a40e 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -18,6 +18,7 @@
 # include "hw.h"
 # include "flash.h"
 # include "blockdev.h"
+# include "sysbus.h"
 
 # define NAND_CMD_READ00x00
 # define NAND_CMD_READ10x01
@@ -47,7 +48,9 @@
 # define MAX_PAGE  0x800
 # define MAX_OOB   0x40
 
+typedef struct NANDFlashState NANDFlashState;
 struct NANDFlashState {
+SysBusDevice busdev;
 uint8_t manf_id, chip_id;
 uint8_t buswidth; /* in BYTES */
 int size, pages;
@@ -215,8 +218,9 @@ static const struct {
 [0xc5] = { 2048,   16, 0, 0, LP_OPTIONS16 },
 };
 
-static void nand_reset(NANDFlashState *s)
+static void nand_reset(DeviceState *dev)
 {
+NANDFlashState *s = FROM_SYSBUS(NANDFlashState, sysbus_from_qdev(dev));
 s->cmd = NAND_CMD_READ0;
 s->addr = 0;
 s->addrlen = 0;
@@ -270,7 +274,7 @@ static void nand_command(NANDFlashState *s)
 break;
 
 case NAND_CMD_RESET:
-nand_reset(s);
+nand_reset(&s->busdev.qdev);
 break;
 
 case NAND_CMD_PAGEPROGRAM1:
@@ -354,15 +358,84 @@ static const VMStateDescription vmstate_nand = {
 }
 };
 
+static int nand_device_init(SysBusDevice *dev)
+{
+int pagesize;
+NANDFlashState *s = FROM_SYSBUS(NANDFlashState, dev);
+s->buswidth = nand_flash_ids[s->chip_id].width >> 3;
+s->size = nand_flash_ids[s->chip_id].size << 20;
+if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
+s->page_shift = 11;
+s->erase_shift = 6;
+} else {
+s->page_shift = nand_flash_ids[s->chip_id].page_shift;
+s->erase_shift = nand_flash_ids[s->chip_id].erase_shift;
+}
+
+switch (1 << s->page_shift) {
+case 256:
+nand_init_256(s);
+break;
+case 512:
+nand_init_512(s);
+break;
+case 2048:
+nand_init_2048(s);
+break;
+default:
+hw_error("%s: Unsupported NAND block size.\n", __func__);
+}
+
+pagesize = 1 << s->oob_shift;
+s->mem_oob = 1;
+if (s->bdrv && bdrv_getlength(s->bdrv) >=
+(s->pages << s->page_shift) + (s->pages << s->oob_shift)) {
+pagesize = 0;
+s->mem_oob = 0;
+}
+
+if (!s->bdrv) {
+pagesize += 1 << s->page_shift;
+}
+if (pagesize) {
+s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
+0xff, s->pages * pagesize);
+}
+/* Give s->ioaddr a sane value in case we save state before it is used. */
+s->ioaddr = s->io;
+
+return 0;
+}
+
+static SysBusDeviceInfo nand_info = {
+.init = nand_device_init,
+.qdev.name = "nand",
+.qdev.size = sizeof(NANDFlashState),
+.qdev.reset = nand_reset,
+.qdev.vmsd = &vmstate_nand,
+.qdev.props = (Property[]) {
+DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0),
+DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0),
+DEFINE_PROP_DRIVE("drive", NANDFlashState, bdrv),
+DEFINE_

[Qemu-devel] [PATCH 09/12] onenand: Ignore zero writes to boot command space

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Ignore zero writes to the boot command space; Linux will issue
these in the powerdown/reset sequence.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/onenand.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/onenand.c b/hw/onenand.c
index 9f02736..0edcfe2 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -550,6 +550,13 @@ static void onenand_write(void *opaque, target_phys_addr_t 
addr,
 s->boot[0][2 << s->shift] = s->wpstatus & 0xff;
 break;
 
+case 0x:
+/* ignore zero writes without error messages,
+ * linux omap2/3 kernel will issue these upon
+ * powerdown/reset sequence.
+ */
+break;
+
 default:
 fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
 __FUNCTION__, value);
-- 
1.7.1




[Qemu-devel] [PATCH 11/12] hw/sysbus: Add sysbus_mmio_unmap() for unmapping a region

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Add support for unmapping a SysBus device's mmio region, via a new
function sysbus_mmio_unmap(). This simply reverses the effect of
sysbus_mmio_map().

Signed-off-by: Juha Riihimäki 
Signed-off-by: Peter Maydell 
---
 hw/sysbus.c |   17 +
 hw/sysbus.h |1 +
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 2e22be7..021c653 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -39,6 +39,23 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq 
irq)
 }
 }
 
+void sysbus_mmio_unmap(SysBusDevice *dev, int n)
+{
+assert(n >= 0 && n < dev->num_mmio);
+
+if (dev->mmio[n].addr == (target_phys_addr_t)-1) {
+/* region already unmapped */
+return;
+}
+if (dev->mmio[n].cb) {
+dev->mmio[n].cb(dev, (target_phys_addr_t)-1);
+} else {
+cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
+ IO_MEM_UNASSIGNED);
+}
+dev->mmio[n].addr = (target_phys_addr_t)-1;
+}
+
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr)
 {
 assert(n >= 0 && n < dev->num_mmio);
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 4e8cb16..4f93b70 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -53,6 +53,7 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t 
ioport, pio_addr_t size);
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
+void sysbus_mmio_unmap(SysBusDevice *dev, int n);
 
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
-- 
1.7.1




[Qemu-devel] [PATCH 05/12] hw/nand: Writing to NAND can only clear bits

2011-07-15 Thread Peter Maydell
Writing to a NAND device cannot set bits, it can only clear them;
implement this rather than simply copying the data.

Signed-off-by: Peter Maydell 
---
 hw/nand.c |   17 +
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/hw/nand.c b/hw/nand.c
index e6c551d..d068eb6 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -75,6 +75,15 @@ struct NANDFlashState {
 uint32_t ioaddr_vmstate;
 };
 
+static void mem_and(uint8_t *dest, const uint8_t *src, size_t n)
+{
+/* Like memcpy() but we logical-AND the data into the destination */
+int i;
+for (i = 0; i < n; i++) {
+dest[i] &= src[i];
+}
+}
+
 # define NAND_NO_AUTOINCR  0x0001
 # define NAND_BUSWIDTH_16  0x0002
 # define NAND_NO_PADDING   0x0004
@@ -595,7 +604,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState 
*s)
 return;
 
 if (!s->bdrv) {
-memcpy(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) +
+mem_and(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) +
 s->offset, s->io, s->iolen);
 } else if (s->mem_oob) {
 sector = SECTOR(s->addr);
@@ -606,10 +615,10 @@ static void glue(nand_blk_write_, 
PAGE_SIZE)(NANDFlashState *s)
 return;
 }
 
-memcpy(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off));
+mem_and(iobuf + (soff | off), s->io, MIN(s->iolen, PAGE_SIZE - off));
 if (off + s->iolen > PAGE_SIZE) {
 page = PAGE(s->addr);
-memcpy(s->storage + (page << OOB_SHIFT), s->io + PAGE_SIZE - off,
+mem_and(s->storage + (page << OOB_SHIFT), s->io + PAGE_SIZE - off,
 MIN(OOB_SIZE, off + s->iolen - PAGE_SIZE));
 }
 
@@ -624,7 +633,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState 
*s)
 return;
 }
 
-memcpy(iobuf + soff, s->io, s->iolen);
+mem_and(iobuf + soff, s->io, s->iolen);
 
 if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1)
 printf("%s: write error in sector %" PRIu64 "\n", __func__, 
sector);
-- 
1.7.1




[Qemu-devel] [PATCH 02/12] hw/nand: Support large NAND devices

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Add support for NAND devices of over 1Gb.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/nand.c |   48 +++-
 1 files changed, 27 insertions(+), 21 deletions(-)

diff --git a/hw/nand.c b/hw/nand.c
index d6204d9..18aa226 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -6,6 +6,10 @@
  * Copyright (c) 2006 Openedhand Ltd.
  * Written by Andrzej Zaborowski 
  *
+ * Support for additional features based on "MT29F2G16ABCWP 2Gx16"
+ * datasheet from Micron Technology and "NAND02G-B2C" datasheet
+ * from ST Microelectronics.
+ *
  * This code is licensed under the GNU GPL v2.
  */
 
@@ -57,14 +61,15 @@ struct NANDFlashState {
 uint8_t *ioaddr;
 int iolen;
 
-uint32_t cmd, addr;
+uint32_t cmd;
+uint64_t addr;
 int addrlen;
 int status;
 int offset;
 
 void (*blk_write)(NANDFlashState *s);
 void (*blk_erase)(NANDFlashState *s);
-void (*blk_load)(NANDFlashState *s, uint32_t addr, int offset);
+void (*blk_load)(NANDFlashState *s, uint64_t addr, int offset);
 
 uint32_t ioaddr_vmstate;
 };
@@ -318,7 +323,7 @@ static const VMStateDescription vmstate_nand = {
 VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState),
 VMSTATE_INT32(iolen, NANDFlashState),
 VMSTATE_UINT32(cmd, NANDFlashState),
-VMSTATE_UINT32(addr, NANDFlashState),
+VMSTATE_UINT64(addr, NANDFlashState),
 VMSTATE_INT32(addrlen, NANDFlashState),
 VMSTATE_INT32(status, NANDFlashState),
 VMSTATE_INT32(offset, NANDFlashState),
@@ -432,7 +437,7 @@ uint8_t nand_getio(NANDFlashState *s)
 
 /* Allow sequential reading */
 if (!s->iolen && s->cmd == NAND_CMD_READ0) {
-offset = (s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
+offset = (int)(s->addr & ((1 << s->addr_shift) - 1)) + s->offset;
 s->offset = 0;
 
 s->blk_load(s, s->addr, offset);
@@ -526,7 +531,7 @@ void nand_done(NANDFlashState *s)
 /* Program a single page */
 static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState *s)
 {
-uint32_t off, page, sector, soff;
+uint64_t off, page, sector, soff;
 uint8_t iobuf[(PAGE_SECTORS + 2) * 0x200];
 if (PAGE(s->addr) >= s->pages)
 return;
@@ -539,7 +544,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState 
*s)
 off = (s->addr & PAGE_MASK) + s->offset;
 soff = SECTOR_OFFSET(s->addr);
 if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1) {
-printf("%s: read error in sector %i\n", __FUNCTION__, sector);
+printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
 return;
 }
 
@@ -551,20 +556,20 @@ static void glue(nand_blk_write_, 
PAGE_SIZE)(NANDFlashState *s)
 }
 
 if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS) == -1)
-printf("%s: write error in sector %i\n", __FUNCTION__, sector);
+printf("%s: write error in sector %" PRIu64 "\n", __func__, 
sector);
 } else {
 off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset;
 sector = off >> 9;
 soff = off & 0x1ff;
 if (bdrv_read(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1) {
-printf("%s: read error in sector %i\n", __FUNCTION__, sector);
+printf("%s: read error in sector %" PRIu64 "\n", __func__, sector);
 return;
 }
 
 memcpy(iobuf + soff, s->io, s->iolen);
 
 if (bdrv_write(s->bdrv, sector, iobuf, PAGE_SECTORS + 2) == -1)
-printf("%s: write error in sector %i\n", __FUNCTION__, sector);
+printf("%s: write error in sector %" PRIu64 "\n", __func__, 
sector);
 }
 s->offset = 0;
 }
@@ -572,7 +577,7 @@ static void glue(nand_blk_write_, PAGE_SIZE)(NANDFlashState 
*s)
 /* Erase a single block */
 static void glue(nand_blk_erase_, PAGE_SIZE)(NANDFlashState *s)
 {
-uint32_t i, page, addr;
+uint64_t i, page, addr;
 uint8_t iobuf[0x200] = { [0 ... 0x1ff] = 0xff, };
 addr = s->addr & ~((1 << (ADDR_SHIFT + s->erase_shift)) - 1);
 
@@ -589,34 +594,35 @@ static void glue(nand_blk_erase_, 
PAGE_SIZE)(NANDFlashState *s)
 page = SECTOR(addr + (ADDR_SHIFT + s->erase_shift));
 for (; i < page; i ++)
 if (bdrv_write(s->bdrv, i, iobuf, 1) == -1)
-printf("%s: write error in sector %i\n", __FUNCTION__, i);
+printf("%s: write error in sector %" PRIu64 "\n", __func__, i);
 } else {
 addr = PAGE_START(addr);
 page = addr >> 9;
 if (bdrv_read(s->bdrv, page, iobuf, 1) == -1)
-printf("%s: read error in sector %i\n", __FUNCTION__, page);
+printf("%s: read error in sector %" PRIu64 "\n", __func__, page);
 memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0

[Qemu-devel] live snapshot wiki updated

2011-07-15 Thread Jes Sorensen
Hi,

I have been updating the live snapshot wiki for qemu to try and cover
the commands we will want for async snapshot handling too.

http://wiki.qemu.org/Features/Snapshots

Cheers,
Jes



[Qemu-devel] [PATCH 04/12] hw/nand: Support multiple reads following READ STATUS

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

After receiving READ STATUS command all subsequent IO reads should return
the status register value until another command is issued.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/nand.c |   11 ---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/nand.c b/hw/nand.c
index 2e98f25..e6c551d 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -496,9 +496,14 @@ uint32_t nand_getio(NANDFlashState *s)
 for (offset = s->buswidth; offset--;) {
 x |= s->ioaddr[offset] << (offset << 3);
 }
-s->addr   += s->buswidth;
-s->ioaddr += s->buswidth;
-s->iolen  -= s->buswidth;
+/* after receiving READ STATUS command all subsequent reads will
+ * return the status register value until another command is issued
+ */
+if (s->cmd != NAND_CMD_READSTATUS) {
+s->addr   += s->buswidth;
+s->ioaddr += s->buswidth;
+s->iolen  -= s->buswidth;
+}
 return x;
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH 12/12] hw/onenand: qdevify

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Qdevify the ONENAND device.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/flash.h   |8 +-
 hw/onenand.c |  208 +-
 2 files changed, 167 insertions(+), 49 deletions(-)

diff --git a/hw/flash.h b/hw/flash.h
index 1064fd0..bbf397a 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -38,10 +38,10 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 /* onenand.c */
 void onenand_base_update(void *opaque, target_phys_addr_t new);
 void onenand_base_unmap(void *opaque);
-void *onenand_init(BlockDriverState *bdrv,
-   uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-   int regshift, qemu_irq irq);
-void *onenand_raw_otp(void *opaque);
+DeviceState *onenand_init(BlockDriverState *bdrv,
+  uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
+  int regshift, qemu_irq irq);
+void *onenand_raw_otp(DeviceState *onenand_device);
 
 /* ecc.c */
 typedef struct {
diff --git a/hw/onenand.c b/hw/onenand.c
index 981d23c..16fd29a 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -23,6 +23,7 @@
 #include "flash.h"
 #include "irq.h"
 #include "blockdev.h"
+#include "sysbus.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT 11
@@ -31,6 +32,7 @@
 #define BLOCK_SHIFT(PAGE_SHIFT + 6)
 
 typedef struct {
+SysBusDevice busdev;
 struct {
 uint16_t man;
 uint16_t dev;
@@ -45,6 +47,7 @@ typedef struct {
 uint8_t *image;
 uint8_t *otp;
 uint8_t *current;
+uint8_t current_direction;
 ram_addr_t ram;
 uint8_t *boot[2];
 uint8_t *data[2][2];
@@ -100,31 +103,45 @@ enum {
 ONEN_LOCK_UNLOCKED = 1 << 2,
 };
 
-void onenand_base_update(void *opaque, target_phys_addr_t new)
+static void onenand_base_updatefn(SysBusDevice *dev, target_phys_addr_t new)
 {
-OneNANDState *s = (OneNANDState *) opaque;
+OneNANDState *s = (OneNANDState *)dev;
+if (s->base != new) {
+if (s->base != (target_phys_addr_t)-1) {
+cpu_register_physical_memory(s->base, 0x1 << s->shift,
+ IO_MEM_UNASSIGNED);
+}
+if (new != (target_phys_addr_t)-1) {
+/* XXX: We should use IO_MEM_ROMD but we broke it earlier...
+ * Both 0x ... 0x01ff and 0x8000 ... 0x800f can be used to
+ * write boot commands.  Also take note of the BWPS bit.  */
+cpu_register_physical_memory(new + (0x << s->shift),
+ 0x0200 << s->shift, s->iomemtype);
+cpu_register_physical_memory(new + (0x0200 << s->shift),
+ 0xbe00 << s->shift,
+ (s->ram + (0x0200 << s->shift))
+ | IO_MEM_RAM);
+if (s->iomemtype) {
+cpu_register_physical_memory_offset(new + (0xc000 << s->shift),
+0x4000 << s->shift,
+s->iomemtype,
+(0xc000 << s->shift));
+}
+}
+s->base = new;
+}
+}
 
-s->base = new;
-
-/* XXX: We should use IO_MEM_ROMD but we broke it earlier...
- * Both 0x ... 0x01ff and 0x8000 ... 0x800f can be used to
- * write boot commands.  Also take note of the BWPS bit.  */
-cpu_register_physical_memory(s->base + (0x << s->shift),
-0x0200 << s->shift, s->iomemtype);
-cpu_register_physical_memory(s->base + (0x0200 << s->shift),
-0xbe00 << s->shift,
-(s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
-if (s->iomemtype)
-cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
-0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
+/* This wrapper can go away as soon as omap_gpmc is qdevified */
+void onenand_base_update(void *opaque, target_phys_addr_t new)
+{
+onenand_base_updatefn(opaque, new);
 }
 
+/* Also only needed for pre-qdev omap_gpmc */
 void onenand_base_unmap(void *opaque)
 {
-OneNANDState *s = (OneNANDState *) opaque;
-
-cpu_register_physical_memory(s->base,
-0x1 << s->shift, IO_MEM_UNASSIGNED);
+sysbus_mmio_unmap(sysbus_from_qdev((DeviceState *)opaque), 0);
 }
 
 static void onenand_intr_update(OneNANDState *s)
@@ -132,6 +149,67 @@ static void onenand_intr_update(OneNANDState *s)
 qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
 }
 
+static void onenand_pre_save(void *opaque)
+{
+OneNANDState *s = opaque;
+if (s->current == s->otp) {
+s->current_direction = 1;

[Qemu-devel] [PATCH 03/12] hw/nand: Support devices wider than 8 bits

2011-07-15 Thread Peter Maydell
From: Juha Riihimäki 

Support NAND devices which are wider than 8 bits.

Signed-off-by: Juha Riihimäki 
[Riku Voipio: Fixes and restructuring patchset]
Signed-off-by: Riku Voipio 
[Peter Maydell: More fixes and cleanups for upstream submission]
Signed-off-by:  Peter Maydell 
---
 hw/flash.h |5 ++-
 hw/nand.c  |  119 +++-
 2 files changed, 89 insertions(+), 35 deletions(-)

diff --git a/hw/flash.h b/hw/flash.h
index a992bb8..132ad29 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -24,8 +24,9 @@ void nand_done(NANDFlashState *s);
 void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
   uint8_t ce, uint8_t wp, uint8_t gnd);
 void nand_getpins(NANDFlashState *s, int *rb);
-void nand_setio(NANDFlashState *s, uint8_t value);
-uint8_t nand_getio(NANDFlashState *s);
+void nand_setio(NANDFlashState *s, uint32_t value);
+uint32_t nand_getio(NANDFlashState *s);
+uint32_t nand_getbuswidth(NANDFlashState *s);
 
 #define NAND_MFR_TOSHIBA   0x98
 #define NAND_MFR_SAMSUNG   0xec
diff --git a/hw/nand.c b/hw/nand.c
index 18aa226..2e98f25 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -49,6 +49,7 @@
 
 struct NANDFlashState {
 uint8_t manf_id, chip_id;
+uint8_t buswidth; /* in BYTES */
 int size, pages;
 int page_shift, oob_shift, erase_shift, addr_shift;
 uint8_t *storage;
@@ -215,6 +216,14 @@ static void nand_reset(NANDFlashState *s)
 s->status &= NAND_IOSTATUS_UNPROTCT;
 }
 
+static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value)
+{
+s->ioaddr[s->iolen++] = value;
+for (value = s->buswidth; --value;) {
+s->ioaddr[s->iolen++] = 0;
+}
+}
+
 static void nand_command(NANDFlashState *s)
 {
 unsigned int offset;
@@ -224,15 +233,19 @@ static void nand_command(NANDFlashState *s)
 break;
 
 case NAND_CMD_READID:
-s->io[0] = s->manf_id;
-s->io[1] = s->chip_id;
-s->io[2] = 'Q';/* Don't-care byte (often 0xa5) */
-if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
-s->io[3] = 0x15;   /* Page Size, Block Size, Spare Size.. */
-else
-s->io[3] = 0xc0;   /* Multi-plane */
 s->ioaddr = s->io;
-s->iolen = 4;
+s->iolen = 0;
+nand_pushio_byte(s, s->manf_id);
+nand_pushio_byte(s, s->chip_id);
+nand_pushio_byte(s, 'Q'); /* Don't-care byte (often 0xa5) */
+if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
+/* Page Size, Block Size, Spare Size; bit 6 indicates
+ * 8 vs 16 bit width NAND.
+ */
+nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15);
+} else {
+nand_pushio_byte(s, 0xc0); /* Multi-plane */
+}
 break;
 
 case NAND_CMD_RANDOMREAD2:
@@ -277,9 +290,9 @@ static void nand_command(NANDFlashState *s)
 break;
 
 case NAND_CMD_READSTATUS:
-s->io[0] = s->status;
 s->ioaddr = s->io;
-s->iolen = 1;
+s->iolen = 0;
+nand_pushio_byte(s, s->status);
 break;
 
 default:
@@ -357,8 +370,10 @@ void nand_getpins(NANDFlashState *s, int *rb)
 *rb = 1;
 }
 
-void nand_setio(NANDFlashState *s, uint8_t value)
+void nand_setio(NANDFlashState *s, uint32_t value)
 {
+int i;
+
 if (!s->ce && s->cle) {
 if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) {
 if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2)
@@ -404,36 +419,64 @@ void nand_setio(NANDFlashState *s, uint8_t value)
 s->addr = (s->addr & mask) | v;
 s->addrlen ++;
 
-if (s->addrlen == 1 && s->cmd == NAND_CMD_READID)
-nand_command(s);
-
-if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&
-s->addrlen == 3 && (
-s->cmd == NAND_CMD_READ0 ||
-s->cmd == NAND_CMD_PAGEPROGRAM1))
-nand_command(s);
-if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) &&
-   s->addrlen == 4 && (
-s->cmd == NAND_CMD_READ0 ||
-s->cmd == NAND_CMD_PAGEPROGRAM1))
-nand_command(s);
+switch (s->addrlen) {
+case 1:
+if (s->cmd == NAND_CMD_READID) {
+nand_command(s);
+}
+break;
+case 2: /* fix cache address as a byte address */
+s->addr <<= (s->buswidth - 1);
+break;
+case 3:
+if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
+&& (s->cmd == NAND_CMD_READ0
+|| s->cmd == NAND_CMD_PAGEPROGRAM1)) {
+nand_command(s);
+}
+break;
+case 4:
+if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)
+&& nand_flash_ids[s->chip_id].size < 256 /* 1Gb or less */
+&& (s->cmd == NAND_CMD_READ0 ||
+  

[Qemu-devel] [PATCH 07/12] onenand: Pass BlockDriverState to init function

2011-07-15 Thread Peter Maydell
Pass the BlockDriverState to the onenand init function so it doesn't
need to look up the drive itself.

Signed-off-by: Peter Maydell 
---
 hw/flash.h   |3 ++-
 hw/nseries.c |   10 ++
 hw/onenand.c |   14 --
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/hw/flash.h b/hw/flash.h
index 43260ce..1aae43d 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -38,7 +38,8 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 /* onenand.c */
 void onenand_base_update(void *opaque, target_phys_addr_t new);
 void onenand_base_unmap(void *opaque);
-void *onenand_init(uint32_t id, int regshift, qemu_irq irq);
+void *onenand_init(BlockDriverState *bdrv, uint32_t id,
+   int regshift, qemu_irq irq);
 void *onenand_raw_otp(void *opaque);
 
 /* ecc.c */
diff --git a/hw/nseries.c b/hw/nseries.c
index 32f2f53..4fef05d 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -31,6 +31,7 @@
 #include "hw.h"
 #include "bt.h"
 #include "loader.h"
+#include "blockdev.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
@@ -163,13 +164,14 @@ static const uint8_t n8x0_cal_bt_id[] = {
 static void n8x0_nand_setup(struct n800_s *s)
 {
 char *otp_region;
+DriveInfo *dinfo;
 
+dinfo = drive_get(IF_MTD, 0, 0);
 /* Either ec40xx or ec48xx are OK for the ID */
+s->nand = onenand_init(dinfo ? dinfo->bdrv : 0, 0xec4800, 1,
+   qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
 omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
-onenand_base_unmap,
-(s->nand = onenand_init(0xec4800, 1,
-qdev_get_gpio_in(s->cpu->gpio,
-N8X0_ONENAND_GPIO;
+ onenand_base_unmap, s->nand);
 otp_region = onenand_raw_otp(s->nand);
 
 memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
diff --git a/hw/onenand.c b/hw/onenand.c
index 71c1ab4..3a19d7f 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -615,10 +615,10 @@ static CPUWriteMemoryFunc * const onenand_writefn[] = {
 onenand_write,
 };
 
-void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
+void *onenand_init(BlockDriverState *bdrv, uint32_t id,
+   int regshift, qemu_irq irq)
 {
 OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
-DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
 uint32_t size = 1 << (24 + ((id >> 12) & 7));
 void *ram;
 
@@ -632,11 +632,13 @@ void *onenand_init(uint32_t id, int regshift, qemu_irq 
irq)
 s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
 s->iomemtype = cpu_register_io_memory(onenand_readfn,
 onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
-if (!dinfo)
+s->bdrv = bdrv;
+if (!s->bdrv) {
 s->image = memset(qemu_malloc(size + (size >> 5)),
-0xff, size + (size >> 5));
-else
-s->bdrv = dinfo->bdrv;
+  0xff, size + (size >> 5));
+} else {
+s->bdrv_cur = s->bdrv;
+}
 s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
 0xff, (64 + 2) << PAGE_SHIFT);
 s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
-- 
1.7.1




[Qemu-devel] [PATCH 01/12] hw/nand: Pass block device state to init function

2011-07-15 Thread Peter Maydell
Pass the BlockDeviceState to the nand_init() function rather
than having it look it up via drive_get() itself.

Signed-off-by: Peter Maydell 
---
 hw/axis_dev88.c |6 +-
 hw/flash.h  |2 +-
 hw/nand.c   |8 ++--
 hw/spitz.c  |4 +++-
 hw/tc6393xb.c   |5 -
 5 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 0e2135a..de1f5a5 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -30,6 +30,7 @@
 #include "loader.h"
 #include "elf.h"
 #include "cris-boot.h"
+#include "blockdev.h"
 
 #define D(x)
 #define DNAND(x)
@@ -251,6 +252,7 @@ void axisdev88_init (ram_addr_t ram_size,
 CPUState *env;
 DeviceState *dev;
 SysBusDevice *s;
+DriveInfo *nand;
 qemu_irq irq[30], nmi[2], *cpu_irq;
 void *etraxfs_dmac;
 struct etraxfs_dma_client *eth[2] = {NULL, NULL};
@@ -278,7 +280,9 @@ void axisdev88_init (ram_addr_t ram_size,
 
 
   /* Attach a NAND flash to CS1.  */
-nand_state.nand = nand_init(NAND_MFR_STMICRO, 0x39);
+nand = drive_get(IF_MTD, 0, 0);
+nand_state.nand = nand_init(nand ? nand->bdrv : NULL,
+NAND_MFR_STMICRO, 0x39);
 nand_regs = cpu_register_io_memory(nand_read, nand_write, &nand_state,
DEVICE_NATIVE_ENDIAN);
 cpu_register_physical_memory(0x1000, 0x0500, nand_regs);
diff --git a/hw/flash.h b/hw/flash.h
index c22e1a9..a992bb8 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -19,7 +19,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, 
ram_addr_t off,
 
 /* nand.c */
 typedef struct NANDFlashState NANDFlashState;
-NANDFlashState *nand_init(int manf_id, int chip_id);
+NANDFlashState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
 void nand_done(NANDFlashState *s);
 void nand_setpins(NANDFlashState *s, uint8_t cle, uint8_t ale,
   uint8_t ce, uint8_t wp, uint8_t gnd);
diff --git a/hw/nand.c b/hw/nand.c
index 37e51d7..d6204d9 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -14,7 +14,6 @@
 # include "hw.h"
 # include "flash.h"
 # include "blockdev.h"
-/* FIXME: Pass block device as an argument.  */
 
 # define NAND_CMD_READ00x00
 # define NAND_CMD_READ10x01
@@ -451,20 +450,17 @@ uint8_t nand_getio(NANDFlashState *s)
 return *(s->ioaddr ++);
 }
 
-NANDFlashState *nand_init(int manf_id, int chip_id)
+NANDFlashState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id)
 {
 int pagesize;
 NANDFlashState *s;
-DriveInfo *dinfo;
 
 if (nand_flash_ids[chip_id].size == 0) {
 hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
 }
 
 s = (NANDFlashState *) qemu_mallocz(sizeof(NANDFlashState));
-dinfo = drive_get(IF_MTD, 0, 0);
-if (dinfo)
-s->bdrv = dinfo->bdrv;
+s->bdrv = bdrv;
 s->manf_id = manf_id;
 s->chip_id = chip_id;
 s->size = nand_flash_ids[s->chip_id].size << 20;
diff --git a/hw/spitz.c b/hw/spitz.c
index 006f7a9..78e9c34 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -169,11 +169,13 @@ static void sl_flash_register(PXA2xxState *cpu, int size)
 static int sl_nand_init(SysBusDevice *dev) {
 int iomemtype;
 SLNANDState *s;
+DriveInfo *nand;
 
 s = FROM_SYSBUS(SLNANDState, dev);
 
 s->ctl = 0;
-s->nand = nand_init(s->manf_id, s->chip_id);
+nand = drive_get(IF_MTD, 0, 0);
+s->nand = nand_init(nand ? nand->bdrv : NULL, s->manf_id, s->chip_id);
 
 iomemtype = cpu_register_io_memory(sl_readfn,
 sl_writefn, s, DEVICE_NATIVE_ENDIAN);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index ed49e94..4de0819 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -12,6 +12,7 @@
 #include "flash.h"
 #include "console.h"
 #include "pixel_ops.h"
+#include "blockdev.h"
 
 #define IRQ_TC6393_NAND0
 #define IRQ_TC6393_MMC 1
@@ -566,6 +567,7 @@ TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq)
 {
 int iomemtype;
 TC6393xbState *s;
+DriveInfo *nand;
 CPUReadMemoryFunc * const tc6393xb_readfn[] = {
 tc6393xb_readb,
 tc6393xb_readw,
@@ -586,7 +588,8 @@ TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq)
 
 s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS);
 
-s->flash = nand_init(NAND_MFR_TOSHIBA, 0x76);
+nand = drive_get(IF_MTD, 0, 0);
+s->flash = nand_init(nand ? nand->bdrv : NULL, NAND_MFR_TOSHIBA, 0x76);
 
 iomemtype = cpu_register_io_memory(tc6393xb_readfn,
 tc6393xb_writefn, s, DEVICE_NATIVE_ENDIAN);
-- 
1.7.1




Re: [Qemu-devel] [PATCH] v6 revamp acpitable parsing and allow to specify complete (headerful) table

2011-07-15 Thread John Baboval

Is there something I can do to help take this patch the rest of the way?

I'd hate to see it die because of a style issue and a compiler warning.

-John

On 06/15/2011 02:19 PM, Blue Swirl wrote:

On Sat, Jun 11, 2011 at 1:29 AM, Michael Tokarev  wrote:

I've given up on this one.  Personally I don't need
this stuff for my win7 guests since I can hack either
bios or the O/S loader to include all the necessary
verifications for the win7 activation to work.  I
tried to make this process to be legal (no hacks
or "cracks" needed) and easy for others, but since
noone is interested in this after 6 versions and 5
resends, I wont continue - what I am trying to achieve
by pushing this so hard, after all?

Thanks to everyone who gave (mostly code style) comments -
at least I know the changes has been read by someone.

Frustrated,

Sorry about that. I get this error:
/src/qemu/hw/acpi.c: In function 'acpi_table_add':
/src/qemu/hw/acpi.c:167: error: format '%u' expects type 'unsigned
int', but argument 4 has type 'size_t'


  /mjt

12.05.2011 18:44, Michael Tokarev wrote:

This patch almost rewrites acpi_table_add() function
(but still leaves it using old get_param_value() interface).
The result is that it's now possible to specify whole table
(together with a header) in an external file, instead of just
data portion, with a new file= parameter, but at the same time
it's still possible to specify header fields as before.

Now with the checkpatch.pl formatting fixes, thanks to
Stefan Hajnoczi for suggestions, with changes from
Isaku Yamahata, and with my further refinements.

v5: rediffed against current qemu/master.
v6: fix one "} else {" coding style defect (noted by Blue Swirl)

Signed-off-by: Michael Tokarev
---
  hw/acpi.c   |  292 ---
  qemu-options.hx |7 +-
  2 files changed, 175 insertions(+), 124 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index ad40fb4..4316189 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -22,17 +22,29 @@

  struct acpi_table_header
  {
-char signature [4];/* ACPI signature (4 ASCII characters) */
+uint16_t _length; /* our length, not actual part of the hdr */
+  /* XXX why we have 2 length fields here? */
+char sig[4];  /* ACPI signature (4 ASCII characters) */
  uint32_t length;  /* Length of table, in bytes, including header 
*/
  uint8_t revision; /* ACPI Specification minor version # */
  uint8_t checksum; /* To make sum of entire table == 0 */
-char oem_id [6];   /* OEM identification */
-char oem_table_id [8]; /* OEM table identification */
+char oem_id[6];   /* OEM identification */
+char oem_table_id[8]; /* OEM table identification */
  uint32_t oem_revision;/* OEM revision number */
-char asl_compiler_id [4]; /* ASL compiler vendor ID */
+char asl_compiler_id[4];  /* ASL compiler vendor ID */
  uint32_t asl_compiler_revision; /* ASL compiler revision number */
  } __attribute__((packed));

+#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
+#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra prefix */
+
+static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] =
+"\0\0"   /* fake _length (2) */
+"QEMU\0\0\0\0\1\0"   /* sig (4), len(4), revno (1), csum (1) */
+"QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
+"QEMU\1\0\0\0"   /* ASL compiler ID (4), version (4) */
+;
+
  char *acpi_tables;
  size_t acpi_tables_len;

@@ -45,158 +57,192 @@ static int acpi_checksum(const uint8_t *data, int len)
  return (-sum)&  0xff;
  }

+/* like strncpy() but zero-fills the tail of destination */
+static void strzcpy(char *dst, const char *src, size_t size)
+{
+size_t len = strlen(src);
+if (len>= size) {
+len = size;
+} else {
+  memset(dst + len, 0, size - len);
+}
+memcpy(dst, src, len);
+}
+
+/* XXX fixme: this function uses obsolete argument parsing interface */
  int acpi_table_add(const char *t)
  {
-static const char *dfl_id = "QEMUQEMU";
  char buf[1024], *p, *f;
-struct acpi_table_header acpi_hdr;
  unsigned long val;
-uint32_t length;
-struct acpi_table_header *acpi_hdr_p;
-size_t off;
+size_t len, start, allen;
+bool has_header;
+int changed;
+int r;
+struct acpi_table_header hdr;
+
+r = 0;
+r |= get_param_value(buf, sizeof(buf), "data", t) ? 1 : 0;
+r |= get_param_value(buf, sizeof(buf), "file", t) ? 2 : 0;
+switch (r) {
+case 0:
+buf[0] = '\0';

Missing 'break' or comment about fall through.


+case 1:
+has_header = false;
+break;
+case 2:
+has_header = true;
+break;
+default:
+fprintf(stderr, "acpitable: both data and file are specified\n");
+return -1;
+}
+
+if (!acpi_tables) {
+allen = sizeof(uint16_t);
+  

[Qemu-devel] [PATCH] report serial devices created with -device in the PIIX4 config space

2011-07-15 Thread Paolo Bonzini
Serial and parallel devices created with -device are not reported in
the PIIX4 configuration space, and are hence not picked up by the DSDT.
This upsets Windows, which hides them altogether from the guest.

To avoid this, check at the end of machine initialization whether the
corresponding I/O ports have been registered.  The new function in
ioport.c does this; this also requires a tweak to isa_unassign_ioport.

I left the comment in piix4_pm_initfn since the registers I moved do
seem to match the 82371AB datasheet.  There are some quirks though.
We are setting this bit:

"Device 8 EIO Enable (EIO_EN_DEV8)—R/W. 1=Enable PCI access to the
device 8 enabled I/O ranges to be claimed by PIIX4 and forwarded
to the ISA/EIO bus. 0=Disable. The LPT_MON_EN must be set to enable
the decode."

but not LPT_MON_EN (bit 18 at 50h):

LPT Port Enable (LPT_MON_EN)—R/W. 1=Enable accesses to parallel
port address range (LPT_DEC_SEL) to generate a device 8 (parallel
port) decode event. 0=Disable.

We're also setting the LPT_DEC_SEL field (that's the 0x60 written to
63h) to 11, which means reserved, rather than to 01 (378h-37Fh).

Likewise we're not setting SA_MON_EN, SB_MON_EN (respectively bit 14
and bit 16 at address 50h) for the serial ports.  However, we're setting
COMA_DEC_SEL and COMB_DEC_SEL correctly, unlike the corresponding register
for the parallel port.

All these fields are left as they are, since they are probably only
meant to be used in the DSDT.

Signed-off-by: Paolo Bonzini 
---
 hw/acpi_piix4.c |   23 ++-
 ioport.c|   19 +--
 ioport.h|2 +-
 3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 350558b..03de3ad 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -23,6 +23,7 @@
 #include "acpi.h"
 #include "sysemu.h"
 #include "range.h"
+#include "ioport.h"
 
 //#define DEBUG
 
@@ -63,6 +64,7 @@ typedef struct PIIX4PMState {
 qemu_irq irq;
 qemu_irq smi_irq;
 int kvm_enabled;
+Notifier machine_ready;
 
 /* for pci hotplug */
 ACPIGPE gpe;
@@ -311,6 +313,19 @@ static void piix4_powerdown(void *opaque, int irq, int 
power_failing)
 acpi_pm1_evt_power_down(pm1a, tmr);
 }
 
+static void piix4_pm_machine_ready(struct Notifier* n)
+{
+PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);
+uint8_t *pci_conf;
+
+pci_conf = s->dev.config;
+pci_conf[0x5f] = (isa_is_ioport_assigned(0x378) ? 0x80 : 0) | 0x10;
+pci_conf[0x63] = 0x60;
+pci_conf[0x67] = (isa_is_ioport_assigned(0x3f8) ? 0x08 : 0) |
+   (isa_is_ioport_assigned(0x2f8) ? 0x90 : 0);
+
+}
+
 static int piix4_pm_initfn(PCIDevice *dev)
 {
 PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev);
@@ -337,11 +352,6 @@ static int piix4_pm_initfn(PCIDevice *dev)
 
 /* XXX: which specification is used ? The i82731AB has different
mappings */
-pci_conf[0x5f] = (parallel_hds[0] != NULL ? 0x80 : 0) | 0x10;
-pci_conf[0x63] = 0x60;
-pci_conf[0x67] = (serial_hds[0] != NULL ? 0x08 : 0) |
-   (serial_hds[1] != NULL ? 0x90 : 0);
-
 pci_conf[0x90] = s->smb_io_base | 1;
 pci_conf[0x91] = s->smb_io_base >> 8;
 pci_conf[0xd2] = 0x09;
@@ -354,12 +364,14 @@ static int piix4_pm_initfn(PCIDevice *dev)
 qemu_system_powerdown = *qemu_allocate_irqs(piix4_powerdown, s, 1);
 
 pm_smbus_init(&s->dev.qdev, &s->smb);
+s->machine_ready.notify = piix4_pm_machine_ready;
+qemu_add_machine_init_done_notifier(&s->machine_ready);
 qemu_register_reset(piix4_reset, s);
 piix4_acpi_system_hot_add_init(dev->bus, s);
 
 return 0;
 }
 
 i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq cmos_s3, qemu_irq smi_irq,
int kvm_enabled)
diff --git a/ioport.c b/ioport.c
index 2e971fa..0d2611d 100644
--- a/ioport.c
+++ b/ioport.c
@@ -245,18 +245,25 @@ void isa_unassign_ioport(pio_addr_t start, int length)
 int i;
 
 for(i = start; i < start + length; i++) {
-ioport_read_table[0][i] = default_ioport_readb;
-ioport_read_table[1][i] = default_ioport_readw;
-ioport_read_table[2][i] = default_ioport_readl;
+ioport_read_table[0][i] = NULL;
+ioport_read_table[1][i] = NULL;
+ioport_read_table[2][i] = NULL;
 
-ioport_write_table[0][i] = default_ioport_writeb;
-ioport_write_table[1][i] = default_ioport_writew;
-ioport_write_table[2][i] = default_ioport_writel;
+ioport_write_table[0][i] = NULL;
+ioport_write_table[1][i] = NULL;
+ioport_write_table[2][i] = NULL;
 
 ioport_opaque[i] = NULL;
 }
 }
 
+bool isa_is_ioport_assigned(pio_addr_t start)
+{
+return (ioport_read_table[0][start] || ioport_write_table[0][start] ||
+   ioport_read_table[1][start] || ioport_write_table[1][start] ||
+   ioport_read_table[2][start] || ioport_write_table[2]

Re: [Qemu-devel] [QAPI+QGA 3/3] QEMU Guest Agent (virtagent) v7

2011-07-15 Thread Luiz Capitulino
On Fri, 15 Jul 2011 09:15:18 +0800
Zhi Yong Wu  wrote:

> On Fri, Jul 15, 2011 at 4:00 AM, Michael Roth  
> wrote:
> > This is Set 3/3 of the QAPI+QGA patchsets.
> >
> > These patches apply on top of qapi-backport-set2-v6, and can also be 
> > obtained from:
> > git://repo.or.cz/qemu/mdroth.git qapi-backport-set3-v7
> >
> > (Set1+2 are a backport of some of the QAPI-related work from Anthony's
> > glib tree. The main goal is to get the basic code generation infrastructure 
> > in
> > place so that it can be used by the guest agent to implement a QMP-like 
> > guest
> > interface, and so that future work regarding the QMP conversion to QAPI can 
> > be
> > decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent
> > (virtagent), rebased on the new code QAPI code generation infrastructure. 
> > This
> > is the first user of QAPI, QMP will follow.)
> > ___
> >
> > CHANGES SINCE V6:
> >  - Made "/dev/virtio-ports/org.qemu.guest_agent.0" default device path for 
> > agent
> >  - Consolidated uneeded fcntl() calls into qemu_open()
> >  - JSON/QMP parse errors now propagated to client
> >  - Replaced non-assertion uses of g_error() with exit()
> >  - Added guest-file-flush
> >  - Removed limit on max read size for guest-file-read
> >  - 'count' parameters to guest-file-read/guest-file-write are now optional 
> > (default to 4KB and size of provided buffer, base64-decoded, respectively)
> >  - Removed redundant 'file_' and 'shutdown_' prefixes from 
> > guest-file-*/guest-shutdown commands, switched to "-" in place of "_" in 
> > parameter names, renamed guest-file-read's "buf" param to "buf-b64" and 
> > guest-file-write's "data_b64" param to "buf-b64" for consistency.
> >  - guest-fsfreeze-freeze now returns error objects on error rather as part 
> > of it's integer return values, and on error will unfreeze previously frozen 
> > filesystems.
> >  - GUEST_FSFREEZE_STATUS_INPROGRESS removed, GUEST_FSFREEZE_STATUS_ERROR 
> > now serves the explicit purpose of noting a failure to find a previously 
> > mounted filesytem/directory after initial freeze, or failure to unfreeze 1 
> > or more filesystems.
> >  - -c/--channel option to qemu-ga is now -m/--method
> >
> > CHANGES SINCE V5:
> >  - switched to using qemu malloc/list functions where possible
> >  - removed unused proxy_path field in struct GAState
> >  - pid file now opened write-only, removed lockf() in favor of O_EXCL, 
> > added SIGINT/SIGTERM signal handlers to handle cleanup
> >  - cleaned up error-handling, switched to asserts where appropriate, 
> > removed unecessary gotos and NULL checks for qemu_free()/qobject_decref()
> >  - refactored send_payload() using helper functions
> >  - fixed improper handling of pidfile fd==0
> >  - changed guest-shutdown's "shutdown_mode" param to "mode"
> >  - switched to using kernel-generated FDs for guest-file-open rather than 
> > an autoincrement value
> >  - add maximum chunk size of guest-file-read/guest-file-write
> >  - added checks to avoid guest-file-write from writing data beyond the 
> > provided data buffer
> >  - made logging best-effort, removed handling of failures to log as errors
> >  - guest-shutdown exec errors now logged to guest syslog, clarified 
> > shutdown's asynchronous, no gauruntee nature in schema.
> >
> > CHANGES SINCE V4:
> >  - Removed timeout mechanism via worker thread/pthread_cancel due to 
> > potential memory leak. Will re-introduce guest-side timeout support in 
> > future version.
> >  - Fixed up fsfreeze code to use enums specified within the guest agent's 
> > qapi schema.
> >  - Fixed memory leak due to a log statement, and added missing cleanup 
> > functions for heap-allocated g_error objects.
> >  - Made "mode" param to guest-file-open optional, defaults to "r" 
> > (read-only)
> >
> > CHANGES SINCE V3:
> >  - Fixed error-handling issues in fsfreeze commands leading to certain 
> > mounted directories causing freeze/thaw operations to fail
> >  - Added cleanup hook to thaw filesystems on graceful guest agent exit
> >  - Removed unused enum values and added additional details to schema 
> > documentation
> >  - Fixed build issue that was missed due to deprecated files in source 
> > tree, removed unused includes
> >
> > CHANGES SINCE V2:
> >  - Rebased on new QAPI code generation framework
> >  - Dropped ability for QMP to act as a proxy for the guest agent, will be 
> > added when new QMP server is backported from Anthony's glib tree
> >  - Replaced negotiation/control events with a simple 2-way handshake 
> > implemented by a standard RPC (guest-sync)
> >  - Removed enforcement of "pristine" sessions, state is now 
> > global/persistant across multiple clients/connections
> >  - Fixed segfault in logging code
> >  - Added Jes' filesystem freeze patches
> >  - General cleanups
> >
> > CHANGES SINCE V1:
> >  - Added guest agent worker thread to execute RPCs in the guest. With this 
> > in place we have a reliable timeout mechanism for hung commands, currently 

[Qemu-devel] [RFC][PATCH 3/9] block: Add bdrv_co_readv/writev emulation

2011-07-15 Thread Kevin Wolf
In order to be able to call bdrv_co_readv/writev for drivers that don't
implement the functions natively, add an emulation that uses the AIO functions
to implement them.

Signed-off-by: Kevin Wolf 
---
 block.c  |   86 +++--
 trace-events |1 +
 2 files changed, 78 insertions(+), 9 deletions(-)

diff --git a/block.c b/block.c
index 79a5008..fc1712f 100644
--- a/block.c
+++ b/block.c
@@ -64,6 +64,12 @@ static BlockDriverAIOCB 
*bdrv_co_aio_readv_em(BlockDriverState *bs,
 static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
 BlockDriverCompletionFunc *cb, void *opaque);
+static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *iov);
+static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *iov);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -182,14 +188,19 @@ void bdrv_register(BlockDriver *bdrv)
 bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em;
 bdrv->bdrv_read = bdrv_read_em;
 bdrv->bdrv_write = bdrv_write_em;
- } else if (!bdrv->bdrv_aio_readv) {
-/* add AIO emulation layer */
-bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
-bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
-} else if (!bdrv->bdrv_read) {
-/* add synchronous IO emulation layer */
-bdrv->bdrv_read = bdrv_read_em;
-bdrv->bdrv_write = bdrv_write_em;
+ } else {
+bdrv->bdrv_co_readv = bdrv_co_readv_em;
+bdrv->bdrv_co_writev = bdrv_co_writev_em;
+
+if (!bdrv->bdrv_aio_readv) {
+/* add AIO emulation layer */
+bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
+bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
+} else if (!bdrv->bdrv_read) {
+/* add synchronous IO emulation layer */
+bdrv->bdrv_read = bdrv_read_em;
+bdrv->bdrv_write = bdrv_write_em;
+}
 }
 
 if (!bdrv->bdrv_aio_flush)
@@ -2652,7 +2663,7 @@ static void coroutine_fn bdrv_co_rw(void *opaque)
 BlockDriverAIOCBCoroutine *acb = opaque;
 BlockDriverState *bs = acb->common.bs;
 
-if (acb->is_write) {
+if (!acb->is_write) {
 acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector,
 acb->req.nb_sectors, acb->req.qiov);
 } else {
@@ -2849,6 +2860,63 @@ void qemu_aio_release(void *p)
 }
 
 /**/
+/* Coroutine block device emulation */
+
+typedef struct CoroutineIOCompletion {
+Coroutine *coroutine;
+int ret;
+} CoroutineIOCompletion;
+
+static void bdrv_co_io_em_complete(void *opaque, int ret)
+{
+CoroutineIOCompletion *co = opaque;
+
+co->ret = ret;
+qemu_coroutine_enter(co->coroutine, NULL);
+}
+
+static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
+  int nb_sectors, QEMUIOVector *iov,
+  bool is_write)
+{
+CoroutineIOCompletion co = {
+.coroutine = qemu_coroutine_self(),
+.ret = -EINPROGRESS,
+};
+BlockDriverAIOCB *acb;
+
+if (is_write) {
+acb = bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
+  bdrv_co_io_em_complete, &co);
+} else {
+acb = bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
+ bdrv_co_io_em_complete, &co);
+}
+
+trace_bdrv_co_io(is_write, acb);
+if (!acb) {
+return -EIO;
+}
+qemu_coroutine_yield();
+
+return co.ret;
+}
+
+static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *iov)
+{
+return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, false);
+}
+
+static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors,
+ QEMUIOVector *iov)
+{
+return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
+}
+
+/**/
 /* removable device support */
 
 /**
diff --git a/trace-events b/trace-events
index 3cd9118..b835c61 100644
--- a/trace-events
+++ b/trace-events
@@ -57,6 +57,7 @@ disable bdrv_aio_writev(void *bs, int64_t sector_num, int 
nb_sectors, void *opaq
 disable bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
 disable bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p 
sector_num %"PRId64" nb_sectors %d"
 disable bdrv_co_write

Re: [Qemu-devel] [PATCH v7 4/4] guest agent: add guest agent RPCs/commands

2011-07-15 Thread Luiz Capitulino
On Thu, 14 Jul 2011 15:00:34 -0500
Michael Roth  wrote:

> This adds the initial set of QMP/QAPI commands provided by the guest
> agent:
> 
> guest-sync
> guest-ping
> guest-info
> guest-shutdown
> guest-file-open
> guest-file-read
> guest-file-write
> guest-file-seek
> guest-file-flush
> guest-file-close
> guest-fsfreeze-freeze
> guest-fsfreeze-thaw
> guest-fsfreeze-status
> 
> The input/output specification for these commands are documented in the
> schema.
> 
> Example usage:
> 
>   host:
> qemu -device virtio-serial \
>  -chardev socket,path=/tmp/vs0.sock,server,nowait,id=qga0 \
>  -device virtserialport,chardev=qga0,name=org.qemu.quest_agent.0
>  ...
> 
> echo "{'execute':'guest-info'}" | socat stdio unix-connect:/tmp/qga0.sock
> 
>   guest:
> qemu-ga -m virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent.0 \
> -p /var/run/qemu-guest-agent.pid -d
> 
> Signed-off-by: Michael Roth 
> ---
>  Makefile   |   15 ++-
>  qapi-schema-guest.json |  217 +++
>  qemu-ga.c  |4 +
>  qerror.c   |8 +
>  qerror.h   |6 +
>  qga/guest-agent-commands.c |  512 
> 
>  qga/guest-agent-core.h |2 +
>  7 files changed, 762 insertions(+), 2 deletions(-)
>  create mode 100644 qapi-schema-guest.json
>  create mode 100644 qga/guest-agent-commands.c
> 
> diff --git a/Makefile b/Makefile
> index b2e8593..f98e127 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -175,15 +175,26 @@ $(qapi-dir)/test-qmp-commands.h: 
> $(qapi-dir)/test-qmp-marshal.c
>  $(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json 
> $(SRC_PATH)/scripts/qapi-commands.py
>   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
> "$(qapi-dir)" -p "test-" < $<, "  GEN   $@")
>  
> +$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
> +$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json 
> $(SRC_PATH)/scripts/qapi-types.py
> + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o 
> "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
> +$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
> +$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json 
> $(SRC_PATH)/scripts/qapi-visit.py
> + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o 
> "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
> +$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json 
> $(SRC_PATH)/scripts/qapi-commands.py
> + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
> "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
> +
>  test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
> test-qapi-types.h test-qapi-visit.c test-qapi-visit.h)
>  test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o 
> qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
> json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o 
> $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
>  
>  test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
> test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
> test-qmp-commands.h)
>  test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
> qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
> qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
> qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
> $(qapi-dir)/test-qmp-marshal.o module.o
>  
> -QGALIB=qga/guest-agent-command-state.o
> +QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
> +
> +qemu-ga.o: $(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h 
> $(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qmp-marshal.c
>  
> -qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
> $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) 
> $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o 
> qapi/qmp-dispatch.o qapi/qmp-registry.o
> +qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
> $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) 
> $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o 
> qapi/qmp-dispatch.o qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o 
> $(qapi-dir)/qga-qapi-types.o $(qapi-dir)/qga-qmp-marshal.o
>  
>  QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
>  
> diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
> new file mode 100644
> index 000..a18d6f8
> --- /dev/null
> +++ b/qapi-schema-guest.json
> @@ -0,0 +1,217 @@
> +# *-*- Mode: Python -*-*
> +
> +##
> +# @guest-sync:
> +#
> +# Echo back a unique integer value
> +#
> +# This is used by clients talking to the guest agent over the
> +# wire to ensure the stream is in sync and doesn't contain stale
> +# data from previous clie

[Qemu-devel] [RFC][PATCH 1/9] block: Add bdrv_co_readv/writev

2011-07-15 Thread Kevin Wolf
Add new block driver callbacks bdrv_co_readv/writev, which work on a
QEMUIOVector like bdrv_aio_*, but don't need a callback. The function may only
be called inside a coroutine, so a block driver implementing this interface can
yield instead of blocking during I/O.

Signed-off-by: Kevin Wolf 
---
 Makefile.objs |2 +-
 block.c   |   46 ++
 block.h   |5 +
 block_int.h   |6 ++
 trace-events  |2 ++
 5 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/Makefile.objs b/Makefile.objs
index d9ade62..170a656 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -25,6 +25,7 @@ coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o 
async.o
 block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o 
qemu-sockets.o
+block-obj-y += $(coroutine-obj-y)
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
@@ -79,7 +80,6 @@ common-obj-y += readline.o console.o cursor.o qemu-error.o
 common-obj-y += $(oslib-obj-y)
 common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
-common-obj-y += $(coroutine-obj-y)
 
 common-obj-y += tcg-runtime.o host-utils.o
 common-obj-y += irq.o ioport.o input.o
diff --git a/block.c b/block.c
index 24a25d5..a57d168 100644
--- a/block.c
+++ b/block.c
@@ -1121,6 +1121,52 @@ int bdrv_write_sync(BlockDriverState *bs, int64_t 
sector_num,
 buf, BDRV_SECTOR_SIZE * nb_sectors);
 }
 
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+int nb_sectors, QEMUIOVector *qiov)
+{
+BlockDriver *drv = bs->drv;
+
+trace_bdrv_co_readv(bs, sector_num, nb_sectors);
+
+if (!drv) {
+return -ENOMEDIUM;
+}
+if (bdrv_check_request(bs, sector_num, nb_sectors)) {
+return -EIO;
+}
+
+return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+}
+
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+int nb_sectors, QEMUIOVector *qiov)
+{
+BlockDriver *drv = bs->drv;
+
+trace_bdrv_co_writev(bs, sector_num, nb_sectors);
+
+if (!bs->drv) {
+return -ENOMEDIUM;
+}
+if (bs->read_only) {
+return -EACCES;
+}
+if (bdrv_check_request(bs, sector_num, nb_sectors)) {
+return -EIO;
+}
+
+if (bs->dirty_bitmap) {
+set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
+}
+
+if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
+bs->wr_highest_sector = sector_num + nb_sectors - 1;
+}
+
+return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
+}
+
+
 /**
  * Truncate file to 'offset' bytes (needed only for file protocols)
  */
diff --git a/block.h b/block.h
index 859d1d9..413dd4b 100644
--- a/block.h
+++ b/block.h
@@ -4,6 +4,7 @@
 #include "qemu-aio.h"
 #include "qemu-common.h"
 #include "qemu-option.h"
+#include "qemu-coroutine.h"
 #include "qobject.h"
 
 /* block.c */
@@ -87,6 +88,10 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
 const void *buf, int count);
 int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num,
 const uint8_t *buf, int nb_sectors);
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
+int nb_sectors, QEMUIOVector *qiov);
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+int nb_sectors, QEMUIOVector *qiov);
 int bdrv_truncate(BlockDriverState *bs, int64_t offset);
 int64_t bdrv_getlength(BlockDriverState *bs);
 void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
diff --git a/block_int.h b/block_int.h
index 1e265d2..6fe6369 100644
--- a/block_int.h
+++ b/block_int.h
@@ -27,6 +27,7 @@
 #include "block.h"
 #include "qemu-option.h"
 #include "qemu-queue.h"
+#include "qemu-coroutine.h"
 
 #define BLOCK_FLAG_ENCRYPT 1
 #define BLOCK_FLAG_COMPAT6 4
@@ -76,6 +77,11 @@ struct BlockDriver {
 int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
 int nb_sectors);
 
+int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+
 int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
 int num_reqs);
 int (*bdrv_merge_requests)(BlockDriverState *bs, BlockRequest* a,
diff --git a/trace-events b/trace-events
index ebe4df9..3cd9118 100644
--- a/trace-events
+++ b/trace-events
@@ -55,6 +55,8 @@ disable bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque 
%p"
 disable bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void 
*opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 disable bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void 
*opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 disabl

[Qemu-devel] [RFC][PATCH 8/9] coroutines: Use one global bottom half for CoQueue

2011-07-15 Thread Kevin Wolf
Now that AsyncContexts don't exist any more, we can use one global bottom half
for restarting coroutines instead of allocating a new one every time (before
removing AsyncContexts, the problem with having a global BH was that it had to
belong to a single AsyncContexts and wouldn't be executed in a different one -
which leads to deadlocks)

Signed-off-by: Kevin Wolf 
---
 qemu-coroutine-lock.c |   19 ++-
 1 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index abaa1f7..a80f437 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -30,14 +30,10 @@
 
 static QTAILQ_HEAD(, Coroutine) unlock_bh_queue =
 QTAILQ_HEAD_INITIALIZER(unlock_bh_queue);
-
-struct unlock_bh {
-QEMUBH *bh;
-};
+static QEMUBH* unlock_bh;
 
 static void qemu_co_queue_next_bh(void *opaque)
 {
-struct unlock_bh *unlock_bh = opaque;
 Coroutine *next;
 
 trace_qemu_co_queue_next_bh();
@@ -45,14 +41,15 @@ static void qemu_co_queue_next_bh(void *opaque)
 QTAILQ_REMOVE(&unlock_bh_queue, next, co_queue_next);
 qemu_coroutine_enter(next, NULL);
 }
-
-qemu_bh_delete(unlock_bh->bh);
-qemu_free(unlock_bh);
 }
 
 void qemu_co_queue_init(CoQueue *queue)
 {
 QTAILQ_INIT(&queue->entries);
+
+if (!unlock_bh) {
+unlock_bh = qemu_bh_new(qemu_co_queue_next_bh, NULL);
+}
 }
 
 void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
@@ -65,7 +62,6 @@ void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
 
 bool qemu_co_queue_next(CoQueue *queue)
 {
-struct unlock_bh *unlock_bh;
 Coroutine *next;
 
 next = QTAILQ_FIRST(&queue->entries);
@@ -73,10 +69,7 @@ bool qemu_co_queue_next(CoQueue *queue)
 QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
 QTAILQ_INSERT_TAIL(&unlock_bh_queue, next, co_queue_next);
 trace_qemu_co_queue_next(next);
-
-unlock_bh = qemu_malloc(sizeof(*unlock_bh));
-unlock_bh->bh = qemu_bh_new(qemu_co_queue_next_bh, unlock_bh);
-qemu_bh_schedule(unlock_bh->bh);
+qemu_bh_schedule(unlock_bh);
 }
 
 return (next != NULL);
-- 
1.7.6




[Qemu-devel] [RFC][PATCH 4/9] coroutines: Locks

2011-07-15 Thread Kevin Wolf
Signed-off-by: Kevin Wolf 
---
 Makefile.objs |2 +-
 qemu-coroutine-int.h  |1 +
 qemu-coroutine-lock.c |  124 +
 qemu-coroutine.h  |   62 
 trace-events  |8 +++
 5 files changed, 196 insertions(+), 1 deletions(-)
 create mode 100644 qemu-coroutine-lock.c

diff --git a/Makefile.objs b/Makefile.objs
index 170a656..9d838dd 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -12,7 +12,7 @@ oslib-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
 
 ###
 # coroutines
-coroutine-obj-y = qemu-coroutine.o
+coroutine-obj-y = qemu-coroutine.o qemu-coroutine-lock.o
 ifeq ($(CONFIG_UCONTEXT_COROUTINE),y)
 coroutine-obj-$(CONFIG_POSIX) += coroutine-ucontext.o
 else
diff --git a/qemu-coroutine-int.h b/qemu-coroutine-int.h
index 64915c2..d495615 100644
--- a/qemu-coroutine-int.h
+++ b/qemu-coroutine-int.h
@@ -38,6 +38,7 @@ struct Coroutine {
 void *entry_arg;
 Coroutine *caller;
 QLIST_ENTRY(Coroutine) pool_next;
+QTAILQ_ENTRY(Coroutine) co_queue_next;
 };
 
 Coroutine *qemu_coroutine_new(void);
diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
new file mode 100644
index 000..abaa1f7
--- /dev/null
+++ b/qemu-coroutine-lock.c
@@ -0,0 +1,124 @@
+/*
+ * coroutine queues and locks
+ *
+ * Copyright (c) 2011 Kevin Wolf 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "qemu-coroutine.h"
+#include "qemu-coroutine-int.h"
+#include "qemu-queue.h"
+#include "trace.h"
+
+static QTAILQ_HEAD(, Coroutine) unlock_bh_queue =
+QTAILQ_HEAD_INITIALIZER(unlock_bh_queue);
+
+struct unlock_bh {
+QEMUBH *bh;
+};
+
+static void qemu_co_queue_next_bh(void *opaque)
+{
+struct unlock_bh *unlock_bh = opaque;
+Coroutine *next;
+
+trace_qemu_co_queue_next_bh();
+while ((next = QTAILQ_FIRST(&unlock_bh_queue))) {
+QTAILQ_REMOVE(&unlock_bh_queue, next, co_queue_next);
+qemu_coroutine_enter(next, NULL);
+}
+
+qemu_bh_delete(unlock_bh->bh);
+qemu_free(unlock_bh);
+}
+
+void qemu_co_queue_init(CoQueue *queue)
+{
+QTAILQ_INIT(&queue->entries);
+}
+
+void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
+{
+Coroutine *self = qemu_coroutine_self();
+QTAILQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
+qemu_coroutine_yield();
+assert(qemu_in_coroutine());
+}
+
+bool qemu_co_queue_next(CoQueue *queue)
+{
+struct unlock_bh *unlock_bh;
+Coroutine *next;
+
+next = QTAILQ_FIRST(&queue->entries);
+if (next) {
+QTAILQ_REMOVE(&queue->entries, next, co_queue_next);
+QTAILQ_INSERT_TAIL(&unlock_bh_queue, next, co_queue_next);
+trace_qemu_co_queue_next(next);
+
+unlock_bh = qemu_malloc(sizeof(*unlock_bh));
+unlock_bh->bh = qemu_bh_new(qemu_co_queue_next_bh, unlock_bh);
+qemu_bh_schedule(unlock_bh->bh);
+}
+
+return (next != NULL);
+}
+
+bool qemu_co_queue_empty(CoQueue *queue)
+{
+return (QTAILQ_FIRST(&queue->entries) == NULL);
+}
+
+void qemu_co_mutex_init(CoMutex *mutex)
+{
+memset(mutex, 0, sizeof(*mutex));
+qemu_co_queue_init(&mutex->queue);
+}
+
+void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex)
+{
+Coroutine *self = qemu_coroutine_self();
+
+trace_qemu_co_mutex_lock_entry(mutex, self);
+
+while (mutex->locked) {
+qemu_co_queue_wait(&mutex->queue);
+}
+
+mutex->locked = true;
+
+trace_qemu_co_mutex_lock_return(mutex, self);
+}
+
+void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex)
+{
+Coroutine *self = qemu_coroutine_self();
+
+trace_qemu_co_mutex_unlock_entry(mutex, self);
+
+assert(mutex->locked == true);
+assert(qemu_in_coroutine());
+
+mutex->locked = false;
+qemu_co_queue_next(&mutex->queue);
+
+trace_qemu_co_mutex_unlock_return(mutex, self);
+}
diff --git a/qemu-corout

[Qemu-devel] [RFC][PATCH 0/9] Use coroutines in the block layer

2011-07-15 Thread Kevin Wolf
Based on Stefan's latest coroutine patches. This series makes qcow and qcow2
take advantage of the new coroutine infrastructure. Both formats used
synchronous operations for accessing their metadata and blocked the guest CPU
during that time. With coroutines, the I/O will happen asynchronously in the
background and the CPU won't be blocked any more.

Kevin Wolf (9):
  block: Add bdrv_co_readv/writev
  block: Emulate AIO functions with bdrv_co_readv/writev
  block: Add bdrv_co_readv/writev emulation
  coroutines: Locks
  qcow2: Use coroutines
  qcow: Use coroutines
  async: Remove AsyncContext
  coroutines: Use one global bottom half for CoQueue
  block: Use bdrv_co_* instead of synchronous versions in coroutines

 Makefile.objs |4 +-
 async.c   |   98 ++-
 block.c   |  271 ++--
 block.h   |5 +
 block/qcow.c  |  180 +++-
 block/qcow2-cluster.c |   26 ++---
 block/qcow2.c |  240 
 block/qcow2.h |5 +-
 block/qed-table.c |   14 ---
 block/qed.c   |4 -
 block_int.h   |6 +
 linux-aio.c   |   24 +
 posix-aio-compat.c|   11 --
 qemu-common.h |4 -
 qemu-coroutine-int.h  |1 +
 qemu-coroutine-lock.c |  117 +
 qemu-coroutine.h  |   62 +++
 trace-events  |   11 ++
 18 files changed, 636 insertions(+), 447 deletions(-)
 create mode 100644 qemu-coroutine-lock.c

-- 
1.7.6




Re: [Qemu-devel] [PATCH] v6 revamp acpitable parsing and allow to specify complete (headerful) table

2011-07-15 Thread Blue Swirl
On Fri, Jul 15, 2011 at 6:18 PM, John Baboval
 wrote:
> Is there something I can do to help take this patch the rest of the way?
>
> I'd hate to see it die because of a style issue and a compiler warning.

There's also suspicious missing 'break' statement. How about fixing
the issues and submitting the patch?

> -John
>
> On 06/15/2011 02:19 PM, Blue Swirl wrote:
>>
>> On Sat, Jun 11, 2011 at 1:29 AM, Michael Tokarev  wrote:
>>>
>>> I've given up on this one.  Personally I don't need
>>> this stuff for my win7 guests since I can hack either
>>> bios or the O/S loader to include all the necessary
>>> verifications for the win7 activation to work.  I
>>> tried to make this process to be legal (no hacks
>>> or "cracks" needed) and easy for others, but since
>>> noone is interested in this after 6 versions and 5
>>> resends, I wont continue - what I am trying to achieve
>>> by pushing this so hard, after all?
>>>
>>> Thanks to everyone who gave (mostly code style) comments -
>>> at least I know the changes has been read by someone.
>>>
>>> Frustrated,
>>
>> Sorry about that. I get this error:
>> /src/qemu/hw/acpi.c: In function 'acpi_table_add':
>> /src/qemu/hw/acpi.c:167: error: format '%u' expects type 'unsigned
>> int', but argument 4 has type 'size_t'
>>
>>>  /mjt
>>>
>>> 12.05.2011 18:44, Michael Tokarev wrote:

 This patch almost rewrites acpi_table_add() function
 (but still leaves it using old get_param_value() interface).
 The result is that it's now possible to specify whole table
 (together with a header) in an external file, instead of just
 data portion, with a new file= parameter, but at the same time
 it's still possible to specify header fields as before.

 Now with the checkpatch.pl formatting fixes, thanks to
 Stefan Hajnoczi for suggestions, with changes from
 Isaku Yamahata, and with my further refinements.

 v5: rediffed against current qemu/master.
 v6: fix one "} else {" coding style defect (noted by Blue Swirl)

 Signed-off-by: Michael Tokarev
 ---
  hw/acpi.c       |  292
 ---
  qemu-options.hx |    7 +-
  2 files changed, 175 insertions(+), 124 deletions(-)

 diff --git a/hw/acpi.c b/hw/acpi.c
 index ad40fb4..4316189 100644
 --- a/hw/acpi.c
 +++ b/hw/acpi.c
 @@ -22,17 +22,29 @@

  struct acpi_table_header
  {
 -    char signature [4];    /* ACPI signature (4 ASCII characters) */
 +    uint16_t _length;         /* our length, not actual part of the hdr
 */
 +                              /* XXX why we have 2 length fields here?
 */
 +    char sig[4];              /* ACPI signature (4 ASCII characters) */
      uint32_t length;          /* Length of table, in bytes, including
 header */
      uint8_t revision;         /* ACPI Specification minor version # */
      uint8_t checksum;         /* To make sum of entire table == 0 */
 -    char oem_id [6];       /* OEM identification */
 -    char oem_table_id [8]; /* OEM table identification */
 +    char oem_id[6];           /* OEM identification */
 +    char oem_table_id[8];     /* OEM table identification */
      uint32_t oem_revision;    /* OEM revision number */
 -    char asl_compiler_id [4]; /* ASL compiler vendor ID */
 +    char asl_compiler_id[4];  /* ASL compiler vendor ID */
      uint32_t asl_compiler_revision; /* ASL compiler revision number */
  } __attribute__((packed));

 +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
 +#define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra
 prefix */
 +
 +static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] =
 +    "\0\0"                   /* fake _length (2) */
 +    "QEMU\0\0\0\0\1\0"       /* sig (4), len(4), revno (1), csum (1) */
 +    "QEMUQEQEMUQEMU\1\0\0\0" /* OEM id (6), table (8), revno (4) */
 +    "QEMU\1\0\0\0"           /* ASL compiler ID (4), version (4) */
 +    ;
 +
  char *acpi_tables;
  size_t acpi_tables_len;

 @@ -45,158 +57,192 @@ static int acpi_checksum(const uint8_t *data, int
 len)
      return (-sum)&  0xff;
  }

 +/* like strncpy() but zero-fills the tail of destination */
 +static void strzcpy(char *dst, const char *src, size_t size)
 +{
 +    size_t len = strlen(src);
 +    if (len>= size) {
 +        len = size;
 +    } else {
 +      memset(dst + len, 0, size - len);
 +    }
 +    memcpy(dst, src, len);
 +}
 +
 +/* XXX fixme: this function uses obsolete argument parsing interface */
  int acpi_table_add(const char *t)
  {
 -    static const char *dfl_id = "QEMUQEMU";
      char buf[1024], *p, *f;
 -    struct acpi_table_header acpi_hdr;
      unsigned long val;
 -    uint32_t length;
 -    struct acpi_table_header *acpi_hdr_p;
 

[Qemu-devel] [RFC][PATCH 5/9] qcow2: Use coroutines

2011-07-15 Thread Kevin Wolf
Signed-off-by: Kevin Wolf 
---
 block/qcow2-cluster.c |   26 +++---
 block/qcow2.c |  240 ++---
 block/qcow2.h |5 +-
 3 files changed, 102 insertions(+), 169 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 882f50a..81cf77d 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -697,12 +697,12 @@ err:
  * m->depends_on is set to NULL and the other fields in m are meaningless.
  *
  * If the cluster is newly allocated, m->nb_clusters is set to the number of
- * contiguous clusters that have been allocated. This may be 0 if the request
- * conflict with another write request in flight; in this case, m->depends_on
- * is set and the remaining fields of m are meaningless.
+ * contiguous clusters that have been allocated. In this case, the other
+ * fields of m are valid and contain information about the first allocated
+ * cluster.
  *
- * If m->nb_clusters is non-zero, the other fields of m are valid and contain
- * information about the first allocated cluster.
+ * If the request conflicts with another write request in flight, the coroutine
+ * is queued and will be reentered when the dependency has completed.
  *
  * Return 0 on success and -errno in error cases
  */
@@ -721,6 +721,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, 
uint64_t offset,
 return ret;
 }
 
+again:
 nb_clusters = size_to_clusters(s, n_end << 9);
 
 nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
@@ -792,12 +793,12 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, 
uint64_t offset,
 }
 
 if (nb_clusters == 0) {
-/* Set dependency and wait for a callback */
-m->depends_on = old_alloc;
-m->nb_clusters = 0;
-*num = 0;
-
-goto out_wait_dependency;
+/* Wait for the dependency to complete. We need to recheck
+ * the free/allocated clusters when we continue. */
+qemu_co_mutex_unlock(&s->lock);
+qemu_co_queue_wait(&old_alloc->dependent_requests);
+qemu_co_mutex_lock(&s->lock);
+goto again;
 }
 }
 }
@@ -834,9 +835,6 @@ out:
 
 return 0;
 
-out_wait_dependency:
-return qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
-
 fail:
 qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
 fail_put:
diff --git a/block/qcow2.c b/block/qcow2.c
index 48e1b95..f07d550 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -276,6 +276,9 @@ static int qcow2_open(BlockDriverState *bs, int flags)
 goto fail;
 }
 
+/* Initialise locks */
+qemu_co_mutex_init(&s->lock);
+
 #ifdef DEBUG_ALLOC
 qcow2_check_refcounts(bs);
 #endif
@@ -379,7 +382,6 @@ typedef struct QCowAIOCB {
 uint64_t cluster_offset;
 uint8_t *cluster_data;
 bool is_write;
-BlockDriverAIOCB *hd_aiocb;
 QEMUIOVector hd_qiov;
 QEMUBH *bh;
 QCowL2Meta l2meta;
@@ -389,8 +391,6 @@ typedef struct QCowAIOCB {
 static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
 {
 QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-if (acb->hd_aiocb)
-bdrv_aio_cancel(acb->hd_aiocb);
 qemu_aio_release(acb);
 }
 
@@ -399,46 +399,16 @@ static AIOPool qcow2_aio_pool = {
 .cancel = qcow2_aio_cancel,
 };
 
-static void qcow2_aio_read_cb(void *opaque, int ret);
-static void qcow2_aio_write_cb(void *opaque, int ret);
-
-static void qcow2_aio_rw_bh(void *opaque)
-{
-QCowAIOCB *acb = opaque;
-qemu_bh_delete(acb->bh);
-acb->bh = NULL;
-
-if (acb->is_write) {
-qcow2_aio_write_cb(opaque, 0);
-} else {
-qcow2_aio_read_cb(opaque, 0);
-}
-}
-
-static int qcow2_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb)
-{
-if (acb->bh)
-return -EIO;
-
-acb->bh = qemu_bh_new(cb, acb);
-if (!acb->bh)
-return -EIO;
-
-qemu_bh_schedule(acb->bh);
-
-return 0;
-}
-
-static void qcow2_aio_read_cb(void *opaque, int ret)
+/*
+ * Returns 0 when the request is completed successfully, 1 when there is still
+ * a part left to do and -errno in error cases.
+ */
+static int qcow2_aio_read_cb(QCowAIOCB *acb)
 {
-QCowAIOCB *acb = opaque;
 BlockDriverState *bs = acb->common.bs;
 BDRVQcowState *s = bs->opaque;
 int index_in_cluster, n1;
-
-acb->hd_aiocb = NULL;
-if (ret < 0)
-goto done;
+int ret;
 
 /* post process the read buffer */
 if (!acb->cluster_offset) {
@@ -463,8 +433,7 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
 
 if (acb->remaining_sectors == 0) {
 /* request completed */
-ret = 0;
-goto done;
+return 0;
 }
 
 /* prepare next AIO request */
@@ -477,7 +446,7 @@ static void qcow2_aio_read_cb(void *opaque, int ret)
 ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
 &acb->cur_nr_sect

[Qemu-devel] [RFC][PATCH 2/9] block: Emulate AIO functions with bdrv_co_readv/writev

2011-07-15 Thread Kevin Wolf
Use the bdrv_co_readv/writev callbacks to implement bdrv_aio_readv/writev and
bdrv_read/write if a driver provides the coroutine version instead of the
synchronous or AIO version.

Signed-off-by: Kevin Wolf 
---
 block.c |   98 ++-
 1 files changed, 97 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index a57d168..79a5008 100644
--- a/block.c
+++ b/block.c
@@ -28,6 +28,7 @@
 #include "block_int.h"
 #include "module.h"
 #include "qemu-objects.h"
+#include "qemu-coroutine.h"
 
 #ifdef CONFIG_BSD
 #include 
@@ -57,6 +58,12 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t 
sector_num,
 uint8_t *buf, int nb_sectors);
 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
  const uint8_t *buf, int nb_sectors);
+static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
+int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+BlockDriverCompletionFunc *cb, void *opaque);
+static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
+int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+BlockDriverCompletionFunc *cb, void *opaque);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -169,7 +176,13 @@ void path_combine(char *dest, int dest_size,
 
 void bdrv_register(BlockDriver *bdrv)
 {
-if (!bdrv->bdrv_aio_readv) {
+if (bdrv->bdrv_co_readv) {
+/* Emulate AIO by coroutines, and sync by AIO */
+bdrv->bdrv_aio_readv = bdrv_co_aio_readv_em;
+bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em;
+bdrv->bdrv_read = bdrv_read_em;
+bdrv->bdrv_write = bdrv_write_em;
+ } else if (!bdrv->bdrv_aio_readv) {
 /* add AIO emulation layer */
 bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
 bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
@@ -2607,6 +2620,89 @@ static BlockDriverAIOCB 
*bdrv_aio_writev_em(BlockDriverState *bs,
 return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
 }
 
+
+typedef struct BlockDriverAIOCBCoroutine {
+BlockDriverAIOCB common;
+BlockRequest req;
+bool is_write;
+QEMUBH* bh;
+} BlockDriverAIOCBCoroutine;
+
+static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
+{
+qemu_aio_flush();
+}
+
+static AIOPool bdrv_em_co_aio_pool = {
+.aiocb_size = sizeof(BlockDriverAIOCBCoroutine),
+.cancel = bdrv_aio_co_cancel_em,
+};
+
+static void bdrv_co_rw_bh(void *opaque)
+{
+BlockDriverAIOCBCoroutine *acb = opaque;
+
+acb->common.cb(acb->common.opaque, acb->req.error);
+qemu_bh_delete(acb->bh);
+qemu_aio_release(acb);
+}
+
+static void coroutine_fn bdrv_co_rw(void *opaque)
+{
+BlockDriverAIOCBCoroutine *acb = opaque;
+BlockDriverState *bs = acb->common.bs;
+
+if (acb->is_write) {
+acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector,
+acb->req.nb_sectors, acb->req.qiov);
+} else {
+acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector,
+acb->req.nb_sectors, acb->req.qiov);
+}
+
+acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
+qemu_bh_schedule(acb->bh);
+}
+
+static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+   int64_t sector_num,
+   QEMUIOVector *qiov,
+   int nb_sectors,
+   BlockDriverCompletionFunc *cb,
+   void *opaque,
+   bool is_write)
+{
+Coroutine *co;
+BlockDriverAIOCBCoroutine *acb;
+
+acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
+acb->req.sector = sector_num;
+acb->req.nb_sectors = nb_sectors;
+acb->req.qiov = qiov;
+acb->is_write = is_write;
+
+co = qemu_coroutine_create(bdrv_co_rw);
+qemu_coroutine_enter(co, acb);
+
+return &acb->common;
+}
+
+static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
+int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+BlockDriverCompletionFunc *cb, void *opaque)
+{
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
+ false);
+}
+
+static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
+int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
+BlockDriverCompletionFunc *cb, void *opaque)
+{
+return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
+ true);
+}
+
 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
 BlockDriverCompletionFunc *cb, void *opaque)
 {
-- 
1.7.6




[Qemu-devel] [RFC][PATCH 6/9] qcow: Use coroutines

2011-07-15 Thread Kevin Wolf
The old qcow format is another user of the AsyncContext infrastructure.
Converting it to coroutines (and therefore CoMutexes) allows to remove
AsyncContexts.

Signed-off-by: Kevin Wolf 
---
 block/qcow.c |  180 --
 1 files changed, 62 insertions(+), 118 deletions(-)

diff --git a/block/qcow.c b/block/qcow.c
index 227b104..6f7973c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -73,6 +73,7 @@ typedef struct BDRVQcowState {
 uint32_t crypt_method_header;
 AES_KEY aes_encrypt_key;
 AES_KEY aes_decrypt_key;
+CoMutex lock;
 } BDRVQcowState;
 
 static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
@@ -517,11 +518,11 @@ static AIOPool qcow_aio_pool = {
 
 static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
 int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-BlockDriverCompletionFunc *cb, void *opaque, int is_write)
+int is_write)
 {
 QCowAIOCB *acb;
 
-acb = qemu_aio_get(&qcow_aio_pool, bs, cb, opaque);
+acb = qemu_aio_get(&qcow_aio_pool, bs, NULL, NULL);
 if (!acb)
 return NULL;
 acb->hd_aiocb = NULL;
@@ -542,48 +543,15 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
 return acb;
 }
 
-static void qcow_aio_read_cb(void *opaque, int ret);
-static void qcow_aio_write_cb(void *opaque, int ret);
-
-static void qcow_aio_rw_bh(void *opaque)
-{
-QCowAIOCB *acb = opaque;
-qemu_bh_delete(acb->bh);
-acb->bh = NULL;
-
-if (acb->is_write) {
-qcow_aio_write_cb(opaque, 0);
-} else {
-qcow_aio_read_cb(opaque, 0);
-}
-}
-
-static int qcow_schedule_bh(QEMUBHFunc *cb, QCowAIOCB *acb)
-{
-if (acb->bh) {
-return -EIO;
-}
-
-acb->bh = qemu_bh_new(cb, acb);
-if (!acb->bh) {
-return -EIO;
-}
-
-qemu_bh_schedule(acb->bh);
-
-return 0;
-}
-
-static void qcow_aio_read_cb(void *opaque, int ret)
+static int qcow_aio_read_cb(void *opaque)
 {
 QCowAIOCB *acb = opaque;
 BlockDriverState *bs = acb->common.bs;
 BDRVQcowState *s = bs->opaque;
 int index_in_cluster;
+int ret;
 
 acb->hd_aiocb = NULL;
-if (ret < 0)
-goto done;
 
  redo:
 /* post process the read buffer */
@@ -605,8 +573,8 @@ static void qcow_aio_read_cb(void *opaque, int ret)
 
 if (acb->nb_sectors == 0) {
 /* request completed */
-ret = 0;
-goto done;
+qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
+return 0;
 }
 
 /* prepare next AIO request */
@@ -623,11 +591,12 @@ static void qcow_aio_read_cb(void *opaque, int ret)
 acb->hd_iov.iov_base = (void *)acb->buf;
 acb->hd_iov.iov_len = acb->n * 512;
 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-acb->hd_aiocb = bdrv_aio_readv(bs->backing_hd, acb->sector_num,
-&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
-if (acb->hd_aiocb == NULL) {
-ret = -EIO;
-goto done;
+qemu_co_mutex_unlock(&s->lock);
+ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
+acb->n, &acb->hd_qiov);
+qemu_co_mutex_lock(&s->lock);
+if (ret < 0) {
+return -EIO;
 }
 } else {
 /* Note: in this case, no need to wait */
@@ -637,64 +606,55 @@ static void qcow_aio_read_cb(void *opaque, int ret)
 } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
 /* add AIO support for compressed blocks ? */
 if (decompress_cluster(bs, acb->cluster_offset) < 0) {
-ret = -EIO;
-goto done;
+return -EIO;
 }
 memcpy(acb->buf,
s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
 goto redo;
 } else {
 if ((acb->cluster_offset & 511) != 0) {
-ret = -EIO;
-goto done;
+return -EIO;
 }
 acb->hd_iov.iov_base = (void *)acb->buf;
 acb->hd_iov.iov_len = acb->n * 512;
 qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-acb->hd_aiocb = bdrv_aio_readv(bs->file,
+qemu_co_mutex_unlock(&s->lock);
+ret = bdrv_co_readv(bs->file,
 (acb->cluster_offset >> 9) + index_in_cluster,
-&acb->hd_qiov, acb->n, qcow_aio_read_cb, acb);
-if (acb->hd_aiocb == NULL) {
-ret = -EIO;
-goto done;
+acb->n, &acb->hd_qiov);
+qemu_co_mutex_lock(&s->lock);
+if (ret < 0) {
+return ret;
 }
 }
 
-return;
-
-done:
-if (acb->qiov->niov > 1) {
-qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
-qemu_vfree(acb->orig_buf);
-}
-acb->common.cb(acb->common.opaque, ret);
-qemu_aio_release(acb);
+return 1;
 }
 
-stati

Re: [Qemu-devel] [PATCH v7 4/4] guest agent: add guest agent RPCs/commands

2011-07-15 Thread Michael Roth

On 07/15/2011 11:23 AM, Luiz Capitulino wrote:

On Thu, 14 Jul 2011 15:00:34 -0500
Michael Roth  wrote:


This adds the initial set of QMP/QAPI commands provided by the guest
agent:

guest-sync
guest-ping
guest-info
guest-shutdown
guest-file-open
guest-file-read
guest-file-write
guest-file-seek
guest-file-flush
guest-file-close
guest-fsfreeze-freeze
guest-fsfreeze-thaw
guest-fsfreeze-status

The input/output specification for these commands are documented in the
schema.

Example usage:

   host:
 qemu -device virtio-serial \
  -chardev socket,path=/tmp/vs0.sock,server,nowait,id=qga0 \
  -device virtserialport,chardev=qga0,name=org.qemu.quest_agent.0
  ...

 echo "{'execute':'guest-info'}" | socat stdio unix-connect:/tmp/qga0.sock

   guest:
 qemu-ga -m virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent.0 \
 -p /var/run/qemu-guest-agent.pid -d

Signed-off-by: Michael Roth
---
  Makefile   |   15 ++-
  qapi-schema-guest.json |  217 +++
  qemu-ga.c  |4 +
  qerror.c   |8 +
  qerror.h   |6 +
  qga/guest-agent-commands.c |  512 
  qga/guest-agent-core.h |2 +
  7 files changed, 762 insertions(+), 2 deletions(-)
  create mode 100644 qapi-schema-guest.json
  create mode 100644 qga/guest-agent-commands.c

diff --git a/Makefile b/Makefile
index b2e8593..f98e127 100644
--- a/Makefile
+++ b/Makefile
@@ -175,15 +175,26 @@ $(qapi-dir)/test-qmp-commands.h: 
$(qapi-dir)/test-qmp-marshal.c
  $(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json 
$(SRC_PATH)/scripts/qapi-commands.py
$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p 
"test-"<  $<, "  GEN   $@")

+$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
+$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-types.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p 
"qga-"<  $<, "  GEN   $@")
+$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
+$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-visit.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p 
"qga-"<  $<, "  GEN   $@")
+$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json 
$(SRC_PATH)/scripts/qapi-commands.py
+   $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p 
"qga-"<  $<, "  GEN   $@")
+
  test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h 
test-qapi-visit.c test-qapi-visit.h)
  test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o 
qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o 
$(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o

  test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
test-qmp-commands.h)
  test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
$(qapi-dir)/test-qmp-marshal.o module.o

-QGALIB=qga/guest-agent-command-state.o
+QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
+
+qemu-ga.o: $(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h 
$(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qmp-marshal.c

-qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
$(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
$(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o 
qapi/qmp-registry.o
+qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
$(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) 
$(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o 
qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o $(qapi-dir)/qga-qapi-types.o 
$(qapi-dir)/qga-qmp-marshal.o

  QEMULIBS=libhw32 libhw64 libuser libdis libdis-user

diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
new file mode 100644
index 000..a18d6f8
--- /dev/null
+++ b/qapi-schema-guest.json
@@ -0,0 +1,217 @@
+# *-*- Mode: Python -*-*
+
+##
+# @guest-sync:
+#
+# Echo back a unique integer value
+#
+# This is used by clients talking to the guest agent over the
+# wire to ensure the stream is in sync and doesn't contain stale
+# data from previous client. All guest agent responses should be
+# ignored until the provided unique integer value is returned,
+# and it is up to the client to handle stale whole or
+# partially-d

[Qemu-devel] [RFC][PATCH 9/9] block: Use bdrv_co_* instead of synchronous versions in coroutines

2011-07-15 Thread Kevin Wolf
If we're already in a coroutine, there is no reason to use the synchronous
version of block layer functions when a coroutine one exists. This makes
bdrv_read/write/flush use bdrv_co_* when used inside a coroutine.

Signed-off-by: Kevin Wolf 
---
 block.c |   43 +++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 18d1197..a4990b4 100644
--- a/block.c
+++ b/block.c
@@ -70,6 +70,7 @@ static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
 static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
  int64_t sector_num, int nb_sectors,
  QEMUIOVector *iov);
+static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
 QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -950,6 +951,17 @@ int bdrv_read(BlockDriverState *bs, int64_t sector_num,
 {
 BlockDriver *drv = bs->drv;
 
+if (qemu_in_coroutine()) {
+QEMUIOVector qiov;
+struct iovec iov = {
+.iov_base = (void *)buf,
+.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+};
+
+qemu_iovec_init_external(&qiov, &iov, 1);
+return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
+}
+
 if (!drv)
 return -ENOMEDIUM;
 if (bdrv_check_request(bs, sector_num, nb_sectors))
@@ -996,6 +1008,18 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
const uint8_t *buf, int nb_sectors)
 {
 BlockDriver *drv = bs->drv;
+
+if (qemu_in_coroutine()) {
+QEMUIOVector qiov;
+struct iovec iov = {
+.iov_base = (void *)buf,
+.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+};
+
+qemu_iovec_init_external(&qiov, &iov, 1);
+return bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
+}
+
 if (!bs->drv)
 return -ENOMEDIUM;
 if (bs->read_only)
@@ -1642,6 +1666,10 @@ int bdrv_flush(BlockDriverState *bs)
 return 0;
 }
 
+if (qemu_in_coroutine()) {
+return bdrv_co_flush_em(bs);
+}
+
 if (bs->drv && bs->drv->bdrv_flush) {
 return bs->drv->bdrv_flush(bs);
 }
@@ -2910,6 +2938,21 @@ static int coroutine_fn 
bdrv_co_writev_em(BlockDriverState *bs,
 return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
 }
 
+static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
+{
+CoroutineIOCompletion co = {
+.coroutine = qemu_coroutine_self(),
+};
+BlockDriverAIOCB *acb;
+
+acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
+if (!acb) {
+return -EIO;
+}
+qemu_coroutine_yield();
+return co.ret;
+}
+
 /**/
 /* removable device support */
 
-- 
1.7.6




[Qemu-devel] [RFC][PATCH 7/9] async: Remove AsyncContext

2011-07-15 Thread Kevin Wolf
The purpose of AsyncContexts was to protect qcow and qcow2 against reentrancy
during an emulated bdrv_read/write (which includes a qemu_aio_wait() call and
can run AIO callbacks of different requests if it weren't for AsyncContexts).

Now both qcow and qcow2 are protected by CoMutexes and AsyncContexts can be
removed.

Signed-off-by: Kevin Wolf 
---
 async.c|   98 
 block.c|6 ---
 block/qed-table.c  |   14 ---
 block/qed.c|4 --
 linux-aio.c|   24 +
 posix-aio-compat.c |   11 --
 qemu-common.h  |4 --
 7 files changed, 9 insertions(+), 152 deletions(-)

diff --git a/async.c b/async.c
index fd313df..3fe70b9 100644
--- a/async.c
+++ b/async.c
@@ -25,92 +25,8 @@
 #include "qemu-common.h"
 #include "qemu-aio.h"
 
-/*
- * An AsyncContext protects the callbacks of AIO requests and Bottom Halves
- * against interfering with each other. A typical example is qcow2 that accepts
- * asynchronous requests, but relies for manipulation of its metadata on
- * synchronous bdrv_read/write that doesn't trigger any callbacks.
- *
- * However, these functions are often emulated using AIO which means that AIO
- * callbacks must be run - but at the same time we must not run callbacks of
- * other requests as they might start to modify metadata and corrupt the
- * internal state of the caller of bdrv_read/write.
- *
- * To achieve the desired semantics we switch into a new AsyncContext.
- * Callbacks must only be run if they belong to the current AsyncContext.
- * Otherwise they need to be queued until their own context is active again.
- * This is how you can make qemu_aio_wait() wait only for your own callbacks.
- *
- * The AsyncContexts form a stack. When you leave a AsyncContexts, you always
- * return to the old ("parent") context.
- */
-struct AsyncContext {
-/* Consecutive number of the AsyncContext (position in the stack) */
-int id;
-
-/* Anchor of the list of Bottom Halves belonging to the context */
-struct QEMUBH *first_bh;
-
-/* Link to parent context */
-struct AsyncContext *parent;
-};
-
-/* The currently active AsyncContext */
-static struct AsyncContext *async_context = &(struct AsyncContext) { 0 };
-
-/*
- * Enter a new AsyncContext. Already scheduled Bottom Halves and AIO callbacks
- * won't be called until this context is left again.
- */
-void async_context_push(void)
-{
-struct AsyncContext *new = qemu_mallocz(sizeof(*new));
-new->parent = async_context;
-new->id = async_context->id + 1;
-async_context = new;
-}
-
-/* Run queued AIO completions and destroy Bottom Half */
-static void bh_run_aio_completions(void *opaque)
-{
-QEMUBH **bh = opaque;
-qemu_bh_delete(*bh);
-qemu_free(bh);
-qemu_aio_process_queue();
-}
-/*
- * Leave the currently active AsyncContext. All Bottom Halves belonging to the
- * old context are executed before changing the context.
- */
-void async_context_pop(void)
-{
-struct AsyncContext *old = async_context;
-QEMUBH **bh;
-
-/* Flush the bottom halves, we don't want to lose them */
-while (qemu_bh_poll());
-
-/* Switch back to the parent context */
-async_context = async_context->parent;
-qemu_free(old);
-
-if (async_context == NULL) {
-abort();
-}
-
-/* Schedule BH to run any queued AIO completions as soon as possible */
-bh = qemu_malloc(sizeof(*bh));
-*bh = qemu_bh_new(bh_run_aio_completions, bh);
-qemu_bh_schedule(*bh);
-}
-
-/*
- * Returns the ID of the currently active AsyncContext
- */
-int get_async_context_id(void)
-{
-return async_context->id;
-}
+/* Anchor of the list of Bottom Halves belonging to the context */
+static struct QEMUBH *first_bh;
 
 /***/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -130,8 +46,8 @@ QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
 bh = qemu_mallocz(sizeof(QEMUBH));
 bh->cb = cb;
 bh->opaque = opaque;
-bh->next = async_context->first_bh;
-async_context->first_bh = bh;
+bh->next = first_bh;
+first_bh = bh;
 return bh;
 }
 
@@ -141,7 +57,7 @@ int qemu_bh_poll(void)
 int ret;
 
 ret = 0;
-for (bh = async_context->first_bh; bh; bh = next) {
+for (bh = first_bh; bh; bh = next) {
 next = bh->next;
 if (!bh->deleted && bh->scheduled) {
 bh->scheduled = 0;
@@ -153,7 +69,7 @@ int qemu_bh_poll(void)
 }
 
 /* remove deleted bhs */
-bhp = &async_context->first_bh;
+bhp = &first_bh;
 while (*bhp) {
 bh = *bhp;
 if (bh->deleted) {
@@ -199,7 +115,7 @@ void qemu_bh_update_timeout(int *timeout)
 {
 QEMUBH *bh;
 
-for (bh = async_context->first_bh; bh; bh = bh->next) {
+for (bh = first_bh; bh; bh = bh->next) {
 if (!bh->deleted && bh->scheduled) {
 if (bh->idle) {
 /* idle bottom halves

Re: [Qemu-devel] [PATCH 4/5] xen: Fix the memory registration to reflect of what is done by Xen.

2011-07-15 Thread Stefano Stabellini
On Fri, 15 Jul 2011, Anthony PERARD wrote:
> A Xen guest memory is allocated by libxc. But this memory is not
> allocated continuously, instead, it leaves the VGA IO memory space not
> allocated, same for the MMIO space (at HVM_BELOW_4G_MMIO_START of size
> HVM_BELOW_4G_MMIO_LENGTH).
> 
> So to reflect that, we do not register the physical memory for this two
> holes. But we still keep only one RAMBlock for the all RAM as it is more
> easier than have two separate blocks (1 above 4G). Also this prevent QEMU
> from use the MMIO space for a ROM.
> 
> Signed-off-by: Anthony PERARD 
> ---
>  xen-all.c |   21 ++---
>  1 files changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/xen-all.c b/xen-all.c
> index 2c0a62d..76d5c5c 100644
> --- a/xen-all.c
> +++ b/xen-all.c
> @@ -144,6 +144,12 @@ static void xen_ram_init(ram_addr_t ram_size)
>  new_block->host = NULL;
>  new_block->offset = 0;
>  new_block->length = ram_size;
> +if (ram_size >= HVM_BELOW_4G_RAM_END) {
> +/* Xen does not allocate the memory continuously, and keep a hole at
> + * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH
> + */
> +new_block->length += HVM_BELOW_4G_MMIO_LENGTH;
> +}
>  
>  QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
>  
> @@ -152,20 +158,21 @@ static void xen_ram_init(ram_addr_t ram_size)
>  memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
> 0xff, new_block->length >> TARGET_PAGE_BITS);
>  
> -if (ram_size >= 0xe000 ) {
> -above_4g_mem_size = ram_size - 0xe000;
> -below_4g_mem_size = 0xe000;
> +if (ram_size >= HVM_BELOW_4G_RAM_END) {
> +above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END;
> +below_4g_mem_size = HVM_BELOW_4G_RAM_END;
>  } else {
>  below_4g_mem_size = ram_size;
>  }
>  
> -cpu_register_physical_memory(0, below_4g_mem_size, new_block->offset);
> -#if TARGET_PHYS_ADDR_BITS > 32
> +cpu_register_physical_memory(0, 0xa, 0);
> +/* Skip of the VGA IO memory space */
> +cpu_register_physical_memory(0xc, below_4g_mem_size - 0xc,
> + 0xc);
 
Shouldn't we avoid registering any memory for the whole video ram area?
I mean:

0xa - 0x10





Re: [Qemu-devel] [PATCH 0/5] Enable QEMU to handle more than 2GB with Xen.

2011-07-15 Thread Stefano Stabellini
On Fri, 15 Jul 2011, Anthony PERARD wrote:
> Hi all,
> 
> Xen is not limited by the QEMU's virtual address space for the allocation of
> the guest RAM. So even with a QEMU 32bits, a Xen guest can have more than 4 GB
> of RAM.
> 
> With this serie, we will be able to run a guest with more than 4GB. The main
> point is to change ram_addr_t from ulong to uin64 when QEMU is configure with
> Xen. The second point is better register the memory in QEMU.
> 
> Regards,
> 
> 
> Anthony PERARD (5):
>   xen: Fix xen_enabled().
>   exec.c: Use ram_addr_t in cpu_physical_memory_rw(...).
>   cpu-common: Have a ram_addr_t of uint64 with Xen.
>   xen: Fix the memory registration to reflect of what is done by Xen.
>   vl.c: Check the asked ram_size later.
> 
>  cpu-common.h |8 
>  exec.c   |   13 +++--
>  hw/xen.h |2 +-
>  vl.c |   14 --
>  xen-all.c|   23 +++
>  5 files changed, 39 insertions(+), 21 deletions(-)
 
All the patches look good to me, just a comment on the 4th patch.



Re: [Qemu-devel] Wiki spam

2011-07-15 Thread Stefan Weil

Am 04.07.2011 10:05, schrieb Stefan Hajnoczi:

On Mon, Jul 4, 2011 at 8:27 AM, Brad Hards  wrote:

On Mon, 4 Jul 2011 03:15:06 PM Stefan Hajnoczi wrote:

Thanks.  I have a regular wiki account so I checked the Recent Changes
page and undid the spam changes that I saw:

http://wiki.qemu.org/Special:RecentChanges

Is there a way to completely remove it? There is still spam on the wiki
showing at:
http://wiki.qemu.org/index.php?title=Special:DeadendPages&limit=500&offset=0

I'd prefer not to have it in the history at all if thats possible.


Only an administrator can delete pages:

http://www.mediawiki.org/wiki/Help:Deleting_a_page

Stefan


Wiki spammers are still very active on qemu.org (see
http://wiki.qemu.org/Special:RecentChanges).

The QEMU wiki needs more technical protection against spam
and also more administrators who can remove spam pages
(I can't, so I simply emptied the pages I just found).

Cheers,
Stefan Weil




Re: [Qemu-devel] [Xen-devel] Re: [PATCH 4/5] xen: Fix the memory registration to reflect of what is done by Xen.

2011-07-15 Thread Anthony PERARD
On Fri, Jul 15, 2011 at 18:05, Stefano Stabellini
 wrote:
> Shouldn't we avoid registering any memory for the whole video ram area?
> I mean:
>
> 0xa - 0x10

No, because SeaBIOS load the Options ROM (VGA Bios, PXE) to the area
between 0xc and 0x10, and this go through QEMU.

The area between 0xa and 0xc is registred later by the
cirrus_vga bits, as IO.

-- 
Anthony PERARD



Re: [Qemu-devel] [PATCH v7 4/4] guest agent: add guest agent RPCs/commands

2011-07-15 Thread Luiz Capitulino
On Fri, 15 Jul 2011 12:21:55 -0500
Michael Roth  wrote:

> On 07/15/2011 11:23 AM, Luiz Capitulino wrote:
> > On Thu, 14 Jul 2011 15:00:34 -0500
> > Michael Roth  wrote:
> >
> >> This adds the initial set of QMP/QAPI commands provided by the guest
> >> agent:
> >>
> >> guest-sync
> >> guest-ping
> >> guest-info
> >> guest-shutdown
> >> guest-file-open
> >> guest-file-read
> >> guest-file-write
> >> guest-file-seek
> >> guest-file-flush
> >> guest-file-close
> >> guest-fsfreeze-freeze
> >> guest-fsfreeze-thaw
> >> guest-fsfreeze-status
> >>
> >> The input/output specification for these commands are documented in the
> >> schema.
> >>
> >> Example usage:
> >>
> >>host:
> >>  qemu -device virtio-serial \
> >>   -chardev socket,path=/tmp/vs0.sock,server,nowait,id=qga0 \
> >>   -device virtserialport,chardev=qga0,name=org.qemu.quest_agent.0
> >>   ...
> >>
> >>  echo "{'execute':'guest-info'}" | socat stdio 
> >> unix-connect:/tmp/qga0.sock
> >>
> >>guest:
> >>  qemu-ga -m virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent.0 \
> >>  -p /var/run/qemu-guest-agent.pid -d
> >>
> >> Signed-off-by: Michael Roth
> >> ---
> >>   Makefile   |   15 ++-
> >>   qapi-schema-guest.json |  217 +++
> >>   qemu-ga.c  |4 +
> >>   qerror.c   |8 +
> >>   qerror.h   |6 +
> >>   qga/guest-agent-commands.c |  512 
> >> 
> >>   qga/guest-agent-core.h |2 +
> >>   7 files changed, 762 insertions(+), 2 deletions(-)
> >>   create mode 100644 qapi-schema-guest.json
> >>   create mode 100644 qga/guest-agent-commands.c
> >>
> >> diff --git a/Makefile b/Makefile
> >> index b2e8593..f98e127 100644
> >> --- a/Makefile
> >> +++ b/Makefile
> >> @@ -175,15 +175,26 @@ $(qapi-dir)/test-qmp-commands.h: 
> >> $(qapi-dir)/test-qmp-marshal.c
> >>   $(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json 
> >> $(SRC_PATH)/scripts/qapi-commands.py
> >>$(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
> >> "$(qapi-dir)" -p "test-"<  $<, "  GEN   $@")
> >>
> >> +$(qapi-dir)/qga-qapi-types.c: $(qapi-dir)/qga-qapi-types.h
> >> +$(qapi-dir)/qga-qapi-types.h: $(SRC_PATH)/qapi-schema-guest.json 
> >> $(SRC_PATH)/scripts/qapi-types.py
> >> +  $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o 
> >> "$(qapi-dir)" -p "qga-"<  $<, "  GEN   $@")
> >> +$(qapi-dir)/qga-qapi-visit.c: $(qapi-dir)/qga-qapi-visit.h
> >> +$(qapi-dir)/qga-qapi-visit.h: $(SRC_PATH)/qapi-schema-guest.json 
> >> $(SRC_PATH)/scripts/qapi-visit.py
> >> +  $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o 
> >> "$(qapi-dir)" -p "qga-"<  $<, "  GEN   $@")
> >> +$(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json 
> >> $(SRC_PATH)/scripts/qapi-commands.py
> >> +  $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o 
> >> "$(qapi-dir)" -p "qga-"<  $<, "  GEN   $@")
> >> +
> >>   test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
> >> test-qapi-types.h test-qapi-visit.c test-qapi-visit.h)
> >>   test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o 
> >> qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o 
> >> json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
> >> qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
> >>
> >>   test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c 
> >> test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c 
> >> test-qmp-commands.h)
> >>   test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o 
> >> qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) 
> >> qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o 
> >> qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o 
> >> $(qapi-dir)/test-qmp-marshal.o module.o
> >>
> >> -QGALIB=qga/guest-agent-command-state.o
> >> +QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
> >> +
> >> +qemu-ga.o: $(qapi-dir)/qga-qapi-types.c $(qapi-dir)/qga-qapi-types.h 
> >> $(qapi-dir)/qga-qapi-visit.c $(qapi-dir)/qga-qmp-marshal.c
> >>
> >> -qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
> >> $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) 
> >> $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o 
> >> qapi/qmp-dispatch.o qapi/qmp-registry.o
> >> +qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o 
> >> $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) 
> >> $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o 
> >> qapi/qmp-dispatch.o qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o 
> >> $(qapi-dir)/qga-qapi-types.o $(qapi-dir)/qga-qmp-marshal.o
> >>
> >>   QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
> >>
> >>

Re: [Qemu-devel] [PATCHv2 0/3] ds1225y: qdev-ification (used in MIPS Jazz)

2011-07-15 Thread Hervé Poussineau

Ping ?

Hervé Poussineau a écrit :

This patchset qdev-ifies the ds1225y device, used in MIPS Jazz emulation.

Changes since v1:
- rebased
- split into multiple patches as per Markus advice

Hervé Poussineau (3):
  ds1225y: Remove protection stuff, which doesn't belong to this device
  ds1225y: use trace framework
  ds1225y: convert to qdev device, and use it in MIPS Jazz emulation

 hw/ds1225y.c   |  152 ---
 hw/mips.h  |4 --
 hw/mips_jazz.c |   11 +++-
 trace-events   |4 ++
 4 files changed, 90 insertions(+), 81 deletions(-)

  





[Qemu-devel] [RELEASE] LTTng-UST 0.15 (Qemu support & tutorial)

2011-07-15 Thread Mathieu Desnoyers
LTTng-UST, the Linux Trace Toolkit Next Generation Userspace Tracer, is
port of the low-overhead tracing capabilities of the LTTng kernel tracer
to user-space. The library "libust" enables tracing of applications and
libraries.

Changelog:

* Add backward compability for tracepoint API (still planned
  for deprecation, but should make the transition smoother).
  The API transition will happen when UST 2.0 is ready. There is no
  point in making multiple API breakage when unneeded.

tracing qemu-kvm with UST is now working again with UST 0.15 (0.14 did
break it).

Project website: http://lttng.org/ust/
Download link: http://lttng.org/files/ust/releases/
(please refer to the UST Manual for installation instructions)

A quick walkthrough for tracing kvm-qemu with UST:

git clone git://git.lttng.org/userspace-rcu.git
(install: see README)
git clone git://git.lttng.org/ust.git
(install: see README)

In my case, I enabled qemu_malloc, qemu_realloc, qemu_free,
qemu_memalign, qemu_vmalloc, qemu_vfree by editing the "trace-events"
file in the toplevel source directory (this file is qemu-specific, not
the usual interface UST provides):

# qemu-malloc.c
qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
qemu_free(void *ptr) "ptr %p"

# osdep.c
qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu 
ptr %p"
qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
qemu_vfree(void *ptr) "ptr %p"


./configure --enable-trace-backend=ust
make

ldd x86_64-softmmu/qemu-system-x86_64
...
   libust.so.0 => /usr/local/lib/libust.so.0 (0x7fa39fc74000)
(it's linked with libust)

usttrace x86_64-softmmu/qemu-system-x86_64
...
stop it (ctrl-c)

See resulting trace in:
$HOME/.usttraces/hostname-timestamp

UST 0.15 traces can be viewed with lttv: git clone git://git.lttng.org/lttv.git
(install: view README)

To view the trace (e.g.):

% lttv -m textDump -t % 
/home/compudj/.usttraces/ok-20110715144748823020811/32575_5629652727107472206
...
ust.qemu_free: 1552840.525993542 
(/home/compudj/.usttraces/ok-20110715144748823020811/32575_5629652727107472206/ust_6),
 0, 0, , , 0, 0x0, MODE_UNKNOWN { ptr = 0x1187680 }
ust.qemu_free: 1552840.525994061 
(/home/compudj/.usttraces/ok-20110715144748823020811/32575_5629652727107472206/ust_6),
 0, 0, , , 0, 0x0, MODE_UNKNOWN { ptr = 0x1187660 }


-- 
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com



[Qemu-devel] [PATCH 2/3] w64: Add definition of FMT_pid

2011-07-15 Thread Stefan Weil
For mingw-w64, pid_t is _pid_t which is __int64,
so this platform needs its own definition of FMT_pid.

Signed-off-by: Stefan Weil 
---
 osdep.h |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/osdep.h b/osdep.h
index a817017..252d050 100644
--- a/osdep.h
+++ b/osdep.h
@@ -130,6 +130,8 @@ int qemu_madvise(void *addr, size_t len, int advice);
 
 #if defined(__HAIKU__) && defined(__i386__)
 #define FMT_pid "%ld"
+#elif defined(WIN64)
+#define FMT_pid "%" PRId64
 #else
 #define FMT_pid "%d"
 #endif
-- 
1.7.2.5




[Qemu-devel] [PATCH 3/3] w32: Fix format string regression

2011-07-15 Thread Stefan Weil
Commit 953ffe0f935f40c0d6061d69e76e0339393b54f8
introduced FMT_pid which is wrong for w32 and w64 getpid():
those getpid() implementations always return an int value.

Signed-off-by: Stefan Weil 
---
 os-win32.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/os-win32.c b/os-win32.c
index b6652af..e153058 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -258,7 +258,7 @@ int qemu_create_pidfile(const char *filename)
 if (file == INVALID_HANDLE_VALUE) {
 return -1;
 }
-len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid());
+len = snprintf(buffer, sizeof(buffer), "%d\n", getpid());
 ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
  &overlap, NULL);
 if (ret == 0) {
-- 
1.7.2.5




[Qemu-devel] New patches for w32, w64

2011-07-15 Thread Stefan Weil
Here are some small patches needed for the w32 and w64 platforms.

[PATCH 1/3] Fix conversions from pointer to tcg_target_long
[PATCH 2/3] w64: Add definition of FMT_pid
[PATCH 3/3] w32: Fix format string regression

Kind regards,
Stefan



[Qemu-devel] [PATCH 1/3] Fix conversions from pointer to tcg_target_long

2011-07-15 Thread Stefan Weil
tcg_gen_exit_tb takes a parameter of type tcg_target_long,
so the type casts of pointer to long should be replaced by
type casts of pointer to tcg_target_long.

These changes are needed for build environments where
sizeof(long) != sizeof(void *), especially for w64.

See 4b4a72e55660abf7efe85aca78762dcfea5519ad which fixed the
same issue for the other targets.

Cc: Alexander Graf 
Cc: Guan Xuetao 
Signed-off-by: Stefan Weil 
---
 target-s390x/translate.c |2 +-
 target-unicore32/translate.c |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 77fb448..6a22fde 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -830,7 +830,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, 
target_ulong pc)
 /* jump to same page: we can use a direct jump */
 tcg_gen_goto_tb(tb_num);
 tcg_gen_movi_i64(psw_addr, pc);
-tcg_gen_exit_tb((long)tb + tb_num);
+tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
 } else {
 /* jump to another page: currently not optimized */
 tcg_gen_movi_i64(psw_addr, pc);
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index a15e42d..4ecb0f1 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1056,7 +1056,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, 
uint32_t dest)
 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
 tcg_gen_goto_tb(n);
 gen_set_pc_im(dest);
-tcg_gen_exit_tb((long)tb + n);
+tcg_gen_exit_tb((tcg_target_long)tb + n);
 } else {
 gen_set_pc_im(dest);
 tcg_gen_exit_tb(0);
-- 
1.7.2.5




Re: [Qemu-devel] [PATCH] Avoid CPU endian memory accesses in devices

2011-07-15 Thread Blue Swirl
On Fri, Jul 15, 2011 at 12:56 AM, Alexander Graf  wrote:
>
>
>
>
> Am 14.07.2011 um 21:34 schrieb Blue Swirl :
>
>> Don't compile virtio.c in hwlib, it depends on memory accesses
>> performed in CPU endianness.
>>
>> Make loads and stores in CPU endianness unavailable to devices
>> and poison them to avoid further bugs.
>
> Very nice :). Couldn't test execute it, but:
>
> Acked-by: Alexander Graf 

By the way, another way would be to change virtio to always use LE
accesses. This would need changes to KVM on PPC and s390x. Would that
be possible?



Re: [Qemu-devel] [PATCH 2/3] w64: Add definition of FMT_pid

2011-07-15 Thread Andreas Färber

Am 15.07.2011 um 21:38 schrieb Stefan Weil:


For mingw-w64, pid_t is _pid_t which is __int64,
so this platform needs its own definition of FMT_pid.

Signed-off-by: Stefan Weil 


Ah, that's probably lld then and thus different from the existing  
definitions.


Reviewed-by: Andreas Färber 

Andreas


---
osdep.h |2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/osdep.h b/osdep.h
index a817017..252d050 100644
--- a/osdep.h
+++ b/osdep.h
@@ -130,6 +130,8 @@ int qemu_madvise(void *addr, size_t len, int  
advice);


#if defined(__HAIKU__) && defined(__i386__)
#define FMT_pid "%ld"
+#elif defined(WIN64)
+#define FMT_pid "%" PRId64
#else
#define FMT_pid "%d"
#endif
--
1.7.2.5





Re: [Qemu-devel] [PATCH 3/3] w32: Fix format string regression

2011-07-15 Thread Andreas Färber

Am 15.07.2011 um 21:38 schrieb Stefan Weil:


Commit 953ffe0f935f40c0d6061d69e76e0339393b54f8
introduced FMT_pid which is wrong for w32 and w64 getpid():
those getpid() implementations always return an int value.


Where is __int64 FMT_pid used then if not for the returned pid?

Andreas



Signed-off-by: Stefan Weil 
---
os-win32.c |2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/os-win32.c b/os-win32.c
index b6652af..e153058 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -258,7 +258,7 @@ int qemu_create_pidfile(const char *filename)
if (file == INVALID_HANDLE_VALUE) {
return -1;
}
-len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid());
+len = snprintf(buffer, sizeof(buffer), "%d\n", getpid());
ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
  &overlap, NULL);
if (ret == 0) {
--
1.7.2.5







Re: [Qemu-devel] [PATCH] Avoid CPU endian memory accesses in devices

2011-07-15 Thread Alexander Graf

On 07/15/2011 10:02 PM, Blue Swirl wrote:

On Fri, Jul 15, 2011 at 12:56 AM, Alexander Graf  wrote:




Am 14.07.2011 um 21:34 schrieb Blue Swirl:


Don't compile virtio.c in hwlib, it depends on memory accesses
performed in CPU endianness.

Make loads and stores in CPU endianness unavailable to devices
and poison them to avoid further bugs.

Very nice :). Couldn't test execute it, but:

Acked-by: Alexander Graf

By the way, another way would be to change virtio to always use LE
accesses. This would need changes to KVM on PPC and s390x. Would that
be possible?


The code is already in Linux for quite a while, other OSs started 
implementing it (Solaris) and the spec is pretty specific on fields 
being in target endianness.


The virtio v2 spec will hopefully fix this, but that should end up in a 
different module then :)



Alex




Re: [Qemu-devel] Wiki spam

2011-07-15 Thread Anthony Liguori

On 07/15/2011 12:24 PM, Stefan Weil wrote:


Wiki spammers are still very active on qemu.org (see
http://wiki.qemu.org/Special:RecentChanges).

The QEMU wiki needs more technical protection against spam
and also more administrators who can remove spam pages
(I can't, so I simply emptied the pages I just found).


There's no simple solution to spam.  Even captcha's are limited as many 
spammers are just using mechanical turks plus OCR to defeat captchas.


recaptcha had some problems recently so I had to disable it on the wiki 
which led to an influx of spam.  It seems to be working fine again so 
I've reenabled it.  Hopefully the spam activity will dramatically drop 
again.


Regards,

Anthony Liguori


Cheers,
Stefan Weil







Re: [Qemu-devel] [PATCH] report serial devices created with -device in the PIIX4 config space

2011-07-15 Thread Andreas Färber

Am 15.07.2011 um 17:10 schrieb Paolo Bonzini:


Serial and parallel devices created with -device are not reported in
the PIIX4 configuration space, and are hence not picked up by the  
DSDT.

This upsets Windows, which hides them altogether from the guest.

To avoid this, check at the end of machine initialization whether the
corresponding I/O ports have been registered.  The new function in
ioport.c does this; this also requires a tweak to isa_unassign_ioport.

I left the comment in piix4_pm_initfn since the registers I moved do
seem to match the 82371AB datasheet.  There are some quirks though.
We are setting this bit:

   "Device 8 EIO Enable (EIO_EN_DEV8)—R/W. 1=Enable PCI access to the
   device 8 enabled I/O ranges to be claimed by PIIX4 and forwarded
   to the ISA/EIO bus. 0=Disable. The LPT_MON_EN must be set to enable
   the decode."

but not LPT_MON_EN (bit 18 at 50h):

   LPT Port Enable (LPT_MON_EN)—R/W. 1=Enable accesses to parallel
   port address range (LPT_DEC_SEL) to generate a device 8 (parallel
   port) decode event. 0=Disable.

We're also setting the LPT_DEC_SEL field (that's the 0x60 written to
63h) to 11, which means reserved, rather than to 01 (378h-37Fh).

Likewise we're not setting SA_MON_EN, SB_MON_EN (respectively bit 14
and bit 16 at address 50h) for the serial ports.  However, we're  
setting
COMA_DEC_SEL and COMB_DEC_SEL correctly, unlike the corresponding  
register

for the parallel port.

All these fields are left as they are, since they are probably only
meant to be used in the DSDT.

Signed-off-by: Paolo Bonzini 
---
hw/acpi_piix4.c |   23 ++-
ioport.c|   19 +--
ioport.h|2 +-
3 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 350558b..03de3ad 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c


@@ -311,6 +313,19 @@ static void piix4_powerdown(void *opaque, int  
irq, int power_failing)

acpi_pm1_evt_power_down(pm1a, tmr);
}

+static void piix4_pm_machine_ready(struct Notifier* n)
+{
+PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready);


DO_UPCAST()? I assume we have it for a reason.


diff --git a/ioport.c b/ioport.c
index 2e971fa..0d2611d 100644
--- a/ioport.c
+++ b/ioport.c
@@ -245,18 +245,25 @@ void isa_unassign_ioport(pio_addr_t start, int  
length)

int i;

for(i = start; i < start + length; i++) {
-ioport_read_table[0][i] = default_ioport_readb;
-ioport_read_table[1][i] = default_ioport_readw;
-ioport_read_table[2][i] = default_ioport_readl;
+ioport_read_table[0][i] = NULL;
+ioport_read_table[1][i] = NULL;
+ioport_read_table[2][i] = NULL;

-ioport_write_table[0][i] = default_ioport_writeb;
-ioport_write_table[1][i] = default_ioport_writew;
-ioport_write_table[2][i] = default_ioport_writel;
+ioport_write_table[0][i] = NULL;
+ioport_write_table[1][i] = NULL;
+ioport_write_table[2][i] = NULL;


Does this make a change as to whether unhandled I/O ports are reported  
in debug mode?


What do you think of Gleb's recent request to convert all ioports to  
IORanges? I briefly looked into it but feared that needlessly using  
uint64_t for all parameters might damage performance on 32-bit hosts.


The ioport changes look okay otherwise.

Andreas


Re: [Qemu-devel] [RFC] New thread for the VM migration

2011-07-15 Thread Anthony Liguori

On 07/15/2011 02:59 AM, Paolo Bonzini wrote:

On 07/14/2011 06:07 PM, Avi Kivity wrote:


Maybe we can do this via a magic subsection whose contents are the
hotplug event.


What about making the device list just another "thing" that has to be
migrated live, together with block and ram?


In an ideal world, you would only create the backends on the destination 
node and all of the devices would be created through the migration process.


Regards,

Anthony Liguori


Paolo






Re: [Qemu-devel] [PATCH v4] hw/pc: Support system flash memory with -pflash parameter

2011-07-15 Thread Jordan Justen
Hi all,

Are there any concerns with this patch?

I haven't heard much feedback, except:
* Jes Sorensen - March 28 - code style
* Aurelien Jarno - April 18 - Reviewed-by

Thanks,

-Jordan

On Fri, Jul 8, 2011 at 12:37, Jordan Justen  wrote:
> If -pflash is specified and -bios is specified then pflash will
> be mapped just below the system rom using hw/pflash_cfi01.c.
>
> If -pflash is specified on the command line, but -bios is
> not specified, then 'bios.bin' will NOT be loaded, and
> instead the -pflash flash image will be mapped just below
> 4GB in place of the normal rom image.
>
> Signed-off-by: Jordan Justen 
> Reviewed-by: Aurelien Jarno 
> ---
>  default-configs/i386-softmmu.mak   |    1 +
>  default-configs/x86_64-softmmu.mak |    1 +
>  hw/pc.c                            |  161 
> +++-
>  3 files changed, 125 insertions(+), 38 deletions(-)
>
> diff --git a/default-configs/i386-softmmu.mak 
> b/default-configs/i386-softmmu.mak
> index 55589fa..8697cd4 100644
> --- a/default-configs/i386-softmmu.mak
> +++ b/default-configs/i386-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>  CONFIG_SOUND=y
>  CONFIG_HPET=y
>  CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/default-configs/x86_64-softmmu.mak 
> b/default-configs/x86_64-softmmu.mak
> index 8895028..eca9284 100644
> --- a/default-configs/x86_64-softmmu.mak
> +++ b/default-configs/x86_64-softmmu.mak
> @@ -21,3 +21,4 @@ CONFIG_PIIX_PCI=y
>  CONFIG_SOUND=y
>  CONFIG_HPET=y
>  CONFIG_APPLESMC=y
> +CONFIG_PFLASH_CFI01=y
> diff --git a/hw/pc.c b/hw/pc.c
> index a3e8539..e25354f 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -41,6 +41,7 @@
>  #include "sysemu.h"
>  #include "blockdev.h"
>  #include "ui/qemu-spice.h"
> +#include "flash.h"
>
>  /* output Bochs bios info messages */
>  //#define DEBUG_BIOS
> @@ -957,70 +958,154 @@ void pc_cpus_init(const char *cpu_model)
>     }
>  }
>
> -void pc_memory_init(const char *kernel_filename,
> -                    const char *kernel_cmdline,
> -                    const char *initrd_filename,
> -                    ram_addr_t below_4g_mem_size,
> -                    ram_addr_t above_4g_mem_size)
> +static void pc_isa_bios_init(ram_addr_t ram_offset, int ram_size)
>  {
> -    char *filename;
> -    int ret, linux_boot, i;
> -    ram_addr_t ram_addr, bios_offset, option_rom_offset;
> -    int bios_size, isa_bios_size;
> -    void *fw_cfg;
> -
> -    linux_boot = (kernel_filename != NULL);
> +    int isa_bios_size;
>
> -    /* allocate RAM */
> -    ram_addr = qemu_ram_alloc(NULL, "pc.ram",
> -                              below_4g_mem_size + above_4g_mem_size);
> -    cpu_register_physical_memory(0, 0xa, ram_addr);
> -    cpu_register_physical_memory(0x10,
> -                 below_4g_mem_size - 0x10,
> -                 ram_addr + 0x10);
> -    if (above_4g_mem_size > 0) {
> -        cpu_register_physical_memory(0x1ULL, above_4g_mem_size,
> -                                     ram_addr + below_4g_mem_size);
> +    /* map the last 128KB of the BIOS in ISA space */
> +    isa_bios_size = ram_size;
> +    if (isa_bios_size > (128 * 1024)) {
> +        isa_bios_size = 128 * 1024;
>     }
> +    ram_offset = ram_offset + ram_size - isa_bios_size;
> +    cpu_register_physical_memory(0x10 - isa_bios_size,
> +                                 isa_bios_size,
> +                                 ram_offset | IO_MEM_ROM);
> +}
> +
> +static int pc_system_rom_init(void)
> +{
> +    int ret;
> +    int bios_size;
> +    ram_addr_t bios_offset;
> +    char *filename;
>
>     /* BIOS load */
> -    if (bios_name == NULL)
> +    if (bios_name == NULL) {
>         bios_name = BIOS_FILENAME;
> +    }
>     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
>     if (filename) {
>         bios_size = get_image_size(filename);
>     } else {
>         bios_size = -1;
>     }
> -    if (bios_size <= 0 ||
> -        (bios_size % 65536) != 0) {
> -        goto bios_error;
> +
> +    if (bios_size <= 0 || (bios_size % 65536) != 0) {
> +        ret = -1;
> +    } else {
> +        bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> +        ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
>     }
> -    bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size);
> -    ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
> +
>     if (ret != 0) {
> -    bios_error:
>         fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
>         exit(1);
>     }
> +
>     if (filename) {
>         qemu_free(filename);
>     }
> -    /* map the last 128KB of the BIOS in ISA space */
> -    isa_bios_size = bios_size;
> -    if (isa_bios_size > (128 * 1024))
> -        isa_bios_size = 128 * 1024;
> -    cpu_register_physical_memory(0x10 - isa_bios_size,
> -                                 isa_bios_size,
> -                                 (bios_offset + bios_size - isa_bios_size) | 
> IO_MEM_ROM);
>
> -    option_rom_offset