Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Michael S. Tsirkin
On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
 * Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
  On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
   I like the idea of disconnect; if part of the device_del method 
   was to
   invoke a disconnect method, we could implement that for block, 
   net, etc;
   
   I'd think we'd want to send the notification, then disconnect.
   Struggling with whether it's worth having some reasonable timeout
   between notification and disconnect.  
  
  The problem with this is that it has no analog in real world.
  In real world, you can send some notifications to the guest, and 
  you can
  remove the card.  Tying them together is what created the problem 
  in the
  first place.
  
  Timeouts can be implemented by management, maybe with a nice dialog
  being shown to the user.
 
 Very true.  I'm fine with forcing a disconnect during the removal path
 prior to notification.  Do we want a new disconnect method at the 
 device
 level (pci)? or just use the existing removal callback and call that
 during the initial hotremov event?

Not sure what you mean by that, but I don't see a device doing anything
differently wrt surprise or ordered removal. So probably the existing
callback should do. I don't think we need to talk about disconnect:
since we decided we are emulating device removal, let's call it
just that.
   
   Because current the removal process depends on the guest actually
   responding.  What I'm suggesting is that, in Marcus's term, and what
   drive_unplug() implements, is to disconnect the host block device from
   the guest device to prevent any further access to it in the case the
   guest doesn't respond to the removal request made via ACPI.
   
   Very specifically, what we're suggesting instead of the drive_unplug()
   command so to complete the device removal operation without waiting for
   the guest to respond; that's what's going to happen if we invoke the
   response callback; it will appear as if the guest responded whether it
   did or not.
   
   What I was suggesting above was to instead of calling the callback for
   handing the guest response was to add a device function called
   disconnect which would remove any association of host resources from
   guest resources before we notified the guest.  Thinking about it again
   I'm not sure this is useful, but if we're going to remove the device
   without the guests knowledge, I'm not sure how useful sending the
   removal requests via ACPI is in the first place.
   
   My feeling is that I'd like to have explicit control over the disconnect
   from host resources separate from the device removal *if* we're going to
   retain the guest notification.  If we don't care to notify the guest,
   then we can just do device removal without notifying the guest
   and be done with it.
  
  I imagine management would typically want to do this:
  1. notify guest
  2. wait a bit
  3. remove device
 
 Yes; but this argues for (1) being a separate command from (3)

Yes. Long term I think we will want a way to do that.

 unless we
 require (3) to include (1) and (2) in the qemu implementation.
 
 Currently we implement:
 
 1. device_del (attempt to remove device)
 2. notify guest
 3. if guest responds, remove device
 4. disconnect host resource from device on destruction
 
 With my drive_unplug patch we do:
 
 1. disconnect host resource from device

This is what drive_unplug does, right?

 2. device_del (attempt to remove device)
 3. notify guest
 4. if guest responds, remove device
 
 I think we're suggesting to instead do (if we keep disconnect as part of
 device_del)
 
 1. device_del (attemp to remove device)
 2. notify guest
 3. invoke device destruction callback resulting in disconnect host resource 
 from device
 4. if guest responds, invoke device destruction path a second time.

By response you mean eject?  No, this is not what I was suggesting.
I was really suggesting that your patch is fine :)
Sorry about confusion.

I was also saying that from what I hear, the pci express support
will at some point need interfaces to
- notify guest about device removal/addition
- get eject from guest
- remove device without talking to guest
- add device without talking to guest
- suppress device deletion on eject

All this can be generic and can work through express
configuration mechanisms or through acpi for pci.
But this is completely separate from unplugging
the host backend, which should be possible at any point.

 
 -- 
 Ryan Harper
 Software Engineer; Linux Technology Center
 IBM Corp., Austin, Tx
 ry...@us.ibm.com



[Qemu-devel] Re: [PATCH v7 2/6] pcie/aer: helper functions for pcie aer capability

2010-11-03 Thread Michael S. Tsirkin
On Wed, Nov 03, 2010 at 10:24:30AM +0900, Isaku Yamahata wrote:
 On Tue, Nov 02, 2010 at 02:57:12PM +0200, Michael S. Tsirkin wrote:
   +static void pcie_aer_clear_error(PCIDevice *dev);
   +static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg);
   +
  
  so what exactly is the order of calls that makes
  removing the forward declarations impractical?
  Is there a recursive call? If yes I'd like to
  see it documented much better.
 
 Why do you think forward declaration is so bad?
 I don't see any such consensus and I don't think they aren't
 accused generally like goto.
 Can you please elaborate why you're trying so hard to prevent it?

Well no, I do not claim they are that bad. In my opinion avoiding them
just makes for a slightly better code usually:
- They make for code duplication where if you change
  a function there's another place to edit.
- Just generally add more code.
- Avoiding forward declarations makes you put functions
  in some sensible order.
- Also makes you avoid recursion where a loop will do.
But all this doesn't always apply. I was trying to understand
whether there's recursion here that I am missing.
If there is a comment might be helpful.

 -- 
 yamahata



[Qemu-devel] MSI broken?

2010-11-03 Thread Gerd Hoffmann

 Hi,

What is the status if the recently merged MSI support?

I'm trying to use it to add msi support to the intel-hda driver (current 
wip patch attached).  Everything works fine up to the point where it 
comes to delivering the interrupt to the guest.  msi_notify pretends to 
signal the guest:


msi_notify:243 intel-hda:30 notify vector 0x0 address: 0xfee01008 data: 
0x4151


The guest never ever receives this interrupt though:

[r...@localhost ~]# grep hda /proc/interrupts
 43:  0   PCI-MSI-edge  hda_intel

Ideas anyone?

thanks,
  Gerd

From b2ca133855b78e5b6cfc3e52220769a031485939 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann kra...@redhat.com
Date: Wed, 3 Nov 2010 10:14:48 +0100
Subject: [PATCH] intel-hda: msi support [wip]

---
 hw/intel-hda.c |   30 --
 1 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 126cf54..63cccbe 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -19,6 +19,7 @@
 
 #include hw.h
 #include pci.h
+#include msi.h
 #include qemu-timer.h
 #include audiodev.h
 #include intel-hda.h
@@ -188,6 +189,7 @@ struct IntelHDAState {
 
 /* properties */
 uint32_t debug;
+uint32_t msi;
 };
 
 struct IntelHDAReg {
@@ -268,6 +270,7 @@ static void intel_hda_update_int_sts(IntelHDAState *d)
 
 static void intel_hda_update_irq(IntelHDAState *d)
 {
+int msi = d-msi  msi_enabled(d-pci);
 int level;
 
 intel_hda_update_int_sts(d);
@@ -276,8 +279,15 @@ static void intel_hda_update_irq(IntelHDAState *d)
 } else {
 level = 0;
 }
-dprint(d, 2, %s: level %d\n, __FUNCTION__, level);
-qemu_set_irq(d-pci.irq[0], level);
+dprint(d, 2, %s: level %d [%s]\n, __FUNCTION__,
+   level, msi ? msi : intx);
+if (msi) {
+if (level) {
+msi_notify(d-pci, 0);
+}
+} else {
+qemu_set_irq(d-pci.irq[0], level);
+}
 }
 
 static int intel_hda_send_command(IntelHDAState *d, uint32_t verb)
@@ -1132,6 +1142,8 @@ static int intel_hda_init(PCIDevice *pci)
   intel_hda_mmio_write, d);
 pci_register_bar(d-pci, 0, 0x4000, PCI_BASE_ADDRESS_SPACE_MEMORY,
  intel_hda_map);
+if (d-msi)
+msi_init(d-pci, 0, 1, true, false);
 
 hda_codec_bus_init(d-pci.qdev, d-codecs,
intel_hda_response, intel_hda_xfer);
@@ -1143,10 +1155,22 @@ static int intel_hda_exit(PCIDevice *pci)
 {
 IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
 
+if (d-msi)
+msi_uninit(d-pci);
 cpu_unregister_io_memory(d-mmio_addr);
 return 0;
 }
 
+static void intel_hda_write_config(PCIDevice *pci, uint32_t addr,
+   uint32_t val, int len)
+{
+IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
+
+pci_default_write_config(pci, addr, val, len);
+if (d-msi)
+msi_write_config(pci, addr, val, len);
+}
+
 static int intel_hda_post_load(void *opaque, int version)
 {
 IntelHDAState* d = opaque;
@@ -1230,8 +1254,10 @@ static PCIDeviceInfo intel_hda_info = {
 .qdev.reset   = intel_hda_reset,
 .init = intel_hda_init,
 .exit = intel_hda_exit,
+.config_write = intel_hda_write_config,
 .qdev.props   = (Property[]) {
 DEFINE_PROP_UINT32(debug, IntelHDAState, debug, 0),
+DEFINE_PROP_UINT32(msi, IntelHDAState, msi, 0),
 DEFINE_PROP_END_OF_LIST(),
 }
 };
-- 
1.7.1



[Qemu-devel] [PATCH RESEND] Fixed default IRQ assignment for PL190 VIC.

2010-11-03 Thread Himanshu Chauhan
Everywhere else vect_addr[16] is returned on a read of default vector address
but updation is done only on default_addr in structure.

Signed-off-by: Himanshu Chauhan hschau...@nulltrace.org
---
 hw/pl190.c |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/hw/pl190.c b/hw/pl190.c
index a4bc9c1..7363b87 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -187,6 +187,7 @@ static void pl190_write(void *opaque, target_phys_addr_t 
offset, uint32_t val)
 break;
 case 13: /* DEFVECTADDR */
 s-default_addr = val;
+s-vect_addr[16] = val;
 break;
 case 0xc0: /* ITCR */
 if (val) {
-- 
1.7.0.4


- End forwarded message -



[Qemu-devel] [PATCH v2] spice: add audio

2010-11-03 Thread Gerd Hoffmann
Add support for the spice audio interface.  With this patch applied
audio can be forwarded over the network from/to the spice client.  Both
recording and playback is supported.

The driver is first in the driver list, but the can_be_default flag is
set only in case spice is active.  So if you have the spice protocol
enabled the spice audio driver is the default one, otherwise whatever
comes first after spice in the list.  Overriding the default using
QEMU_AUDIO_DRV works in any case.

[ v2: audio codestyle: add spaces before open parenthesis ]
[ v2: add const to silence array ]

Signed-off-by: Gerd Hoffmann kra...@redhat.com
Cc: malc av1...@comtv.ru
---
 Makefile.objs  |1 +
 audio/audio.c  |3 +
 audio/audio_int.h  |1 +
 audio/spiceaudio.c |  327 
 ui/qemu-spice.h|1 +
 ui/spice-core.c|1 +
 6 files changed, 334 insertions(+), 0 deletions(-)
 create mode 100644 audio/spiceaudio.c

diff --git a/Makefile.objs b/Makefile.objs
index faf485e..15569af 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -102,6 +102,7 @@ common-obj-$(CONFIG_SPICE) += ui/spice-core.o 
ui/spice-input.o ui/spice-display.
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
 audio-obj-$(CONFIG_OSS) += ossaudio.o
+audio-obj-$(CONFIG_SPICE) += spiceaudio.o
 audio-obj-$(CONFIG_COREAUDIO) += coreaudio.o
 audio-obj-$(CONFIG_ALSA) += alsaaudio.o
 audio-obj-$(CONFIG_DSOUND) += dsoundaudio.o
diff --git a/audio/audio.c b/audio/audio.c
index ad51077..ade342e 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -44,6 +44,9 @@
 that we generate the list.
 */
 static struct audio_driver *drvtab[] = {
+#ifdef CONFIG_SPICE
+spice_audio_driver,
+#endif
 CONFIG_AUDIO_DRIVERS
 no_audio_driver,
 wav_audio_driver
diff --git a/audio/audio_int.h b/audio/audio_int.h
index d8560b6..d66f2c3 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -209,6 +209,7 @@ extern struct audio_driver coreaudio_audio_driver;
 extern struct audio_driver dsound_audio_driver;
 extern struct audio_driver esd_audio_driver;
 extern struct audio_driver pa_audio_driver;
+extern struct audio_driver spice_audio_driver;
 extern struct audio_driver winwave_audio_driver;
 extern struct mixeng_volume nominal_volume;
 
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
new file mode 100644
index 000..51ba53a
--- /dev/null
+++ b/audio/spiceaudio.c
@@ -0,0 +1,327 @@
+#include hw/hw.h
+#include qemu-timer.h
+#include ui/qemu-spice.h
+
+#define AUDIO_CAP spice
+#include audio.h
+#include audio_int.h
+
+#define LINE_IN_SAMPLES 1024
+#define LINE_OUT_SAMPLES 1024
+
+typedef struct SpiceRateCtl {
+int64_t   start_ticks;
+int64_t   bytes_sent;
+} SpiceRateCtl;
+
+typedef struct SpiceVoiceOut {
+HWVoiceOuthw;
+SpicePlaybackInstance sin;
+SpiceRateCtl  rate;
+int   active;
+uint32_t  *frame;
+uint32_t  *fpos;
+uint32_t  fsize;
+} SpiceVoiceOut;
+
+typedef struct SpiceVoiceIn {
+HWVoiceIn hw;
+SpiceRecordInstance   sin;
+SpiceRateCtl  rate;
+int   active;
+uint32_t  samples[LINE_IN_SAMPLES];
+} SpiceVoiceIn;
+
+static const SpicePlaybackInterface playback_sif = {
+.base.type  = SPICE_INTERFACE_PLAYBACK,
+.base.description   = playback,
+.base.major_version = SPICE_INTERFACE_PLAYBACK_MAJOR,
+.base.minor_version = SPICE_INTERFACE_PLAYBACK_MINOR,
+};
+
+static const SpiceRecordInterface record_sif = {
+.base.type  = SPICE_INTERFACE_RECORD,
+.base.description   = record,
+.base.major_version = SPICE_INTERFACE_RECORD_MAJOR,
+.base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
+};
+
+static void *spice_audio_init (void)
+{
+if (!using_spice) {
+return NULL;
+}
+return spice_audio_init;
+}
+
+static void spice_audio_fini (void *opaque)
+{
+/* nothing */
+}
+
+static void rate_start (SpiceRateCtl *rate)
+{
+memset (rate, 0, sizeof (*rate));
+rate-start_ticks = qemu_get_clock (vm_clock);
+}
+
+static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
+{
+int64_t now;
+int64_t ticks;
+int64_t bytes;
+int64_t samples;
+
+now = qemu_get_clock (vm_clock);
+ticks = now - rate-start_ticks;
+bytes = muldiv64 (ticks, info-bytes_per_second, get_ticks_per_sec ());
+samples = (bytes - rate-bytes_sent)  info-shift;
+if (samples  0 || samples  65536) {
+fprintf (stderr, Resetting rate control (% PRId64  samples)\n, 
samples);
+rate_start (rate);
+samples = 0;
+}
+rate-bytes_sent += samples  info-shift;
+return samples;
+}
+
+/* playback */
+
+static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
+{
+SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
+struct audsettings settings;
+

[Qemu-devel] [RFC][PATCH v2 00/10] virtagent: host/guest RPC communication agent

2010-11-03 Thread Michael Roth
This set of patches is meant to be applied on top of the Virtproxy v1 patchset, 
which was submitted a couple weeks ago and can also be obtained at:

git://repo.or.cz/qemu/mdroth.git virtproxy_v1

OVERVIEW:

There are a wide range of use cases motivating the need for a guest agent of 
some sort to extend the functionality/usability/control offered by QEMU. Some 
examples include graceful guest shutdown/reboot and notifications thereof, 
copy/paste syncing between host/guest, guest statistics gathering, file access, 
etc.

Ideally these would all be served by a single, easilly extensible agent that 
can be deployed in a wide range of guests. Virtagent is an XMLRPC server 
integrated into the Virtproxy guest daemon and aimed at providing this type of 
functionality.

CHANGES IN V2:

 - All RPC communication is now done using asynchronous/non-blocking read/write 
handlers
 - Previously fork()'d RPC server loop is now integrated into qemu-vp/virtproxy 
i/o loop
 - Cleanups/suggestions from previous RFC

DESIGN:

There are actually 2 RPC servers:

1) a server in the guest integrated into the Virtproxy guest daemon which 
handles RPC requests from QEMU
2) a server in the host (integrated into the Virtproxy host daemon, which we 
plan to integrate directly into qemu) to handle RPC requests sent by the guest 
agent (mainly for handling asynchronous events reported by the agent).

At the Virtagent level, communication is done via standard RPCs (HTTP between 
host and guest). Virtproxy transparently handles transport over a network or 
isa/virtio serial channel, allowing the agent to be deployed on older guests 
which may not support virtio-serial.

Currently there are only 2 RPCs implemented for the guest server (getfile and 
getdmesg), and 0 for the host. Additional RPCs can be added fairly easily, but 
are dependent on feedback from here and elsewhere. ping/status, shutdown, and 
reboot are likely candidates (although the latter 2 will likely require 
asynchronous notifications to the host RPC server to implement reliably).

EXAMPLE USAGE:

The commandline options are a little convoluted right now; this will addressed 
in later revisions.

 - Configure guest agent to talk to host via virtio-serial
# start guest with virtio-serial. for example (RHEL6s13):
qemu \
-device virtio-serial \
-chardev socket,path=/tmp/test0-virtioconsole.sock,server,nowait,id=test0 \
-device virtconsole,chardev=test0,name=test0 \
-chardev socket,path=/tmp/test1-virtio-serial.sock,server,nowait,id=test1 \
-device virtserialport,chardev=test1,name=test1 \
-chardev socket,path=/tmp/test2-virtio-serial.sock,server,nowait,id=test2 \
-device virtserialport,chardev=test2,name=test2 \
-monitor stdio
...
# in the host:
./qemu-vp -c unix-connect:/tmp/test2-virtio-serial.sock:- \
  -o virtagent:/tmp/virtagent-guest-client.sock:-
# in the guest:
./qemu-vp -c virtserial-open:/dev/virtio-ports/test2:- -g
...
# monitor commands
(qemu) agent_viewdmesg
[139311.710326] wlan0: deauthenticating from 00:30:bd:f7:12:d5 by local 
choice (reason=3)
[139323.469857] wlan0: deauthenticating from 00:21:29:cd:41:ee by local 
choice (reason=3)
...
[257683.375646] wlan0: authenticated
[257683.375684] wlan0: associate with AP 00:30:bd:f7:12:d5 (try 1)
[257683.377932] wlan0: RX AssocResp from 00:30:bd:f7:12:d5 (capab=0x411 
status=0 aid=4)
[257683.377940] wlan0: associated

(qemu) agent_viewfile /proc/meminfo
MemTotal:3985488 kB
MemFree:  400524 kB
Buffers:  220556 kB
Cached:  2073160 kB
SwapCached:0 kB
...
Hugepagesize:   2048 kB
DirectMap4k:8896 kB
DirectMap2M: 4110336 kB

KNOWN ISSUES/PLANS:
 - the client socket that qemu connects to send RPCs is a hardcoded filepath. 
This is unacceptable as the socket is channel/process specific and things will 
break when multiple guests are started.
 - capability negotiation will be needed to handle version/architecture 
differences.
 - proper channel negotiation is needed to avoid hung monitors and such when a 
guest reboots or the guest agent is stopped for whatever reason. additionally, 
a timeout may need to be imposed on the amount of time the http read handler 
can block the monitor.
 - additional host-to-guest RPCs as well as asynchronous notifications via 
guest-to-host RPCs for events such as shutdown/reboot/agent up/agent down

 Makefile|2 +-
 Makefile.target |2 +-
 configure   |   25 +++
 hmp-commands.hx |   32 
 monitor.c   |1 +
 qemu-vp.c   |  115 +-
 qerror.c|4 +
 qerror.h|3 +
 qmp-commands.hx |   68 
 virtagent-common.c  |  431 +++
 virtagent-common.h  |   73 +
 virtagent-daemon.c  |  253 ++
 

[Qemu-devel] [RFC][PATCH v2 05/10] virtagent: add getfile RPC

2010-11-03 Thread Michael Roth
Add RPC to retrieve a guest file. A size limit of some sort will
eventually be needed else we can block the monitor for arbitrarily long
periods of time. This interface is intended for smaller reads like
peeking at logs and /proc and such.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtagent-daemon.c |   53 
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/virtagent-daemon.c b/virtagent-daemon.c
index 71a36d4..bf28be2 100644
--- a/virtagent-daemon.c
+++ b/virtagent-daemon.c
@@ -15,6 +15,57 @@
 #include virtagent-daemon.h
 #include virtagent-common.h
 
+/* RPC functions common to guest/host daemons */
+
+static xmlrpc_value *getfile(xmlrpc_env *env,
+xmlrpc_value *param,
+void *user_data)
+{
+const char *path;
+char *file_contents = NULL;
+char buf[VA_FILEBUF_LEN];
+int fd, ret, count = 0;
+xmlrpc_value *result = NULL;
+
+/* parse argument array */
+xmlrpc_decompose_value(env, param, (s), path);
+if (env-fault_occurred) {
+return NULL;
+}
+
+fd = open(path, O_RDONLY);
+if (fd == -1) {
+LOG(open failed: %s, strerror(errno));
+xmlrpc_faultf(env, open failed: %s, strerror(errno));
+return NULL;
+}
+
+while ((ret = read(fd, buf, VA_FILEBUF_LEN))  0) {
+file_contents = qemu_realloc(file_contents, count + VA_FILEBUF_LEN);
+memcpy(file_contents + count, buf, ret);
+count += ret;
+if (count  VA_GETFILE_MAX) {
+xmlrpc_faultf(env, max file size (%d bytes) exceeded,
+  VA_GETFILE_MAX);
+goto EXIT_CLOSE_BAD;
+}
+}
+if (ret == -1) {
+LOG(read failed: %s, strerror(errno));
+xmlrpc_faultf(env, read failed: %s, strerror(errno));
+goto EXIT_CLOSE_BAD;
+}
+
+result = xmlrpc_build_value(env, 6, file_contents, count);
+
+EXIT_CLOSE_BAD:
+if (file_contents) {
+qemu_free(file_contents);
+}
+close(fd);
+return result;
+}
+
 static int va_accept(int listen_fd) {
 struct sockaddr_in saddr;
 struct sockaddr *addr;
@@ -42,6 +93,8 @@ typedef struct RPCFunction {
 } RPCFunction;
 
 static RPCFunction guest_functions[] = {
+{ .func = getfile,
+  .func_name = getfile },
 { NULL, NULL }
 };
 static RPCFunction host_functions[] = {
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 09/10] virtagent: Makefile/configure changes to build virtagent bits

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile|2 +-
 Makefile.target |2 +-
 configure   |   25 +
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 2dd64a3..b513d33 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@ qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o 
$(trace-obj-y) $(block-ob
 
 qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) 
$(block-obj-y) $(qobject-obj-y) $(version-obj-y)
 
-qemu-vp$(EXESUF): qemu-vp.o virtproxy.o qemu-tool.o qemu-error.o 
qemu-sockets.c $(block-obj-y) $(qobject-obj-y)
+qemu-vp$(EXESUF): qemu-vp.o virtproxy.o virtagent-daemon.o virtagent-common.o 
qemu-tool.o qemu-error.o qemu-sockets.c $(trace-obj-y) $(block-obj-y) 
$(qobject-obj-y) $(version-obj-y)
 
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h  $  $@,  GEN   $@)
diff --git a/Makefile.target b/Makefile.target
index c48cbcc..f8f4c13 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -164,7 +164,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 
-obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o virtagent.o 
virtagent-common.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
diff --git a/configure b/configure
index 27f92e0..cfddad7 100755
--- a/configure
+++ b/configure
@@ -1261,6 +1261,31 @@ EOF
 fi
 
 ##
+# xmlrpc-c probe
+
+# Look for the xmlrpc-c config program
+if test -n $cross_prefix  has ${cross_prefix}xmlrpc-c-config; then
+  xmlrpccconfig=${cross_prefix}xmlrpc-c-config
+elif has xmlrpc-c-config; then
+  xmlrpccconfig=xmlrpc-c-config
+else
+  feature_not_found xmlrpc-c
+fi
+
+cat  $TMPC  EOF
+#include xmlrpc.h
+int main(void) { xmlrpc_env env; xmlrpc_env_init(env); return 0; }
+EOF
+xmlrpc_cflags=`$xmlrpccconfig --cflags 2 /dev/null`
+xmlrpc_libs=`$xmlrpccconfig client server-util --libs 2 /dev/null`
+if compile_prog $xmlrpc_cflags $xmlrpc_libs; then
+  libs_softmmu=$xmlrpc_libs $libs_softmmu
+  libs_tools=$xmlrpc_libs $libs_tools
+else
+  feature_not_found xmlrpc-c
+fi
+
+##
 # VNC TLS detection
 if test $vnc_tls != no ; then
   cat  $TMPC EOF
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 04/10] virtagent: base RPC client definitions

2010-11-03 Thread Michael Roth
Base skeleton and helpers for executing RPC commands. Monitor commands
will result in a connect() being issued to the virtagent service socket,
which will then be transported to the listening RPC server in the guest
via the virtproxy layer, RPC requests are then sent/recieved via http
over the resulting connection.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 monitor.c   |1 +
 qerror.c|4 +++
 qerror.h|3 ++
 virtagent.c |   88 +++
 virtagent.h |   25 +
 5 files changed, 121 insertions(+), 0 deletions(-)
 create mode 100644 virtagent.c
 create mode 100644 virtagent.h

diff --git a/monitor.c b/monitor.c
index 260cc02..6c99206 100644
--- a/monitor.c
+++ b/monitor.c
@@ -42,6 +42,7 @@
 #include audio/audio.h
 #include disas.h
 #include balloon.h
+#include virtagent.h
 #include qemu-timer.h
 #include migration.h
 #include kvm.h
diff --git a/qerror.c b/qerror.c
index ac2cdaf..2f111a9 100644
--- a/qerror.c
+++ b/qerror.c
@@ -200,6 +200,10 @@ static const QErrorStringTable qerror_table[] = {
 .error_fmt = QERR_VNC_SERVER_FAILED,
 .desc  = Could not start VNC server on %(target),
 },
+{
+.error_fmt = QERR_RPC_FAILED,
+.desc  = An RPC error has occurred,
+},
 {}
 };
 
diff --git a/qerror.h b/qerror.h
index 943a24b..43cce4a 100644
--- a/qerror.h
+++ b/qerror.h
@@ -165,4 +165,7 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_VNC_SERVER_FAILED \
 { 'class': 'VNCServerFailed', 'data': { 'target': %s } }
 
+#define QERR_RPC_FAILED \
+{ 'class': 'RPCFailed', 'data': { 'code': %i, 'message': %s } }
+
 #endif /* QERROR_H */
diff --git a/virtagent.c b/virtagent.c
new file mode 100644
index 000..84dcf3b
--- /dev/null
+++ b/virtagent.c
@@ -0,0 +1,88 @@
+/*
+ * virt-agent - host/guest RPC client functions
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include qemu_socket.h
+#include virtagent-daemon.h
+#include virtagent-common.h
+#include virtagent.h
+
+static int rpc_has_error(xmlrpc_env *env)
+{
+if (env-fault_occurred) {
+LOG(An RPC error has occurred (%i): %s\n, env-fault_code, 
env-fault_string);
+//qerror_report(QERR_RPC_FAILED, env-fault_code, env-fault_string);
+return -1;
+}
+return 0;
+}
+
+/*
+ * Get a connected socket that can be used to make an RPC call
+ * This interface will eventually return the connected virtproxy socket for the
+ * virt-agent channel
+ */
+static int get_transport_fd(void)
+{
+/* TODO: eventually this will need a path that is unique to other
+ * instances of qemu-vp/qemu. for the integrated qemu-vp we should
+ * explore the possiblity of not requiring a unix socket under the
+ * covers, as well as having client init code set up the oforward
+ * for the service rather than qemu-vp
+ */
+int ret;
+int fd = unix_connect(GUEST_AGENT_PATH_CLIENT);
+if (fd  0) {
+LOG(failed to connect to virtagent service);
+}
+ret = fcntl(fd, F_GETFL);
+ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
+return fd;
+}
+
+static int rpc_execute(xmlrpc_env *const env, const char *function,
+   xmlrpc_value *params, VARPCData *rpc_data)
+{
+xmlrpc_mem_block *call_xml;
+int fd, ret;
+
+fd = get_transport_fd();
+if (fd  0) {
+LOG(invalid fd);
+ret = -1;
+goto out;
+}
+
+call_xml = XMLRPC_MEMBLOCK_NEW(char, env, 0);
+xmlrpc_serialize_call(env, call_xml, function, params);
+if (rpc_has_error(env)) {
+ret = -EREMOTE;
+goto out_callxml;
+}
+
+rpc_data-send_req_xml = call_xml;
+
+ret = va_rpc_send_request(rpc_data, fd);
+if (ret != 0) {
+ret = -1;
+goto out_callxml;
+} else {
+ret = 0;
+goto out;
+}
+
+out_callxml:
+XMLRPC_MEMBLOCK_FREE(char, call_xml);
+out:
+return ret;
+}
diff --git a/virtagent.h b/virtagent.h
new file mode 100644
index 000..abdb32a
--- /dev/null
+++ b/virtagent.h
@@ -0,0 +1,25 @@
+/*
+ * virt-agent - host/guest RPC client functions
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VIRTAGENT_H
+#define VIRTAGENT_H
+
+#include monitor.h
+#include virtagent-common.h
+
+#define GUEST_AGENT_PATH_CLIENT /tmp/virtagent-guest-client.sock
+#define HOST_AGENT_PATH_CLIENT /tmp/virtagent-host-client.sock
+#define VA_MAX_CHUNK_SIZE 4096 /* max bytes at a time for get/send file */
+
+#endif 

[Qemu-devel] [RFC][PATCH v2 06/10] virtagent: add agent_viewfile command

2010-11-03 Thread Michael Roth
Utilize the getfile RPC to provide a means to view text files in the
guest. Getfile can handle binary files as well but we don't advertise
that here due to the special handling requiring to store it and provide
it back to the user (base64 encoding it for instance). Hence the
potentially confusing viewfile as opposed to getfile.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 hmp-commands.hx |   16 +
 qmp-commands.hx |   33 ++
 virtagent.c |   99 +++
 virtagent.h |4 ++
 4 files changed, 152 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 81999aa..e9a7f4a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1211,6 +1211,22 @@ show available trace events and their state
 ETEXI
 #endif
 
+{
+.name   = agent_viewfile,
+.args_type  = filepath:s,
+.params = filepath,
+.help   = Echo a file from the guest filesystem,
+.user_print = do_agent_viewfile_print,
+.mhandler.cmd_async = do_agent_viewfile,
+.flags  = MONITOR_CMD_ASYNC,
+},
+
+STEXI
+...@item agent_viewfile @var{filepath}
+...@findex agent_viewfile
+Echo the file identified by @var{filepath} on the guest filesystem
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 793cf1c..efa2137 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -738,6 +738,39 @@ Example:
 EQMP
 
 {
+.name   = agent_viewfile,
+.args_type  = filepath:s,
+.params = filepath,
+.help   = Echo a file from the guest filesystem,
+.user_print = monitor_user_noop,
+.mhandler.cmd_async = do_agent_viewfile,
+.flags  = MONITOR_CMD_ASYNC,
+},
+
+STEXI
+...@item agent_viewfile @var{filepath}
+...@findex agent_viewfile
+Echo the file identified by @var{filepath} on the guest filesystem
+ETEXI
+SQMP
+agent_viewfile
+
+
+Echo the file identified by @var{filepath} from the guest filesystem.
+
+Arguments:
+
+- filepath: Full guest path of the desired file
+
+Example:
+
+- { execute: agent_viewfile,
+arguments: { filepath: /sys/kernel/kexec_loaded } }
+- { return: { contents: 0 } }
+
+EQMP
+
+{
 .name   = qmp_capabilities,
 .args_type  = ,
 .params = ,
diff --git a/virtagent.c b/virtagent.c
index 84dcf3b..187bb28 100644
--- a/virtagent.c
+++ b/virtagent.c
@@ -86,3 +86,102 @@ out_callxml:
 out:
 return ret;
 }
+
+void do_agent_viewfile_print(Monitor *mon, const QObject *data)
+{
+QDict *qdict;
+const char *contents = NULL;
+int i;
+
+qdict = qobject_to_qdict(data);
+if (!qdict_haskey(qdict, contents)) {
+return;
+}
+
+contents = qdict_get_str(qdict, contents);
+if (contents != NULL) {
+ /* monitor_printf truncates so do it in chunks. also, file_contents
+  * may not be null-termed at proper location so explicitly calc
+  * last chunk sizes */
+for (i = 0; i  strlen(contents); i += 1024) {
+monitor_printf(mon, %.1024s, contents + i);
+}
+}
+monitor_printf(mon, \n);
+}
+
+static void do_agent_viewfile_cb(void *opaque)
+{
+VARPCData *rpc_data = opaque;
+xmlrpc_value *resp = NULL;
+char *file_contents = NULL;
+int file_size, ret;
+xmlrpc_env env;
+QDict *qdict = qdict_new();
+
+if (rpc_data-status != VA_RPC_STATUS_OK) {
+LOG(error handling RPC request);
+goto out_no_resp;
+}
+
+xmlrpc_env_init(env);
+resp = xmlrpc_parse_response(env, rpc_data-resp_xml,
+ rpc_data-resp_xml_len);
+if (rpc_has_error(env)) {
+ret = -1;
+goto out_no_resp;
+}
+
+xmlrpc_parse_value(env, resp, 6, file_contents, file_size);
+if (rpc_has_error(env)) {
+ret = -1;
+goto out;
+}
+
+if (file_contents != NULL) {
+qdict_put(qdict, contents,
+  qstring_from_substr(file_contents, 0, file_size-1));
+}
+
+out:
+xmlrpc_DECREF(resp);
+out_no_resp:
+rpc_data-mon_cb(rpc_data-mon_data, QOBJECT(qdict));
+}
+
+/*
+ * do_agent_viewfile(): View a text file in the guest
+ */
+int do_agent_viewfile(Monitor *mon, const QDict *mon_params,
+  MonitorCompletion cb, void *opaque)
+{
+xmlrpc_env env;
+xmlrpc_value *params;
+VARPCData *rpc_data;
+const char *filepath;
+int ret;
+
+filepath = qdict_get_str(mon_params, filepath);
+xmlrpc_env_init(env);
+params = xmlrpc_build_value(env, (s), filepath);
+if (rpc_has_error(env)) {
+return -1;
+}
+
+rpc_data = qemu_mallocz(sizeof(VARPCData));
+rpc_data-cb = do_agent_viewfile_cb;
+rpc_data-mon_cb = cb;
+rpc_data-mon_data = opaque;
+
+ret = rpc_execute(env, getfile, params, rpc_data);
+if (ret == -EREMOTE) {
+monitor_printf(mon, RPC Failed (%i): %s\n, 

[Qemu-devel] [RFC][PATCH v2 02/10] virtagent: base definitions for host/guest RPC daemon

2010-11-03 Thread Michael Roth
Basic skeleton code for RPC daemon loop. This is shared by both the
guest-side RPC server as well as the host-side one (the advertised RPCs
for each by guest/host-specific arrays).

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtagent-daemon.c |  156 
 virtagent-daemon.h |   20 +++
 2 files changed, 176 insertions(+), 0 deletions(-)
 create mode 100644 virtagent-daemon.c
 create mode 100644 virtagent-daemon.h

diff --git a/virtagent-daemon.c b/virtagent-daemon.c
new file mode 100644
index 000..71a36d4
--- /dev/null
+++ b/virtagent-daemon.c
@@ -0,0 +1,156 @@
+/*
+ * virt-agent - host/guest RPC daemon functions
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#include qemu_socket.h
+#include virtagent-daemon.h
+#include virtagent-common.h
+
+static int va_accept(int listen_fd) {
+struct sockaddr_in saddr;
+struct sockaddr *addr;
+socklen_t len;
+int fd;
+
+while (1) {
+len = sizeof(saddr);
+addr = (struct sockaddr *)saddr;
+fd = qemu_accept(listen_fd, addr, len);
+if (fd  0  errno != EINTR) {
+LOG(accept() failed);
+break;
+} else if (fd = 0) {
+TRACE(accepted connection);
+break;
+}
+}
+return fd;
+}
+
+typedef struct RPCFunction {
+xmlrpc_value *(*func)(xmlrpc_env *env, xmlrpc_value *param, void *unused);
+const char *func_name;
+} RPCFunction;
+
+static RPCFunction guest_functions[] = {
+{ NULL, NULL }
+};
+static RPCFunction host_functions[] = {
+{ NULL, NULL }
+};
+
+static void va_register_functions(xmlrpc_env *env, xmlrpc_registry *registry,
+  RPCFunction *list)
+{
+int i;
+for (i = 0; list[i].func != NULL; ++i) {
+TRACE(adding func: %s, list[i].func_name);
+xmlrpc_registry_add_method(env, registry, NULL, list[i].func_name,
+   list[i].func, NULL);
+}
+}
+
+typedef struct VARPCServerState {
+int listen_fd;
+xmlrpc_env env;
+xmlrpc_registry *registry;
+} VARPCServerState;
+
+static void va_accept_handler(void *opaque);
+
+static void va_rpc_send_cb(void *opaque)
+{
+VARPCData *rpc_data = opaque;
+VARPCServerState *s = rpc_data-opaque;
+
+TRACE(called);
+if (rpc_data-status != VA_RPC_STATUS_OK) {
+LOG(error sending RPC response);
+} else {
+TRACE(RPC completed);
+}
+
+TRACE(waiting for RPC request...);
+vp_set_fd_handler(s-listen_fd, va_accept_handler, NULL, s);
+}
+
+static void va_rpc_read_cb(void *opaque)
+{
+VARPCData *rpc_data = opaque;
+VARPCServerState *s = rpc_data-opaque;
+
+TRACE(called);
+if (rpc_data-status != VA_RPC_STATUS_OK) {
+LOG(error reading RPC request);
+goto out_bad;
+}
+
+rpc_data-send_resp_xml = 
+xmlrpc_registry_process_call(s-env, s-registry, NULL,
+ rpc_data-req_xml, rpc_data-req_xml_len);
+if (rpc_data-send_resp_xml == NULL) {
+LOG(error handling RPC request);
+goto out_bad;
+}
+
+rpc_data-cb = va_rpc_send_cb;
+return;
+
+out_bad:
+TRACE(waiting for RPC request...);
+vp_set_fd_handler(s-listen_fd, va_accept_handler, NULL, s);
+}
+
+static void va_accept_handler(void *opaque)
+{
+VARPCServerState *s = opaque;
+VARPCData *rpc_data;
+int ret, fd;
+
+TRACE(called);
+fd = va_accept(s-listen_fd);
+if (fd  0) {
+TRACE(connection error: %s, strerror(errno));
+return;
+}
+ret = fcntl(fd, F_GETFL);
+ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
+
+TRACE(RPC client connected, reading RPC request...);
+rpc_data = qemu_mallocz(sizeof(VARPCData));
+rpc_data-cb = va_rpc_read_cb;
+rpc_data-opaque = s;
+ret = va_rpc_read_request(rpc_data, fd);
+if (ret != 0) {
+LOG(error setting up read handler);
+qemu_free(rpc_data);
+return;
+}
+vp_set_fd_handler(s-listen_fd, NULL, NULL, NULL);
+}
+
+int va_server_start(int listen_fd, bool is_host)
+{
+VARPCServerState *s;
+RPCFunction *func_list = is_host ? host_functions : guest_functions;
+
+s = qemu_mallocz(sizeof(VARPCServerState));
+s-listen_fd = listen_fd;
+xmlrpc_env_init(s-env);
+s-registry = xmlrpc_registry_new(s-env);
+va_register_functions(s-env, s-registry, func_list);
+
+TRACE(waiting for RPC request...);
+vp_set_fd_handler(s-listen_fd, va_accept_handler, NULL, s);
+
+return 0;
+}
diff --git a/virtagent-daemon.h b/virtagent-daemon.h
new file mode 100644
index 000..da926b3
--- /dev/null
+++ b/virtagent-daemon.h
@@ -0,0 +1,20 @@
+/*
+ * virt-agent - host/guest RPC daemon 

[Qemu-devel] [RFC][PATCH v2 07/10] virtagent: add getdmesg RPC

2010-11-03 Thread Michael Roth
Add RPC to view guest dmesg output.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtagent-daemon.c |   44 
 virtagent-daemon.h |1 +
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/virtagent-daemon.c b/virtagent-daemon.c
index bf28be2..181edac 100644
--- a/virtagent-daemon.c
+++ b/virtagent-daemon.c
@@ -66,6 +66,48 @@ EXIT_CLOSE_BAD:
 return result;
 }
 
+/* getdmesg(): return dmesg output
+ * rpc return values:
+ *   - dmesg output as a string
+ */
+static xmlrpc_value *getdmesg(xmlrpc_env *env,
+  xmlrpc_value *param,
+  void *user_data)
+{
+char *dmesg_buf = NULL, cmd[256];
+int ret;
+xmlrpc_value *result = NULL;
+FILE *pipe;
+
+dmesg_buf = qemu_mallocz(VA_DMESG_LEN + 2048);
+sprintf(cmd, dmesg -s %d, VA_DMESG_LEN);
+
+pipe = popen(cmd, r);
+if (pipe == NULL) {
+LOG(popen failed: %s, strerror(errno));
+xmlrpc_faultf(env, popen failed: %s, strerror(errno));
+goto EXIT_NOCLOSE;
+}
+
+ret = fread(dmesg_buf, sizeof(char), VA_DMESG_LEN, pipe);
+if (!ferror(pipe)) {
+dmesg_buf[ret] = '\0';
+TRACE(dmesg:\n%s, dmesg_buf);
+result = xmlrpc_build_value(env, s, dmesg_buf);
+} else {
+LOG(fread failed);
+xmlrpc_faultf(env, popen failed: %s, strerror(errno));
+}
+
+pclose(pipe);
+EXIT_NOCLOSE:
+if (dmesg_buf) {
+qemu_free(dmesg_buf);
+}
+
+return result;
+}
+
 static int va_accept(int listen_fd) {
 struct sockaddr_in saddr;
 struct sockaddr *addr;
@@ -95,6 +137,8 @@ typedef struct RPCFunction {
 static RPCFunction guest_functions[] = {
 { .func = getfile,
   .func_name = getfile },
+{ .func = getdmesg,
+  .func_name = getdmesg },
 { NULL, NULL }
 };
 static RPCFunction host_functions[] = {
diff --git a/virtagent-daemon.h b/virtagent-daemon.h
index da926b3..d19f8e3 100644
--- a/virtagent-daemon.h
+++ b/virtagent-daemon.h
@@ -16,5 +16,6 @@
 #define HOST_AGENT_PATH /tmp/virtagent-host.sock
 #define VA_GETFILE_MAX 1  30
 #define VA_FILEBUF_LEN 16384
+#define VA_DMESG_LEN 16384
 
 int va_server_start(int listen_fd, bool is_host);
-- 
1.7.0.4




[Qemu-devel] [RFC][PATCH v2 10/10] virtproxy: add compat defs for linking against vl.c

2010-11-03 Thread Michael Roth
Virtagent depends on basic qemu functions re-implemented by qemu-vp to
allow it to be used in output of qemu (in particular, to allow the
client code to be used for guest-to-host RPC calls). To build virtagent
into qemu we need to define these in terms of the built-in qemu
functions.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile.target |2 +-
 virtproxy-builtin.c |   30 ++
 2 files changed, 31 insertions(+), 1 deletions(-)
 create mode 100644 virtproxy-builtin.c

diff --git a/Makefile.target b/Makefile.target
index f8f4c13..d72b2be 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -164,7 +164,7 @@ endif #CONFIG_BSD_USER
 # System emulator target
 ifdef CONFIG_SOFTMMU
 
-obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o virtagent.o 
virtagent-common.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o virtagent.o 
virtagent-common.o virtproxy-builtin.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
 obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
diff --git a/virtproxy-builtin.c b/virtproxy-builtin.c
new file mode 100644
index 000..c3416b3
--- /dev/null
+++ b/virtproxy-builtin.c
@@ -0,0 +1,30 @@
+/*
+ * virt-proxy - host/guest communication layer builtin definitions
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+/* the following are functions we define in terms of qemu when linked
+ * against qemu/vl.c. these will be added on an as-needed basis
+ */
+
+#include qemu-char.h
+#include virtproxy.h
+
+int vp_set_fd_handler(int fd,
+IOHandler *fd_read,
+IOHandler *fd_write,
+void *opaque)
+{
+return qemu_set_fd_handler(fd, fd_read, fd_write, opaque);
+}
+
+
-- 
1.7.0.4




[Qemu-devel] [vgabios patch v2 03/11] - preparing for release 0.6c

2010-11-03 Thread Gerd Hoffmann
From: Volker Ruppert i...@vruppert.de

---
 ChangeLog |   35 +++
 README|6 ++
 2 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 75be5bd..35bf00a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2009-01-25 16:46  vruppert
+
+   * vbe.c (1.62), vbe.h (1.28), vbetables-gen.c (1.5):
+
+   - added support for a lot more non-standard VBE modes (e.g. widescreen 
modes)
+   - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, 
VRAM size
+ in 64k pages stored in VBE register)
+   - check if VBE mode is supported with current VRAM size
+
+2009-01-24 11:02  vruppert
+
+   * clext.c (1.14), vbe.c (1.61), vgabios.c (1.68):
+
+   - use VBE LFB address from PCI base address if present (rewrite of the 
cirrus
+ specific function in main vgabios code)
+   - removed unnecessary spaces
+
+2008-12-14 09:29  vruppert
+
+   * clext.c (1.13):
+
+   - added DPMS support to cirrus vgabios (patch from Gleb Natapov)
+
+2008-05-30 17:28  vruppert
+
+   * README (1.16):
+
+   - updated for release 0.6b
+
+2008-05-22 12:55  vruppert
+
+   * ChangeLog (1.27), README (1.15):
+
+   - preparations for release 0.6b
+
 2008-05-11 08:40  vruppert
 
* biossums.c (1.6):
diff --git a/README b/README
index 90141d4..ce67aeb 100644
--- a/README
+++ b/README
@@ -90,6 +90,12 @@ For any information on qemu, visit the website 
http://fabrice.bellard.free.fr/qe
 
 History
 ---
+vgabios-0.6c : not yet released
+  - Volker
+. added DPMS support to cirrus vgabios (patch from Gleb Natapov)
+. use VBE LFB address from PCI base address if present
+. added support for a lot more non-standard VBE modes (e.g. widescreen 
modes)
+
 vgabios-0.6b : May 30 2008
   - Volker
 . added PCI data structure for the Cirrus VGABIOS images
-- 
1.7.1




[Qemu-devel] [RFC][PATCH v2 01/10] virtagent: add common rpc transport defs

2010-11-03 Thread Michael Roth
Common code for sending/recieving RPCs via http over virtproxy channel.
All communication is done via asynchronous read/write handlers and using
non-blocking reads/writes

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtagent-common.c |  431 
 virtagent-common.h |   73 +
 2 files changed, 504 insertions(+), 0 deletions(-)
 create mode 100644 virtagent-common.c
 create mode 100644 virtagent-common.h

diff --git a/virtagent-common.c b/virtagent-common.c
new file mode 100644
index 000..cc58938
--- /dev/null
+++ b/virtagent-common.c
@@ -0,0 +1,431 @@
+/*
+ * virt-agent - common host/guest RPC functions
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Adam Litkeagli...@linux.vnet.ibm.com
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include virtagent-common.h
+
+#define VA_READ true
+#define VA_SEND false
+
+enum va_rpc_type {
+VA_RPC_REQUEST,
+VA_RPC_RESPONSE,
+};
+
+typedef struct VARPCState {
+char hdr[VA_HDR_LEN_MAX];
+int fd;
+size_t hdr_len;
+size_t hdr_pos;
+enum {
+VA_READ_START,
+VA_READ_HDR,
+VA_READ_BODY,
+VA_SEND_START,
+VA_SEND_HDR,
+VA_SEND_BODY,
+} state;
+enum va_rpc_type rpc_type;
+char *content;
+size_t content_len;
+size_t content_pos;
+VARPCData *data;
+} VARPCState;
+
+static void va_rpc_read_handler(void *opaque);
+static void va_rpc_send_handler(void *opaque);
+
+static int end_of_header(char *buf, int end_pos)
+{
+return !strncmp(buf+(end_pos-2), \n\r\n, 3);
+}
+
+static void va_rpc_hdr_init(VARPCState *s) {
+const char *preamble;
+
+TRACE(called);
+/* essentially ignored in the context of virtagent, but might as well */
+if (s-rpc_type == VA_RPC_REQUEST) {
+preamble = POST /RPC2 HTTP/1.1;
+} else if (s-rpc_type == VA_RPC_RESPONSE) {
+preamble = HTTP/1.1 200 OK;
+} else {
+s-hdr_len = 0;
+return;
+}
+
+s-hdr_len = sprintf(s-hdr,
+ %s EOL
+ Content-Type: text/xml EOL
+ Content-Length: %u EOL EOL,
+ preamble,
+ (uint32_t)s-content_len);
+}
+
+static void va_rpc_parse_hdr(VARPCState *s)
+{
+int i, line_pos = 0;
+char line_buf[4096];
+
+for (i = 0; i  VA_HDR_LEN_MAX; ++i) {
+if (s-hdr[i] != '\n') {
+/* read line */
+line_buf[line_pos++] = s-hdr[i];
+} else {
+/* process line */
+if (strncmp(line_buf, Content-Length: , 16) == 0) {
+s-content_len = atoi(line_buf[16]);
+return;
+}
+line_pos = 0;
+}
+}
+}
+
+static VARPCState *va_rpc_state_new(VARPCData *data, int fd,
+enum va_rpc_type rpc_type, bool read)
+{
+VARPCState *s = qemu_mallocz(sizeof(VARPCState));
+
+s-rpc_type = rpc_type;
+s-fd = fd;
+s-data = data;
+if (s-data == NULL) {
+goto EXIT_BAD;
+}
+
+if (read) {
+s-state = VA_READ_START;
+s-content = NULL;
+} else {
+s-state = VA_SEND_START;
+if (rpc_type == VA_RPC_REQUEST) {
+s-content = XMLRPC_MEMBLOCK_CONTENTS(char, s-data-send_req_xml);
+s-content_len = XMLRPC_MEMBLOCK_SIZE(char, s-data-send_req_xml);
+} else if (rpc_type == VA_RPC_RESPONSE) {
+s-content = XMLRPC_MEMBLOCK_CONTENTS(char, 
s-data-send_resp_xml);
+s-content_len = XMLRPC_MEMBLOCK_SIZE(char, 
s-data-send_resp_xml);
+} else {
+LOG(unknown rcp type);
+goto EXIT_BAD;
+}
+va_rpc_hdr_init(s);
+if (s-hdr_len == 0) {
+LOG(failed to initialize http header);
+goto EXIT_BAD;
+}
+}
+
+return s;
+EXIT_BAD:
+qemu_free(s);
+return NULL;
+}
+
+/* called by va_rpc_read_handler after reading requests */
+static int va_rpc_send_response(VARPCData *data, int fd)
+{
+VARPCState *s = va_rpc_state_new(data, fd, VA_RPC_RESPONSE, VA_SEND);
+
+TRACE(called);
+if (s == NULL) {
+LOG(failed to set up RPC state);
+return -1;
+}
+TRACE(setting up send handler for RPC request);
+vp_set_fd_handler(fd, NULL, va_rpc_send_handler, s);
+
+return 0;
+}
+
+static void va_rpc_read_handler_completion(VARPCState *s) {
+int ret;
+
+if (s-rpc_type == VA_RPC_REQUEST) {
+/* server read request, call it's cb function then set up
+ * a send handler for the rpc response if there weren't any
+ * communication errors
+ */ 
+s-data-cb(s-data);
+if (s-data-status == VA_RPC_STATUS_OK) {
+ret = va_rpc_send_response(s-data, s-fd);
+  

[Qemu-devel] [vgabios patch v2 09/11] update pci_get_lfb_addr for vmware vga

2010-11-03 Thread Gerd Hoffmann
vmware vga has the framebuffer at pci region 1 not 0.  This patch makes
pci_get_lfb_addr check region 1 too.  It also gives names to the
numbered labels to make the code more readable.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 vgabios.c |   23 ++-
 1 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/vgabios.c b/vgabios.c
index 2e8b5d7..c1e312b 100644
--- a/vgabios.c
+++ b/vgabios.c
@@ -3852,26 +3852,31 @@ _pci_get_lfb_addr:
 mov dl, #0x00
 call pci_read_reg
 cmp ax, #0x
-jz pci_get_lfb_addr_5
- pci_get_lfb_addr_3:
+jz pci_get_lfb_addr_fail
+ pci_get_lfb_addr_next_dev:
 mov dl, #0x00
 call pci_read_reg
 cmp ax, bx ;; check vendor
-jz pci_get_lfb_addr_4
+jz pci_get_lfb_addr_found
 add cx, #0x8
 cmp cx, #0x200 ;; search bus #0 and #1
-jb pci_get_lfb_addr_3
- pci_get_lfb_addr_5:
+jb pci_get_lfb_addr_next_dev
+ pci_get_lfb_addr_fail:
 xor dx, dx ;; no LFB
-jmp pci_get_lfb_addr_6
- pci_get_lfb_addr_4:
+jmp pci_get_lfb_addr_return
+ pci_get_lfb_addr_found:
 mov dl, #0x10 ;; I/O space #0
 call pci_read_reg
 test ax, #0xfff1
-jnz pci_get_lfb_addr_5
+jz pci_get_lfb_addr_success
+mov dl, #0x14 ;; I/O space #1
+call pci_read_reg
+test ax, #0xfff1
+jnz pci_get_lfb_addr_fail
+ pci_get_lfb_addr_success:
 shr eax, #16
 mov dx, ax ;; LFB address
- pci_get_lfb_addr_6:
+ pci_get_lfb_addr_return:
   pop eax
   mov ax, dx
   pop dx
-- 
1.7.1




[Qemu-devel] [vgabios patch v2 10/11] Add qemu vmware vga pci bios

2010-11-03 Thread Gerd Hoffmann
Add PCI vgabios for the qemu vmware vga (15ad:0405).
Name it vgabios-vmware.bin.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 58f064e..2a093e8 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ RELVERS = `pwd | sed s-.*/-- | sed s/vgabios// | sed 
s/-//`
 
 VGABIOS_DATE = -DVGABIOS_DATE=\$(RELDATE)\
 
-all: bios cirrus-bios stdvga-bios
+all: bios cirrus-bios stdvga-bios vmware-bios
 
 bios: vgabios.bin vgabios.debug.bin
 
@@ -22,6 +22,8 @@ cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin
 
 stdvga-bios: vgabios-stdvga.bin vgabios-stdvga.debug.bin
 
+vmware-bios: vgabios-vmware.bin vgabios-vmware.debug.bin
+
 clean:
/bin/rm -f  biossums vbetables-gen vbetables.h *.o *.s *.ld86 \
   temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core 
vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak
@@ -39,6 +41,8 @@ vgabios-cirrus.bin   : VGAFLAGS := -DCIRRUS -DPCIBIOS
 vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG
 vgabios-stdvga.bin   : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 
-DPCI_DID=0x
 vgabios-stdvga.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 
-DPCI_DID=0x -DDEBUG
+vgabios-vmware.bin   : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad 
-DPCI_DID=0x0405
+vgabios-vmware.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad 
-DPCI_DID=0x0405 -DDEBUG
 
 # dist names
 vgabios.bin  : DISTNAME := VGABIOS-lgpl-latest.bin
@@ -47,6 +51,8 @@ vgabios-cirrus.bin   : DISTNAME := 
VGABIOS-lgpl-latest.cirrus.bin
 vgabios-cirrus.debug.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.debug.bin
 vgabios-stdvga.bin   : DISTNAME := VGABIOS-lgpl-latest.stdvga.bin
 vgabios-stdvga.debug.bin : DISTNAME := VGABIOS-lgpl-latest.stdvga.debug.bin
+vgabios-vmware.bin   : DISTNAME := VGABIOS-lgpl-latest.vmware.bin
+vgabios-vmware.debug.bin : DISTNAME := VGABIOS-lgpl-latest.vmware.debug.bin
 
 # dependencies
 vgabios.bin  : $(VGA_FILES) $(VBE_FILES) biossums
@@ -55,6 +61,8 @@ vgabios-cirrus.bin   : $(VGA_FILES) clext.c biossums
 vgabios-cirrus.debug.bin : $(VGA_FILES) clext.c biossums
 vgabios-stdvga.bin   : $(VGA_FILES) $(VBE_FILES) biossums
 vgabios-stdvga.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-vmware.bin   : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-vmware.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums
 
 # build rule
 %.bin:
-- 
1.7.1




[Qemu-devel] [vgabios patch v2 02/11] - added support for a lot more non-standard VBE modes (e.g. widescreen modes) - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, VRAM size in 64

2010-11-03 Thread Gerd Hoffmann
From: Volker Ruppert i...@vruppert.de

---
 vbe.c   |   31 ++--
 vbe.h   |   70 --
 vbetables-gen.c |   43 +
 3 files changed, 91 insertions(+), 53 deletions(-)

diff --git a/vbe.c b/vbe.c
index 92e3d0d..ecff90d 100644
--- a/vbe.c
+++ b/vbe.c
@@ -38,8 +38,6 @@
 #include vbe.h
 #include vbetables.h
 
-#define VBE_TOTAL_VIDEO_MEMORY_DIV_64K 
(VBE_DISPI_TOTAL_VIDEO_MEMORY_MB*1024/64)
-
 // The current OEM Software Revision of this VBE Bios
 #define VBE_OEM_SOFTWARE_REV 0x0002;
 
@@ -715,7 +713,7 @@ vbe_init:
   mov  [bx], al
   pop  bx
   pop  ds
-  mov  ax, # VBE_DISPI_ID4
+  mov  ax, # VBE_DISPI_ID5
   call dispi_set_id
 no_vbe_interface:
 #if defined(USE_BX_INFO) || defined(DEBUG)
@@ -742,7 +740,19 @@ no_vbe_flag:
   mov  ds, ax
   mov  si, #_no_vbebios_info_string
   jmp  _display_string
-ASM_END  
+
+; helper function for memory size calculation
+
+lmulul:
+  and eax, #0x
+  shl ebx, #16
+  or  eax, ebx
+  SEG SS
+  mul eax, dword ptr [di]
+  mov ebx, eax
+  shr ebx, #16
+  ret
+ASM_END
 
 /** Function 00h - Return VBE Controller Information
  * 
@@ -765,6 +775,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 Bit16uvbe2_info;
 Bit16ucur_mode=0;
 Bit16ucur_ptr=34;
+Bit16usize_64k;
 ModeInfoListItem  *cur_info=mode_info_list;
 
 status = read_word(ss, AX);
@@ -820,8 +831,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 vbe_info_block.VideoModePtr_Seg= ES ;
 vbe_info_block.VideoModePtr_Off= DI + 34;
 
-// VBE Total Memory (in 64b blocks)
-vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K;
+// VBE Total Memory (in 64k blocks)
+outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIDEO_MEMORY_64K);
+vbe_info_block.TotalMemory = inw(VBE_DISPI_IOPORT_DATA);
 
 if (vbe2_info)
 {
@@ -845,8 +857,11 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 
 do
 {
+size_64k = (Bit16u)((Bit32u)cur_info-info.XResolution * 
cur_info-info.XResolution * cur_info-info.BitsPerPixel)  19;
+
 if ((cur_info-info.XResolution = dispi_get_max_xres()) 
-(cur_info-info.BitsPerPixel = dispi_get_max_bpp())) {
+(cur_info-info.BitsPerPixel = dispi_get_max_bpp()) 
+(size_64k = vbe_info_block.TotalMemory)) {
 #ifdef DEBUG
   printf(VBE found mode %x = %x\n, cur_info-mode,cur_mode);
 #endif
@@ -855,7 +870,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
   cur_ptr+=2;
 } else {
 #ifdef DEBUG
-  printf(VBE mode %x (xres=%x / bpp=%02x) not supported by 
display\n, 
cur_info-mode,cur_info-info.XResolution,cur_info-info.BitsPerPixel);
+  printf(VBE mode %x (xres=%x / bpp=%02x) not supported \n, 
cur_info-mode,cur_info-info.XResolution,cur_info-info.BitsPerPixel);
 #endif
 }
 cur_info++;
diff --git a/vbe.h b/vbe.h
index 60434ac..72cb045 100644
--- a/vbe.h
+++ b/vbe.h
@@ -275,39 +275,41 @@ typedef struct ModeInfoListItem
 //like 0xE000
 
 
-  #define VBE_DISPI_BANK_ADDRESS  0xA
-  #define VBE_DISPI_BANK_SIZE_KB  64
-  
-  #define VBE_DISPI_MAX_XRES  1024
-  #define VBE_DISPI_MAX_YRES  768
-  
-  #define VBE_DISPI_IOPORT_INDEX  0x01CE
-  #define VBE_DISPI_IOPORT_DATA   0x01CF
-  
-  #define VBE_DISPI_INDEX_ID  0x0
-  #define VBE_DISPI_INDEX_XRES0x1
-  #define VBE_DISPI_INDEX_YRES0x2
-  #define VBE_DISPI_INDEX_BPP 0x3
-  #define VBE_DISPI_INDEX_ENABLE  0x4
-  #define VBE_DISPI_INDEX_BANK0x5
-  #define VBE_DISPI_INDEX_VIRT_WIDTH  0x6
-  #define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
-  #define VBE_DISPI_INDEX_X_OFFSET0x8
-  #define VBE_DISPI_INDEX_Y_OFFSET0x9
-  
-  #define VBE_DISPI_ID0   0xB0C0
-  #define VBE_DISPI_ID1   0xB0C1
-  #define VBE_DISPI_ID2   0xB0C2
-  #define VBE_DISPI_ID3   0xB0C3
-  #define VBE_DISPI_ID4   0xB0C4
-  
-  #define VBE_DISPI_DISABLED  0x00
-  #define VBE_DISPI_ENABLED   0x01
-  #define VBE_DISPI_GETCAPS   0x02
-  #define VBE_DISPI_8BIT_DAC  0x20
-  #define VBE_DISPI_LFB_ENABLED   0x40
-  #define VBE_DISPI_NOCLEARMEM0x80
-  
-  #define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE000
+  #define VBE_DISPI_BANK_ADDRESS   0xA
+  #define VBE_DISPI_BANK_SIZE_KB   64
+
+  #define VBE_DISPI_MAX_XRES   2560
+  #define VBE_DISPI_MAX_YRES   1600
+
+  #define VBE_DISPI_IOPORT_INDEX   0x01CE
+  #define VBE_DISPI_IOPORT_DATA0x01CF
+
+  #define VBE_DISPI_INDEX_ID   0x0
+  #define VBE_DISPI_INDEX_XRES  

[Qemu-devel] [RFC][PATCH v2 08/10] virtagent: add agent_viewdmesg command

2010-11-03 Thread Michael Roth
Add commands to view guest dmesg output. Currently it is a 16K buffer.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 hmp-commands.hx |   16 +
 qmp-commands.hx |   35 +++
 virtagent.c |   99 +++
 virtagent.h |3 ++
 4 files changed, 153 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e9a7f4a..0e7a6c9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1227,6 +1227,22 @@ STEXI
 Echo the file identified by @var{filepath} on the guest filesystem
 ETEXI
 
+{
+.name   = agent_viewdmesg,
+.args_type  = ,
+.params = ,
+.help   = View guest dmesg output,
+.user_print = do_agent_viewdmesg_print,
+.mhandler.cmd_async = do_agent_viewdmesg,
+.flags  = MONITOR_CMD_ASYNC,
+},
+
+STEXI
+...@item agent_viewdmesg
+...@findex agent_viewdmesg
+View guest dmesg output
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/qmp-commands.hx b/qmp-commands.hx
index efa2137..dc319b7 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -771,6 +771,41 @@ Example:
 EQMP
 
 {
+.name   = agent_viewdmesg,
+.args_type  = ,
+.params = ,
+.help   = View guest dmesg output,
+.user_print = do_agent_viewdmesg_print,
+.mhandler.cmd_async = do_agent_viewdmesg,
+.flags  = MONITOR_CMD_ASYNC,
+},
+
+STEXI
+...@item agent_viewdmesg
+...@findex agent_viewdmesg
+View guest dmesg output
+ETEXI
+SQMP
+agent_viewdmesg
+
+
+View guest dmesg output
+
+Arguments:
+
+(none)
+
+Example:
+
+- { execute: agent_viewdmesg }
+- { return: {
+   contents: [353487.942215] usb 1-4: USB disconnect, address 9\n...
+ }
+   }
+
+EQMP
+
+{
 .name   = qmp_capabilities,
 .args_type  = ,
 .params = ,
diff --git a/virtagent.c b/virtagent.c
index 187bb28..e1fceed 100644
--- a/virtagent.c
+++ b/virtagent.c
@@ -185,3 +185,102 @@ int do_agent_viewfile(Monitor *mon, const QDict 
*mon_params,
 
 return 0;
 }
+
+void do_agent_viewdmesg_print(Monitor *mon, const QObject *data)
+{
+QDict *qdict;
+const char *contents = NULL;
+int i;
+
+qdict = qobject_to_qdict(data);
+if (!qdict_haskey(qdict, contents)) {
+goto out;
+}
+
+contents = qdict_get_str(qdict, contents);
+if (contents != NULL) {
+ /* monitor_printf truncates so do it in chunks. also, file_contents
+  * may not be null-termed at proper location so explicitly calc
+  * last chunk sizes */
+for (i = 0; i  strlen(contents); i += 1024) {
+monitor_printf(mon, %.1024s, contents + i);
+}
+}
+
+out:
+monitor_printf(mon, \n);
+}
+
+static void do_agent_viewdmesg_cb(void *opaque)
+{
+VARPCData *rpc_data = opaque;
+xmlrpc_value *resp = NULL;
+char *dmesg = NULL;
+int ret;
+xmlrpc_env env;
+QDict *qdict = qdict_new();
+
+if (rpc_data-status != VA_RPC_STATUS_OK) {
+LOG(error handling RPC request);
+goto out_no_resp;
+}
+
+xmlrpc_env_init(env);
+resp = xmlrpc_parse_response(env, rpc_data-resp_xml,
+ rpc_data-resp_xml_len);
+if (rpc_has_error(env)) {
+ret = -1;
+goto out_no_resp;
+}
+
+xmlrpc_parse_value(env, resp, s, dmesg);
+if (rpc_has_error(env)) {
+ret = -1;
+goto out;
+}
+
+if (dmesg != NULL) {
+qdict_put(qdict, contents, qstring_from_str(dmesg));
+}
+
+out:
+xmlrpc_DECREF(resp);
+out_no_resp:
+rpc_data-mon_cb(rpc_data-mon_data, QOBJECT(qdict));
+}
+
+/*
+ * do_agent_viewdmesg(): View guest dmesg output
+ */
+int do_agent_viewdmesg(Monitor *mon, const QDict *mon_params,
+  MonitorCompletion cb, void *opaque)
+{
+xmlrpc_env env;
+xmlrpc_value *params;
+VARPCData *rpc_data;
+int ret;
+
+xmlrpc_env_init(env);
+
+params = xmlrpc_build_value(env, (n));
+if (rpc_has_error(env)) {
+return -1;
+}
+
+rpc_data = qemu_mallocz(sizeof(VARPCData));
+rpc_data-cb = do_agent_viewdmesg_cb;
+rpc_data-mon_cb = cb;
+rpc_data-mon_data = opaque;
+
+ret = rpc_execute(env, getdmesg, params, rpc_data);
+if (ret == -EREMOTE) {
+monitor_printf(mon, RPC Failed (%i): %s\n, env.fault_code,
+   env.fault_string);
+return -1;
+} else if (ret == -1) {
+monitor_printf(mon, RPC communication error\n);
+return -1;
+}
+
+return 0;
+}
diff --git a/virtagent.h b/virtagent.h
index d027eac..82a6924 100644
--- a/virtagent.h
+++ b/virtagent.h
@@ -25,5 +25,8 @@
 void do_agent_viewfile_print(Monitor *mon, const QObject *qobject);
 int do_agent_viewfile(Monitor *mon, const QDict *mon_params,
   MonitorCompletion cb, void *opaque);
+void do_agent_viewdmesg_print(Monitor *mon, const QObject *qobject);
+int 

[Qemu-devel] [vgabios patch v2 01/11] - use VBE LFB address from PCI base address if present (rewrite of the cirrus specific function in main vgabios code) - removed unnecessary spaces

2010-11-03 Thread Gerd Hoffmann
From: Volker Ruppert i...@vruppert.de

---
 clext.c   |   51 ++-
 vbe.c |   59 ---
 vgabios.c |   58 ++
 3 files changed, 92 insertions(+), 76 deletions(-)

diff --git a/clext.c b/clext.c
index c7a2ad0..b0b6834 100644
--- a/clext.c
+++ b/clext.c
@@ -948,7 +948,8 @@ cirrus_vesa_01h_3:
   ;; 32-bit LFB address
   xor ax, ax
   stosw
-  call cirrus_get_lfb_addr
+  mov ax, #0x1013 ;; vendor Cirrus
+  call _pci_get_lfb_addr
   stosw
   or ax, ax
   jz cirrus_vesa_01h_4
@@ -1293,54 +1294,6 @@ cgm_2:
 cgm_3:
   ret
 
-  ; get LFB address
-  ; out - ax:LFB address (high 16 bit)
-  ;; NOTE - may be called in protected mode
-cirrus_get_lfb_addr:
-  push cx
-  push dx
-  push eax
-xor cx, cx
-mov dl, #0x00
-call cirrus_pci_read
-cmp ax, #0x
-jz cirrus_get_lfb_addr_5
- cirrus_get_lfb_addr_3:
-mov dl, #0x00
-call cirrus_pci_read
-cmp ax, #0x1013 ;; cirrus
-jz cirrus_get_lfb_addr_4
-add cx, #0x8
-cmp cx, #0x200 ;; search bus #0 and #1
-jb cirrus_get_lfb_addr_3
- cirrus_get_lfb_addr_5:
-xor dx, dx ;; no LFB
-jmp cirrus_get_lfb_addr_6
- cirrus_get_lfb_addr_4:
-mov dl, #0x10 ;; I/O space #0
-call cirrus_pci_read
-test ax, #0xfff1
-jnz cirrus_get_lfb_addr_5
-shr eax, #16
-mov dx, ax ;; LFB address
- cirrus_get_lfb_addr_6:
-  pop eax
-  mov ax, dx
-  pop dx
-  pop cx
-  ret
-
-cirrus_pci_read:
-  mov eax, #0x0080
-  mov ax, cx
-  shl eax, #8
-  mov al, dl
-  mov dx, #0xcf8
-  out dx, eax
-  add dl, #4
-  in  eax, dx
-  ret
-
 ;; out - al:bytes per pixel
 cirrus_get_bpp_bytes:
   push dx
diff --git a/vbe.c b/vbe.c
index 6173ca0..92e3d0d 100644
--- a/vbe.c
+++ b/vbe.c
@@ -766,9 +766,9 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 Bit16ucur_mode=0;
 Bit16ucur_ptr=34;
 ModeInfoListItem  *cur_info=mode_info_list;
-
+
 status = read_word(ss, AX);
-
+
 #ifdef DEBUG
 printf(VBE vbe_biosfn_return_vbe_info ES%x DI%x AX%x\n,ES,DI,status);
 #endif
@@ -784,7 +784,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
  (vbe_info_block.VbeSignature[1] == 'B') 
  (vbe_info_block.VbeSignature[2] == 'E') 
  (vbe_info_block.VbeSignature[3] == '2')) ||
- 
+
 ((vbe_info_block.VbeSignature[0] == 'V') 
  (vbe_info_block.VbeSignature[1] == 'E') 
  (vbe_info_block.VbeSignature[2] == 'S') 
@@ -796,20 +796,20 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 #endif
 }
 #endif
-
+
 // VBE Signature
 vbe_info_block.VbeSignature[0] = 'V';
 vbe_info_block.VbeSignature[1] = 'E';
 vbe_info_block.VbeSignature[2] = 'S';
 vbe_info_block.VbeSignature[3] = 'A';
-
+
 // VBE Version supported
 vbe_info_block.VbeVersion = 0x0200;
-
+
 // OEM String
 vbe_info_block.OemStringPtr_Seg = 0xc000;
 vbe_info_block.OemStringPtr_Off = vbebios_copyright;
-
+
 // Capabilities
 vbe_info_block.Capabilities[0] = VBE_CAPABILITY_8BIT_DAC;
 vbe_info_block.Capabilities[1] = 0;
@@ -824,7 +824,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 vbe_info_block.TotalMemory = VBE_TOTAL_VIDEO_MEMORY_DIV_64K;
 
 if (vbe2_info)
-   {
+{
 // OEM Stuff
 vbe_info_block.OemSoftwareRev = VBE_OEM_SOFTWARE_REV;
 vbe_info_block.OemVendorNamePtr_Seg = 0xc000;
@@ -837,12 +837,12 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 // copy updates in vbe_info_block back
 memcpyb(ES, DI, ss, vbe_info_block, sizeof(vbe_info_block));
 }
-   else
-   {
+else
+{
 // copy updates in vbe_info_block back (VBE 1.x compatibility)
 memcpyb(ES, DI, ss, vbe_info_block, 256);
-   }
-
+}
+
 do
 {
 if ((cur_info-info.XResolution = dispi_get_max_xres()) 
@@ -860,7 +860,7 @@ Bit16u *AX;Bit16u ES;Bit16u DI;
 }
 cur_info++;
 } while (cur_info-mode != VBE_VESA_MODE_END_OF_LIST);
-
+
 // Add vesa mode list terminator
 write_word(ES, DI + cur_ptr, cur_info-mode);
 
@@ -888,32 +888,37 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
 ModeInfoBlock info;
 ModeInfoListItem  *cur_info;
 Boolean   using_lfb;
+Bit16ulfb_addr;
 
 #ifdef DEBUG
 printf(VBE vbe_biosfn_return_mode_information ES%x DI%x 
CX%x\n,ES,DI,CX);
 #endif
 
 using_lfb=((CX  VBE_MODE_LINEAR_FRAME_BUFFER) == 
VBE_MODE_LINEAR_FRAME_BUFFER);
-
+
 CX = (CX  0x1ff);
-
+
 cur_info = mode_info_find_mode(CX, using_lfb, cur_info);
 
 if (cur_info != 0)
 {
 #ifdef DEBUG
   

[Qemu-devel] [vgabios patch v2 04/11] - biosfn_write_teletype: fixed attribute when scrolling in text mode

2010-11-03 Thread Gerd Hoffmann
From: Volker Ruppert i...@vruppert.de

---
 vgabios.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/vgabios.c b/vgabios.c
index fbc3588..ea3aae8 100644
--- a/vgabios.c
+++ b/vgabios.c
@@ -2039,7 +2039,9 @@ Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
   {
if(vga_modes[line].class==TEXT)
 {
- biosfn_scroll(0x01,0x07,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
+ address=SCREEN_MEM_START(nbcols,nbrows,page)+(xcurs+(ycurs-1)*nbcols)*2;
+ attr=read_byte(vga_modes[line].sstart,address+1);
+ biosfn_scroll(0x01,attr,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
 }
else
 {
@@ -2047,7 +2049,7 @@ Bit8u car;Bit8u page;Bit8u attr;Bit8u flag;
 }
ycurs-=1;
   }
- 
+
  // Set the cursor for the page
  cursor=ycurs; cursor=8; cursor+=xcurs;
  biosfn_set_cursor_pos(page,cursor);
-- 
1.7.1




[Qemu-devel] [RFC][PATCH v2 03/10] virtagent: qemu-vp, integrate virtagent server

2010-11-03 Thread Michael Roth
This allows the guest RPC server to be integrated into the
qemu-vp/virtproxy i/o loop

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qemu-vp.c |  115 -
 1 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/qemu-vp.c b/qemu-vp.c
index 0cc0e67..8944e68 100644
--- a/qemu-vp.c
+++ b/qemu-vp.c
@@ -37,6 +37,7 @@
 #include qemu-option.h
 #include qemu_socket.h
 #include virtproxy.h
+#include virtagent-daemon.h
 
 static bool verbose_enabled = 0;
 #define DEBUG_ENABLED
@@ -246,14 +247,18 @@ static void usage(const char *cmd)
 [-o oforward_opts ...]\n
 QEMU virt-proxy communication channel\n
 \n
-  -c, --channelchannel options of the form:\n
-   method:addr:port[:channel_id]\n
-  -o, --oforward   oforward options of the form:\n
-   service_id:addr:port[:channel_id]\n
-  -i, --iforward   iforward options of the form:\n
-   service_id:addr:port[:channel_id]\n
-  -v, --verbosedisplay extra debugging information\n
-  -h, --help   display this help and exit\n
+  -c, --channel channel options of the form:\n
+method:addr:port[:channel_id]\n
+  -p, --host-agent  host rpc server, options of the form:\n
+[channel_id]\n
+  -g, --guest-agent guest rpc server, options of the form:\n
+[channel_id]\n
+  -o, --oforwardoforward options of the form:\n
+service_id:addr:port[:channel_id]\n
+  -i, --iforwardiforward options of the form:\n
+service_id:addr:port[:channel_id]\n
+  -v, --verbose display extra debugging information\n
+  -h, --helpdisplay this help and exit\n
 \n
   channels are used to establish a data connection between 2 end-points in\n
   the host or the guest (connection method specified by method).\n
@@ -527,13 +532,44 @@ static int init_iforwards(void) {
 return 0;
 }
 
+static int init_agent(const VPData *agent_iforward, bool is_host) {
+QemuOpts *opts = agent_iforward-opts;
+int listen_fd, ret;
+
+INFO(initializing agent...);
+if (verbose_enabled) {
+qemu_opts_print(opts, NULL);
+}
+
+/* create unix socket pair that agent http/rpc daemon will listen on */
+listen_fd = unix_listen_opts(agent_iforward-opts);
+if (listen_fd  0) {
+return -1;
+}
+
+/* start RPC server */
+ret = va_server_start(listen_fd, is_host);
+if (ret != 0) {
+warnx(error starting RPC server);
+goto err;
+}
+
+return 0;
+
+err:
+closesocket(listen_fd);
+return -1;
+}
+
 int main(int argc, char **argv)
 {
-const char *sopt = hVvi:o:c:;
+const char *sopt = hVvi:o:c:g::p::;
 struct option lopt[] = {
 { help, 0, NULL, 'h' },
 { version, 0, NULL, 'V' },
 { verbose, 0, NULL, 'v' },
+{ host-agent, 0, NULL, 'p' },
+{ guest-agent, 0, NULL, 'g' },
 { iforward, 0, NULL, 'i' },
 { oforward, 0, NULL, 'o' },
 { channel, 0, NULL, 'c' },
@@ -543,10 +579,13 @@ int main(int argc, char **argv)
 QTAILQ_INIT(iforwards);
 QTAILQ_INIT(oforwards);
 QTAILQ_INIT(channels);
+VPData *guest_agent_iforward = NULL;
+VPData *host_agent_iforward = NULL;
 
 while ((ch = getopt_long(argc, argv, sopt, lopt, opt_ind)) != -1) {
 QemuOpts *opts;
 VPData *data;
+char optarg_tmp[VP_ARG_LEN];
 switch (ch) {
 case 'i':
 opts = qemu_opts_create(vp_opts, NULL, 0);
@@ -578,6 +617,50 @@ int main(int argc, char **argv)
 data-opts = opts;
 QTAILQ_INSERT_TAIL(channels, data, next);
 break;
+case 'g':
+/* create pre-baked iforward for guest agent */
+if (guest_agent_iforward) {
+errx(EXIT_FAILURE, only one --guest-agent argument allowed);
+}
+opts = qemu_opts_create(vp_opts, NULL, 0);
+if (optarg == 0) {
+sprintf(optarg_tmp, %s:%s:-, GUEST_AGENT_SERVICE_ID,
+ GUEST_AGENT_PATH);
+} else {
+sprintf(optarg_tmp, %s:%s:-:%d, GUEST_AGENT_SERVICE_ID,
+ GUEST_AGENT_PATH, atoi(optarg));
+}
+ret = vp_parse(opts, optarg_tmp, 0);
+if (ret) {
+errx(EXIT_FAILURE, error parsing arg: %s, optarg);
+}
+data = qemu_mallocz(sizeof(VPData));
+data-opts = opts;
+QTAILQ_INSERT_TAIL(iforwards, data, next);
+guest_agent_iforward = data;
+break;
+case 'p':
+/* create pre-baked iforward for host agent */
+if (host_agent_iforward) {
+errx(EXIT_FAILURE, only one --host-agent argument allowed);
+}
+opts = qemu_opts_create(vp_opts, NULL, 0);
+if (optarg == 0) {
+

[Qemu-devel] [vgabios patch v2 07/11] Add defines for PCI IDs.

2010-11-03 Thread Gerd Hoffmann
This patch allows to set PCI vendor and device IDs using defines
(PCI_VID and PCI_DID).  Use it for vgabios.bin.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile  |4 ++--
 vbe.c |6 +-
 vgabios.c |5 +
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index c3c744c..d440b93 100644
--- a/Makefile
+++ b/Makefile
@@ -31,8 +31,8 @@ VGA_FILES := vgabios.c vgabios.h vgafonts.h vgatables.h
 VBE_FILES := vbe.h vbe.c vbetables.h
 
 # build flags
-vgabios.bin  : VGAFLAGS := -DVBE
-vgabios.debug.bin: VGAFLAGS := -DVBE -DDEBUG
+vgabios.bin  : VGAFLAGS := -DVBE -DPCI_VID=0x1234
+vgabios.debug.bin: VGAFLAGS := -DVBE -DPCI_VID=0x1234 -DDEBUG
 vgabios-cirrus.bin   : VGAFLAGS := -DCIRRUS -DPCIBIOS 
 vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG
 
diff --git a/vbe.c b/vbe.c
index ecff90d..1fab2f9 100644
--- a/vbe.c
+++ b/vbe.c
@@ -925,7 +925,11 @@ Bit16u *AX;Bit16u CX; Bit16u ES;Bit16u DI;
 if (using_lfb) {
   info.NumberOfBanks = 1;
 }
-lfb_addr = pci_get_lfb_addr(0x1234); // experimental vendor
+#ifdef PCI_VID
+lfb_addr = pci_get_lfb_addr(PCI_VID);
+#else
+lfb_addr = 0;
+#endif
 if (lfb_addr  0) {
   info.PhysBasePtr = ((Bit32u)lfb_addr  16);
 }
diff --git a/vgabios.c b/vgabios.c
index ea3aae8..2e8b5d7 100644
--- a/vgabios.c
+++ b/vgabios.c
@@ -210,8 +210,13 @@ vgabios_pci_data:
 .word 0x1013
 .word 0x00b8 // CLGD5446
 #else
+#ifdef PCI_VID
+.word PCI_VID
+.word PCI_DID
+#else
 #error Unknown PCI vendor and device id
 #endif
+#endif
 .word 0 // reserved
 .word 0x18 // dlen
 .byte 0 // revision
-- 
1.7.1




[Qemu-devel] [vgabios patch v2 11/11] Add qemu qxl vga pci bios

2010-11-03 Thread Gerd Hoffmann
Add PCI vgabios for the qemu qxl vga (1b36:0100).
Name it vgabios-qxl.bin.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 2a093e8..578721a 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ RELVERS = `pwd | sed s-.*/-- | sed s/vgabios// | sed 
s/-//`
 
 VGABIOS_DATE = -DVGABIOS_DATE=\$(RELDATE)\
 
-all: bios cirrus-bios stdvga-bios vmware-bios
+all: bios cirrus-bios stdvga-bios vmware-bios qxl-bios
 
 bios: vgabios.bin vgabios.debug.bin
 
@@ -24,6 +24,8 @@ stdvga-bios: vgabios-stdvga.bin vgabios-stdvga.debug.bin
 
 vmware-bios: vgabios-vmware.bin vgabios-vmware.debug.bin
 
+qxl-bios: vgabios-qxl.bin vgabios-qxl.debug.bin
+
 clean:
/bin/rm -f  biossums vbetables-gen vbetables.h *.o *.s *.ld86 \
   temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core 
vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak
@@ -43,6 +45,8 @@ vgabios-stdvga.bin   : VGAFLAGS := -DVBE -DPCIBIOS 
-DPCI_VID=0x1234 -DPCI_DI
 vgabios-stdvga.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 
-DPCI_DID=0x -DDEBUG
 vgabios-vmware.bin   : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad 
-DPCI_DID=0x0405
 vgabios-vmware.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x15ad 
-DPCI_DID=0x0405 -DDEBUG
+vgabios-qxl.bin  : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1b36 
-DPCI_DID=0x0100
+vgabios-qxl.debug.bin: VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1b36 
-DPCI_DID=0x0100 -DDEBUG
 
 # dist names
 vgabios.bin  : DISTNAME := VGABIOS-lgpl-latest.bin
@@ -53,6 +57,8 @@ vgabios-stdvga.bin   : DISTNAME := 
VGABIOS-lgpl-latest.stdvga.bin
 vgabios-stdvga.debug.bin : DISTNAME := VGABIOS-lgpl-latest.stdvga.debug.bin
 vgabios-vmware.bin   : DISTNAME := VGABIOS-lgpl-latest.vmware.bin
 vgabios-vmware.debug.bin : DISTNAME := VGABIOS-lgpl-latest.vmware.debug.bin
+vgabios-qxl.bin  : DISTNAME := VGABIOS-lgpl-latest.qxl.bin
+vgabios-qxl.debug.bin: DISTNAME := VGABIOS-lgpl-latest.qxl.debug.bin
 
 # dependencies
 vgabios.bin  : $(VGA_FILES) $(VBE_FILES) biossums
@@ -63,6 +69,8 @@ vgabios-stdvga.bin   : $(VGA_FILES) $(VBE_FILES) biossums
 vgabios-stdvga.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums
 vgabios-vmware.bin   : $(VGA_FILES) $(VBE_FILES) biossums
 vgabios-vmware.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-qxl.bin  : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-qxl.debug.bin: $(VGA_FILES) $(VBE_FILES) biossums
 
 # build rule
 %.bin:
-- 
1.7.1




[Qemu-devel] [vgabios patch v2 05/11] - updates for release 0.6c

2010-11-03 Thread Gerd Hoffmann
From: Volker Ruppert i...@vruppert.de

---
 ChangeLog |   12 
 README|3 ++-
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 35bf00a..dbaed5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-04-07 20:18  vruppert
+
+   * vgabios.c (1.69):
+
+   - biosfn_write_teletype: fixed attribute when scrolling in text mode
+
+2009-04-06 20:17  vruppert
+
+   * ChangeLog (1.28), README (1.17):
+
+   - preparing for release 0.6c
+
 2009-01-25 16:46  vruppert
 
* vbe.c (1.62), vbe.h (1.28), vbetables-gen.c (1.5):
diff --git a/README b/README
index ce67aeb..c68b573 100644
--- a/README
+++ b/README
@@ -90,11 +90,12 @@ For any information on qemu, visit the website 
http://fabrice.bellard.free.fr/qe
 
 History
 ---
-vgabios-0.6c : not yet released
+vgabios-0.6c : Apr 08 2009
   - Volker
 . added DPMS support to cirrus vgabios (patch from Gleb Natapov)
 . use VBE LFB address from PCI base address if present
 . added support for a lot more non-standard VBE modes (e.g. widescreen 
modes)
+. minor bugfixes
 
 vgabios-0.6b : May 30 2008
   - Volker
-- 
1.7.1




[Qemu-devel] [PATCH v3 1/4] Add new vgabios binaries to blobs list.

2010-11-03 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 02698e9..663d1a1 100644
--- a/Makefile
+++ b/Makefile
@@ -178,8 +178,9 @@ ar  de en-us  fi  fr-be  hr it  lv  nl 
pl  ru th \
 common  de-ch  es fo  fr-ca  hu ja  mk  nl-be  pt  sl tr
 
 ifdef INSTALL_BLOBS
-BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin ppc_rom.bin \
-openbios-sparc32 openbios-sparc64 openbios-ppc \
+BLOBS=bios.bin vgabios.bin vgabios-cirrus.bin \
+vgabios-stdvga.bin vgabios-vmware.bin vgabios-qxl.bin \
+ppc_rom.bin openbios-sparc32 openbios-sparc64 openbios-ppc \
 gpxe-eepro100-80861209.rom \
 gpxe-eepro100-80861229.rom \
 pxe-e1000.bin \
-- 
1.7.1




[Qemu-devel] [vgabios patch v2 06/11] Makefile cleanup

2010-11-03 Thread Gerd Hoffmann
Use a single rule for building bios binaries.
Use target specific variables to set compile flags.

This makes it more obvious what the differences between the versions
are.  It also makes it easier to add new bios binaries with slightly
different settings.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile |   76 +++--
 1 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/Makefile b/Makefile
index 00e8c66..c3c744c 100644
--- a/Makefile
+++ b/Makefile
@@ -16,8 +16,7 @@ VGABIOS_DATE = -DVGABIOS_DATE=\$(RELDATE)\
 
 all: bios cirrus-bios
 
-
-bios: biossums vgabios.bin vgabios.debug.bin
+bios: vgabios.bin vgabios.debug.bin
 
 cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin
 
@@ -27,6 +26,39 @@ clean:
 
 dist-clean: clean
 
+# source files
+VGA_FILES := vgabios.c vgabios.h vgafonts.h vgatables.h
+VBE_FILES := vbe.h vbe.c vbetables.h
+
+# build flags
+vgabios.bin  : VGAFLAGS := -DVBE
+vgabios.debug.bin: VGAFLAGS := -DVBE -DDEBUG
+vgabios-cirrus.bin   : VGAFLAGS := -DCIRRUS -DPCIBIOS 
+vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG
+
+# dist names
+vgabios.bin  : DISTNAME := VGABIOS-lgpl-latest.bin
+vgabios.debug.bin: DISTNAME := VGABIOS-lgpl-latest.debug.bin
+vgabios-cirrus.bin   : DISTNAME := VGABIOS-lgpl-latest.cirrus.bin
+vgabios-cirrus.debug.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.debug.bin
+
+# dependencies
+vgabios.bin  : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios.debug.bin: $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-cirrus.bin   : $(VGA_FILES) clext.c biossums
+vgabios-cirrus.debug.bin : $(VGA_FILES) clext.c biossums
+
+# build rule
+%.bin:
+   $(GCC) -E -P vgabios.c $(VGABIOS_VERS) $(VGAFLAGS) $(VGABIOS_DATE)  
_$*_.c
+   $(BCC) -o $*.s -C-c -D__i86__ -S -0 _$*_.c
+   sed -e 's/^\.text//' -e 's/^\.data//' $*.s  _$*_.s
+   $(AS86) _$*_.s -b $*.bin -u -w- -g -0 -j -O -l $*.txt
+   rm -f _$*_.s _$*_.c $*.s
+   mv $*.bin $(DISTNAME)
+   ./biossums $(DISTNAME)
+   ls -l $(DISTNAME)
+
 release: 
VGABIOS_VERS=\-DVGABIOS_VERS=\\\$(RELVERS) make bios cirrus-bios
/bin/rm -f  *.o *.s *.ld86 \
@@ -37,46 +69,6 @@ release:
cp VGABIOS-lgpl-latest.cirrus.debug.bin ../$(RELEASE).cirrus.debug.bin
tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/
 
-vgabios.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h
-   $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DVBE $(VGABIOS_DATE)  
_vgabios_.c
-   $(BCC) -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c
-   sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s  _vgabios_.s
-   $(AS86) _vgabios_.s -b vgabios.bin -u -w- -g -0 -j -O -l vgabios.txt
-   rm -f _vgabios_.s _vgabios_.c vgabios.s
-   mv vgabios.bin VGABIOS-lgpl-latest.bin
-   ./biossums VGABIOS-lgpl-latest.bin
-   ls -l VGABIOS-lgpl-latest.bin
-
-vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c 
vbetables.h
-   $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DVBE -DDEBUG $(VGABIOS_DATE)  
_vgabios-debug_.c
-   $(BCC) -o vgabios-debug.s -C-c -D__i86__ -S -0 _vgabios-debug_.c
-   sed -e 's/^\.text//' -e 's/^\.data//' vgabios-debug.s  
_vgabios-debug_.s
-   $(AS86) _vgabios-debug_.s -b vgabios.debug.bin -u -w- -g -0 -j -O -l 
vgabios.debug.txt
-   rm -f _vgabios-debug_.s _vgabios-debug_.c vgabios-debug.s
-   mv vgabios.debug.bin VGABIOS-lgpl-latest.debug.bin
-   ./biossums VGABIOS-lgpl-latest.debug.bin
-   ls -l VGABIOS-lgpl-latest.debug.bin
-
-vgabios-cirrus.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c
-   $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS -DPCIBIOS 
$(VGABIOS_DATE)  _vgabios-cirrus_.c
-   $(BCC) -o vgabios-cirrus.s -C-c -D__i86__ -S -0 _vgabios-cirrus_.c
-   sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus.s  
_vgabios-cirrus_.s
-   $(AS86) _vgabios-cirrus_.s -b vgabios-cirrus.bin -u -w- -g -0 -j -O -l 
vgabios.cirrus.txt
-   rm -f _vgabios-cirrus_.s _vgabios-cirrus_.c vgabios-cirrus.s
-   mv vgabios-cirrus.bin VGABIOS-lgpl-latest.cirrus.bin
-   ./biossums VGABIOS-lgpl-latest.cirrus.bin
-   ls -l VGABIOS-lgpl-latest.cirrus.bin
-
-vgabios-cirrus.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c
-   $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS -DCIRRUS_DEBUG 
-DPCIBIOS $(VGABIOS_DATE)  _vgabios-cirrus-debug_.c
-   $(BCC) -o vgabios-cirrus-debug.s -C-c -D__i86__ -S -0 
_vgabios-cirrus-debug_.c
-   sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus-debug.s  
_vgabios-cirrus-debug_.s
-   $(AS86) _vgabios-cirrus-debug_.s -b vgabios.cirrus.debug.bin -u -w- -g 
-0 -j -O -l vgabios.cirrus.debug.txt
-   rm -f _vgabios-cirrus-debug_.s _vgabios-cirrus-debug_.c 
vgabios-cirrus-debug.s
-   mv vgabios.cirrus.debug.bin VGABIOS-lgpl-latest.cirrus.debug.bin
-   ./biossums 

[Qemu-devel] [PATCH v3 4/4] more stdvga cleanups.

2010-11-03 Thread Gerd Hoffmann
video.x is gone now.  It was the only user of the
vga bios_offset + bios_size logic.  Zap it.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/mips_malta.c   |2 +-
 hw/pc.c   |2 +-
 hw/pc.h   |3 +--
 hw/ppc_newworld.c |2 +-
 hw/ppc_oldworld.c |2 +-
 hw/ppc_prep.c |2 +-
 hw/sun4u.c|2 +-
 hw/vga-pci.c  |   42 --
 hw/vga.c  |2 --
 hw/vga_int.h  |2 --
 10 files changed, 15 insertions(+), 46 deletions(-)

diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 8026071..6be8aa7 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -977,7 +977,7 @@ void mips_malta_init (ram_addr_t ram_size,
 } else if (vmsvga_enabled) {
 pci_vmsvga_init(pci_bus);
 } else if (std_vga_enabled) {
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 }
 }
 
diff --git a/hw/pc.c b/hw/pc.c
index 69b13bf..0e44df8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -993,7 +993,7 @@ void pc_vga_init(PCIBus *pci_bus)
 fprintf(stderr, %s: vmware_vga: no PCI bus\n, __FUNCTION__);
 } else if (std_vga_enabled) {
 if (pci_bus) {
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 } else {
 isa_vga_init();
 }
diff --git a/hw/pc.h b/hw/pc.h
index 63b0249..6852790 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -154,8 +154,7 @@ enum vga_retrace_method {
 extern enum vga_retrace_method vga_retrace_method;
 
 int isa_vga_init(void);
-int pci_vga_init(PCIBus *bus,
- unsigned long vga_bios_offset, int vga_bios_size);
+int pci_vga_init(PCIBus *bus);
 int isa_vga_mm_init(target_phys_addr_t vram_base,
 target_phys_addr_t ctrl_base, int it_shift);
 
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 4369337..305b2d4 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -316,7 +316,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
 machine_arch = ARCH_MAC99;
 }
 /* init basic PC hardware */
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 
 escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24],
serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index a2f9ddf..5efc93d 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -227,7 +227,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
 }
 pic = heathrow_pic_init(pic_mem_index, 1, heathrow_irqs);
 pci_bus = pci_grackle_init(0xfec0, pic);
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 
 escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
serial_hds[1], ESCC_CLOCK, 4);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index a6915f7..b1f9cc7 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -694,7 +694,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
 cpu_register_physical_memory(0x8000, 0x0080, PPC_io_memory);
 
 /* init basic PC hardware */
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 //openpic = openpic_init(0x, 0xF000, 1);
 //pit = pit_init(0x40, i8259[0]);
 rtc_init(2000, NULL);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 45a46d6..5292ac6 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -767,7 +767,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
 pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, irq, pci_bus2,
pci_bus3);
 isa_mem_base = APB_PCI_IO_BASE;
-pci_vga_init(pci_bus, 0, 0);
+pci_vga_init(pci_bus);
 
 // XXX Should be pci_bus3
 pci_ebus_init(pci_bus, -1);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index eef0e3c..b09789c 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -52,14 +52,11 @@ static void vga_map(PCIDevice *pci_dev, int region_num,
 {
 PCIVGAState *d = (PCIVGAState *)pci_dev;
 VGACommonState *s = d-vga;
-if (region_num == PCI_ROM_SLOT) {
-cpu_register_physical_memory(addr, s-bios_size, s-bios_offset);
-} else {
-cpu_register_physical_memory(addr, s-vram_size, s-vram_offset);
-s-map_addr = addr;
-s-map_end = addr + s-vram_size;
-vga_dirty_log_start(s);
-}
+
+cpu_register_physical_memory(addr, s-vram_size, s-vram_offset);
+s-map_addr = addr;
+s-map_end = addr + s-vram_size;
+vga_dirty_log_start(s);
 }
 
 static void pci_vga_write_config(PCIDevice *d,
@@ -95,31 +92,12 @@ static int pci_vga_initfn(PCIDevice *dev)
  pci_register_bar(d-dev, 0, VGA_RAM_SIZE,
   PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
 
- if (s-bios_size) {
-unsigned int bios_total_size;
-/* must be a power of two */
-bios_total_size = 1;
-while (bios_total_size  s-bios_size)
-bios_total_size = 1;
-pci_register_bar(d-dev, PCI_ROM_SLOT, bios_total_size,
- 

[Qemu-devel] [vgabios patch v2 00/11] vgabios update

2010-11-03 Thread Gerd Hoffmann
  Hi,

This patch series updates the vgabios, the patches are intended for
the vgabios.git tree @ git.qemu.org

The first five patches are taken from the vgabios cvs and update the
vgabios.git tree @ qemu.org to vgabios release 0.6c.  As this update
depends on a newer bochs API it fully works on qemu 0.13 and master
only.  When using this vgabios version on qemu 0.12 vesa bios support
will break.

The last six patches cleanup the build system a bit, add a proper
PCIROM header so seabios will happily load the roms from the PCI option
rom bar and add vgabios binaries for all current and the upcoming qxl
vga device.

Changes in v2:
 * added proper signed-off to my patches.

please pull,
  Gerd

The following changes since commit 6e62666cfc19e7fd45dd0d7c3ad62fd8d0b5f67a:

  - added DPMS support to cirrus vgabios (patch from Gleb Natapov) (2008-12-14 
08:29:48 +)

are available in the git repository at:
  git://anongit.freedesktop.org/~kraxel/vgabios pcibios.2

Gerd Hoffmann (6):
  Makefile cleanup
  Add defines for PCI IDs.
  Add qemu stdvga pci bios
  update pci_get_lfb_addr for vmware vga
  Add qemu vmware vga pci bios
  Add qemu qxl vga pci bios

Volker Ruppert (5):
  - use VBE LFB address from PCI base address if present (rewrite of the 
cirrus specific function in main vgabios code) - removed unnecessary spaces
  - added support for a lot more non-standard VBE modes (e.g. widescreen 
modes) - requires latest Bochs VBE code (16 MB video memory, VBE_DISPI_ID5, 
VRAM size in 64k pages stored in VBE register) - check if VBE mode is supported 
with current VRAM size
  - preparing for release 0.6c
  - biosfn_write_teletype: fixed attribute when scrolling in text mode
  - updates for release 0.6c

 ChangeLog   |   47 +
 Makefile|  102 ---
 README  |7 
 clext.c |   51 +--
 vbe.c   |   94 ---
 vbe.h   |   70 +++--
 vbetables-gen.c |   43 +--
 vgabios.c   |   74 ++-
 8 files changed, 314 insertions(+), 174 deletions(-)



[Qemu-devel] [PATCH v3 3/4] switch vmware_vga to pci vgabios

2010-11-03 Thread Gerd Hoffmann
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/vmware_vga.c |7 +--
 1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 3d25c14..9337fdb 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -114,14 +114,12 @@ struct pci_vmsvga_state_s {
 # define SVGA_IO_BASE  SVGA_LEGACY_BASE_PORT
 # define SVGA_IO_MUL   1
 # define SVGA_FIFO_SIZE0x1
-# define SVGA_MEM_BASE 0xe000
 # define SVGA_PCI_DEVICE_IDPCI_DEVICE_ID_VMWARE_SVGA2
 #else
 # define SVGA_ID   SVGA_ID_1
 # define SVGA_IO_BASE  SVGA_LEGACY_BASE_PORT
 # define SVGA_IO_MUL   4
 # define SVGA_FIFO_SIZE0x1
-# define SVGA_MEM_BASE 0xe000
 # define SVGA_PCI_DEVICE_IDPCI_DEVICE_ID_VMWARE_SVGA
 #endif
 
@@ -1219,10 +1217,6 @@ static void vmsvga_init(struct vmsvga_state_s *s, int 
vga_ram_size)
 vga_init(s-vga);
 vmstate_register(NULL, 0, vmstate_vga_common, s-vga);
 
-vga_init_vbe(s-vga);
-
-rom_add_vga(VGABIOS_FILENAME);
-
 vmsvga_reset(s);
 }
 
@@ -1320,6 +1314,7 @@ static PCIDeviceInfo vmsvga_info = {
 .qdev.size= sizeof(struct pci_vmsvga_state_s),
 .qdev.vmsd= vmstate_vmware_vga,
 .init = pci_vmsvga_initfn,
+.romfile  = vgabios-vmware.bin,
 };
 
 static void vmsvga_register(void)
-- 
1.7.1




[Qemu-devel] [PATCH v3 0/4] use new vgabios.

2010-11-03 Thread Gerd Hoffmann
  Hi,

This patch series will put the new vgabios into use for stdvga and
vmware_vga.  The vgabios patches this patch series depends on have
just been posted to the list.

For obvious reasons it depends on the new vgabios binaries being
present, i.e. vgabios patches being committed to vgabios.git, subtree
being updated and vgabios binaries being recompiled + committed to
qemu.git.

Changes in v3:
  * rebase to master.
  * added proper signed-off.

Changes in v2:
  * rebase to master, resolve video.x removal conflict.
  * add a new clean up patch, removes bits which where
used by video.x code only.

please pull,
  Gerd

The following changes since commit 7d72e76228351d18a856f1e4f5365b59d3205dc3:

  intel-hda: documentation update (2010-11-02 00:41:04 +0300)

are available in the git repository at:
  git://anongit.freedesktop.org/spice/qemu vgabios.3

Gerd Hoffmann (4):
  Add new vgabios binaries to blobs list.
  switch stdvga to pci vgabios
  switch vmware_vga to pci vgabios
  more stdvga cleanups.

 Makefile  |5 +++--
 hw/mips_malta.c   |2 +-
 hw/pc.c   |2 +-
 hw/pc.h   |3 +--
 hw/ppc_newworld.c |2 +-
 hw/ppc_oldworld.c |2 +-
 hw/ppc_prep.c |2 +-
 hw/sun4u.c|2 +-
 hw/vga-pci.c  |   43 ---
 hw/vga.c  |2 --
 hw/vga_int.h  |2 --
 hw/vmware_vga.c   |7 +--
 12 files changed, 19 insertions(+), 55 deletions(-)



[Qemu-devel] [vgabios patch v2 08/11] Add qemu stdvga pci bios

2010-11-03 Thread Gerd Hoffmann
Add PCI vgabios for the qemu standard vga (1234:).
Name it vgabios-stdvga.bin.

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 Makefile |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index d440b93..58f064e 100644
--- a/Makefile
+++ b/Makefile
@@ -14,12 +14,14 @@ RELVERS = `pwd | sed s-.*/-- | sed s/vgabios// | sed 
s/-//`
 
 VGABIOS_DATE = -DVGABIOS_DATE=\$(RELDATE)\
 
-all: bios cirrus-bios
+all: bios cirrus-bios stdvga-bios
 
 bios: vgabios.bin vgabios.debug.bin
 
 cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin
 
+stdvga-bios: vgabios-stdvga.bin vgabios-stdvga.debug.bin
+
 clean:
/bin/rm -f  biossums vbetables-gen vbetables.h *.o *.s *.ld86 \
   temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core 
vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak
@@ -35,18 +37,24 @@ vgabios.bin  : VGAFLAGS := -DVBE 
-DPCI_VID=0x1234
 vgabios.debug.bin: VGAFLAGS := -DVBE -DPCI_VID=0x1234 -DDEBUG
 vgabios-cirrus.bin   : VGAFLAGS := -DCIRRUS -DPCIBIOS 
 vgabios-cirrus.debug.bin : VGAFLAGS := -DCIRRUS -DPCIBIOS -DCIRRUS_DEBUG
+vgabios-stdvga.bin   : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 
-DPCI_DID=0x
+vgabios-stdvga.debug.bin : VGAFLAGS := -DVBE -DPCIBIOS -DPCI_VID=0x1234 
-DPCI_DID=0x -DDEBUG
 
 # dist names
 vgabios.bin  : DISTNAME := VGABIOS-lgpl-latest.bin
 vgabios.debug.bin: DISTNAME := VGABIOS-lgpl-latest.debug.bin
 vgabios-cirrus.bin   : DISTNAME := VGABIOS-lgpl-latest.cirrus.bin
 vgabios-cirrus.debug.bin : DISTNAME := VGABIOS-lgpl-latest.cirrus.debug.bin
+vgabios-stdvga.bin   : DISTNAME := VGABIOS-lgpl-latest.stdvga.bin
+vgabios-stdvga.debug.bin : DISTNAME := VGABIOS-lgpl-latest.stdvga.debug.bin
 
 # dependencies
 vgabios.bin  : $(VGA_FILES) $(VBE_FILES) biossums
 vgabios.debug.bin: $(VGA_FILES) $(VBE_FILES) biossums
 vgabios-cirrus.bin   : $(VGA_FILES) clext.c biossums
 vgabios-cirrus.debug.bin : $(VGA_FILES) clext.c biossums
+vgabios-stdvga.bin   : $(VGA_FILES) $(VBE_FILES) biossums
+vgabios-stdvga.debug.bin : $(VGA_FILES) $(VBE_FILES) biossums
 
 # build rule
 %.bin:
-- 
1.7.1




[Qemu-devel] [PATCH v3 2/4] switch stdvga to pci vgabios

2010-11-03 Thread Gerd Hoffmann
Make stdvga provide the new vgabios binary (with pcibios support)
using the PCI option rom bar.  Seabios will happily load it from
there.  The new vga bios will also lookup the framebuffer address
in pci config space, so the magic bochs lfb @ 0xe000 is not
needed any more - zap it.

Without the patch:

  # dmesg | grep framebuffer
  vesafb: framebuffer at 0xe000, mapped to 0xf7e8, using 1875k, total 
8192k
  # lspci -vs2
  00:02.0 VGA compatible controller: Technical Corp. Device  (prog-if 00 
[VGA controller])
Subsystem: Qumranet, Inc. Device 1100
Physical Slot: 2
Flags: fast devsel
Memory at f000 (32-bit, prefetchable) [size=8M]
Expansion ROM at unassigned [disabled]

With patch applied:

  # dmesg | grep framebuffer
  vesafb: framebuffer at 0xf000, mapped to 0xf7e8, using 1875k, total 
8192k
  # lspci -vs2
  00:02.0 VGA compatible controller: Technical Corp. Device  (prog-if 00 
[VGA controller])
Subsystem: Qumranet, Inc. Device 1100
Physical Slot: 2
Flags: fast devsel
Memory at f000 (32-bit, prefetchable) [size=8M]
Expansion ROM at f080 [disabled] [size=64K]

cheers,
  Gerd

Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/vga-pci.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 2315f70..eef0e3c 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -103,11 +103,10 @@ static int pci_vga_initfn(PCIDevice *dev)
 bios_total_size = 1;
 pci_register_bar(d-dev, PCI_ROM_SLOT, bios_total_size,
  PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
+ } else {
+ if (dev-romfile == NULL)
+ dev-romfile = qemu_strdup(vgabios-stdvga.bin);
  }
-
-vga_init_vbe(s);
- /* ROM BIOS */
- rom_add_vga(VGABIOS_FILENAME);
  return 0;
 }
 
-- 
1.7.1




Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Ryan Harper
* Michael S. Tsirkin m...@redhat.com [2010-11-03 02:22]:
 On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
  * Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
   On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
I like the idea of disconnect; if part of the device_del method 
was to
invoke a disconnect method, we could implement that for block, 
net, etc;

I'd think we'd want to send the notification, then disconnect.
Struggling with whether it's worth having some reasonable 
timeout
between notification and disconnect.  
   
   The problem with this is that it has no analog in real world.
   In real world, you can send some notifications to the guest, and 
   you can
   remove the card.  Tying them together is what created the problem 
   in the
   first place.
   
   Timeouts can be implemented by management, maybe with a nice 
   dialog
   being shown to the user.
  
  Very true.  I'm fine with forcing a disconnect during the removal 
  path
  prior to notification.  Do we want a new disconnect method at the 
  device
  level (pci)? or just use the existing removal callback and call that
  during the initial hotremov event?
 
 Not sure what you mean by that, but I don't see a device doing 
 anything
 differently wrt surprise or ordered removal. So probably the existing
 callback should do. I don't think we need to talk about disconnect:
 since we decided we are emulating device removal, let's call it
 just that.

Because current the removal process depends on the guest actually
responding.  What I'm suggesting is that, in Marcus's term, and what
drive_unplug() implements, is to disconnect the host block device from
the guest device to prevent any further access to it in the case the
guest doesn't respond to the removal request made via ACPI.

Very specifically, what we're suggesting instead of the drive_unplug()
command so to complete the device removal operation without waiting for
the guest to respond; that's what's going to happen if we invoke the
response callback; it will appear as if the guest responded whether it
did or not.

What I was suggesting above was to instead of calling the callback for
handing the guest response was to add a device function called
disconnect which would remove any association of host resources from
guest resources before we notified the guest.  Thinking about it again
I'm not sure this is useful, but if we're going to remove the device
without the guests knowledge, I'm not sure how useful sending the
removal requests via ACPI is in the first place.

My feeling is that I'd like to have explicit control over the disconnect
from host resources separate from the device removal *if* we're going to
retain the guest notification.  If we don't care to notify the guest,
then we can just do device removal without notifying the guest
and be done with it.
   
   I imagine management would typically want to do this:
   1. notify guest
   2. wait a bit
   3. remove device
  
  Yes; but this argues for (1) being a separate command from (3)
 
 Yes. Long term I think we will want a way to do that.
 
  unless we
  require (3) to include (1) and (2) in the qemu implementation.
  
  Currently we implement:
  
  1. device_del (attempt to remove device)
  2. notify guest
  3. if guest responds, remove device
  4. disconnect host resource from device on destruction
  
  With my drive_unplug patch we do:
  
  1. disconnect host resource from device
 
 This is what drive_unplug does, right?

Correct.

 
  2. device_del (attempt to remove device)
  3. notify guest
  4. if guest responds, remove device
  
  I think we're suggesting to instead do (if we keep disconnect as part of
  device_del)
  
  1. device_del (attemp to remove device)
  2. notify guest
  3. invoke device destruction callback resulting in disconnect host resource 
  from device
  4. if guest responds, invoke device destruction path a second time.
 
 By response you mean eject?  No, this is not what I was suggesting.
 I was really suggesting that your patch is fine :)
 Sorry about confusion.

I don't mean eject; I mean responding to the ACPI event by writing a
response to the PCI chipset which QEMU then in turn will invoke the
qdev_unplug() path which ultimately kills the device and the Drive and
BlockState objects.

 
 I was also saying that from what I hear, the pci express support
 will at some point need interfaces to
 - notify guest about device removal/addition
 - get eject from guest
 - remove device without talking to guest
 - add device without talking to guest
 - suppress device deletion on eject
 
 All this can be generic and can work through express
 configuration mechanisms or through acpi for pci.
 But this is 

[Qemu-devel] [Bug 626781] Re: Live migration: bandwitdth calculation and rate limiting not working

2010-11-03 Thread eslay
Hi,

I issued a bug report (626781) months ago. Any news on it? By the way, I
think it is really a bug other than a question.

Regards,
eslay

** Changed in: qemu
   Status: New = Invalid

** Converted to question:
   https://answers.launchpad.net/qemu/+question/132364

-- 
Live migration: bandwitdth calculation and rate limiting not working
https://bugs.launchpad.net/bugs/626781
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: Invalid

Bug description:
I am using QEMU 0.12.5 to perform live migration between 2 Linux hosts. One 
Linux Host has 6 cores and 24G RAM, the other has 2 cores and 16G RAM. For each 
host, I have one Ethernet interface for NFS storage, another interface for live 
migration and a third interface for the VM to communicate to outside network. 
Each interface has 1G bandwidth.

It is observed that programs like below (which generates dirty pages very 
quickly) will hang the live migration:

#include stdio.h
#include stdlib.h

main()
{ 
unsigned char *array; 
long int i,j,k;
unsigned char c;
long int loop=0;
array=malloc(1024*1024*1024);
while(1)
{
for(i=0;i1024;i++)
{
c=0;
for(j=0;j1024;j++)
{
c++;
for(k=0;k1024;k++)
{
array[i*1024*1024+j*1024+k]=c;
}
}
}
loop++;
if(loop%256==0) printf(%ld\n,loop);
   }
}


It is observed that the traffic down time (measured by ping -f from a 3rd 
host) has dependency on RAM size of the virtual machine:

RAM SizeTraffic Down Time   Total Migration Time
1024M   0.5s  33s
2048M   0.7s  34s
4096M   2.7s  39s
8912M   5.3s  45s
16384M  7.2s 61s

Using the command migrate_set_downtime in QEMU console won't improve the 
problem.

Function ram_save_live() in vl.c shows that live migration has three stages:

Stage 1 is some preparation work.
 
Stage 2 is to transfer VM RAM to target host and keep the VM alive at source 
host. In Stage 2, the realtime migration bandwidth is calculated (Line 
3099~3117 in vl.c). At the end of Stage 2 (Line 3130), the expected left time 
of RAM transmission is calculated (Left RAM Size / Calculated Bandwidth). If 
the expected left time is less than the max migration down time, Stage 2 is 
ended and Stage 3 starts.
 
Stage 3 is to stop the VM at the source host, transfer left RAM at full speed, 
and then start the VM at the target host. The period of Stage 3 is believed to 
be the period when the outside lost connection to the VM.
 
This is how live migration is supposed to work.

There is a parameter max_throttle in migration.c, which sets the max allowed 
bandwidth for rate limiting. The default value of this parameter is 32Mb/s (if 
not using command migrate_set_speed to change the value). But it does not 
matter because the rate limiting faction does not work anyway. There is another 
parameter max_downtime in migration.c, which sets the max allowed traffic 
down time for live migration.By default the value is set to 30ms (if not using 
command migrate_set_downtime to change the value). This value to way too 
small, so if using the source code above, live migration will hang. Stage 2 
will never end since the expected left time would never be less than 30ms. 
However, changing the parameter to something like 1000ms will solve the hanging 
problem.

After changing the default value of max_downtime, the long traffic down time 
problem still exits. The following faults are found:
 
a) The bandwidth calculation in ram_save_live() (the first attachment) is 
wrong. The bandwidth should equal to data transferred divided by the period of 
transmission time. The period of transmission time should be the interval 
between two consecutive calls of function ram_save_live(), which is usually 
100ms (There should be a timer interrupt to control this). However, what the 
code use is the execution time of the while loop between Line 3102 and 3109. 
That is usually 2~5ms! This will yield to unreasonable large bandwidth 
(6~12Gb/s), and in turn will make the estimated execution time of Stage 3 
inaccurate. For example, if the estimated execution time of Stage 3 is 900ms, 
the actual execution time can be  like10s!
 
b) The rate limiting function (qemu_file_rate_limit() which calls 
buffered_rate_limit() in buffered_file.c) does not work at all. No matter 
what parameters are set, the rate limiting function behaves the same: in Stage 
2, in most time the migration bandwidth is ~400 Mb/s. When a certain condition 
is fulfilled (I don't know exactly what condition but definitely not the number 
of iteration times), QEMU will read the VM RAM at full speed and throw 
everything to the Ethernet link. This stalls the CPU and 

Re: [Qemu-devel] MSI broken?

2010-11-03 Thread Isaku Yamahata
On Wed, Nov 03, 2010 at 12:03:15PM +0100, Gerd Hoffmann wrote:
  Hi,

 What is the status if the recently merged MSI support?

 I'm trying to use it to add msi support to the intel-hda driver (current  
 wip patch attached).  Everything works fine up to the point where it  
 comes to delivering the interrupt to the guest.  msi_notify pretends to  
 signal the guest:

 msi_notify:243 intel-hda:30 notify vector 0x0 address: 0xfee01008 data:  
 0x4151

 The guest never ever receives this interrupt though:

 [r...@localhost ~]# grep hda /proc/interrupts
  43:  0   PCI-MSI-edge  hda_intel

 Ideas anyone?

Let's track it down futher.
Were acpi_mem_writel() and apic_send_msi() in hw/apic.c called or not?
-- 
yamahata



Re: [Qemu-devel] MSI broken?

2010-11-03 Thread Gerd Hoffmann

On 11/03/10 13:34, Isaku Yamahata wrote:

On Wed, Nov 03, 2010 at 12:03:15PM +0100, Gerd Hoffmann wrote:

  Hi,

What is the status if the recently merged MSI support?

I'm trying to use it to add msi support to the intel-hda driver (current
wip patch attached).  Everything works fine up to the point where it
comes to delivering the interrupt to the guest.  msi_notify pretends to
signal the guest:

msi_notify:243 intel-hda:30 notify vector 0x0 address: 0xfee01008 data:
0x4151

The guest never ever receives this interrupt though:

[r...@localhost ~]# grep hda /proc/interrupts
  43:  0   PCI-MSI-edge  hda_intel

Ideas anyone?


Let's track it down futher.
Were acpi_mem_writel() and apic_send_msi() in hw/apic.c called or not?


No such function in my tree (savannah/master).

Looks like some bits needed for msi are not merged yet?

cheers,
  Gerd



Re: [Qemu-devel] MSI broken?

2010-11-03 Thread Isaku Yamahata
On Wed, Nov 03, 2010 at 01:40:59PM +0100, Gerd Hoffmann wrote:
 On 11/03/10 13:34, Isaku Yamahata wrote:
 On Wed, Nov 03, 2010 at 12:03:15PM +0100, Gerd Hoffmann wrote:
   Hi,

 What is the status if the recently merged MSI support?

 I'm trying to use it to add msi support to the intel-hda driver (current
 wip patch attached).  Everything works fine up to the point where it
 comes to delivering the interrupt to the guest.  msi_notify pretends to
 signal the guest:

 msi_notify:243 intel-hda:30 notify vector 0x0 address: 0xfee01008 data:
 0x4151

 The guest never ever receives this interrupt though:

 [r...@localhost ~]# grep hda /proc/interrupts
   43:  0   PCI-MSI-edge  hda_intel

 Ideas anyone?

 Let's track it down futher.
 Were acpi_mem_writel() and apic_send_msi() in hw/apic.c called or not?

 No such function in my tree (savannah/master).

 Looks like some bits needed for msi are not merged yet?

Sorry typo. s/acpi/apic/.

I'm looking at 7d72e76228351d18a856f1e4f5365b59d3205dc3
of git://git.savannah.nongnu.org/qemu.git



 cheers,
   Gerd


-- 
yamahata



Re: [Qemu-devel] [PATCHv2 4/8] Store IDE bus id in IDEBus structure for easy access.

2010-11-03 Thread Markus Armbruster
Here's a generic answer to the question which of the device's buses is
this?

int qbus_index(BusState *bus)
{
BusState *b;
int i, index;

index = -1;
i = 0;
QLIST_FOREACH(b, bus-parent-child_bus, sibling) {
if (b == bus) {
index = i;
}
i++;
}
assert(0 = index  index  i);
return i - 1 - index;
}

The bus created first has index 0.

Note that the child_bus holds the children in reverse creation order,
and we can't traverse it backwards.  Same problem also visible with
makes info qtree:

  dev: piix3-ide, id 
[...]
bus: ide.1
  type IDE
bus: ide.0
  type IDE



Re: [Qemu-devel] [PATCHv2 4/8] Store IDE bus id in IDEBus structure for easy access.

2010-11-03 Thread Gleb Natapov
On Wed, Nov 03, 2010 at 02:39:52PM +0100, Markus Armbruster wrote:
 Here's a generic answer to the question which of the device's buses is
 this?
 
 int qbus_index(BusState *bus)
 {
 BusState *b;
 int i, index;
 
 index = -1;
 i = 0;
 QLIST_FOREACH(b, bus-parent-child_bus, sibling) {
 if (b == bus) {
 index = i;
 }
 i++;
 }
 assert(0 = index  index  i);
 return i - 1 - index;
 }
 
 The bus created first has index 0.
 
 Note that the child_bus holds the children in reverse creation order,
 and we can't traverse it backwards.  Same problem also visible with
 makes info qtree:
 
   dev: piix3-ide, id 
 [...]
 bus: ide.1
   type IDE
 bus: ide.0
   type IDE
Isn't this too implementation dependant? Are you against adding bus_id
to IDEBus? And will it work with ISA? I do not think IDEBus is
added to bus-parent-child_bus in case of ISA otherwise why both
IDEBuses have same name in isapc. Currently I have following patch
queued. It should fix isapc case too.

Fix isapc IDE bus creation

Currently we create two ide buses with the same name, so it is impossible
to use -device ide-drive,bus= to address all possible disks in the isapc
machine. Fix that by giving different names to different ide buses. Also
store IDE bus id in IDEBus structure for easy access.

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index ff80dd5..b2cbdbc 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -257,8 +257,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
 pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
 
 irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
-ide_bus_new(d-bus[0], d-dev.qdev);
-ide_bus_new(d-bus[1], d-dev.qdev);
+ide_bus_new(d-bus[0], d-dev.qdev, 0);
+ide_bus_new(d-bus[1], d-dev.qdev, 1);
 ide_init2(d-bus[0], irq[0]);
 ide_init2(d-bus[1], irq[1]);
 
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 4165543..bde2664 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -448,6 +448,7 @@ struct IDEBus {
 IDEDevice *slave;
 BMDMAState *bmdma;
 IDEState ifs[2];
+uint8_t bus_id;
 uint8_t unit;
 uint8_t cmd;
 qemu_irq irq;
@@ -564,7 +565,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo 
*hd0,
 void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
 
 /* hw/ide/qdev.c */
-void ide_bus_new(IDEBus *idebus, DeviceState *dev);
+void ide_bus_new(IDEBus *idebus, DeviceState *dev, uint8_t bus_id);
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
 
 #endif /* HW_IDE_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 9b94495..b000ab8 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -66,8 +66,9 @@ static const VMStateDescription vmstate_ide_isa = {
 static int isa_ide_initfn(ISADevice *dev)
 {
 ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
+static uint8_t bus_id = 0;
 
-ide_bus_new(s-bus, s-dev.qdev);
+ide_bus_new(s-bus, s-dev.qdev, bus_id++);
 ide_init_ioport(s-bus, s-iobase, s-iobase2);
 isa_init_irq(dev, s-irq, s-isairq);
 isa_init_ioport_range(dev, s-iobase, 8);
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 6206201..e56777f 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -129,8 +129,8 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
 
 vmstate_register(d-dev.qdev, 0, vmstate_ide_pci, d);
 
-ide_bus_new(d-bus[0], d-dev.qdev);
-ide_bus_new(d-bus[1], d-dev.qdev);
+ide_bus_new(d-bus[0], d-dev.qdev, 0);
+ide_bus_new(d-bus[1], d-dev.qdev, 1);
 ide_init_ioport(d-bus[0], 0x1f0, 0x3f6);
 ide_init_ioport(d-bus[1], 0x170, 0x376);
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 336ffe1..220729e 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -29,9 +29,13 @@ static struct BusInfo ide_bus_info = {
 .size  = sizeof(IDEBus),
 };
 
-void ide_bus_new(IDEBus *idebus, DeviceState *dev)
+void ide_bus_new(IDEBus *idebus, DeviceState *dev, uint8_t bus_id)
 {
-qbus_create_inplace(idebus-qbus, ide_bus_info, dev, NULL);
+char name[10];
+
+snprintf(name, sizeof(name), ide.%d, bus_id); 
+qbus_create_inplace(idebus-qbus, ide_bus_info, dev, name);
+idebus-bus_id = bus_id;
 }
 
 static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
diff --git a/hw/ide/via.c b/hw/ide/via.c
index b2c7cad..cc48b2b 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -158,8 +158,8 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
 
 vmstate_register(dev-qdev, 0, vmstate_ide_pci, d);
 
-ide_bus_new(d-bus[0], d-dev.qdev);
-ide_bus_new(d-bus[1], d-dev.qdev);
+ide_bus_new(d-bus[0], d-dev.qdev, 0);
+ide_bus_new(d-bus[1], d-dev.qdev, 1);
 ide_init2(d-bus[0], isa_reserve_irq(14));
 ide_init2(d-bus[1], isa_reserve_irq(15));
 ide_init_ioport(d-bus[0], 0x1f0, 0x3f6);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 3d07ce5..cec6c9b 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -163,7 +163,7 @@ static void 

[Qemu-devel] [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Stefan Hajnoczi
Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
handler that deletes its IOHandler is exposed to .fd_write() being
called on the deleted IOHandler.

This patch fixes deletion so that .fd_read() and .fd_write() are never
called on an IOHandler that is marked for deletion.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 vl.c |   15 ---
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index 7038952..6f56123 100644
--- a/vl.c
+++ b/vl.c
@@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
 IOHandlerRecord *pioh;
 
 QLIST_FOREACH_SAFE(ioh, io_handlers, next, pioh) {
-if (ioh-deleted) {
-QLIST_REMOVE(ioh, next);
-qemu_free(ioh);
-continue;
-}
-if (ioh-fd_read  FD_ISSET(ioh-fd, rfds)) {
+if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd, rfds)) {
 ioh-fd_read(ioh-opaque);
 }
-if (ioh-fd_write  FD_ISSET(ioh-fd, wfds)) {
+if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd, wfds)) {
 ioh-fd_write(ioh-opaque);
 }
+
+/* Do this last in case read/write handlers marked it for deletion 
*/
+if (ioh-deleted) {
+QLIST_REMOVE(ioh, next);
+qemu_free(ioh);
+}
 }
 }
 
-- 
1.7.2.3




[Qemu-devel] Re: [RFC][PATCH 1/3] Linux/Guest unmapped page cache control

2010-11-03 Thread Christoph Lameter
On Fri, 29 Oct 2010, Balbir Singh wrote:

 A lot of the code is borrowed from zone_reclaim_mode logic for
 __zone_reclaim(). One might argue that the with ballooning and
 KSM this feature is not very useful, but even with ballooning,

Interesting use of zone reclaim. I am having a difficult time reviewing
the patch since you move and modify functions at the same time. Could you
separate that out a bit?

 +#define UNMAPPED_PAGE_RATIO 16

Maybe come up with a scheme that allows better configuration of the
mininum? I think in some setting we may want an absolute limit and in
other a fraction of something (total zone size or working set?)


 +bool should_balance_unmapped_pages(struct zone *zone)
 +{
 + if (unmapped_page_control 
 + (zone_unmapped_file_pages(zone) 
 + UNMAPPED_PAGE_RATIO * zone-min_unmapped_pages))
 + return true;
 + return false;
 +}





[Qemu-devel] Re: [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Juan Quintela
Stefan Hajnoczi stefa...@linux.vnet.ibm.com wrote:
 Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
 handler that deletes its IOHandler is exposed to .fd_write() being
 called on the deleted IOHandler.

 This patch fixes deletion so that .fd_read() and .fd_write() are never
 called on an IOHandler that is marked for deletion.

Reviewed by: Juan Quintela quint...@redhat.com

But once here, what (appart from networking) reads and writes to the
same fd?  And that removes the IOHandler on read while there are write
stuff pending?

Later, Juan.

 Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
 ---
  vl.c |   15 ---
  1 files changed, 8 insertions(+), 7 deletions(-)

 diff --git a/vl.c b/vl.c
 index 7038952..6f56123 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
  IOHandlerRecord *pioh;
  
  QLIST_FOREACH_SAFE(ioh, io_handlers, next, pioh) {
 -if (ioh-deleted) {
 -QLIST_REMOVE(ioh, next);
 -qemu_free(ioh);
 -continue;
 -}
 -if (ioh-fd_read  FD_ISSET(ioh-fd, rfds)) {
 +if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd, rfds)) {
  ioh-fd_read(ioh-opaque);
  }
 -if (ioh-fd_write  FD_ISSET(ioh-fd, wfds)) {
 +if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd, wfds)) {
  ioh-fd_write(ioh-opaque);
  }
 +
 +/* Do this last in case read/write handlers marked it for 
 deletion */
 +if (ioh-deleted) {
 +QLIST_REMOVE(ioh, next);
 +qemu_free(ioh);
 +}
  }
  }



Re: [Qemu-devel] Re: [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Stefan Hajnoczi
On Wed, Nov 3, 2010 at 2:39 PM, Juan Quintela quint...@redhat.com wrote:
 Stefan Hajnoczi stefa...@linux.vnet.ibm.com wrote:
 Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
 handler that deletes its IOHandler is exposed to .fd_write() being
 called on the deleted IOHandler.

 This patch fixes deletion so that .fd_read() and .fd_write() are never
 called on an IOHandler that is marked for deletion.

 Reviewed by: Juan Quintela quint...@redhat.com

 But once here, what (appart from networking) reads and writes to the
 same fd?  And that removes the IOHandler on read while there are write
 stuff pending?

VNC

Stefan



Re: [Qemu-devel] [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Anthony Liguori

On 11/03/2010 09:29 AM, Stefan Hajnoczi wrote:

Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
handler that deletes its IOHandler is exposed to .fd_write() being
called on the deleted IOHandler.

This patch fixes deletion so that .fd_read() and .fd_write() are never
called on an IOHandler that is marked for deletion.

Signed-off-by: Stefan Hajnoczistefa...@linux.vnet.ibm.com
---
  vl.c |   15 ---
  1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index 7038952..6f56123 100644
--- a/vl.c
+++ b/vl.c
@@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
  IOHandlerRecord *pioh;

  QLIST_FOREACH_SAFE(ioh,io_handlers, next, pioh) {
-if (ioh-deleted) {
-QLIST_REMOVE(ioh, next);
-qemu_free(ioh);
-continue;
-}
-if (ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
+if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
  ioh-fd_read(ioh-opaque);
  }
-if (ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
+if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
  ioh-fd_write(ioh-opaque);
  }
+
+/* Do this last in case read/write handlers marked it for deletion 
*/
+if (ioh-deleted) {
+QLIST_REMOVE(ioh, next);
+qemu_free(ioh);
+}
  }
   


This isn't enough.  If you end up with a handler deleting the next 
pointer and the current pointer, you'll end up running off the end of 
the list.


The original commit should be reverted.

Regards,

Anthony Liguori


  }

   





Re: [Qemu-devel] [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Anthony Liguori

On 11/03/2010 09:29 AM, Stefan Hajnoczi wrote:

Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
handler that deletes its IOHandler is exposed to .fd_write() being
called on the deleted IOHandler.

This patch fixes deletion so that .fd_read() and .fd_write() are never
called on an IOHandler that is marked for deletion.

Signed-off-by: Stefan Hajnoczistefa...@linux.vnet.ibm.com
---
  vl.c |   15 ---
  1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index 7038952..6f56123 100644
--- a/vl.c
+++ b/vl.c
@@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
  IOHandlerRecord *pioh;

  QLIST_FOREACH_SAFE(ioh,io_handlers, next, pioh) {
-if (ioh-deleted) {
-QLIST_REMOVE(ioh, next);
-qemu_free(ioh);
-continue;
-}
-if (ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
+if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
  ioh-fd_read(ioh-opaque);
  }
-if (ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
+if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
  ioh-fd_write(ioh-opaque);
  }
+
+/* Do this last in case read/write handlers marked it for deletion 
*/
+if (ioh-deleted) {
+QLIST_REMOVE(ioh, next);
+qemu_free(ioh);
+}
   


Actually, on second thought, I think this is correct although I still 
think reverting is a better strategy.


Regards,

Anthony Liguori


  }
  }

   





[Qemu-devel] Re: [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Juan Quintela
Anthony Liguori anth...@codemonkey.ws wrote:
 On 11/03/2010 09:29 AM, Stefan Hajnoczi wrote:
 Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
 handler that deletes its IOHandler is exposed to .fd_write() being
 called on the deleted IOHandler.

 This patch fixes deletion so that .fd_read() and .fd_write() are never
 called on an IOHandler that is marked for deletion.

 Signed-off-by: Stefan Hajnoczistefa...@linux.vnet.ibm.com
 ---
   vl.c |   15 ---
   1 files changed, 8 insertions(+), 7 deletions(-)

 diff --git a/vl.c b/vl.c
 index 7038952..6f56123 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
   IOHandlerRecord *pioh;

   QLIST_FOREACH_SAFE(ioh,io_handlers, next, pioh) {
 -if (ioh-deleted) {
 -QLIST_REMOVE(ioh, next);
 -qemu_free(ioh);
 -continue;
 -}
 -if (ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
 +if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd,rfds)) {
   ioh-fd_read(ioh-opaque);
   }
 -if (ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
 +if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd,wfds)) {
   ioh-fd_write(ioh-opaque);
   }
 +
 +/* Do this last in case read/write handlers marked it for 
 deletion */
 +if (ioh-deleted) {
 +QLIST_REMOVE(ioh, next);
 +qemu_free(ioh);
 +}
   }


 This isn't enough.  If you end up with a handler deleting the next
 pointer and the current pointer, you'll end up running off the end of
 the list.

What is the point of that?

That a handler can remove itself is ok.
But that a handler can remove also the next in a list that is used for
other things looks pretty insane to me.

 The original commit should be reverted.

If that behaviour is expected, then I agree that we should revert it.
But I would consider that behaviour wrong.

Later, Juan.

 Regards,

 Anthony Liguori

   }





Re: [Qemu-devel] MSI broken?

2010-11-03 Thread Gerd Hoffmann

  Hi,


Let's track it down futher.
Were acpi_mem_writel() and apic_send_msi() in hw/apic.c called or not?


No such function in my tree (savannah/master).

Looks like some bits needed for msi are not merged yet?


Sorry typo. s/acpi/apic/.


The attached patch gives me:

msi_notify:243 intel-hda:30 notify vector 0x0 address: 0xfee01008 data: 
0x4151

apic_send_msi:775 dest 1 vector 81 dest_mode 0 trigger_mode 0 delivery 1
apic_find_dest:443 no apic found for dest 1

cheers,
  Gerd
diff --git a/hw/apic.c b/hw/apic.c
index 63d62c7..9b3ba10 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -439,6 +439,8 @@ static int apic_find_dest(uint8_t dest)
 return i;
 }
 
+fprintf(stderr, %s:%d no apic found for dest %d\n,
+__FUNCTION__, __LINE__, dest);
 return -1;
 }
 
@@ -769,6 +771,8 @@ static void apic_send_msi(target_phys_addr_t addr, uint32 
data)
 uint8_t trigger_mode = (data  MSI_DATA_TRIGGER_SHIFT)  0x1;
 uint8_t delivery = (data  MSI_DATA_DELIVERY_MODE_SHIFT)  0x7;
 /* XXX: Ignore redirection hint. */
+fprintf(stderr, %s:%d dest %d vector %d dest_mode %d trigger_mode %d 
delivery %d\n,
+__FUNCTION__, __LINE__, dest, vector, dest_mode, trigger_mode, 
delivery);
 apic_deliver_irq(dest, dest_mode, delivery, vector, 0, trigger_mode);
 }
 


Re: [Qemu-devel] [PATCHv2 4/8] Store IDE bus id in IDEBus structure for easy access.

2010-11-03 Thread Markus Armbruster
Gleb Natapov g...@redhat.com writes:

 On Wed, Nov 03, 2010 at 02:39:52PM +0100, Markus Armbruster wrote:
 Here's a generic answer to the question which of the device's buses is
 this?
 
 int qbus_index(BusState *bus)
 {
 BusState *b;
 int i, index;
 
 index = -1;
 i = 0;
 QLIST_FOREACH(b, bus-parent-child_bus, sibling) {
 if (b == bus) {
 index = i;
 }
 i++;
 }
 assert(0 = index  index  i);
 return i - 1 - index;
 }
 
 The bus created first has index 0.
 
 Note that the child_bus holds the children in reverse creation order,
 and we can't traverse it backwards.  Same problem also visible with
 makes info qtree:
 
   dev: piix3-ide, id 
 [...]
 bus: ide.1
   type IDE
 bus: ide.0
   type IDE
 Isn't this too implementation dependant?

Well, it's the implementation depending on itself.

  Are you against adding bus_id
 to IDEBus?

Against is too hard a word.  If it's a general question, I'd prefer a
general answer.

And will it work with ISA? I do not think IDEBus is
 added to bus-parent-child_bus in case of ISA otherwise why both
 IDEBuses have same name in isapc. Currently I have following patch
 queued. It should fix isapc case too.

You're right, it's not helpful there: two separate devices, both
providing just one bus.

 Fix isapc IDE bus creation
 
 Currently we create two ide buses with the same name, so it is impossible
 to use -device ide-drive,bus= to address all possible disks in the isapc
 machine. Fix that by giving different names to different ide buses. Also
 store IDE bus id in IDEBus structure for easy access.

Changing the name of the second default isa-ide device's bus to ide.1
is fine with me.

But with that change in place, why do we need to store the bus number?
Why can't we just use the name?

Moreover, I think the meaning of bus number is unclear.  See comments
inline.

 diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
 index ff80dd5..b2cbdbc 100644
 --- a/hw/ide/cmd646.c
 +++ b/hw/ide/cmd646.c
 @@ -257,8 +257,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
  pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
  
  irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
 -ide_bus_new(d-bus[0], d-dev.qdev);
 -ide_bus_new(d-bus[1], d-dev.qdev);
 +ide_bus_new(d-bus[0], d-dev.qdev, 0);
 +ide_bus_new(d-bus[1], d-dev.qdev, 1);
  ide_init2(d-bus[0], irq[0]);
  ide_init2(d-bus[1], irq[1]);
  
 diff --git a/hw/ide/internal.h b/hw/ide/internal.h
 index 4165543..bde2664 100644
 --- a/hw/ide/internal.h
 +++ b/hw/ide/internal.h
 @@ -448,6 +448,7 @@ struct IDEBus {
  IDEDevice *slave;
  BMDMAState *bmdma;
  IDEState ifs[2];
 +uint8_t bus_id;

Why is this uint8_t?

  uint8_t unit;
  uint8_t cmd;
  qemu_irq irq;
 @@ -564,7 +565,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, 
 DriveInfo *hd0,
  void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
  
  /* hw/ide/qdev.c */
 -void ide_bus_new(IDEBus *idebus, DeviceState *dev);
 +void ide_bus_new(IDEBus *idebus, DeviceState *dev, uint8_t bus_id);
  IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
  
  #endif /* HW_IDE_INTERNAL_H */
 diff --git a/hw/ide/isa.c b/hw/ide/isa.c
 index 9b94495..b000ab8 100644
 --- a/hw/ide/isa.c
 +++ b/hw/ide/isa.c
 @@ -66,8 +66,9 @@ static const VMStateDescription vmstate_ide_isa = {
  static int isa_ide_initfn(ISADevice *dev)
  {
  ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
 +static uint8_t bus_id = 0;
  
 -ide_bus_new(s-bus, s-dev.qdev);
 +ide_bus_new(s-bus, s-dev.qdev, bus_id++);
  ide_init_ioport(s-bus, s-iobase, s-iobase2);
  isa_init_irq(dev, s-irq, s-isairq);
  isa_init_ioport_range(dev, s-iobase, 8);

Works for any number of isa-ide devices.  Each one provides one IDE bus,
and the buses are numbered 0, ... in the order the isa-ide devices are
created.

 diff --git a/hw/ide/piix.c b/hw/ide/piix.c
 index 6206201..e56777f 100644
 --- a/hw/ide/piix.c
 +++ b/hw/ide/piix.c
 @@ -129,8 +129,8 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
  
  vmstate_register(d-dev.qdev, 0, vmstate_ide_pci, d);
  
 -ide_bus_new(d-bus[0], d-dev.qdev);
 -ide_bus_new(d-bus[1], d-dev.qdev);
 +ide_bus_new(d-bus[0], d-dev.qdev, 0);
 +ide_bus_new(d-bus[1], d-dev.qdev, 1);
  ide_init_ioport(d-bus[0], 0x1f0, 0x3f6);
  ide_init_ioport(d-bus[1], 0x170, 0x376);
  

Each piix3-ide device provides two IDE buses numbered 0 and 1.

If you create multiple IDE controller devices, then the IDE bus numbers
and names clash, unless they're all isa-ide devices.

What is the IDE bus number supposed to mean?

Example: default piix3-ide plus a tertiary IDE channel
-M pc -device isa-ide,iobase=0x1e8,iobase2=0x3ee,irq=11

 diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
 index 336ffe1..220729e 100644
 --- a/hw/ide/qdev.c
 +++ 

[Qemu-devel] [RFC][RESEND][PATCH v1 00/15] virtproxy: host/guest communication layer

2010-11-03 Thread Michael Roth
This set of patches is a prereq for the proposed guest agent (virtagent), so 
resending these to accompany this morning's virtagent v2 submission.

OVERVIEW:

Virtproxy proxies and multiplexes socket streams over a data channel between a 
host and a guest (currently network connections, emulated serial, or 
virtio-serial channels are supported). This allows for services such as guest 
data collection agents, host/guest file transfer, and event generation/handling 
to be implemented/deployed as basic socket-based daemons, independently of the 
actual data channel.

This code is intended to provide a channel-independent abstraction layer for 
communicating with a QEMU-specific guest agent (in particular, the virtagent 
RPC guest agent which will follow this in a seperate patchset), but may have 
general utility beyond this (for instance: ssh/sftp/other guest agents/etc over 
isa/virtio serial), and so is submitted here as a seperate patchset.

Currently this communication involves 2 daemons (common code): 1 in the guest, 
and 1 in the host. Each end multiplexes/demultiplexes/proxies connections from 
the other end. In the future we hope to integrate the host component directly 
into qemu as a chardev.

BUILD/USAGE INFO:
  make qemu-vp
  ./qemu-vp -h

EXAMPLE USAGE:

 - Proxy http and ssh connections from a host to a guest over a virtio-serial 
connection:
# start guest with virtio-serial. for example (RHEL6s13):
qemu \
-device virtio-serial \
-chardev socket,path=/tmp/test0-virtioconsole.sock,server,nowait,id=test0 \
-device virtconsole,chardev=test0,name=test0 \
-chardev socket,path=/tmp/test1-virtio-serial.sock,server,nowait,id=test1 \
-device virtserialport,chardev=test1,name=test1 \
-chardev socket,path=/tmp/test2-virtio-serial.sock,server,nowait,id=test2 \
-device virtserialport,chardev=test2,name=test2 \
...
# in the host:
./qemu-vp -c unix-connect:/tmp/test2-virtio-serial.sock:- -o 
http:127.0.0.1:9080 \
  -o ssh:127.0.0.1:9022
# in the guest:
./qemu-vp -c virtserial-open:/dev/virtio-ports/test2:- -i http:127.0.0.1:80 
\
  -i ssh:127.0.0.1:22

# from host, access guest http server
wget http://locahost:9080
# from host, access guest ssh server
ssh localhost -p 9022

 - Proxy http and ssh connections from a host to a guest over a network 
connection:
# start guest with network connectivity to host
# in the guest:
./qemu-vp -c tcp-listen:guest_ip:9000 -i http:127.0.0.1:80 \
  -i ssh:127.0.0.1:22
# in the host:
./qemu-vp -c tcp-connect:guest_ip:9000 -o http:127.0.0.1:9080 \
  -o ssh:127.0.0.1:9022
...

By specifying -i and -o options in the host and guest, respectively, the 
channel can also be used to establish connections from a guest to a host.

KNOWN ISSUES:

 - Deadlocking the guest: In tests over isa-serial ports I've hit cases where 
the chardev (socket) on the host-side seem to fill up the buffer, likely due to 
qemu rate-limiting data in accordance with the port's baud rate (which may 
explain why i hadn't seen this with network-based or virtio-serial data 
channels. When qemu-vp reads data from client connections it puts it into a 
VPPacket and tries to send the packet in it's entirety back over the channel. 
In this particular case that write() blocks (or vp_send_all() spins if we set 
O_NONBLOCK on the client FD). In the meantime qemu fills up the other end of 
the socket buffer and ends up spinning in qemu-char:send_all(), basically 
causing a deadlock between qemu and qemu-vp, and causing the guest to freeze.

   Currently I'm planning on replacing vp_send_all() with a function that 
simply buffers write()'s, which would allow the use of non-blocking write()'s 
out to the channel/chardev socket while still retaining wholeness/fifo-ordering 
of the VPPackets.

 - Sync issues with virtio-serial: This may or may not be related to the issue 
above, but I noticed some cases where proxied ssh sessions from the guest to 
the host would lag by a few bytes. For instance typing top would result in 
to being displayed, and the p wouldn't show up till I hit another key. This 
could be related to how I'm handling the buffering, but I haven't been able to 
reproduce using a network-based channel.

TODO:

 - Rework vp_send_all() to use buffering to avoid above-mentioned deadlock 
scenario 
 - Integrate qemu-vp directly into qemu by adding a virtproxy chardev device. 
For example:
 ./qemu-vp -c unix-connect:/tmp/vp1-virtio-serial.sock:- -o 
ssh:127.0.0.1:9022
   in the host, would be analogous to:
 qemu \
 -device virtio-serial \
 -chardev virtproxy,oforward=ssh:127.0.0.1:9022,id=vp1 \
 -device virtserialport,chardev=vp1,name=vp1
 - Better channel negotiation to gracefully handle guest reboots/disconnects/etc
 - Add monitor commands to add/remove virtproxy channels/oforwards/iforwards on 
the fly

 .gitignore  |1 +
 Makefile|4 +-
 

[Qemu-devel] [RFC][RESEND][PATCH v1 01/15] virtproxy: base data structures and constants

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |  134 +++
 virtproxy.h |   34 +++
 2 files changed, 168 insertions(+), 0 deletions(-)
 create mode 100644 virtproxy.c
 create mode 100644 virtproxy.h

diff --git a/virtproxy.c b/virtproxy.c
new file mode 100644
index 000..f30b859
--- /dev/null
+++ b/virtproxy.c
@@ -0,0 +1,134 @@
+/*
+ * virt-proxy - host/guest communication layer
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include virtproxy.h
+
+#define VP_SERVICE_ID_LEN 32/* max length of service id string */
+#define VP_PKT_DATA_LEN 1024/* max proxied bytes per VPPacket */
+#define VP_CONN_DATA_LEN 1024   /* max bytes conns can send at a time */
+#define VP_MAGIC 0x1F374059
+
+/* listening fd, one for each service we're forwarding to remote end */
+typedef struct VPOForward {
+VPDriver *drv;
+int listen_fd;
+char service_id[VP_SERVICE_ID_LEN];
+QLIST_ENTRY(VPOForward) next;
+} VPOForward;
+
+/* service_id-path/port mapping of each service forwarded from remote end */
+typedef struct VPIForward {
+VPDriver *drv;
+char service_id[VP_SERVICE_ID_LEN];
+QemuOpts *socket_opts;
+QLIST_ENTRY(VPIForward) next;
+} VPIForward;
+
+/* proxied client/server connected states */
+typedef struct VPConn {
+VPDriver *drv;
+int client_fd;
+int server_fd;
+enum {
+VP_CONN_CLIENT = 1,
+VP_CONN_SERVER,
+} type;
+enum {
+VP_STATE_NEW = 1,   /* accept()'d and registered fd */
+VP_STATE_INIT,  /* sent init pkt to remote end, waiting for ack */
+VP_STATE_CONNECTED, /* client and server connected */
+} state;
+QLIST_ENTRY(VPConn) next;
+} VPConn;
+
+typedef struct VPControlMsg {
+enum {
+VP_CONTROL_CONNECT_INIT = 1,
+VP_CONTROL_CONNECT_ACK,
+VP_CONTROL_CLOSE,
+} type;
+union {
+/* tell remote end connect to server and map client_fd to it */
+struct {
+int client_fd;
+char service_id[VP_SERVICE_ID_LEN];
+} connect_init;
+/* tell remote end we've created the connection to the server,
+ * and give them the corresponding fd to use so we don't have
+ * to do a reverse lookup everytime
+ */
+struct {
+int client_fd;
+int server_fd;
+} connect_ack;
+/* tell remote end to close fd in question, presumably because
+ * connection was closed on our end
+ */
+struct {
+int client_fd;
+int server_fd;
+} close;
+} args;
+} VPControlMsg;
+
+typedef struct VPPacket {
+enum {
+VP_PKT_CONTROL = 1,
+VP_PKT_CLIENT,
+VP_PKT_SERVER,
+} type;
+union {
+VPControlMsg msg;
+struct {
+int client_fd;
+int server_fd;
+int bytes;
+char data[VP_PKT_DATA_LEN];
+} proxied;
+} payload;
+int magic;
+} __attribute__((__packed__)) VPPacket;
+
+struct VPDriver {
+int channel_fd;
+int listen_fd;
+char buf[sizeof(VPPacket)];
+int buflen;
+QLIST_HEAD(, VPOForward) oforwards;
+QLIST_HEAD(, VPIForward) iforwards;
+QLIST_HEAD(, VPConn) conns;
+};
+
+static QemuOptsList vp_socket_opts = {
+.name = vp_socket_opts,
+.head = QTAILQ_HEAD_INITIALIZER(vp_socket_opts.head),
+.desc = {
+{
+.name = path,
+.type = QEMU_OPT_STRING,
+},{
+.name = host,
+.type = QEMU_OPT_STRING,
+},{
+.name = port,
+.type = QEMU_OPT_STRING,
+},{
+.name = ipv4,
+.type = QEMU_OPT_BOOL,
+},{
+.name = ipv6,
+.type = QEMU_OPT_BOOL,
+},
+{ /* end if list */ }
+},
+};
diff --git a/virtproxy.h b/virtproxy.h
new file mode 100644
index 000..0203421
--- /dev/null
+++ b/virtproxy.h
@@ -0,0 +1,34 @@
+/*
+ * virt-proxy - host/guest communication layer
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VIRTPROXY_H
+#define VIRTPROXY_H
+
+#include qemu-common.h
+#include qemu-queue.h
+
+typedef struct VPDriver VPDriver;
+
+/* wrappers for s/vp/qemu/ functions we need */
+int vp_send_all(int fd, const void *buf, int len1);
+int vp_set_fd_handler2(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque);
+int 

[Qemu-devel] [RFC][RESEND][PATCH v1 08/15] virtproxy: interfaces to set/remove/handle VPOForwards

2010-11-03 Thread Michael Roth
Functions to add listener FDs (oforwards) which set up proxied connections
to associated service, and the corresponding handler function to process
to new connections to said FDs and initialize new client connections to
the associated remote server over the channel

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |  103 +++
 virtproxy.h |1 +
 2 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index cc0ac9a..6c3611b 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -12,6 +12,7 @@
  */
 
 #include virtproxy.h
+#include qemu_socket.h
 
 #define DEBUG_VP
 
@@ -314,6 +315,70 @@ static void vp_channel_read(void *opaque)
 }
 }
 
+/* handler to accept() and init new client connections */
+static void vp_oforward_accept(void *opaque)
+{
+VPOForward *f = opaque;
+VPDriver *drv = f-drv;
+
+struct sockaddr_in saddr;
+struct sockaddr *addr;
+socklen_t len;
+int fd, ret;
+VPConn *conn = NULL;
+VPPacket pkt;
+VPControlMsg msg;
+
+TRACE(called with opaque: %p, drv: %p, f, drv);
+
+for(;;) {
+len = sizeof(saddr);
+addr = (struct sockaddr *)saddr;
+fd = qemu_accept(f-listen_fd, addr, len);
+
+if (fd  0  errno != EINTR) {
+TRACE(accept() failed);
+return;
+} else if (fd = 0) {
+TRACE(accepted connection);
+break;
+}
+}
+
+if (drv-channel_fd == -1) {
+TRACE(communication channel not open, closing connection);
+closesocket(fd);
+return;
+}
+
+/* send init packet over channel */
+memset(msg, 0, sizeof(VPControlMsg));
+msg.type = VP_CONTROL_CONNECT_INIT;
+msg.args.connect_init.client_fd = fd;
+pstrcpy(msg.args.connect_init.service_id, VP_SERVICE_ID_LEN, 
f-service_id);
+
+memset(pkt, 0, sizeof(VPPacket));
+pkt.type = VP_PKT_CONTROL;
+pkt.payload.msg = msg;
+pkt.magic = VP_MAGIC;
+
+ret = vp_send_all(drv-channel_fd, pkt, sizeof(VPPacket));
+if (ret == -1) {
+LOG(vp_send_all() failed);
+return;
+}
+
+/* create new VPConn for client */
+conn = qemu_mallocz(sizeof(VPConn));
+conn-drv = drv;
+conn-client_fd = fd;
+conn-type = VP_CONN_CLIENT;
+conn-state = VP_STATE_NEW;
+QLIST_INSERT_HEAD(drv-conns, conn, next);
+
+socket_set_nonblock(fd);
+}
+
 /* create/init VPDriver object */
 VPDriver *vp_new(int fd, bool listen)
 {
@@ -336,3 +401,41 @@ VPDriver *vp_new(int fd, bool listen)
 
 return drv;
 }
+
+/* set/modify/remove a service_id - net/unix listening socket mapping
+ *
+ * service_id is a user-defined id for the service. this is what the
+ * client end will tag it's connections with so that the remote end can
+ * route it to the proper socket on the remote end.
+ *
+ * fd is a listen()'ing socket we want virtproxy to listen for new
+ * connections of this service type on. set fd to -1 to remove the 
+ * existing listening socket for this service_id
+ */
+int vp_set_oforward(VPDriver *drv, int fd, const char *service_id)
+{
+VPOForward *f = get_oforward(drv, service_id);
+
+if (fd == -1) {
+if (f != NULL) {
+vp_set_fd_handler(f-listen_fd, NULL, NULL, NULL);
+QLIST_REMOVE(f, next);
+qemu_free(f);
+}
+return 0;
+}
+
+if (f == NULL) {
+f = qemu_mallocz(sizeof(VPOForward));
+f-drv = drv;
+strncpy(f-service_id, service_id, VP_SERVICE_ID_LEN);
+QLIST_INSERT_HEAD(drv-oforwards, f, next);
+} else {
+closesocket(f-listen_fd);
+}
+
+f-listen_fd = fd;
+vp_set_fd_handler(f-listen_fd, vp_oforward_accept, NULL, f);
+
+return 0;
+}
diff --git a/virtproxy.h b/virtproxy.h
index 3df1691..39d5d40 100644
--- a/virtproxy.h
+++ b/virtproxy.h
@@ -33,5 +33,6 @@ int vp_set_fd_handler(int fd,
 
 /* virtproxy interface */
 VPDriver *vp_new(int fd, bool listen);
+int vp_set_oforward(VPDriver *drv, int fd, const char *service_id);
 
 #endif /* VIRTPROXY_H */
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 02/15] virtproxy: qemu-vp, standalone daemon skeleton

2010-11-03 Thread Michael Roth
Daemon to be run in guest, or on host in standalone mode.
(re-)implements some qemu utility functions used by core virtproxy.c
code via wrapper functions. For built-in virtproxy code we will define
these wrapper functions in terms of qemu's built-in implementations.

Main logic will come in a later patch.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 qemu-vp.c |  151 +
 1 files changed, 151 insertions(+), 0 deletions(-)
 create mode 100644 qemu-vp.c

diff --git a/qemu-vp.c b/qemu-vp.c
new file mode 100644
index 000..5075cdc
--- /dev/null
+++ b/qemu-vp.c
@@ -0,0 +1,151 @@
+/*
+ * virt-proxy - host/guest communication daemon
+ *
+ * Copyright IBM Corp. 2010
+ *
+ * Authors:
+ *  Michael Roth  mdr...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include virtproxy.h
+
+/* mirror qemu I/O-related code for standalone daemon */
+typedef struct IOHandlerRecord {
+int fd;
+IOCanReadHandler *fd_read_poll;
+IOHandler *fd_read;
+IOHandler *fd_write;
+int deleted;
+void *opaque;
+/* temporary data */
+struct pollfd *ufd;
+QLIST_ENTRY(IOHandlerRecord) next;
+} IOHandlerRecord;
+
+static QLIST_HEAD(, IOHandlerRecord) io_handlers =
+QLIST_HEAD_INITIALIZER(io_handlers);
+
+int vp_set_fd_handler2(int fd,
+ IOCanReadHandler *fd_read_poll,
+ IOHandler *fd_read,
+ IOHandler *fd_write,
+ void *opaque)
+{
+IOHandlerRecord *ioh;
+
+if (!fd_read  !fd_write) {
+QLIST_FOREACH(ioh, io_handlers, next) {
+if (ioh-fd == fd) {
+ioh-deleted = 1;
+break;
+}
+}
+} else {
+QLIST_FOREACH(ioh, io_handlers, next) {
+if (ioh-fd == fd)
+goto found;
+}
+ioh = qemu_mallocz(sizeof(IOHandlerRecord));
+QLIST_INSERT_HEAD(io_handlers, ioh, next);
+found:
+ioh-fd = fd;
+ioh-fd_read_poll = fd_read_poll;
+ioh-fd_read = fd_read;
+ioh-fd_write = fd_write;
+ioh-opaque = opaque;
+ioh-deleted = 0;
+}
+return 0;
+}
+
+int vp_set_fd_handler(int fd,
+IOHandler *fd_read,
+IOHandler *fd_write,
+void *opaque)
+{
+return vp_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
+}
+
+int vp_send_all(int fd, const void *buf, int len1)
+{
+int ret, len;
+
+len = len1;
+while (len  0) {
+ret = write(fd, buf, len);
+if (ret  0) {
+if (errno != EINTR  errno != EAGAIN) {
+warn(write() failed);
+return -1;
+}
+} else if (ret == 0) {
+break;
+} else {
+buf += ret;
+len -= ret;
+}
+}
+return len1 - len;
+}
+
+static void main_loop_wait(int nonblocking)
+{
+IOHandlerRecord *ioh;
+fd_set rfds, wfds, xfds;
+int ret, nfds;
+struct timeval tv;
+int timeout = 1000;
+
+if (nonblocking) {
+timeout = 0;
+}
+
+/* poll any events */
+nfds = -1;
+FD_ZERO(rfds);
+FD_ZERO(wfds);
+FD_ZERO(xfds);
+QLIST_FOREACH(ioh, io_handlers, next) {
+if (ioh-deleted)
+continue;
+if (ioh-fd_read 
+(!ioh-fd_read_poll ||
+ ioh-fd_read_poll(ioh-opaque) != 0)) {
+FD_SET(ioh-fd, rfds);
+if (ioh-fd  nfds)
+nfds = ioh-fd;
+}
+if (ioh-fd_write) {
+FD_SET(ioh-fd, wfds);
+if (ioh-fd  nfds)
+nfds = ioh-fd;
+}
+}
+
+tv.tv_sec = timeout / 1000;
+tv.tv_usec = (timeout % 1000) * 1000;
+
+ret = select(nfds + 1, rfds, wfds, xfds, tv);
+
+if (ret  0) {
+IOHandlerRecord *pioh;
+
+QLIST_FOREACH_SAFE(ioh, io_handlers, next, pioh) {
+if (ioh-deleted) {
+QLIST_REMOVE(ioh, next);
+qemu_free(ioh);
+continue;
+}
+if (ioh-fd_read  FD_ISSET(ioh-fd, rfds)) {
+ioh-fd_read(ioh-opaque);
+}
+if (ioh-fd_write  FD_ISSET(ioh-fd, wfds)) {
+ioh-fd_write(ioh-opaque);
+}
+}
+}
+}
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 03/15] virtproxy: add debug functions for virtproxy core

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   17 +
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index f30b859..2f8996c 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -13,6 +13,23 @@
 
 #include virtproxy.h
 
+#define DEBUG_VP
+
+#ifdef DEBUG_VP
+#define TRACE(msg, ...) do { \
+fprintf(stderr, %s:%s():L%d:  msg \n, \
+__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
+} while(0)
+#else
+#define TRACE(msg, ...) \
+do { } while (0)
+#endif
+
+#define LOG(msg, ...) do { \
+fprintf(stderr, %s:%s():  msg \n, \
+__FILE__, __FUNCTION__, ## __VA_ARGS__); \
+} while(0)
+
 #define VP_SERVICE_ID_LEN 32/* max length of service id string */
 #define VP_PKT_DATA_LEN 1024/* max proxied bytes per VPPacket */
 #define VP_CONN_DATA_LEN 1024   /* max bytes conns can send at a time */
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 04/15] virtproxy: list look-up functions conns/oforwards/iforwards

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   44 
 1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 2f8996c..fa17722 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -149,3 +149,47 @@ static QemuOptsList vp_socket_opts = {
 { /* end if list */ }
 },
 };
+
+/* get VPConn by fd, client denotes whether to look for client or server */
+static VPConn *get_conn(const VPDriver *drv, int fd, bool client)
+{
+VPConn *c = NULL;
+int cur_fd;
+
+QLIST_FOREACH(c, drv-conns, next) {
+cur_fd = client ? c-client_fd : c-server_fd;
+if (cur_fd == fd) {
+return c;
+}
+}
+
+return NULL;
+}
+
+/* get VPOForward by service_id */
+static VPOForward *get_oforward(const VPDriver *drv, const char *service_id)
+{
+VPOForward *f = NULL;
+
+QLIST_FOREACH(f, drv-oforwards, next) {
+if (strncmp(f-service_id, service_id, VP_SERVICE_ID_LEN) == 0) {
+return f;
+}
+}
+
+return NULL;
+}
+
+/* get VPIForward by service_id */
+static VPIForward *get_iforward(const VPDriver *drv, const char *service_id)
+{
+VPIForward *f = NULL;
+
+QLIST_FOREACH(f, drv-iforwards, next) {
+if (strncmp(f-service_id, service_id, VP_SERVICE_ID_LEN) == 0) {
+return f;
+}
+}
+
+return NULL;
+}
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 05/15] virtproxy: add accept handler for communication channel

2010-11-03 Thread Michael Roth
This accept()'s connections to the socket we told virt-proxy to listen
for the channel connection on and sets the appropriate read handler for
the resulting FD.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   37 +
 1 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index fa17722..20532c2 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -166,6 +166,8 @@ static VPConn *get_conn(const VPDriver *drv, int fd, bool 
client)
 return NULL;
 }
 
+static void vp_channel_accept(void *opaque);
+
 /* get VPOForward by service_id */
 static VPOForward *get_oforward(const VPDriver *drv, const char *service_id)
 {
@@ -193,3 +195,38 @@ static VPIForward *get_iforward(const VPDriver *drv, const 
char *service_id)
 
 return NULL;
 }
+
+/* accept handler for communication channel
+ *
+ * accept()s connection to communication channel (for sockets), and sets
+ * up the read handler for resulting FD.
+ */
+static void vp_channel_accept(void *opaque)
+{
+VPDriver *drv = opaque;
+struct sockaddr_in saddr;
+struct sockaddr *addr;
+socklen_t len;
+int fd;
+
+TRACE(called with opaque: %p, drv);
+
+for(;;) {
+len = sizeof(saddr);
+addr = (struct sockaddr *)saddr;
+fd = qemu_accept(drv-listen_fd, addr, len);
+
+if (fd  0  errno != EINTR) {
+TRACE(accept() failed);
+return;
+} else if (fd = 0) {
+TRACE(accepted connection);
+break;
+}
+}
+
+drv-channel_fd = fd;
+vp_set_fd_handler(drv-channel_fd, vp_channel_read, NULL, drv);
+/* dont accept anymore connections until channel_fd is closed */
+vp_set_fd_handler(drv-listen_fd, NULL, NULL, NULL);
+}
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 06/15] virtproxy: add read handler for communication channel

2010-11-03 Thread Michael Roth
Handle data coming in over the channel as VPPackets: Process control
messages and forward data from remote client/server connections to the
appropriate server/client FD on our end.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   83 +++
 1 files changed, 83 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 20532c2..c9c3022 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -33,6 +33,7 @@
 #define VP_SERVICE_ID_LEN 32/* max length of service id string */
 #define VP_PKT_DATA_LEN 1024/* max proxied bytes per VPPacket */
 #define VP_CONN_DATA_LEN 1024   /* max bytes conns can send at a time */
+#define VP_CHAN_DATA_LEN 4096   /* max bytes channel can send at a time */
 #define VP_MAGIC 0x1F374059
 
 /* listening fd, one for each service we're forwarding to remote end */
@@ -150,6 +151,8 @@ static QemuOptsList vp_socket_opts = {
 },
 };
 
+static void vp_channel_read(void *opaque);
+
 /* get VPConn by fd, client denotes whether to look for client or server */
 static VPConn *get_conn(const VPDriver *drv, int fd, bool client)
 {
@@ -230,3 +233,83 @@ static void vp_channel_accept(void *opaque)
 /* dont accept anymore connections until channel_fd is closed */
 vp_set_fd_handler(drv-listen_fd, NULL, NULL, NULL);
 }
+
+/* read handler for communication channel
+ *
+ * de-multiplexes data coming in over the channel. for control messages
+ * we process them here, for data destined for a service or client we
+ * send it to the appropriate FD.
+ */
+static void vp_channel_read(void *opaque)
+{
+VPDriver *drv = opaque;
+VPPacket pkt;
+int count, ret, buf_offset;
+char buf[VP_CHAN_DATA_LEN];
+char *pkt_ptr, *buf_ptr;
+
+TRACE(called with opaque: %p, drv);
+
+count = read(drv-channel_fd, buf, sizeof(buf));
+
+if (count == -1) {
+LOG(read() failed: %s, strerror(errno));
+return;
+} else if (count == 0) {
+/* TODO: channel closed, this probably shouldn't happen for guest-side
+ * serial/virtio-serial connections, but need to confirm and consider
+ * what should happen in this case. as it stands this virtproxy 
instance
+ * is basically defunct at this point, same goes for client instances
+ * of virtproxy where the remote end has hung-up.
+ */
+LOG(channel connection closed);
+vp_set_fd_handler(drv-channel_fd, NULL, NULL, drv);
+drv-channel_fd = -1;
+if (drv-listen_fd) {
+vp_set_fd_handler(drv-listen_fd, vp_channel_accept, NULL, drv);
+}
+/* TODO: should close/remove/delete all existing VPConns here */
+}
+
+if (drv-buflen + count = sizeof(VPPacket)) {
+TRACE(initial packet, drv-buflen: %d, drv-buflen);
+pkt_ptr = (char *)pkt;
+memcpy(pkt_ptr, drv-buf, drv-buflen);
+pkt_ptr += drv-buflen;
+memcpy(pkt_ptr, buf, sizeof(VPPacket) - drv-buflen);
+/* handle first packet */
+ret = vp_handle_packet(drv, pkt);
+if (ret != 0) {
+LOG(error handling packet);
+}
+/* handle the rest of the buffer */
+buf_offset = sizeof(VPPacket) - drv-buflen;
+drv-buflen = 0;
+buf_ptr = buf + buf_offset;
+count -= buf_offset;
+while (count  0) {
+if (count = sizeof(VPPacket)) {
+/* handle full packet */
+TRACE(additional packet, drv-buflen: %d, drv-buflen);
+memcpy((void *)pkt, buf_ptr, sizeof(VPPacket));
+ret = vp_handle_packet(drv, pkt);
+if (ret != 0) {
+LOG(error handling packet);
+}
+count -= sizeof(VPPacket);
+buf_ptr += sizeof(VPPacket);
+} else {
+/* buffer the remainder */
+TRACE(buffering packet);
+memcpy(drv-buf, buf_ptr, count);
+drv-buflen = count;
+break;
+}
+}
+} else {
+/* haven't got a full VPPacket yet, buffer for later */
+buf_ptr = drv-buf + drv-buflen;
+memcpy(buf_ptr, buf, count);
+drv-buflen += count;
+}
+}
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 14/15] virtproxy: Makefile/configure changes to build qemu-vp

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 .gitignore |1 +
 Makefile   |4 +++-
 configure  |1 +
 3 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/.gitignore b/.gitignore
index a43e4d1..da307d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,6 +31,7 @@ qemu-img-cmds.texi
 qemu-img-cmds.h
 qemu-io
 qemu-monitor.texi
+qemu-vp
 QMP/qmp-commands.txt
 .gdbinit
 *.a
diff --git a/Makefile b/Makefile
index 252c817..53b58d2 100644
--- a/Makefile
+++ b/Makefile
@@ -127,7 +127,7 @@ version-obj-$(CONFIG_WIN32) += version.o
 ##
 
 qemu-img.o: qemu-img-cmds.h
-qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
+qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o virtproxy.o: $(GENERATED_HEADERS)
 
 qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) 
$(block-obj-y) $(qobject-obj-y) $(version-obj-y)
 
@@ -135,6 +135,8 @@ qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o 
$(trace-obj-y) $(block-ob
 
 qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) 
$(block-obj-y) $(qobject-obj-y) $(version-obj-y)
 
+qemu-vp$(EXESUF): qemu-vp.o virtproxy.o qemu-tool.o qemu-error.o 
qemu-sockets.c $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h  $  $@,  GEN   $@)
 
diff --git a/configure b/configure
index a079a49..27f92e0 100755
--- a/configure
+++ b/configure
@@ -2232,6 +2232,7 @@ if test $softmmu = yes ; then
   tools=qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools
   if [ $linux = yes -o $bsd = yes -o $solaris = yes ] ; then
   tools=qemu-nbd\$(EXESUF) $tools
+  tools=qemu-vp\$(EXESUF) $tools
 if [ $check_utests = yes ]; then
   tools=check-qint check-qstring check-qdict check-qlist $tools
   tools=check-qfloat check-qjson $tools
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 11/15] virtproxy: add vp_handle_packet()

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   23 +++
 1 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 4f56aba..5ec4e77 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -431,6 +431,29 @@ static int vp_handle_data_packet(void *drv, const VPPacket 
*pkt)
 return 0;
 }
 
+static inline int vp_handle_packet(VPDriver *drv, const VPPacket *pkt)
+{
+int ret;
+
+TRACE(called with drv: %p, drv);
+
+if (pkt-magic != VP_MAGIC) {
+LOG(invalid packet magic field);
+return -1;
+}
+
+if (pkt-type == VP_PKT_CONTROL) {
+ret = vp_handle_control_packet(drv, pkt);
+} else if (pkt-type == VP_PKT_CLIENT || pkt-type == VP_PKT_SERVER) {
+ret = vp_handle_data_packet(drv, pkt);
+} else {
+LOG(invalid packet type);
+return -1;
+}
+
+return ret;
+}
+
 /* read handler for communication channel
  *
  * de-multiplexes data coming in over the channel. for control messages
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 09/15] virtproxy: add handler for data packets

2010-11-03 Thread Michael Roth
Process VPPackets coming in from channel and send them to the
appropriate server/client connections.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   42 ++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 6c3611b..57ab2b0 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -235,6 +235,48 @@ static void vp_channel_accept(void *opaque)
 vp_set_fd_handler(drv-listen_fd, NULL, NULL, NULL);
 }
 
+/* handle data packets
+ *
+ * process VPPackets containing data and send them to the corresponding
+ * FDs
+ */
+static int vp_handle_data_packet(void *drv, const VPPacket *pkt)
+{
+int fd, ret;
+
+TRACE(called with drv: %p, drv);
+
+if (pkt-type == VP_PKT_CLIENT) {
+TRACE(recieved client packet, client fd: %d, server fd: %d,
+  pkt-payload.proxied.client_fd, pkt-payload.proxied.server_fd);
+fd = pkt-payload.proxied.server_fd;
+} else if (pkt-type == VP_PKT_SERVER) {
+TRACE(recieved server packet, client fd: %d, server fd: %d,
+  pkt-payload.proxied.client_fd, pkt-payload.proxied.server_fd);
+fd = pkt-payload.proxied.client_fd;
+} else {
+TRACE(unknown packet type);
+return -1;
+}
+
+/* TODO: proxied in non-blocking mode can causes us to spin here
+ * for slow servers/clients. need to use write()'s and maintain
+ * a per-conn write queue that we clear out before sending any
+ * more data to the fd
+ */
+ret = vp_send_all(fd, (void *)pkt-payload.proxied.data,
+pkt-payload.proxied.bytes);
+if (ret == -1) {
+LOG(error sending data over channel);
+return -1;
+} else if (ret != pkt-payload.proxied.bytes) {
+TRACE(buffer full?);
+return -1;
+}
+
+return 0;
+}
+
 /* read handler for communication channel
  *
  * de-multiplexes data coming in over the channel. for control messages
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 13/15] virtproxy: add read handler for proxied connections

2010-11-03 Thread Michael Roth
reads data from client/server connections as they become readable, then
sends the data over the channel

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   80 +++
 1 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 86a8e5b..f3f7f46 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -200,6 +200,86 @@ static VPIForward *get_iforward(const VPDriver *drv, const 
char *service_id)
 return NULL;
 }
 
+/* read handler for proxied connections */
+static void vp_conn_read(void *opaque)
+{
+VPConn *conn = opaque;
+VPDriver *drv = conn-drv;
+VPPacket pkt;
+char buf[VP_CONN_DATA_LEN];
+int fd, count, ret;
+bool client;
+
+TRACE(called with opaque: %p, drv: %p, opaque, drv);
+
+if (conn-state != VP_STATE_CONNECTED) {
+LOG(invalid connection state);
+return;
+}
+
+if (conn-type != VP_CONN_CLIENT  conn-type != VP_CONN_SERVER) {
+LOG(invalid connection type);
+return;
+}
+
+/* TODO: all fields should be explicitly set so we shouldn't
+ * need to memset. this might hurt if we beef up VPPacket size
+ */
+memset(pkt, 0, sizeof(VPPacket));
+pkt.magic = VP_MAGIC;
+
+if (conn-type == VP_CONN_CLIENT) {
+client = true;
+fd = conn-client_fd;
+} else {
+client = false;
+fd = conn-server_fd;
+}
+
+count = read(fd, buf, VP_CONN_DATA_LEN);
+if (count == -1) {
+LOG(read() failed: %s, strerror(errno));
+return;
+} else if (count == 0) {
+/* connection closed, tell remote end to clean up */
+TRACE(connection closed);
+pkt.type = VP_PKT_CONTROL;
+pkt.payload.msg.type = VP_CONTROL_CLOSE;
+if (client) {
+/* we're closing the client, have remote close the server conn */
+TRACE(closing connection for client fd %d, conn-client_fd);
+pkt.payload.msg.args.close.client_fd = -1;
+pkt.payload.msg.args.close.server_fd = conn-server_fd;
+} else {
+TRACE(closing connection for server fd %d, conn-server_fd);
+pkt.payload.msg.args.close.server_fd = -1;
+pkt.payload.msg.args.close.client_fd = conn-client_fd;;
+}
+/* clean up things on our end */
+closesocket(fd);
+vp_set_fd_handler(fd, NULL, NULL, NULL);
+QLIST_REMOVE(conn, next);
+qemu_free(conn);
+} else {
+TRACE(data read);
+pkt.type = client ? VP_PKT_CLIENT : VP_PKT_SERVER;
+pkt.payload.proxied.client_fd = conn-client_fd;
+pkt.payload.proxied.server_fd = conn-server_fd;
+memcpy(pkt.payload.proxied.data, buf, count);
+pkt.payload.proxied.bytes = count;
+}
+
+ret = vp_send_all(drv-channel_fd, (void *)pkt, sizeof(VPPacket));
+if (ret == -1) {
+LOG(error sending data over channel);
+return;
+}
+if (ret != sizeof(VPPacket)) {
+TRACE(buffer full?);
+return;
+}
+}
+
 /* accept handler for communication channel
  *
  * accept()s connection to communication channel (for sockets), and sets
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 15/15] virtproxy: qemu-vp, main logic

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 Makefile  |2 +-
 qemu-vp.c |  469 -
 2 files changed, 469 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 53b58d2..2dd64a3 100644
--- a/Makefile
+++ b/Makefile
@@ -135,7 +135,7 @@ qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o 
$(trace-obj-y) $(block-ob
 
 qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) 
$(block-obj-y) $(qobject-obj-y) $(version-obj-y)
 
-qemu-vp$(EXESUF): qemu-vp.o virtproxy.o qemu-tool.o qemu-error.o 
qemu-sockets.c $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-vp$(EXESUF): qemu-vp.o virtproxy.o qemu-tool.o qemu-error.o 
qemu-sockets.c $(block-obj-y) $(qobject-obj-y)
 
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h  $  $@,  GEN   $@)
diff --git a/qemu-vp.c b/qemu-vp.c
index 5075cdc..0cc0e67 100644
--- a/qemu-vp.c
+++ b/qemu-vp.c
@@ -9,10 +9,54 @@
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  *
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * 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 getopt.h
+#include err.h
+#include qemu-option.h
+#include qemu_socket.h
 #include virtproxy.h
 
+static bool verbose_enabled = 0;
+#define DEBUG_ENABLED
+
+#ifdef DEBUG_ENABLED
+#define DEBUG(msg, ...) do { \
+fprintf(stderr, %s:%s():L%d:  msg \n, \
+__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
+} while(0)
+#else
+#define DEBUG(msg, ...) do {} while (0)
+#endif
+
+#define INFO(msg, ...) do { \
+if (!verbose_enabled) { \
+break; \
+} \
+warnx(msg, ## __VA_ARGS__); \
+} while(0)
+
 /* mirror qemu I/O-related code for standalone daemon */
 typedef struct IOHandlerRecord {
 int fd;
@@ -98,7 +142,7 @@ static void main_loop_wait(int nonblocking)
 fd_set rfds, wfds, xfds;
 int ret, nfds;
 struct timeval tv;
-int timeout = 1000;
+int timeout = 10;
 
 if (nonblocking) {
 timeout = 0;
@@ -149,3 +193,426 @@ static void main_loop_wait(int nonblocking)
 }
 }
 }
+
+#define VP_ARG_LEN 256
+
+static QemuOptsList vp_opts = {
+.name = vpargs,
+.head = QTAILQ_HEAD_INITIALIZER(vp_opts.head),
+.desc = {
+{
+.name = service_id,
+.type = QEMU_OPT_STRING,
+},{
+.name = channel_method,
+.type = QEMU_OPT_STRING,
+},{
+.name = index,
+.type = QEMU_OPT_NUMBER,
+},{
+.name = path,
+.type = QEMU_OPT_STRING,
+},{
+.name = host,
+.type = QEMU_OPT_STRING,
+},{
+.name = port,
+.type = QEMU_OPT_STRING,
+},{
+.name = ipv4,
+.type = QEMU_OPT_BOOL,
+},{
+.name = ipv6,
+.type = QEMU_OPT_BOOL,
+},
+{ /* end if list */ }
+},
+};
+
+typedef struct VPData {
+QemuOpts *opts;
+void *opaque;
+QTAILQ_ENTRY(VPData) next;
+} VPData;
+
+static QTAILQ_HEAD(, VPData) iforwards;
+static QTAILQ_HEAD(, VPData) oforwards;
+static QTAILQ_HEAD(, VPData) channels;
+
+static void usage(const char *cmd)
+{
+printf(
+Usage: %s -c channel_opts [-c ... ] [-i iforward_opts ...] 
+[-o oforward_opts ...]\n
+QEMU virt-proxy communication channel\n
+\n
+  -c, --channelchannel options of the form:\n
+   method:addr:port[:channel_id]\n
+  -o, --oforward   oforward options of the form:\n
+   service_id:addr:port[:channel_id]\n
+  -i, --iforward   iforward options of the form:\n
+   service_id:addr:port[:channel_id]\n
+  -v, --verbosedisplay extra debugging information\n
+  -h, --help   display this help and exit\n
+\n
+ 

[Qemu-devel] [RFC][RESEND][PATCH v1 12/15] virtproxy: interfaces to set/remove VPIForwards

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   59 +++
 virtproxy.h |2 ++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 5ec4e77..86a8e5b 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -658,3 +658,62 @@ int vp_set_oforward(VPDriver *drv, int fd, const char 
*service_id)
 
 return 0;
 }
+
+/* add/modify a service_id - net/unix socket mapping
+ *
+ * service_id is a user-defined id for the service. this is what the
+ * remote end will use to proxy connections to a specific service on
+ * our end.
+ *
+ * if port is NULL, addr is the address of the net socket the
+ * service is running on. otherwise, addr is the path to the unix socket
+ * the service is running on.
+ *
+ * if port AND addr are NULL, find and remove the current iforward
+ * for this service_id if it exists.
+ *
+ * ipv6 is a bool denoting whether or not to use ipv6
+ */
+int vp_set_iforward(VPDriver *drv, const char *service_id, const char *addr,
+const char *port, bool ipv6)
+{
+VPIForward *f = get_iforward(drv, service_id);
+
+if (addr == NULL  port == NULL) {
+if (f != NULL) {
+qemu_opts_del(f-socket_opts);
+QLIST_REMOVE(f, next);
+qemu_free(f);
+}
+return 0;
+}
+
+if (f == NULL) {
+f = qemu_mallocz(sizeof(VPIForward));
+f-drv = drv;
+strncpy(f-service_id, service_id, VP_SERVICE_ID_LEN);
+QLIST_INSERT_HEAD(drv-iforwards, f, next);
+} else {
+qemu_opts_del(f-socket_opts);
+}
+
+/* stick socket-related options in a QemuOpts so we can
+ * utilize qemu socket utility functions directly
+ */
+f-socket_opts = qemu_opts_create(vp_socket_opts, NULL, 0);
+if (port == NULL) {
+/* no port given, assume unix path */
+qemu_opt_set(f-socket_opts, path, addr);
+} else {
+qemu_opt_set(f-socket_opts, host, addr);
+qemu_opt_set(f-socket_opts, port, port);
+}
+
+if (ipv6) {
+qemu_opt_set(f-socket_opts, ipv6, on);
+} else {
+qemu_opt_set(f-socket_opts, ipv4, on);
+}
+
+return 0;
+}
diff --git a/virtproxy.h b/virtproxy.h
index 39d5d40..d2522b3 100644
--- a/virtproxy.h
+++ b/virtproxy.h
@@ -34,5 +34,7 @@ int vp_set_fd_handler(int fd,
 /* virtproxy interface */
 VPDriver *vp_new(int fd, bool listen);
 int vp_set_oforward(VPDriver *drv, int fd, const char *service_id);
+int vp_set_iforward(VPDriver *drv, const char *service_id, const char *addr,
+const char *port, bool ipv6);
 
 #endif /* VIRTPROXY_H */
-- 
1.7.0.4




[Qemu-devel] [RFC][RESEND][PATCH v1 10/15] virtproxy: add handler for control packet

2010-11-03 Thread Michael Roth
Process control packets coming in over the channel. This entails setting
up/tearing down connections to local services initiated from the other
end of the channel.

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |  154 +++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index 57ab2b0..4f56aba 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -235,6 +235,160 @@ static void vp_channel_accept(void *opaque)
 vp_set_fd_handler(drv-listen_fd, NULL, NULL, NULL);
 }
 
+/* handle control packets
+ *
+ * process VPPackets containing control messages
+ */
+static int vp_handle_control_packet(VPDriver *drv, const VPPacket *pkt)
+{
+const VPControlMsg *msg = pkt-payload.msg;
+int ret;
+
+TRACE(called with drv: %p, drv);
+
+switch (msg-type) {
+case VP_CONTROL_CONNECT_INIT: {
+int client_fd = msg-args.connect_init.client_fd;
+int server_fd;
+char service_id[VP_SERVICE_ID_LEN];
+VPPacket resp_pkt;
+VPConn *new_conn;
+VPIForward *iforward;
+
+pstrcpy(service_id, VP_SERVICE_ID_LEN,
+ msg-args.connect_init.service_id);
+TRACE(setting up connection for service id %s, service_id);
+
+/* create server connection on behalf of remote end */
+iforward = get_iforward(drv, service_id);
+if (iforward == NULL) {
+LOG(no forwarder configured for service id);
+return -1;
+}
+
+qemu_opts_print(iforward-socket_opts, NULL);
+if (qemu_opt_get(iforward-socket_opts, host) != NULL) {
+server_fd = inet_connect_opts(iforward-socket_opts);
+} else if (qemu_opt_get(iforward-socket_opts, path) != NULL) {
+server_fd = unix_connect_opts(iforward-socket_opts);
+} else {
+LOG(unable to find listening socket host/addr info);
+return -1;
+}
+
+if (server_fd == -1) {
+LOG(failed to create connection to service with id %s,
+service_id);
+}
+TRACE(server_fd: %d, server_fd);
+
+new_conn = qemu_mallocz(sizeof(VPConn));
+if (!new_conn) {
+LOG(memory allocation failed);
+return -1;
+}
+
+/* send a connect_ack back over the channel */
+/* TODO: all fields should be explicitly set so we shouldn't
+ * need to memset. this might hurt if we beef up VPPacket size
+ */
+memset(resp_pkt, 0, sizeof(resp_pkt));
+resp_pkt.type = VP_PKT_CONTROL;
+resp_pkt.payload.msg.type = VP_CONTROL_CONNECT_ACK;
+resp_pkt.payload.msg.args.connect_ack.server_fd = server_fd;
+resp_pkt.payload.msg.args.connect_ack.client_fd = client_fd;
+resp_pkt.magic = VP_MAGIC;
+
+/* TODO: can this potentially block or cause a deadlock with
+ * the remote end? need to look into potentially buffering these
+ * if it looks like the remote end is waiting for us to read data
+ * off the channel.
+ */
+if (drv-channel_fd == -1) {
+TRACE(channel no longer connected, ignoring packet);
+return -1;
+}
+
+ret = vp_send_all(drv-channel_fd, (void *)resp_pkt, 
sizeof(resp_pkt));
+if (ret == -1) {
+LOG(error sending data over channel);
+return -1;
+}
+if (ret != sizeof(resp_pkt)) {
+TRACE(buffer full? %d bytes remaining, ret);
+return -1;
+}
+
+/* add new VPConn to list and set a read handler for it */
+new_conn-drv = drv;
+new_conn-client_fd = client_fd;
+new_conn-server_fd = server_fd;
+new_conn-type = VP_CONN_SERVER;
+new_conn-state = VP_STATE_CONNECTED;
+QLIST_INSERT_HEAD(drv-conns, new_conn, next);
+vp_set_fd_handler(server_fd, vp_conn_read, NULL, new_conn);
+
+break;
+}
+case VP_CONTROL_CONNECT_ACK: {
+int client_fd = msg-args.connect_ack.client_fd;
+int server_fd = msg-args.connect_ack.server_fd;
+VPConn *conn;
+
+TRACE(recieved ack from remote end for client fd %d, client_fd);
+
+if (server_fd = 0) {
+LOG(remote end sent invalid server fd);
+return -1;
+}
+
+conn = get_conn(drv, client_fd, true);
+
+if (conn == NULL) {
+LOG(failed to find connection with client_fd %d, client_fd);
+return -1;
+}
+
+conn-server_fd = server_fd;
+conn-state = VP_STATE_CONNECTED;
+vp_set_fd_handler(client_fd, vp_conn_read, NULL, conn);
+
+break;
+}
+case VP_CONTROL_CLOSE: {
+int fd;
+VPConn *conn;
+
+TRACE(closing connection on behalf of remote end);
+
+if (msg-args.close.client_fd = 0) {
+fd = msg-args.close.client_fd;
+TRACE(recieved 

[Qemu-devel] [RFC][RESEND][PATCH v1 07/15] virtproxy: add vp_new() VPDriver constructor

2010-11-03 Thread Michael Roth

Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com
---
 virtproxy.c |   23 +++
 virtproxy.h |3 +++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/virtproxy.c b/virtproxy.c
index c9c3022..cc0ac9a 100644
--- a/virtproxy.c
+++ b/virtproxy.c
@@ -313,3 +313,26 @@ static void vp_channel_read(void *opaque)
 drv-buflen += count;
 }
 }
+
+/* create/init VPDriver object */
+VPDriver *vp_new(int fd, bool listen)
+{
+VPDriver *drv = NULL;
+
+drv = qemu_mallocz(sizeof(VPDriver));
+drv-listen_fd = -1;
+drv-channel_fd = -1;
+QLIST_INIT(drv-oforwards);
+QLIST_INIT(drv-conns);
+
+if (listen) {
+/* provided FD is to be listened on for channel connection */
+drv-listen_fd = fd;
+vp_set_fd_handler(drv-listen_fd, vp_channel_accept, NULL, drv);
+} else {
+drv-channel_fd = fd;
+vp_set_fd_handler(drv-channel_fd, vp_channel_read, NULL, drv);
+}
+
+return drv;
+}
diff --git a/virtproxy.h b/virtproxy.h
index 0203421..3df1691 100644
--- a/virtproxy.h
+++ b/virtproxy.h
@@ -31,4 +31,7 @@ int vp_set_fd_handler(int fd,
 IOHandler *fd_write,
 void *opaque);
 
+/* virtproxy interface */
+VPDriver *vp_new(int fd, bool listen);
+
 #endif /* VIRTPROXY_H */
-- 
1.7.0.4




[Qemu-devel] [Bug 611142] Re: seabios should have native scsi support

2010-11-03 Thread Scott Moser
Just a comment, the commands in the summary will boot the first time,
but a reboot will (possibly) fail.  bug 615529 has more info on that.

-- 
seabios should have native scsi support
https://bugs.launchpad.net/bugs/611142
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.

Status in QEMU: New
Status in “qemu-kvm” package in Ubuntu: New
Status in “seabios” package in Ubuntu: New

Bug description:
Binary package hint: seabios

Currently when a grub multiboot image is booted with 'kvm -kernel' and 
'biosdisk' module, it will see block devices of type IDE or virtio.  It will 
not see scsi devices.

To demonstrate this:
$ qemu-img create -f qcow2 disk.img 1G
$ grub-mkrescue --output=rescue.iso
$ grub-mkimage -O i386-pc --output=grub-mb.img biosdisk minicmd part_msdos

An 'ls' inside the grub prompt will show hard disks (hd0) on if:
a.) -drive uses interface of virtio or scsi
or
b.) kvm boots boot from a cdrom or floppy 

For example, with these commands, grub will see a '(hd0)'
$ kvm -drive file=disk.img,if=scsi,boot=on -cdrom rescue.iso -boot d
$ kvm -drive file=disk.img,if=scsi,boot=on -floppy rescue.iso -boot a
$ kvm -drive file=disk.img,if=virtio,boot=on -cdrom rescue.iso -boot d
$ kvm -drive file=disk.img,if=ide,boot=on -cdrom rescue.iso -boot d
$ kvm -drive file=disk.img,if=virtio,boot=on -kernel grub-mb.img 
$ kvm -drive file=disk.img,if=ide,boot=on -kernel grub-mb.img 

But the following will not:
$ kvm -drive file=disk.img,if=scsi,boot=on -kernel grub-mb.img

ProblemType: Bug
DistroRelease: Ubuntu 10.10
Package: seabios 0.6.0-0ubuntu1
ProcVersionSignature: User Name 2.6.32-305.9-ec2 2.6.32.11+drm33.2
Uname: Linux 2.6.32-305-ec2 i686
Architecture: i386
Date: Thu Jul 29 03:21:21 2010
Dependencies:
 
Ec2AMI: ami-e930db80
Ec2AMIManifest: 
ubuntu-images-testing-us/ubuntu-maverick-daily-i386-server-20100727.manifest.xml
Ec2AvailabilityZone: us-east-1b
Ec2InstanceType: m1.small
Ec2Kernel: aki-407d9529
Ec2Ramdisk: unavailable
PackageArchitecture: all
ProcEnviron:
 PATH=(custom, user)
 LANG=en_US.UTF-8
 SHELL=/bin/bash
SourcePackage: seabios





Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Markus Armbruster
Ryan Harper ry...@us.ibm.com writes:

 * Michael S. Tsirkin m...@redhat.com [2010-11-03 02:22]:
 On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
  * Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
   On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
I like the idea of disconnect; if part of the device_del 
method was to
invoke a disconnect method, we could implement that for block, 
net, etc;

I'd think we'd want to send the notification, then disconnect.
Struggling with whether it's worth having some reasonable 
timeout
between notification and disconnect.  
   
   The problem with this is that it has no analog in real world.
   In real world, you can send some notifications to the guest, and 
   you can
   remove the card.  Tying them together is what created the 
   problem in the
   first place.
   
   Timeouts can be implemented by management, maybe with a nice 
   dialog
   being shown to the user.
  
  Very true.  I'm fine with forcing a disconnect during the removal 
  path
  prior to notification.  Do we want a new disconnect method at the 
  device
  level (pci)? or just use the existing removal callback and call 
  that
  during the initial hotremov event?
 
 Not sure what you mean by that, but I don't see a device doing 
 anything
 differently wrt surprise or ordered removal. So probably the existing
 callback should do. I don't think we need to talk about disconnect:
 since we decided we are emulating device removal, let's call it
 just that.

Because current the removal process depends on the guest actually
responding.  What I'm suggesting is that, in Marcus's term, and what
drive_unplug() implements, is to disconnect the host block device from
the guest device to prevent any further access to it in the case the
guest doesn't respond to the removal request made via ACPI.

Very specifically, what we're suggesting instead of the drive_unplug()
command so to complete the device removal operation without waiting for
the guest to respond; that's what's going to happen if we invoke the
response callback; it will appear as if the guest responded whether it
did or not.

What I was suggesting above was to instead of calling the callback for
handing the guest response was to add a device function called
disconnect which would remove any association of host resources from
guest resources before we notified the guest.  Thinking about it again
I'm not sure this is useful, but if we're going to remove the device
without the guests knowledge, I'm not sure how useful sending the
removal requests via ACPI is in the first place.

My feeling is that I'd like to have explicit control over the 
disconnect
from host resources separate from the device removal *if* we're going 
to
retain the guest notification.  If we don't care to notify the guest,
then we can just do device removal without notifying the guest
and be done with it.
   
   I imagine management would typically want to do this:
   1. notify guest
   2. wait a bit
   3. remove device
  
  Yes; but this argues for (1) being a separate command from (3)
 
 Yes. Long term I think we will want a way to do that.
 
  unless we
  require (3) to include (1) and (2) in the qemu implementation.
  
  Currently we implement:
  
  1. device_del (attempt to remove device)
  2. notify guest
  3. if guest responds, remove device
  4. disconnect host resource from device on destruction
  
  With my drive_unplug patch we do:
  
  1. disconnect host resource from device
 
 This is what drive_unplug does, right?

 Correct.

 
  2. device_del (attempt to remove device)
  3. notify guest
  4. if guest responds, remove device
  
  I think we're suggesting to instead do (if we keep disconnect as part of
  device_del)
  
  1. device_del (attemp to remove device)
  2. notify guest
  3. invoke device destruction callback resulting in disconnect host 
  resource from device
  4. if guest responds, invoke device destruction path a second time.
 
 By response you mean eject?  No, this is not what I was suggesting.
 I was really suggesting that your patch is fine :)
 Sorry about confusion.

 I don't mean eject; I mean responding to the ACPI event by writing a
 response to the PCI chipset which QEMU then in turn will invoke the
 qdev_unplug() path which ultimately kills the device and the Drive and
 BlockState objects.

 
 I was also saying that from what I hear, the pci express support
 will at some point need interfaces to
 - notify guest about device removal/addition
 - get eject from guest
 - remove device without talking to guest
 - add device without talking to guest
 - suppress device deletion on eject
 
 All this can be generic and can work through express
 

Re: [Qemu-devel] [PATCHv2 4/8] Store IDE bus id in IDEBus structure for easy access.

2010-11-03 Thread Gleb Natapov
On Wed, Nov 03, 2010 at 04:18:18PM +0100, Markus Armbruster wrote:
 Gleb Natapov g...@redhat.com writes:
 
  On Wed, Nov 03, 2010 at 02:39:52PM +0100, Markus Armbruster wrote:
  Here's a generic answer to the question which of the device's buses is
  this?
  
  int qbus_index(BusState *bus)
  {
  BusState *b;
  int i, index;
  
  index = -1;
  i = 0;
  QLIST_FOREACH(b, bus-parent-child_bus, sibling) {
  if (b == bus) {
  index = i;
  }
  i++;
  }
  assert(0 = index  index  i);
  return i - 1 - index;
  }
  
  The bus created first has index 0.
  
  Note that the child_bus holds the children in reverse creation order,
  and we can't traverse it backwards.  Same problem also visible with
  makes info qtree:
  
dev: piix3-ide, id 
  [...]
  bus: ide.1
type IDE
  bus: ide.0
type IDE
  Isn't this too implementation dependant?
 
 Well, it's the implementation depending on itself.
 
In a sense yes, but we expose internal qdev state in upper layer of the
stack. Look like leaking abstraction problem to me. What if we will
change qdev to store child buses in hash instead of list?

   Are you against adding bus_id
  to IDEBus?
 
 Against is too hard a word.  If it's a general question, I'd prefer a
 general answer.
It is as general as what pci slot/func of a pci device. We store those
in PCIDevice.

 
 And will it work with ISA? I do not think IDEBus is
  added to bus-parent-child_bus in case of ISA otherwise why both
  IDEBuses have same name in isapc. Currently I have following patch
  queued. It should fix isapc case too.
 
 You're right, it's not helpful there: two separate devices, both
 providing just one bus.
 
  Fix isapc IDE bus creation
  
  Currently we create two ide buses with the same name, so it is 
  impossible
  to use -device ide-drive,bus= to address all possible disks in the isapc
  machine. Fix that by giving different names to different ide buses. Also
  store IDE bus id in IDEBus structure for easy access.
 
 Changing the name of the second default isa-ide device's bus to ide.1
 is fine with me.
 
 But with that change in place, why do we need to store the bus number?
 Why can't we just use the name?
This name has no meaning outside of qemu internals. I can derive bus
number from bus name by parsing the string, but I don't see why is it
better than storing bus_id (that was used to create this bus name in the
first place) for easy access.

 
 Moreover, I think the meaning of bus number is unclear.  See comments
 inline.
 
  diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
  index ff80dd5..b2cbdbc 100644
  --- a/hw/ide/cmd646.c
  +++ b/hw/ide/cmd646.c
  @@ -257,8 +257,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
   pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
   
   irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
  -ide_bus_new(d-bus[0], d-dev.qdev);
  -ide_bus_new(d-bus[1], d-dev.qdev);
  +ide_bus_new(d-bus[0], d-dev.qdev, 0);
  +ide_bus_new(d-bus[1], d-dev.qdev, 1);
   ide_init2(d-bus[0], irq[0]);
   ide_init2(d-bus[1], irq[1]);
   
  diff --git a/hw/ide/internal.h b/hw/ide/internal.h
  index 4165543..bde2664 100644
  --- a/hw/ide/internal.h
  +++ b/hw/ide/internal.h
  @@ -448,6 +448,7 @@ struct IDEBus {
   IDEDevice *slave;
   BMDMAState *bmdma;
   IDEState ifs[2];
  +uint8_t bus_id;
 
 Why is this uint8_t?
 
I do not expect to have more then 255 ide buses provided by one device :)

   uint8_t unit;
   uint8_t cmd;
   qemu_irq irq;
  @@ -564,7 +565,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, 
  DriveInfo *hd0,
   void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
   
   /* hw/ide/qdev.c */
  -void ide_bus_new(IDEBus *idebus, DeviceState *dev);
  +void ide_bus_new(IDEBus *idebus, DeviceState *dev, uint8_t bus_id);
   IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
   
   #endif /* HW_IDE_INTERNAL_H */
  diff --git a/hw/ide/isa.c b/hw/ide/isa.c
  index 9b94495..b000ab8 100644
  --- a/hw/ide/isa.c
  +++ b/hw/ide/isa.c
  @@ -66,8 +66,9 @@ static const VMStateDescription vmstate_ide_isa = {
   static int isa_ide_initfn(ISADevice *dev)
   {
   ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
  +static uint8_t bus_id = 0;
   
  -ide_bus_new(s-bus, s-dev.qdev);
  +ide_bus_new(s-bus, s-dev.qdev, bus_id++);
   ide_init_ioport(s-bus, s-iobase, s-iobase2);
   isa_init_irq(dev, s-irq, s-isairq);
   isa_init_ioport_range(dev, s-iobase, 8);
 
 Works for any number of isa-ide devices.  Each one provides one IDE bus,
 and the buses are numbered 0, ... in the order the isa-ide devices are
 created.
 
Except that we use those names to address device on command line. And 
this is very unfortunate since now we can't address all ide devices in
isapc case and in the future we 

[Qemu-devel] Re: [RFC][PATCH 1/3] Linux/Guest unmapped page cache control

2010-11-03 Thread Balbir Singh
* Christoph Lameter c...@linux.com [2010-11-03 09:35:33]:

 On Fri, 29 Oct 2010, Balbir Singh wrote:
 
  A lot of the code is borrowed from zone_reclaim_mode logic for
  __zone_reclaim(). One might argue that the with ballooning and
  KSM this feature is not very useful, but even with ballooning,
 
 Interesting use of zone reclaim. I am having a difficult time reviewing
 the patch since you move and modify functions at the same time. Could you
 separate that out a bit?


Sure, I'll split it out into more readable bits and repost the mm
versions first.
 
  +#define UNMAPPED_PAGE_RATIO 16
 
 Maybe come up with a scheme that allows better configuration of the
 mininum? I think in some setting we may want an absolute limit and in
 other a fraction of something (total zone size or working set?)


Are you suggesting a sysctl or computation based on zone size and
limit, etc? I understand it to be the latter.
 
 
  +bool should_balance_unmapped_pages(struct zone *zone)
  +{
  +   if (unmapped_page_control 
  +   (zone_unmapped_file_pages(zone) 
  +   UNMAPPED_PAGE_RATIO * zone-min_unmapped_pages))
  +   return true;
  +   return false;
  +}
 

Thanks for your review.

-- 
Three Cheers,
Balbir



Re: [Qemu-devel] [PATCHv2 4/8] Store IDE bus id in IDEBus structure for easy access.

2010-11-03 Thread Markus Armbruster
Gleb Natapov g...@redhat.com writes:

 On Wed, Nov 03, 2010 at 04:18:18PM +0100, Markus Armbruster wrote:
 Gleb Natapov g...@redhat.com writes:
 
  On Wed, Nov 03, 2010 at 02:39:52PM +0100, Markus Armbruster wrote:
  Here's a generic answer to the question which of the device's buses is
  this?
  
  int qbus_index(BusState *bus)
  {
  BusState *b;
  int i, index;
  
  index = -1;
  i = 0;
  QLIST_FOREACH(b, bus-parent-child_bus, sibling) {
  if (b == bus) {
  index = i;
  }
  i++;
  }
  assert(0 = index  index  i);
  return i - 1 - index;
  }
  
  The bus created first has index 0.
  
  Note that the child_bus holds the children in reverse creation order,
  and we can't traverse it backwards.  Same problem also visible with
  makes info qtree:
  
dev: piix3-ide, id 
  [...]
  bus: ide.1
type IDE
  bus: ide.0
type IDE
  Isn't this too implementation dependant?
 
 Well, it's the implementation depending on itself.
 
 In a sense yes, but we expose internal qdev state in upper layer of the
 stack. Look like leaking abstraction problem to me. What if we will
 change qdev to store child buses in hash instead of list?

The function is defined in terms of the qdev interface: it depends only
on the order in which the parent device's buses are created.  The fact
that my implementation happens to depend on how we store child buses
doesn't change that.

   Are you against adding bus_id
  to IDEBus?
 
 Against is too hard a word.  If it's a general question, I'd prefer a
 general answer.
 It is as general as what pci slot/func of a pci device. We store those
 in PCIDevice.

It's actually more general than that :)

PCI slot.function is the address of a PCI device on its parent bus.
It's specific to PCI buses.

The bus number is the address of a bus on its parent device.  It's the
same regardless of the device.

 And will it work with ISA? I do not think IDEBus is
  added to bus-parent-child_bus in case of ISA otherwise why both
  IDEBuses have same name in isapc. Currently I have following patch
  queued. It should fix isapc case too.
 
 You're right, it's not helpful there: two separate devices, both
 providing just one bus.
 
  Fix isapc IDE bus creation
  
  Currently we create two ide buses with the same name, so it is 
  impossible
  to use -device ide-drive,bus= to address all possible disks in the 
  isapc
  machine. Fix that by giving different names to different ide buses. 
  Also
  store IDE bus id in IDEBus structure for easy access.
 
 Changing the name of the second default isa-ide device's bus to ide.1
 is fine with me.
 
 But with that change in place, why do we need to store the bus number?
 Why can't we just use the name?
 This name has no meaning outside of qemu internals. I can derive bus
 number from bus name by parsing the string, but I don't see why is it
 better than storing bus_id (that was used to create this bus name in the
 first place) for easy access.

 
 Moreover, I think the meaning of bus number is unclear.  See comments
 inline.
 
  diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
  index ff80dd5..b2cbdbc 100644
  --- a/hw/ide/cmd646.c
  +++ b/hw/ide/cmd646.c
  @@ -257,8 +257,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
   pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
   
   irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
  -ide_bus_new(d-bus[0], d-dev.qdev);
  -ide_bus_new(d-bus[1], d-dev.qdev);
  +ide_bus_new(d-bus[0], d-dev.qdev, 0);
  +ide_bus_new(d-bus[1], d-dev.qdev, 1);
   ide_init2(d-bus[0], irq[0]);
   ide_init2(d-bus[1], irq[1]);
   
  diff --git a/hw/ide/internal.h b/hw/ide/internal.h
  index 4165543..bde2664 100644
  --- a/hw/ide/internal.h
  +++ b/hw/ide/internal.h
  @@ -448,6 +448,7 @@ struct IDEBus {
   IDEDevice *slave;
   BMDMAState *bmdma;
   IDEState ifs[2];
  +uint8_t bus_id;
 
 Why is this uint8_t?
 
 I do not expect to have more then 255 ide buses provided by one device :)

Bah, let's make it an int.

   uint8_t unit;
   uint8_t cmd;
   qemu_irq irq;
  @@ -564,7 +565,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, 
  DriveInfo *hd0,
   void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
   
   /* hw/ide/qdev.c */
  -void ide_bus_new(IDEBus *idebus, DeviceState *dev);
  +void ide_bus_new(IDEBus *idebus, DeviceState *dev, uint8_t bus_id);
   IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
   
   #endif /* HW_IDE_INTERNAL_H */
  diff --git a/hw/ide/isa.c b/hw/ide/isa.c
  index 9b94495..b000ab8 100644
  --- a/hw/ide/isa.c
  +++ b/hw/ide/isa.c
  @@ -66,8 +66,9 @@ static const VMStateDescription vmstate_ide_isa = {
   static int isa_ide_initfn(ISADevice *dev)
   {
   ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
  +static uint8_t bus_id = 0;
   
  -

Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Ryan Harper
* Markus Armbruster arm...@redhat.com [2010-11-03 11:42]:
 Ryan Harper ry...@us.ibm.com writes:
 
  * Michael S. Tsirkin m...@redhat.com [2010-11-03 02:22]:
  On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
   * Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
 I like the idea of disconnect; if part of the device_del 
 method was to
 invoke a disconnect method, we could implement that for 
 block, net, etc;
 
 I'd think we'd want to send the notification, then 
 disconnect.
 Struggling with whether it's worth having some reasonable 
 timeout
 between notification and disconnect.  

The problem with this is that it has no analog in real world.
In real world, you can send some notifications to the guest, 
and you can
remove the card.  Tying them together is what created the 
problem in the
first place.

Timeouts can be implemented by management, maybe with a nice 
dialog
being shown to the user.
   
   Very true.  I'm fine with forcing a disconnect during the 
   removal path
   prior to notification.  Do we want a new disconnect method at 
   the device
   level (pci)? or just use the existing removal callback and call 
   that
   during the initial hotremov event?
  
  Not sure what you mean by that, but I don't see a device doing 
  anything
  differently wrt surprise or ordered removal. So probably the 
  existing
  callback should do. I don't think we need to talk about disconnect:
  since we decided we are emulating device removal, let's call it
  just that.
 
 Because current the removal process depends on the guest actually
 responding.  What I'm suggesting is that, in Marcus's term, and what
 drive_unplug() implements, is to disconnect the host block device 
 from
 the guest device to prevent any further access to it in the case the
 guest doesn't respond to the removal request made via ACPI.
 
 Very specifically, what we're suggesting instead of the 
 drive_unplug()
 command so to complete the device removal operation without waiting 
 for
 the guest to respond; that's what's going to happen if we invoke the
 response callback; it will appear as if the guest responded whether 
 it
 did or not.
 
 What I was suggesting above was to instead of calling the callback 
 for
 handing the guest response was to add a device function called
 disconnect which would remove any association of host resources from
 guest resources before we notified the guest.  Thinking about it 
 again
 I'm not sure this is useful, but if we're going to remove the device
 without the guests knowledge, I'm not sure how useful sending the
 removal requests via ACPI is in the first place.
 
 My feeling is that I'd like to have explicit control over the 
 disconnect
 from host resources separate from the device removal *if* we're 
 going to
 retain the guest notification.  If we don't care to notify the guest,
 then we can just do device removal without notifying the guest
 and be done with it.

I imagine management would typically want to do this:
1. notify guest
2. wait a bit
3. remove device
   
   Yes; but this argues for (1) being a separate command from (3)
  
  Yes. Long term I think we will want a way to do that.
  
   unless we
   require (3) to include (1) and (2) in the qemu implementation.
   
   Currently we implement:
   
   1. device_del (attempt to remove device)
   2. notify guest
   3. if guest responds, remove device
   4. disconnect host resource from device on destruction
   
   With my drive_unplug patch we do:
   
   1. disconnect host resource from device
  
  This is what drive_unplug does, right?
 
  Correct.
 
  
   2. device_del (attempt to remove device)
   3. notify guest
   4. if guest responds, remove device
   
   I think we're suggesting to instead do (if we keep disconnect as part of
   device_del)
   
   1. device_del (attemp to remove device)
   2. notify guest
   3. invoke device destruction callback resulting in disconnect host 
   resource from device
   4. if guest responds, invoke device destruction path a second time.
  
  By response you mean eject?  No, this is not what I was suggesting.
  I was really suggesting that your patch is fine :)
  Sorry about confusion.
 
  I don't mean eject; I mean responding to the ACPI event by writing a
  response to the PCI chipset which QEMU then in turn will invoke the
  qdev_unplug() path which ultimately kills the device and the Drive and
  BlockState objects.
 
  
  I was also saying that from what I hear, the pci express support
  will at some point need interfaces to
  - notify guest 

[Qemu-devel] Re: [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Anthony Liguori

On 11/03/2010 10:12 AM, Juan Quintela wrote:

Anthony Liguorianth...@codemonkey.ws  wrote:
   

On 11/03/2010 09:29 AM, Stefan Hajnoczi wrote:
 

Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
handler that deletes its IOHandler is exposed to .fd_write() being
called on the deleted IOHandler.

This patch fixes deletion so that .fd_read() and .fd_write() are never
called on an IOHandler that is marked for deletion.

Signed-off-by: Stefan Hajnoczistefa...@linux.vnet.ibm.com
---
   vl.c |   15 ---
   1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index 7038952..6f56123 100644
--- a/vl.c
+++ b/vl.c
@@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
   IOHandlerRecord *pioh;

   QLIST_FOREACH_SAFE(ioh,io_handlers, next, pioh) {
-if (ioh-deleted) {
-QLIST_REMOVE(ioh, next);
-qemu_free(ioh);
-continue;
-}
-if (ioh-fd_read   FD_ISSET(ioh-fd,rfds)) {
+if (!ioh-deleted   ioh-fd_read   FD_ISSET(ioh-fd,rfds)) {
   ioh-fd_read(ioh-opaque);
   }
-if (ioh-fd_write   FD_ISSET(ioh-fd,wfds)) {
+if (!ioh-deleted   ioh-fd_write   FD_ISSET(ioh-fd,wfds)) {
   ioh-fd_write(ioh-opaque);
   }
+
+/* Do this last in case read/write handlers marked it for deletion 
*/
+if (ioh-deleted) {
+QLIST_REMOVE(ioh, next);
+qemu_free(ioh);
+}
   }

   

This isn't enough.  If you end up with a handler deleting the next
pointer and the current pointer, you'll end up running off the end of
the list.
 

What is the point of that?

That a handler can remove itself is ok.
But that a handler can remove also the next in a list that is used for
other things looks pretty insane to me.
   


If you have multiple file descriptors registered for something and you 
get an EOF on one of the file descriptors, your clean-up action that 
happens as a result of closing the session may involve deleting more 
than one file descriptor callback.


Regards,

Anthony Liguori


The original commit should be reverted.
 

If that behaviour is expected, then I agree that we should revert it.
But I would consider that behaviour wrong.

Later, Juan.

   

Regards,

Anthony Liguori

 

   }


   





Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-03 Thread Ian Molton

On 01/11/10 15:57, Anthony Liguori wrote:


It very much is. It supports fully visually integrated rendering (no
overlay windows) and even compositing GL window managers work fine,
even if running 3D apps under them.


Does the kernel track userspace pid and pass that information to qemu?


Yes. And the qemu code tracks the PIDs and keeps multiple queues (one 
per pid).


-Ian



Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-03 Thread Ian Molton

On 29/10/10 12:18, Rusty Russell wrote:

On Wed, 27 Oct 2010 11:30:31 pm Ian Molton wrote:

On 19/10/10 11:39, Avi Kivity wrote:

On 10/19/2010 12:31 PM, Ian Molton wrote:



2. should start with a patch to the virtio-pci spec to document what
you're doing


Where can I find that spec?


http://ozlabs.org/~rusty/virtio-spec/


Ok, but I'm not patching that until theres been some review.


Fair enough; it's a bit of a PITA to patch, so it makes sense to get the
details nailed down first.


I thought so :)


Fixed - updated patch tested and attached.


OK. FWIW, I think this is an awesome idea.  I understand others are skeptical,
but this seems simple and if it works and you're happy to maintain it I'm
happy to let you do it :)


Awesoe, thanks Rusty :)



[Qemu-devel] Re: [RFC][PATCH 1/3] Linux/Guest unmapped page cache control

2010-11-03 Thread Christoph Lameter
On Wed, 3 Nov 2010, Balbir Singh wrote:

   +#define UNMAPPED_PAGE_RATIO 16
 
  Maybe come up with a scheme that allows better configuration of the
  mininum? I think in some setting we may want an absolute limit and in
  other a fraction of something (total zone size or working set?)
 

 Are you suggesting a sysctl or computation based on zone size and
 limit, etc? I understand it to be the latter.

Do a computation based on zone size on startup and then allow the
user to modify the absolute size of the page cache?


Hmmm.. That would have to be per zone/node or somehow distributed over all
zones/nodes.





Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Michael S. Tsirkin
On Wed, Nov 03, 2010 at 12:29:10PM -0500, Ryan Harper wrote:
 * Markus Armbruster arm...@redhat.com [2010-11-03 11:42]:
  Ryan Harper ry...@us.ibm.com writes:
  
   * Michael S. Tsirkin m...@redhat.com [2010-11-03 02:22]:
   On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
* Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
 On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
  I like the idea of disconnect; if part of the device_del 
  method was to
  invoke a disconnect method, we could implement that for 
  block, net, etc;
  
  I'd think we'd want to send the notification, then 
  disconnect.
  Struggling with whether it's worth having some reasonable 
  timeout
  between notification and disconnect.  
 
 The problem with this is that it has no analog in real world.
 In real world, you can send some notifications to the guest, 
 and you can
 remove the card.  Tying them together is what created the 
 problem in the
 first place.
 
 Timeouts can be implemented by management, maybe with a nice 
 dialog
 being shown to the user.

Very true.  I'm fine with forcing a disconnect during the 
removal path
prior to notification.  Do we want a new disconnect method at 
the device
level (pci)? or just use the existing removal callback and 
call that
during the initial hotremov event?
   
   Not sure what you mean by that, but I don't see a device doing 
   anything
   differently wrt surprise or ordered removal. So probably the 
   existing
   callback should do. I don't think we need to talk about 
   disconnect:
   since we decided we are emulating device removal, let's call it
   just that.
  
  Because current the removal process depends on the guest actually
  responding.  What I'm suggesting is that, in Marcus's term, and 
  what
  drive_unplug() implements, is to disconnect the host block device 
  from
  the guest device to prevent any further access to it in the case 
  the
  guest doesn't respond to the removal request made via ACPI.
  
  Very specifically, what we're suggesting instead of the 
  drive_unplug()
  command so to complete the device removal operation without 
  waiting for
  the guest to respond; that's what's going to happen if we invoke 
  the
  response callback; it will appear as if the guest responded 
  whether it
  did or not.
  
  What I was suggesting above was to instead of calling the callback 
  for
  handing the guest response was to add a device function called
  disconnect which would remove any association of host resources 
  from
  guest resources before we notified the guest.  Thinking about it 
  again
  I'm not sure this is useful, but if we're going to remove the 
  device
  without the guests knowledge, I'm not sure how useful sending the
  removal requests via ACPI is in the first place.
  
  My feeling is that I'd like to have explicit control over the 
  disconnect
  from host resources separate from the device removal *if* we're 
  going to
  retain the guest notification.  If we don't care to notify the 
  guest,
  then we can just do device removal without notifying the guest
  and be done with it.
 
 I imagine management would typically want to do this:
 1. notify guest
 2. wait a bit
 3. remove device

Yes; but this argues for (1) being a separate command from (3)
   
   Yes. Long term I think we will want a way to do that.
   
unless we
require (3) to include (1) and (2) in the qemu implementation.

Currently we implement:

1. device_del (attempt to remove device)
2. notify guest
3. if guest responds, remove device
4. disconnect host resource from device on destruction

With my drive_unplug patch we do:

1. disconnect host resource from device
   
   This is what drive_unplug does, right?
  
   Correct.
  
   
2. device_del (attempt to remove device)
3. notify guest
4. if guest responds, remove device

I think we're suggesting to instead do (if we keep disconnect as part 
of
device_del)

1. device_del (attemp to remove device)
2. notify guest
3. invoke device destruction callback resulting in disconnect host 
resource from device
4. if guest responds, invoke device destruction path a second time.
   
   By response you mean eject?  No, this is not what I was suggesting.
   I was really suggesting that your patch is fine :)
   Sorry about confusion.
  
   I don't mean eject; I mean responding to the ACPI event by writing a
   response to the PCI chipset which QEMU then in 

Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-03 Thread Ian Molton

On 01/11/10 13:28, Anthony Liguori wrote:

On 11/01/2010 06:53 AM, Alon Levy wrote:



While we (speaking as part of the SPICE developers) want to have the same
support in our virtual GPU for 3d as we have for 2d, we just don't at
this point of time.


Would it be helpful to you to have /something/ that works in the 
interim? I'm happy to work with you guys so that we dont need to 
reinvent the wheel ;-)



Yes, but I think the point is that are two general approaches to
supporting 3d that are being proposed. One approach is to an RPC layer
at the OpenGL level which essentially passes through the host OpenGL
stack. That's what virtio-gl is. This has existed for quite a while and
there are multiple transports for it.


Well, sort of. this version is heavily modified and only the virtio 
transport is supported in it. Its quite a large code cleanup.



It supports serial ports, TCP sockets, a custom ISA extension for x86,


The custom ISA idea is cut too since it fails to play nice with KVM. 
Virtio-gl offers better security too.



Another approach would be to have a virtual GPU and to implement
GPU-level commands for 3d. I have been repeated told that much of the
complexity of Spice is absolutely needed for 3d and that that's a major
part of the design.


I've not seen any implementations of this type that are even close to 
useable.



GPU-level support for 3d operations has a number of advantages mainly
that it's more reasonably portable to things like Windows since the 3d
commands can be a superset of both OpenGL and Direct3d.


Agreed.


Also, Spice has an abstraction layer that doesn't simply passthrough
graphics commands, but translates/sanitizes them first. That's another
advantage over OpenGL passthrough.


I'm not sure that thats actually needed if you are careful about what 
commands you implement on the virtual GPU (and how)



Without a layer to sanitize commands,
a guest can do funky things with the host or other guests.


It shouldnt be possible for the guest to hurt other guests actual GL 
rendering (or the hosts) as each PID is handed a context (or contexts) 
of its own. It is possible for the guest to cause the host problems 
though. this is a design flaw in the whole idea of GL RPC. It *isnt* 
reasonable to make it secure, but it certainly is useful right now since 
theres no alternative available.



I think a Spice-like approach is the best thing long term. In the short
term, I think doing the GL marshalling over virtio-serial makes a ton of
sense since the kernel driver is already present upstream. It exists
exactly for things like this.


The virtio driver enfoces the PID field and understands the packet 
format used. Its better than using serial. Its also just one driver - 
which doesnt have any special interdependencies and can be extended or 
got rid of in future if and when better things come along.



In the very, very short term, I think an external backend to QEMU also
makes a lot of sense because that's something that Just Works today.


Whos written that? The 2007 patch I've been working on and updating 
simply fails to work altogether without huge alterations on current qemu.


My current patch touches a tiny part of the qemu sources. It works today.


I
think we can consider integrating it into QEMU (or at least simplifying
the execution of the backend) but integrating into QEMU is going to
require an awful lot of the existing code to be rewritten. Keeping it
separate has the advantage of allowing something to Just Work as an
interim solution as we wait for proper support in Spice.


I dont know why you think integrating it into qemu is hard? I've already 
done it. I added one virtio driver and a seperate offscreen renderer. it 
touches the qemu code in *one* place. There should be no need to rewrite 
anything.




[Qemu-devel] site down (qemu.org)

2010-11-03 Thread Lluís
For a lack (to my knowledge) for a better place, just say that I cannot
resolve qemu.org.

This affects both the webpage and the git repository. I'm using
git://git.qemu.org/qemu.git, which I thought is the main one.

Thanks,
Lluis

-- 
 And it's much the same thing with knowledge, for whenever you learn
 something new, the whole world becomes that much richer.
 -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
 Tollbooth



Re: [Qemu-devel] Re: [PATCH] Implement a virtio GPU transport

2010-11-03 Thread Anthony Liguori

On 11/03/2010 01:03 PM, Ian Molton wrote:


The virtio driver enfoces the PID field and understands the packet 
format used. Its better than using serial. Its also just one driver - 
which doesnt have any special interdependencies and can be extended or 
got rid of in future if and when better things come along.


Why is it better than using virtio-serial?




In the very, very short term, I think an external backend to QEMU also
makes a lot of sense because that's something that Just Works today.


Whos written that? The 2007 patch I've been working on and updating 
simply fails to work altogether without huge alterations on current qemu.


My current patch touches a tiny part of the qemu sources. It works today.


But it's not at all mergable in the current form.  If you want to do the 
work of getting it into a mergable state (cleaning up the coding style, 
moving it to hw/, etc.) than I'm willing to consider it.  But I don't 
think a custom virtio transport is the right thing to do here.


However, if you want something that Just Works with the least amount of 
code possible, just split it into a separate process and we can stick it 
in a contrib/ directory or something.





I
think we can consider integrating it into QEMU (or at least simplifying
the execution of the backend) but integrating into QEMU is going to
require an awful lot of the existing code to be rewritten. Keeping it
separate has the advantage of allowing something to Just Work as an
interim solution as we wait for proper support in Spice.


I dont know why you think integrating it into qemu is hard? I've 
already done it. 


Adding a file that happens to compile as part of qemu even though it 
doesn't actually integrate with qemu in any meaningful way is not 
integrating.  That's just build system manipulation.


Regards,

Anthony Liguori

I added one virtio driver and a seperate offscreen renderer. it 
touches the qemu code in *one* place. There should be no need to 
rewrite anything.





Re: [Qemu-devel] site down (qemu.org)

2010-11-03 Thread Anthony Liguori

On 11/03/2010 01:14 PM, Lluís wrote:

For a lack (to my knowledge) for a better place, just say that I cannot
resolve qemu.org.

This affects both the webpage and the git repository. I'm using
git://git.qemu.org/qemu.git, which I thought is the main one.
   


The site is actually up but the DNS server seems to be fubar.

I'll register a temporary domain name later tonight when I'm not on a 
public wifi network until we can get qemu.org resolved.


Regards,

Anthony Liguori


Thanks,
 Lluis

   





[Qemu-devel] Re: [PATCH 1/4] Introduce strtosz() library function to convert a string to a byte count.

2010-11-03 Thread Anthony Liguori

On 10/21/2010 10:15 AM, jes.soren...@redhat.com wrote:

From: Jes Sorensenjes.soren...@redhat.com

strtosz() returns -1 on error. It now supports human unit formats in
eg. 1.0G, with better error handling.

The following suffixes are supported:
B/b = bytes
K/k = KB
M/m = MB
G/g = GB
T/t = TB

This patch changes -numa and -m input to use strtosz().

Signed-off-by: Jes Sorensenjes.soren...@redhat.com
   


Applied all.  Thanks.

Regards,

Anthony Liguori


---
  cutils.c  |   88 +
  qemu-common.h |1 +
  vl.c  |   31 ++-
  3 files changed, 99 insertions(+), 21 deletions(-)

diff --git a/cutils.c b/cutils.c
index 5883737..28089aa 100644
--- a/cutils.c
+++ b/cutils.c
@@ -23,6 +23,7 @@
   */
  #include qemu-common.h
  #include host-utils.h
+#includemath.h

  void pstrcpy(char *buf, int buf_size, const char *str)
  {
@@ -283,3 +284,90 @@ int fcntl_setfl(int fd, int flag)
  }
  #endif

+/*
+ * Convert string to bytes, allowing either B/b for bytes, K/k for KB,
+ * M/m for MB, G/g for GB or T/t for TB. Default without any postfix
+ * is MB. End pointer will be returned in *end, if not NULL. A valid
+ * value must be terminated by whitespace, ',' or '\0'. Return -1 on
+ * error.
+ */
+ssize_t strtosz(const char *nptr, char **end)
+{
+ssize_t retval = -1;
+char *endptr, c;
+int mul_required = 0;
+double val, mul, integral, fraction;
+
+errno = 0;
+val = strtod(nptr,endptr);
+if (isnan(val) || endptr == nptr || errno != 0) {
+goto fail;
+}
+integral = modf(val,fraction);
+if (integral != 0) {
+mul_required = 1;
+}
+/*
+ * Any whitespace character is fine for terminating the number,
+ * in addition we accept ',' to handle strings where the size is
+ * part of a multi token argument.
+ */
+c = *endptr;
+if (isspace(c) || c == '\0' || c == ',') {
+c = 0;
+}
+switch (c) {
+case 'B':
+case 'b':
+mul = 1;
+if (mul_required) {
+goto fail;
+}
+break;
+case 'K':
+case 'k':
+mul = 1  10;
+break;
+case 0:
+if (mul_required) {
+goto fail;
+}
+case 'M':
+case 'm':
+mul = 1ULL  20;
+break;
+case 'G':
+case 'g':
+mul = 1ULL  30;
+break;
+case 'T':
+case 't':
+mul = 1ULL  40;
+break;
+default:
+goto fail;
+}
+/*
+ * If not terminated by whitespace, ',', or \0, increment endptr
+ * to point to next character, then check that we are terminated
+ * by an appropriate separating character, ie. whitespace, ',', or
+ * \0. If not, we are seeing trailing garbage, thus fail.
+ */
+if (c != 0) {
+endptr++;
+if (!isspace(*endptr)  *endptr != ','  *endptr != 0) {
+goto fail;
+}
+}
+if ((val * mul= ~(size_t)0) || val  0) {
+goto fail;
+}
+retval = val * mul;
+
+fail:
+if (end) {
+*end = endptr;
+}
+
+return retval;
+}
diff --git a/qemu-common.h b/qemu-common.h
index 81aafa0..0a062d4 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -153,6 +153,7 @@ time_t mktimegm(struct tm *tm);
  int qemu_fls(int i);
  int qemu_fdatasync(int fd);
  int fcntl_setfl(int fd, int flag);
+ssize_t strtosz(const char *nptr, char **end);

  /* path.c */
  void init_paths(const char *prefix);
diff --git a/vl.c b/vl.c
index df414ef..6043fa2 100644
--- a/vl.c
+++ b/vl.c
@@ -734,16 +734,13 @@ static void numa_add(const char *optarg)
  if (get_param_value(option, 128, mem, optarg) == 0) {
  node_mem[nodenr] = 0;
  } else {
-value = strtoull(option,endptr, 0);
-switch (*endptr) {
-case 0: case 'M': case 'm':
-value= 20;
-break;
-case 'G': case 'g':
-value= 30;
-break;
+ssize_t sval;
+sval = strtosz(option, NULL);
+if (sval  0) {
+fprintf(stderr, qemu: invalid numa mem size: %s\n, optarg);
+exit(1);
  }
-node_mem[nodenr] = value;
+node_mem[nodenr] = sval;
  }
  if (get_param_value(option, 128, cpus, optarg) == 0) {
  node_cpumask[nodenr] = 0;
@@ -2163,18 +2160,10 @@ int main(int argc, char **argv, char **envp)
  exit(0);
  break;
  case QEMU_OPTION_m: {
-uint64_t value;
-char *ptr;
+ssize_t value;

-value = strtoul(optarg,ptr, 10);
-switch (*ptr) {
-case 0: case 'M': case 'm':
-value= 20;
-break;
-case 'G': case 'g':
-value= 30;
-break;
-default:
+value = 

Re: [Qemu-devel] [PATCH 1/1] Fold send_all() wrapper unix_write() into one function

2010-11-03 Thread Anthony Liguori

On 11/01/2010 02:02 PM, jes.soren...@redhat.com wrote:

From: Jes Sorensenjes.soren...@redhat.com

The current send_all() wrapper for POSIX calls does nothing but call
unix_write(). Merge them to simplify the code.

Signed-off-by: Jes Sorensenjes.soren...@redhat.com
   


Applied.  Thanks.

Regards,

Anthony Liguori


---
  qemu-char.c |8 ++--
  1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index 6d2dce7..88997f9 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -508,9 +508,10 @@ int send_all(int fd, const void *buf, int len1)

  #else

-static int unix_write(int fd, const uint8_t *buf, int len1)
+int send_all(int fd, const void *_buf, int len1)
  {
  int ret, len;
+const uint8_t *buf = _buf;

  len = len1;
  while (len  0) {
@@ -527,11 +528,6 @@ static int unix_write(int fd, const uint8_t *buf, int len1)
  }
  return len1 - len;
  }
-
-int send_all(int fd, const void *buf, int len1)
-{
-return unix_write(fd, buf, len1);
-}
  #endif /* !_WIN32 */

  #ifndef _WIN32
   





[Qemu-devel] Re: [PATCH] Delete IOHandlers after potentially running them

2010-11-03 Thread Juan Quintela
Anthony Liguori anth...@codemonkey.ws wrote:
 On 11/03/2010 10:12 AM, Juan Quintela wrote:
 Anthony Liguorianth...@codemonkey.ws  wrote:

 On 11/03/2010 09:29 AM, Stefan Hajnoczi wrote:
  
 Since commit 4bed9837309e58d208183f81d8344996744292cf an .fd_read()
 handler that deletes its IOHandler is exposed to .fd_write() being
 called on the deleted IOHandler.

 This patch fixes deletion so that .fd_read() and .fd_write() are never
 called on an IOHandler that is marked for deletion.

 Signed-off-by: Stefan Hajnoczistefa...@linux.vnet.ibm.com
 ---
vl.c |   15 ---
1 files changed, 8 insertions(+), 7 deletions(-)

 diff --git a/vl.c b/vl.c
 index 7038952..6f56123 100644
 --- a/vl.c
 +++ b/vl.c
 @@ -1252,17 +1252,18 @@ void main_loop_wait(int nonblocking)
IOHandlerRecord *pioh;

QLIST_FOREACH_SAFE(ioh,io_handlers, next, pioh) {
 -if (ioh-deleted) {
 -QLIST_REMOVE(ioh, next);
 -qemu_free(ioh);
 -continue;
 -}
 -if (ioh-fd_read   FD_ISSET(ioh-fd,rfds)) {
 +if (!ioh-deleted   ioh-fd_read   
 FD_ISSET(ioh-fd,rfds)) {
ioh-fd_read(ioh-opaque);
}
 -if (ioh-fd_write   FD_ISSET(ioh-fd,wfds)) {
 +if (!ioh-deleted   ioh-fd_write   
 FD_ISSET(ioh-fd,wfds)) {
ioh-fd_write(ioh-opaque);
}
 +
 +/* Do this last in case read/write handlers marked it for 
 deletion */
 +if (ioh-deleted) {
 +QLIST_REMOVE(ioh, next);
 +qemu_free(ioh);
 +}
}


 This isn't enough.  If you end up with a handler deleting the next
 pointer and the current pointer, you'll end up running off the end of
 the list.
  
 What is the point of that?

 That a handler can remove itself is ok.
 But that a handler can remove also the next in a list that is used for
 other things looks pretty insane to me.


 If you have multiple file descriptors registered for something and you
 get an EOF on one of the file descriptors, your clean-up action that
 happens as a result of closing the session may involve deleting more
 than one file descriptor callback.

But that is completely wrong.  you just put an ioh-deleted=1 for the
others, and you are right, no?

Later, Juan.



[Qemu-devel] [RFC][PATCH v1 0/6] backdoor: instruction-based guest-to-QEMU backdoor communication channel

2010-11-03 Thread Lluís
Provides the ability for the guest to communicate with user-provided code inside
QEMU itself.

This backdoor communication channel is based on using instructions, as opposed
to methods based on MMIO/PIO or virtproxy/virtagent.

Then, these instructions are redirected to a set of user-provided routines,
which are expected to be in the static library libbackdoor.a, identified by
the --with-backdoor configuration parameter.

The advantages of this method are:

* Minimal setup for the guest. Can be used with a simple library using
  LD_PRELOAD, or simply adding calls to the macros in backdoor/guest.h.

* Low-overhead. Using instructions does not go through any OS abstraction, not
  even for the setup of the communication channel.

* Non-intrusive wrt OS. It can be used on any OS without prior modifications.

When possible, this will overload unused/meaningless instructions in order to
let the modified guest application to run natively without errors (e.g., using
the CPUID instruction in x86 systems).

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---

Lluís Vilanova (6):
  [arm m68k] move helpers.h to helper.h
  backdoor: handle config-time activation
  backdoor: declare host-side backdoor helpers
  backdoor: declare guest-side interface macros
  backdoor: [i386] provide and implement intruction-based backdoor interface
  backdoor: add a simple example


 .gitignore |1 
 Makefile.target|   40 +++
 backdoor/examples/print/README |   13 +
 backdoor/examples/print/guest/Makefile |7 
 backdoor/examples/print/guest/test.c   |   33 ++
 backdoor/examples/print/host/Makefile  |   13 +
 backdoor/examples/print/host/printcb.c |   36 +++
 backdoor/guest.h   |   54 
 backdoor/helper.h  |   21 +
 configure  |   21 +
 target-arm/helper.c|2 
 target-arm/helper.h|  450 
 target-arm/helpers.h   |  450 
 target-arm/iwmmxt_helper.c |2 
 target-arm/neon_helper.c   |2 
 target-arm/op_helper.c |2 
 target-arm/translate.c |6 
 target-i386/cpuid.c|   27 ++
 target-i386/helper.h   |4 
 target-i386/translate.c|4 
 target-m68k/helper.c   |2 
 target-m68k/helper.h   |   54 
 target-m68k/helpers.h  |   54 
 target-m68k/op_helper.c|2 
 target-m68k/translate.c|6 
 25 files changed, 786 insertions(+), 520 deletions(-)
 create mode 100644 backdoor/examples/print/README
 create mode 100644 backdoor/examples/print/guest/Makefile
 create mode 100644 backdoor/examples/print/guest/test.c
 create mode 100644 backdoor/examples/print/host/Makefile
 create mode 100644 backdoor/examples/print/host/printcb.c
 create mode 100644 backdoor/guest.h
 create mode 100644 backdoor/helper.h
 create mode 100644 target-arm/helper.h
 delete mode 100644 target-arm/helpers.h
 create mode 100644 target-m68k/helper.h
 delete mode 100644 target-m68k/helpers.h




[Qemu-devel] [PATCH v1 1/6] [arm m68k] move helpers.h to helper.h

2010-11-03 Thread Lluís
This provides a consistent naming scheme across all targets.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 target-arm/helper.c|2 
 target-arm/helper.h|  450 
 target-arm/helpers.h   |  450 
 target-arm/iwmmxt_helper.c |2 
 target-arm/neon_helper.c   |2 
 target-arm/op_helper.c |2 
 target-arm/translate.c |6 -
 target-m68k/helper.c   |2 
 target-m68k/helper.h   |   54 +
 target-m68k/helpers.h  |   54 -
 target-m68k/op_helper.c|2 
 target-m68k/translate.c|6 -
 12 files changed, 516 insertions(+), 516 deletions(-)
 create mode 100644 target-arm/helper.h
 delete mode 100644 target-arm/helpers.h
 create mode 100644 target-m68k/helper.h
 delete mode 100644 target-m68k/helpers.h

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2dd64d9..08afe24 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -5,7 +5,7 @@
 #include cpu.h
 #include exec-all.h
 #include gdbstub.h
-#include helpers.h
+#include helper.h
 #include qemu-common.h
 #include host-utils.h
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-arm/helper.h b/target-arm/helper.h
new file mode 100644
index 000..0d1bc47
--- /dev/null
+++ b/target-arm/helper.h
@@ -0,0 +1,450 @@
+#include def-helper.h
+
+DEF_HELPER_1(clz, i32, i32)
+DEF_HELPER_1(sxtb16, i32, i32)
+DEF_HELPER_1(uxtb16, i32, i32)
+
+DEF_HELPER_2(add_setq, i32, i32, i32)
+DEF_HELPER_2(add_saturate, i32, i32, i32)
+DEF_HELPER_2(sub_saturate, i32, i32, i32)
+DEF_HELPER_2(add_usaturate, i32, i32, i32)
+DEF_HELPER_2(sub_usaturate, i32, i32, i32)
+DEF_HELPER_1(double_saturate, i32, s32)
+DEF_HELPER_2(sdiv, s32, s32, s32)
+DEF_HELPER_2(udiv, i32, i32, i32)
+DEF_HELPER_1(rbit, i32, i32)
+DEF_HELPER_1(abs, i32, i32)
+
+#define PAS_OP(pfx)  \
+DEF_HELPER_3(pfx ## add8, i32, i32, i32, ptr) \
+DEF_HELPER_3(pfx ## sub8, i32, i32, i32, ptr) \
+DEF_HELPER_3(pfx ## sub16, i32, i32, i32, ptr) \
+DEF_HELPER_3(pfx ## add16, i32, i32, i32, ptr) \
+DEF_HELPER_3(pfx ## addsubx, i32, i32, i32, ptr) \
+DEF_HELPER_3(pfx ## subaddx, i32, i32, i32, ptr)
+
+PAS_OP(s)
+PAS_OP(u)
+#undef PAS_OP
+
+#define PAS_OP(pfx)  \
+DEF_HELPER_2(pfx ## add8, i32, i32, i32) \
+DEF_HELPER_2(pfx ## sub8, i32, i32, i32) \
+DEF_HELPER_2(pfx ## sub16, i32, i32, i32) \
+DEF_HELPER_2(pfx ## add16, i32, i32, i32) \
+DEF_HELPER_2(pfx ## addsubx, i32, i32, i32) \
+DEF_HELPER_2(pfx ## subaddx, i32, i32, i32)
+PAS_OP(q)
+PAS_OP(sh)
+PAS_OP(uq)
+PAS_OP(uh)
+#undef PAS_OP
+
+DEF_HELPER_2(ssat, i32, i32, i32)
+DEF_HELPER_2(usat, i32, i32, i32)
+DEF_HELPER_2(ssat16, i32, i32, i32)
+DEF_HELPER_2(usat16, i32, i32, i32)
+
+DEF_HELPER_2(usad8, i32, i32, i32)
+
+DEF_HELPER_1(logicq_cc, i32, i64)
+
+DEF_HELPER_3(sel_flags, i32, i32, i32, i32)
+DEF_HELPER_1(exception, void, i32)
+DEF_HELPER_0(wfi, void)
+
+DEF_HELPER_2(cpsr_write, void, i32, i32)
+DEF_HELPER_0(cpsr_read, i32)
+
+DEF_HELPER_3(v7m_msr, void, env, i32, i32)
+DEF_HELPER_2(v7m_mrs, i32, env, i32)
+
+DEF_HELPER_3(set_cp15, void, env, i32, i32)
+DEF_HELPER_2(get_cp15, i32, env, i32)
+
+DEF_HELPER_3(set_cp, void, env, i32, i32)
+DEF_HELPER_2(get_cp, i32, env, i32)
+
+DEF_HELPER_2(get_r13_banked, i32, env, i32)
+DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
+
+DEF_HELPER_1(get_user_reg, i32, i32)
+DEF_HELPER_2(set_user_reg, void, i32, i32)
+
+DEF_HELPER_1(vfp_get_fpscr, i32, env)
+DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
+
+DEF_HELPER_3(vfp_adds, f32, f32, f32, env)
+DEF_HELPER_3(vfp_addd, f64, f64, f64, env)
+DEF_HELPER_3(vfp_subs, f32, f32, f32, env)
+DEF_HELPER_3(vfp_subd, f64, f64, f64, env)
+DEF_HELPER_3(vfp_muls, f32, f32, f32, env)
+DEF_HELPER_3(vfp_muld, f64, f64, f64, env)
+DEF_HELPER_3(vfp_divs, f32, f32, f32, env)
+DEF_HELPER_3(vfp_divd, f64, f64, f64, env)
+DEF_HELPER_1(vfp_negs, f32, f32)
+DEF_HELPER_1(vfp_negd, f64, f64)
+DEF_HELPER_1(vfp_abss, f32, f32)
+DEF_HELPER_1(vfp_absd, f64, f64)
+DEF_HELPER_2(vfp_sqrts, f32, f32, env)
+DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
+DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
+DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
+DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
+DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
+
+DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
+DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
+
+DEF_HELPER_2(vfp_uitos, f32, f32, env)
+DEF_HELPER_2(vfp_uitod, f64, f32, env)
+DEF_HELPER_2(vfp_sitos, f32, f32, env)
+DEF_HELPER_2(vfp_sitod, f64, f32, env)
+
+DEF_HELPER_2(vfp_touis, f32, f32, env)
+DEF_HELPER_2(vfp_touid, f32, f64, env)
+DEF_HELPER_2(vfp_touizs, f32, f32, env)
+DEF_HELPER_2(vfp_touizd, f32, f64, env)
+DEF_HELPER_2(vfp_tosis, f32, f32, env)
+DEF_HELPER_2(vfp_tosid, f32, f64, env)
+DEF_HELPER_2(vfp_tosizs, f32, f32, env)
+DEF_HELPER_2(vfp_tosizd, f32, f64, env)
+
+DEF_HELPER_3(vfp_toshs, f32, f32, i32, env)
+DEF_HELPER_3(vfp_tosls, f32, f32, i32, env)
+DEF_HELPER_3(vfp_touhs, f32, 

[Qemu-devel] [PATCH v1 2/6] backdoor: handle config-time activation

2010-11-03 Thread Lluís
Add a '--with-backdoor' configuration option pointing to user-provided backdoor
callback implementation.

Make is invoked on the user-provided directory, which must build a static
library containing, at least, the implementation of the backdoor helpers.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile.target |   40 
 configure   |   21 +
 2 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index c48cbcc..9152723 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -29,7 +29,7 @@ QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
 endif
 endif
 
-PROGS=$(QEMU_PROG)
+PROGS=$(QEMU_PROG)-prepare $(QEMU_PROG)
 
 ifndef CONFIG_HAIKU
 LIBS+=-lm
@@ -323,8 +323,40 @@ endif # CONFIG_SOFTMMU
 obj-y += $(addprefix ../, $(trace-obj-y))
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
-   $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
+
+.PHONY: force
+force:
+
+#
+# backdoor communication channel
+ifdef CONFIG_BACKDOOR
+VPATH := $(VPATH):$(BACKDOOR_PATH)
+
+LIBBACKDOOR_LIB = libbackdoor/libbackdoor.a
+LIBBACKDOOR_CLEAN = libbackdoor-clean
+
+libbackdoor/Makefile:
+   $(call quiet-command, mkdir -p libbackdoor,   CREAT $(TARGET_DIR)$@)
+   $(call quiet-command, rm -f libbackdoor/Makefile)
+   $(call quiet-command, ln -s $(BACKDOOR_PATH)/Makefile 
libbackdoor/Makefile)
+
+libbackdoor/libbackdoor.a: libbackdoor/Makefile force
+   $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libbackdoor 
\
+   QEMU_CFLAGS=$(QEMU_CFLAGS) -I../target-$(TARGET_BASE_ARCH)
\
+   TARGET_DIR=$(TARGET_DIR)libbackdoor/ VPATH=$(VPATH) 
\
+   SRC_PATH=$(SRC_PATH) V=$(V) libbackdoor.a)
+
+libbackdoor-clean:
+   $(MAKE) $(SUBDIR_MAKEFLAGS) -C $(LIBBACKDOOR_DIR)   
\
+   VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V=$(V) clean || true
+endif
+
+
+
+$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(QEMU_PROG)
+
+$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB)
+   $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB)
 
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
@@ -336,7 +368,7 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
 qmp-commands.h: $(SRC_PATH)/qmp-commands.hx
$(call quiet-command,sh $(SRC_PATH)/hxtool -h  $  $@,  GEN   
$(TARGET_DIR)$@)
 
-clean:
+clean: $(LIBBACKDOOR_CLEAN)
rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
rm -f *.d */*.d tcg/*.o ide/*.o
rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
diff --git a/configure b/configure
index a079a49..991f0b8 100755
--- a/configure
+++ b/configure
@@ -331,6 +331,7 @@ zero_malloc=
 trace_backend=nop
 trace_file=trace
 spice=
+backdoor=
 
 # OS specific
 if check_define __linux__ ; then
@@ -740,6 +741,17 @@ for opt do
   ;;
   --*dir)
   ;;
+  --with-backdoor=*) backdoor=$optarg
+  if test ! -f $backdoor/Makefile; then
+  echo
+  echo Error: cannot make into '$backdoor'
+  echo Please choose a directory where I can run 'make'
+  echo
+  exit 1
+  else
+  backdoor=`readlink -f $backdoor`
+  fi
+  ;;
   *) echo ERROR: unknown option $opt; show_help=yes
   ;;
   esac
@@ -2320,6 +2332,9 @@ echo vhost-net support $vhost_net
 echo Trace backend $trace_backend
 echo Trace output file $trace_file-pid
 echo spice support $spice
+if test -n $backdoor; then
+echo Backdoor comm.$backdoor
+fi
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2579,6 +2594,12 @@ if test $spice = yes ; then
   echo CONFIG_SPICE=y  $config_host_mak
 fi
 
+if test -n $backdoor; then
+  echo CONFIG_BACKDOOR=y  $config_host_mak
+  echo BACKDOOR_PATH=$backdoor  $config_host_mak
+  rm -rf *-{bsd-usr,darwin-user,linux-user,softmmu}/libbackdoor/
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak




[Qemu-devel] [PATCH v1 3/6] backdoor: declare host-side backdoor helpers

2010-11-03 Thread Lluís
These helpers must be implemented by the user on libbackdoor.a.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 backdoor/helper.h |   21 +
 1 files changed, 21 insertions(+), 0 deletions(-)
 create mode 100644 backdoor/helper.h

diff --git a/backdoor/helper.h b/backdoor/helper.h
new file mode 100644
index 000..d3c19d9
--- /dev/null
+++ b/backdoor/helper.h
@@ -0,0 +1,21 @@
+/*
+ * Helpers for instruction-based backdoor communication.
+ *
+ *  Copyright (c) 2010 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/.
+ */
+
+DEF_HELPER_1(backdoor_i8, void, i32);
+DEF_HELPER_2(backdoor_i8_v32, void, i32, i32);




[Qemu-devel] [PATCH v1 5/6] backdoor: [i386] provide and implement intruction-based backdoor interface

2010-11-03 Thread Lluís
Take the unused CPUID 0x40001xxx range as the backdoor instruction.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 backdoor/guest.h|   21 +
 target-i386/cpuid.c |   27 +++
 target-i386/helper.h|4 
 target-i386/translate.c |4 
 4 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/backdoor/guest.h b/backdoor/guest.h
index 8373762..3edcbc6 100644
--- a/backdoor/guest.h
+++ b/backdoor/guest.h
@@ -26,8 +26,29 @@
  * - v32: value of 32 bits
  */
 
+#include stdint.h
+
+#if __i386__ || __i486__ || __x86_64__
+
+#define _BACKDOOR(t, i8, v32)   \
+({  \
+uint32_t eax, ebx, ecx, edx;\
+uint32_t index = (uint32_t)0x40001000 + (t8) + (uint8_t)i8;   \
+uint32_t count = (uint32_t)v32; \
+asm volatile (cpuid   \
+  : =a(eax), =b(ebx), =c(ecx), =d(edx)  \
+  : 0(index), 2(count)  \
+);  \
+eax;\
+})
+
+#define BACKDOOR_i8(i)_BACKDOOR(0, i, 0)
+#define BACKDOOR_i8_v32(i, v) _BACKDOOR(1, i, v)
+
+#else
 
 #error Undefined instruction-based backdoor interface for guest architecture
 
+#endif
 
 #endif /* BACKDOOR__GUEST_H */
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 04ba8d5..5163e69 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -27,6 +27,9 @@
 #include qemu-option.h
 #include qemu-config.h
 
+#include helper.h
+
+
 /* feature flags taken from Intel Processor Identification and the CPUID
  * Instruction and AMD's CPUID Specification.  In cases of disagreement
  * between feature naming conventions, aliases may be added.
@@ -991,6 +994,30 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
 {
+#if defined(CONFIG_BACKDOOR)/* synched with backdoor/guest.h */
+if ((index  ~0xfff) == 0x40001000) {
+int type = (index  8)  0xf;
+uint8_t i8 = index  0x0ff;
+uint32_t v32 = count;
+switch (type) {
+case 0:
+helper_backdoor_i8(i8);
+break;
+case 1:
+helper_backdoor_i8_v32(i8, v32);
+break;
+default:
+printf(invalid backdoor request\n);
+abort();
+}
+*eax = 0;
+*ebx = 0;
+*ecx = 0;
+*edx = 0;
+return;
+}
+#endif
+
 /* test if maximum index reached */
 if (index  0x8000) {
 if (index  env-cpuid_xlevel)
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 6b518ad..979d94e 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -217,4 +217,8 @@ DEF_HELPER_2(rclq, tl, tl, tl)
 DEF_HELPER_2(rcrq, tl, tl, tl)
 #endif
 
+#if defined(CONFIG_BACKDOOR)
+#include backdoor/helper.h
+#endif
+
 #include def-helper.h
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 7b6e3c2..dfdc2f0 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -6941,6 +6941,10 @@ static target_ulong disas_insn(DisasContext *s, 
target_ulong pc_start)
 gen_op_set_cc_op(s-cc_op);
 gen_jmp_im(pc_start - s-cs_base);
 gen_helper_cpuid();
+#if defined(CONFIG_BACKDOOR)
+gen_jmp_im(s-pc);
+gen_eob(s);
+#endif
 break;
 case 0xf4: /* hlt */
 if (s-cpl != 0) {




[Qemu-devel] [PATCH v1 4/6] backdoor: declare guest-side interface macros

2010-11-03 Thread Lluís
Header for the user to include when compiling guest applications that want to
communicate with QEMU through backdoor instructions.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 backdoor/guest.h |   33 +
 1 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 backdoor/guest.h

diff --git a/backdoor/guest.h b/backdoor/guest.h
new file mode 100644
index 000..8373762
--- /dev/null
+++ b/backdoor/guest.h
@@ -0,0 +1,33 @@
+/*
+ * Guest-side interface for instruction-based backdoor communication.
+ *
+ *  Copyright (c) 2010 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef BACKDOOR__GUEST_H
+#define BACKDOOR__GUEST_H
+
+/* Backdoor macro names define the types of its arguments:
+ *
+ * -  i8: immediate of 8 bits
+ * - v32: value of 32 bits
+ */
+
+
+#error Undefined instruction-based backdoor interface for guest architecture
+
+
+#endif /* BACKDOOR__GUEST_H */




[Qemu-devel] [PATCH v1 3/3] trace-instrument: handle config-time activation

2010-11-03 Thread Lluís
Add a '--with-instrument' configuration option pointing to user-provided
instrumentation callbacks.

Make is invoked on the user-provided directory, which must build a static
library that might contain extra code needed by the user-provided
instrumentation.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile.target |   29 ++---
 configure   |   30 ++
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 9152723..90867e7 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -351,12 +351,35 @@ libbackdoor-clean:
VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V=$(V) clean || true
 endif
 
+#
+# static instrumentation
+ifdef CONFIG_INSTRUMENT
+VPATH := $(VPATH):$(INSTRUMENT_PATH)
+
+LIBINSTRUMENT_LIB = libinstrument/libinstrument.a
+LIBINSTRUMENT_CLEAN = libinstrument-clean
+
+libinstrument/Makefile:
+   $(call quiet-command, mkdir -p libinstrument,   CREAT $(TARGET_DIR)$@)
+   $(call quiet-command, rm -f libinstrument/Makefile)
+   $(call quiet-command, ln -s $(INSTRUMENT_PATH)/Makefile 
libinstrument/Makefile)
+
+libinstrument/libinstrument.a: libinstrument/Makefile force
+   $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libinstrument   
\
+   QEMU_CFLAGS=$(QEMU_CFLAGS) -I../target-$(TARGET_BASE_ARCH)
\
+   TARGET_DIR=$(TARGET_DIR)libinstrument/ VPATH=$(VPATH)   
\
+   SRC_PATH=$(SRC_PATH) V=$(V) libinstrument.a)
+
+libinstrument-clean:
+   $(MAKE) $(SUBDIR_MAKEFLAGS) -C $(LIBINSTRUMENT_DIR) 
\
+   VPATH=$(VPATH) SRC_PATH=$(SRC_PATH) V=$(V) clean || true
+endif
 
 
-$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) $(QEMU_PROG)
+$(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB) $(QEMU_PROG)
 
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB)
-   $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB)
+$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB)
+   $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB)
 
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
diff --git a/configure b/configure
index 991f0b8..2476512 100755
--- a/configure
+++ b/configure
@@ -332,6 +332,7 @@ trace_backend=nop
 trace_file=trace
 spice=
 backdoor=
+instrument=
 
 # OS specific
 if check_define __linux__ ; then
@@ -752,6 +753,22 @@ for opt do
   backdoor=`readlink -f $backdoor`
   fi
   ;;
+  --with-instrument=*) instrument=$optarg
+  if test ! -f $instrument/Makefile; then
+  echo
+  echo Error: cannot make into '$instrument'
+  echo Please choose a directory where I can run 'make'
+  echo
+  exit 1
+  elif test ! -f $instrument/trace-instrument.h; then
+  echo
+  echo Error: directory '$instrument' does not contain a 
\trace-instrument.h\ file
+  echo
+  exit 1
+  else
+  instrument=`readlink -f $instrument`
+  fi
+  ;;
   *) echo ERROR: unknown option $opt; show_help=yes
   ;;
   esac
@@ -943,6 +960,8 @@ echo   --trace-file=NAMEFull PATH,NAME of file to 
store traces
 echoDefault:trace-pid
 echo   --disable-spice  disable spice
 echo   --enable-spice   enable spice
+echo   --with-backdoor=PATH enable backdoor communication and compile 
implementation in PATH
+echo   --with-instrument=PATH   enable static instrumentation and compile 
user code in PATH
 echo 
 echo NOTE: The object files are built at the place where configure is 
launched
 exit 1
@@ -2335,6 +2354,9 @@ echo spice support $spice
 if test -n $backdoor; then
 echo Backdoor comm.$backdoor
 fi
+if test -n $instrument; then
+echo Instrumentation   $instrument
+fi
 
 if test $sdl_too_old = yes; then
 echo - Your SDL version is too old - please upgrade to have SDL support
@@ -2600,6 +2622,14 @@ if test -n $backdoor; then
   rm -rf *-{bsd-usr,darwin-user,linux-user,softmmu}/libbackdoor/
 fi
 
+if test -n $instrument; then
+  echo CONFIG_INSTRUMENT=y  $config_host_mak
+  echo INSTRUMENT_PATH=$instrument  $config_host_mak
+  echo TRACETOOL_EXTRA=--instrument  $config_host_mak
+  QEMU_CFLAGS=-I$instrument $QEMU_CFLAGS
+  rm -rf *-{bsd-usr,darwin-user,linux-user,softmmu}/libinstrument/
+fi
+
 # XXX: suppress that
 if [ $bsd = yes ] ; then
   echo CONFIG_BSD=y  $config_host_mak




[Qemu-devel] [RFC][PATCH v1 0/3] trace-instrument: let the user wrap/override code generated from trace-events

2010-11-03 Thread Lluís
Adds a new optional keyword (instrument) to the syntax in trace-events. When
specified, this event property lets the user provide her own implementation for
that tracing event.

Still, in case the user only wants to wrap around the tracing event, tracetool's
original implementation is accessible through function 'trace_##name##_backend',
instead of the original 'trace_##name' (which now the user has to provide).

The user-provided tracing functions are expected to be in the static library
libinstrument.a, identified by the --with-instrument configuration
parameter.

TODO:
 * Having the 'simple' backend generate code even when the disable property is
   present, complicates the flow in 'tracetool'.
   Is this behaviour really needed?

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---

Lluís Vilanova (3):
  trace: rewrite 'tracetool' to facilitate future extensions
  trace-instrument: let the user override events generated by 'tracetool'
  trace-instrument: handle config-time activation


 Makefile|4 -
 Makefile.target |   29 -
 configure   |   30 +
 simpletrace.py  |2 
 trace-events|   23 +++-
 tracetool   |  336 +++
 6 files changed, 289 insertions(+), 135 deletions(-)




[Qemu-devel] [PATCH v1 6/6] backdoor: add a simple example

2010-11-03 Thread Lluís
Provides a guest application that exercices the instruction-based backdoor
communication, as well as a backdoor callback implementation that prints the
guest requests.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 .gitignore |1 +
 backdoor/examples/print/README |   13 
 backdoor/examples/print/guest/Makefile |7 ++
 backdoor/examples/print/guest/test.c   |   33 +
 backdoor/examples/print/host/Makefile  |   13 
 backdoor/examples/print/host/printcb.c |   36 
 6 files changed, 103 insertions(+), 0 deletions(-)
 create mode 100644 backdoor/examples/print/README
 create mode 100644 backdoor/examples/print/guest/Makefile
 create mode 100644 backdoor/examples/print/guest/test.c
 create mode 100644 backdoor/examples/print/host/Makefile
 create mode 100644 backdoor/examples/print/host/printcb.c

diff --git a/.gitignore b/.gitignore
index a43e4d1..e4a351d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@ pc-bios/optionrom/multiboot.bin
 pc-bios/optionrom/multiboot.raw
 .stgit-*
 cscope.*
+backdoor/examples/print/guest/test
diff --git a/backdoor/examples/print/README b/backdoor/examples/print/README
new file mode 100644
index 000..0675f16
--- /dev/null
+++ b/backdoor/examples/print/README
@@ -0,0 +1,13 @@
+This example simply defines instruction-based backdoors to print their
+arguments, along with a guest example code that makes use of backdoor
+instructions.
+
+To compile the host (quemu) run:
+   /path/to/qemu/configure 
--with-backdoor=/path/to/qemu/backdoor/examples/print/host/
+   make
+
+To compile the guest program run:
+   make -C /path/to/qemu/backdoor/examples/print/guest/
+
+Now you can run it with:
+   /path/to/qemu/i386-linux-user/qemu-i386 
/path/to/qemu/backdoor/examples/print/guest/test
diff --git a/backdoor/examples/print/guest/Makefile 
b/backdoor/examples/print/guest/Makefile
new file mode 100644
index 000..ea266f2
--- /dev/null
+++ b/backdoor/examples/print/guest/Makefile
@@ -0,0 +1,7 @@
+CFLAGS += -I../../../../
+PROGS = test
+
+all: $(PROGS)
+
+clean:
+   rm -f $(PROGS)
diff --git a/backdoor/examples/print/guest/test.c 
b/backdoor/examples/print/guest/test.c
new file mode 100644
index 000..aeae948
--- /dev/null
+++ b/backdoor/examples/print/guest/test.c
@@ -0,0 +1,33 @@
+/*
+ * Sample guest program exercising instruction-based backdoor communication.
+ *
+ *  Copyright (c) 2010 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see http://www.gnu.org/licenses/.
+ */
+
+#include stdio.h
+
+#include backdoor/guest.h
+
+int main ()
+{
+int i = 23;
+printf(i8 1\n);
+BACKDOOR_i8(0x01);
+printf(i8_v32 1 32\n);
+BACKDOOR_i8_v32(0x01, 32);
+printf(i8_v32 2 i (%d)\n, i);
+BACKDOOR_i8_v32(0x02, i);
+}
diff --git a/backdoor/examples/print/host/Makefile 
b/backdoor/examples/print/host/Makefile
new file mode 100644
index 000..bfd6311
--- /dev/null
+++ b/backdoor/examples/print/host/Makefile
@@ -0,0 +1,13 @@
+# Makefile for user-provided backdoor code
+
+include $(SRC_PATH)/config-host.mak
+include $(SRC_PATH)/rules.mak
+include $(SRC_PATH)/Makefile.objs
+
+objs = printcb.o
+
+libbackdoor.a: $(objs)
+   $(call quiet-command,rm -f $@  $(AR) rcs $@ $^,  AR
$(TARGET_DIR)$@)
+
+clean:
+   rm -f libbackdoor.a $(objs)
diff --git a/backdoor/examples/print/host/printcb.c 
b/backdoor/examples/print/host/printcb.c
new file mode 100644
index 000..60499c9
--- /dev/null
+++ b/backdoor/examples/print/host/printcb.c
@@ -0,0 +1,36 @@
+/*
+ * Sample user-defined callbacks for backdoor communication.
+ *
+ *  Copyright (c) 2010 Lluís Vilanova vilan...@ac.upc.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, 

[Qemu-devel] [RFC][PATCH v1 0/4] trace-gen: support for trace points in code-generation routines

2010-11-03 Thread Lluís
Adds a new optional keyword (gen) to the syntax in trace-events. When
specified, this event property will generate an extra set of functions that
provide the ability to inject trace points into TCG-generated code. Note that
the regular backend-dependant functions will also be generated.

The extra files generated, and their functions are:

- trace-helper.h
  Declares a 'trace_proxy_##name' TCG helper for each affected trace event.

- trace-helper.c
  Defines a 'trace_proxy_##name' TCG helper for each affected trace event, which
  simply calls 'trace_##name'.
  Note that this scheme neatly blends with the instrument property.

- trace-gen.h
  Defines a 'trace_gen_##name##_backend' function for each affected trace event,
  which handles all the (de)allocation of TCG temporaries and calls
  'gen_helper_trace_proxy_##name'.
  If the instrument property is not present, 'trace_gen_##name' is defined as
  an alias.
  This file is instended to be included instead of trace.h for generating TCG
  calls to trace points.

In order to fully exploit the information available during TCG code generation,
trace events with the gen property can also use TCG data types (e.g.,
TCG_ptr), which are gracefully handled by 'tracetool' when generating the
trace.h and trace.c files.

TODO:
 * Handle TCGv_tl and target_long/target_ulong

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---

Lluís Vilanova (4):
  trace-gen: gracefully handle TCG types in trace-events
  trace-gen: auto-generate TCG helper routines for tracing
  trace-gen: [all] include trace-helper.h on all helper.h files
  trace-gen: auto-generate wrappers to call TCG trace helpers


 .gitignore |2 
 Makefile   |   21 ++-
 Makefile.target|5 -
 target-alpha/helper.h  |2 
 target-arm/helper.h|2 
 target-cris/helper.h   |2 
 target-i386/helper.h   |2 
 target-m68k/helper.h   |2 
 target-microblaze/helper.h |2 
 target-mips/helper.h   |2 
 target-ppc/helper.h|2 
 target-sh4/helper.h|2 
 target-sparc/helper.h  |2 
 trace-events   |8 +
 tracetool  |  366 +++-
 15 files changed, 409 insertions(+), 13 deletions(-)




[Qemu-devel] [PATCH v1 2/3] trace-instrument: let the user override events generated by 'tracetool'

2010-11-03 Thread Lluís
Add a new event keyword (instrument) that lets the user provide her own
implementation of tracing events.

Still, tracetool's original implementation is accessible through function
'_trace_##name' instead of 'trace_##name' (in case the user only wants to wrap
around the event).

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile   |4 ++--
 simpletrace.py |2 +-
 trace-events   |   23 +--
 tracetool  |   23 ++-
 4 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/Makefile b/Makefile
index fec086b..1886317 100644
--- a/Makefile
+++ b/Makefile
@@ -108,12 +108,12 @@ bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
 trace.h: trace.h-timestamp
 trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
-   $(call quiet-command,sh $(SRC_PATH)/tracetool --regular 
--$(TRACE_BACKEND) -h  $  $@,  GEN   trace.h)
+   $(call quiet-command,sh $(SRC_PATH)/tracetool $(TRACETOOL_EXTRA) 
--regular --$(TRACE_BACKEND) -h  $  $@,  GEN   trace.h)
@cmp -s $@ trace.h || cp $@ trace.h
 
 trace.c: trace.c-timestamp
 trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
-   $(call quiet-command,sh $(SRC_PATH)/tracetool --regular 
--$(TRACE_BACKEND) -c  $  $@,  GEN   trace.c)
+   $(call quiet-command,sh $(SRC_PATH)/tracetool $(TRACETOOL_EXTRA) 
--regular --$(TRACE_BACKEND) -c  $  $@,  GEN   trace.c)
@cmp -s $@ trace.c || cp $@ trace.c
 
 trace.o: trace.c $(GENERATED_HEADERS)
diff --git a/simpletrace.py b/simpletrace.py
index c2cf168..0f3fab5 100755
--- a/simpletrace.py
+++ b/simpletrace.py
@@ -19,7 +19,7 @@ header_version  = 0
 
 trace_fmt = '='
 trace_len = struct.calcsize(trace_fmt)
-event_re  = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\)\s+([^]*)')
+event_re  = 
re.compile(r'\s*(disable\s+|instrument\s+)*([a-zA-Z0-9_]+)\(([^)]*)\)\s+([^]*)')
 
 def err(msg):
 sys.stderr.write(msg + '\n')
diff --git a/trace-events b/trace-events
index 4300178..3b91a1c 100644
--- a/trace-events
+++ b/trace-events
@@ -12,21 +12,32 @@
 #
 # Format of a trace event:
 #
-# [disable] name(type1 arg1[, type2 arg2] ...) format-string
+# [property ...] name(type1 arg1[, type2 arg2] ...) 
format-string
 #
 # Example: qemu_malloc(size_t size) size %zu
 #
-# The disable keyword will build without the trace event.
-# In case of 'simple' trace backend, it will allow the trace event to be
-# compiled, but this would be turned off by default. It can be toggled on via
-# the monitor.
-#
 # The name must be a valid as a C function name.
 #
 # Types should be standard C types.  Use void * for pointers because the trace
 # system may not have the necessary headers included.
 #
 # The format-string should be a sprintf()-compatible format string.
+#
+# Properties:
+#
+# - disable
+#   Build QEMU without the trace event.
+#   In case of using the 'simple' trace backend, it will allow the trace event
+#   to be compiled, but this would be turned off by default. It can be toggled
+#   on via the monitor.
+#
+# - instrument
+#   Let the user provide code for the trace event.
+#   The instrument keyword will let the user provide her own 'trace_##name'
+#   implementation on trace-instrument.h and libinstrument.a (their 
location
+#   is identified by the '--with-instrument' configure option).
+#   The original backend-specific function is still available under the name
+#   'trace_##name##_backend'.
 
 # qemu-malloc.c
 disable qemu_malloc(size_t size, void *ptr) size %zu ptr %p
diff --git a/tracetool b/tracetool
index 4bd264f..facb385 100755
--- a/tracetool
+++ b/tracetool
@@ -349,12 +349,21 @@ traceto_h_regular()
 #include qemu-common.h
 EOF
 convert h $1 $2
+if [ $had_instrument = 1 ]; then
+echo '#include trace-instrument.h'
+fi
 echo #endif /* TRACE_H */
 }
 
 line_h_regular()
 {
+# XXX: should still provide instrumentation if event is disabled?
 local instrument
+instrument=$(get_property $1 instrument)
+if [ $instrument = 1 ]; then
+had_instrument=1
+return
+fi
 
 local api func
 api=$(get_api_name $1)
@@ -404,12 +413,18 @@ frontend=nil
 backend=nil
 output=nil
 
+enable_instrument=0
+had_instrument=0
+
 usage()
 {
 cat 2 EOF
-usage: $0 frontend backend output
+usage: $0 [flag] frontend backend output
 Generate tracing code for a file on stdin.
 
+Flags:
+  --instrument  Enable instrumentation
+
 Frontends:
   --regular Regular frontend
 
@@ -427,6 +442,7 @@ EOF
 
 while [ $# -gt 0 ]; do
 case $1 in
+--instrument) enable_instrument=1 ;;
 --regular) frontend=${1#--} ;;
 --nop|--simple|--ust) backend=${1#--} ;;
 -h|-c) output=${1#-} ;;
@@ -443,4 +459,9 @@ fi
 
 traceto_${output}_$frontend $frontend $backend
 
+if [ $had_instrument = 1 -a $enable_instrument = 0 ]; then
+echo ERROR: You must configure QEMU using '--with-instrument' to use the 
'instrument' property in \trace-events\ /dev/stderr
+exit 1
+fi
+
 exit 0




[Qemu-devel] [PATCH v1 1/4] trace-gen: gracefully handle TCG types in trace-events

2010-11-03 Thread Lluís
Some trace events with the gen property will need to use TCG arguments.

As such, modify 'tracetool' to gracefully handle these types and let the backend
code transliterate these types into their native counterpart.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 tracetool |  140 ++---
 1 files changed, 132 insertions(+), 8 deletions(-)

diff --git a/tracetool b/tracetool
index facb385..3172259 100755
--- a/tracetool
+++ b/tracetool
@@ -38,13 +38,71 @@ get_api_name()
 echo $event
 }
 
+# Convenience function to pair elements of two lists (of comma-separated 
values) of equal size
+# $1: list
+# $2: list
+# $3: format (defaults to , $1 $2)
+zip_lists()
+{
+local format
+format=$3
+[ -n $format ] || format=, %s %s
+
+local i elem accum
+i=1
+accum=
+for elem in $1; do
+if [ $elem = ${elem%,} ]; then
+accum=$accum $elem
+else
+accum=$accum ${elem%,}
+eval __elem_$i=\$accum\
+i=$(($i + 1))
+accum=
+fi
+done
+eval __elem_$i=\$accum\
+
+local tmp res
+accum=
+res=
+i=1
+for elem in $2; do
+if [ $elem = ${elem%,} ]; then
+accum=$accum $elem
+else
+accum=$accum ${elem%,}
+eval tmp=\$__elem_$i
+tmp=$(printf $format $tmp $accum)
+res=$res$tmp
+i=$(($i + 1))
+accum=
+fi
+done
+eval tmp=\$__elem_$i
+tmp=$(printf $format $tmp $elem)
+res=$res$tmp
+
+echo $res
+}
+
 # Get the argument list of a trace event, including types and names
+# If given, the second argument is a function name to map on each element of 
the
+# comma-separated list
 get_args()
 {
-local args
-args=${1#*\(}
-args=${args%\)*}
-echo $args
+if [ -z $2 ]; then
+local args
+args=${1#*\(}
+args=${args%\)*}
+echo $args
+else
+local argtypes argnames res
+argtypes=$(get_argtypes $1 $2)
+argnames=$(get_argnames $1)
+res=$(zip_lists $argtypes $argnames)
+echo ${res#, }
+fi
 }
 
 # Get the argument name list of a trace event
@@ -72,6 +130,60 @@ get_argnames()
 fi
 }
 
+# Get the argument type list of a trace event
+# If given, the second argument is a function name to map on each element of 
the
+# comma-separated list
+get_argtypes()
+{
+if [ -z $2 ]; then
+local res elem accum
+res=
+accum=
+for elem in $(get_args $1); do
+if [ ${elem} = ${elem%,} ]; then
+accum=$accum $elem
+else
+[ $elem = ${elem#\*} ] || accum=$accum *
+res=$res, $accum
+accum=
+fi
+done
+accum=${accum% *}
+[ $elem = ${elem#\*} ] || accum=$accum *
+res=$res, $accum
+echo ${res#, }
+else
+local res elem accum
+res=
+accum=
+for elem in $(get_argtypes $1); do
+if [ ${elem} = ${elem%,} ]; then
+accum=$accum $elem
+else
+accum=$accum ${elem%,}
+
+# trim spaces
+accum=${accum## }
+accum=${accum%% }
+# transliterate
+[ -z $2 ] || accum=$($2 $accum)
+
+res=$res, $accum
+accum=
+fi
+done
+
+# trim spaces
+accum=${accum## }
+accum=${accum%% }
+# transliterate
+[ -z $2 ] || accum=$($2 $accum)
+
+res=$res, $accum
+echo ${res#, }
+fi
+}
+
 # Get the number of arguments to a trace event
 get_argc()
 {
@@ -107,6 +219,18 @@ get_fmt()
 echo $fmt
 }
 
+# Transliterate an argument in trace-events (raw) into its native counterpart
+# (e.g., TCGv_i32 - uint32_t)
+native_type()
+{
+case $1 in
+TCGv_i32) echo uint32_t ;;
+TCGv_i64) echo uint64_t ;;
+TCGv_ptr) echo void *   ;;
+*)  echo $1   ;;
+esac
+}
+
 

 ### Backend code
 
@@ -120,7 +244,7 @@ line_h_nop()
 {
 local func args
 func=$(get_func_name $1)
-args=$(get_args $1)
+args=$(get_args $1 native_type)
 
 # Define an empty function for the trace event
 cat EOF
@@ -173,7 +297,7 @@ line_h_simple()
 # XXX: why 'simple' backend does not expand into 'nop' when disabled?
 local func args argc trace_args
 func=$(get_func_name $1)
-args=$(get_args $1)
+args=$(get_args $1 native_type)
 argc=$(get_argc $1)
 
 trace_args=$simple_event_num
@@ -267,7 +391,7 @@ line_h_ust()
 local name func args argnames
 name=$(get_event_name $1)
 func=$(get_func_name $1)
-args=$(get_args $1)
+args=$(get_args $1 native_type)
 argnames=$(get_argnames $1)
 
 cat EOF
@@ -302,7 +426,7 @@ 

[Qemu-devel] [PATCH v1 1/3] trace: rewrite 'tracetool' to facilitate future extensions

2010-11-03 Thread Lluís
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile  |4 -
 tracetool |  315 +
 2 files changed, 194 insertions(+), 125 deletions(-)

diff --git a/Makefile b/Makefile
index 252c817..fec086b 100644
--- a/Makefile
+++ b/Makefile
@@ -108,12 +108,12 @@ bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
 trace.h: trace.h-timestamp
 trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
-   $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -h  
$  $@,  GEN   trace.h)
+   $(call quiet-command,sh $(SRC_PATH)/tracetool --regular 
--$(TRACE_BACKEND) -h  $  $@,  GEN   trace.h)
@cmp -s $@ trace.h || cp $@ trace.h
 
 trace.c: trace.c-timestamp
 trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
-   $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -c  
$  $@,  GEN   trace.c)
+   $(call quiet-command,sh $(SRC_PATH)/tracetool --regular 
--$(TRACE_BACKEND) -c  $  $@,  GEN   trace.c)
@cmp -s $@ trace.c || cp $@ trace.c
 
 trace.o: trace.c $(GENERATED_HEADERS)
diff --git a/tracetool b/tracetool
index 7010858..4bd264f 100755
--- a/tracetool
+++ b/tracetool
@@ -10,28 +10,32 @@
 # Disable pathname expansion, makes processing text with '*' characters simpler
 set -f
 
-usage()
-{
-cat 2 EOF
-usage: $0 [--nop | --simple | --ust] [-h | -c]
-Generate tracing code for a file on stdin.
+
+### Helper routines
 
-Backends:
-  --nop Tracing disabled
-  --simple  Simple built-in backend
-  --ust LTTng User Space Tracing backend
+# Get the name of a trace event
+get_event_name()
+{
+local str i last
+str=${1%%\(*}
+str=${str##* }
+echo $str
+}
 
-Output formats:
-  -hGenerate .h file
-  -cGenerate .c file
-EOF
-exit 1
+# Get the name of the backend-specific function recording the trace event
+get_func_name()
+{
+local name
+name=$(get_event_name $1)
+echo trace_${name}_backend
 }
 
-# Get the name of a trace event
-get_name()
+# Get the name of the public function recording the trace event
+get_api_name()
 {
-echo ${1%%\(*}
+local event
+event=trace_$(get_event_name $1)
+echo $event
 }
 
 # Get the argument list of a trace event, including types and names
@@ -79,6 +83,21 @@ get_argc()
 echo $argc
 }
 
+# See if an event property is set (returns 1 or 0)
+get_property()
+{
+local i str prop
+str=${1%%\(*}
+prop=$2
+for i in $str; do
+if [ $i = $prop ] ; then
+echo 1
+return
+fi
+done
+echo 0
+}
+
 # Get the format string for a trace event
 get_fmt()
 {
@@ -88,70 +107,60 @@ get_fmt()
 echo $fmt
 }
 
-# Get the state of a trace event
-get_state()
-{
-local str disable state
-str=$(get_name $1)
-disable=${str##disable }
-if [ $disable = $str ] ; then
-state=1
-else
-state=0
-fi
-echo $state
-}
+
+### Backend code
 
-linetoh_begin_nop()
+### nop -- H
+begin_h_nop()
 {
 return
 }
 
-linetoh_nop()
+line_h_nop()
 {
-local name args
-name=$(get_name $1)
+local func args
+func=$(get_func_name $1)
 args=$(get_args $1)
 
 # Define an empty function for the trace event
 cat EOF
-static inline void trace_$name($args)
+static inline void $func($args)
 {
 }
 EOF
 }
 
-linetoh_end_nop()
+end_h_nop()
 {
 return
 }
 
-linetoc_begin_nop()
+### nop -- H
+begin_c_nop()
 {
 return
 }
 
-linetoc_nop()
+line_c_nop()
 {
-# No need for function definitions in nop backend
 return
 }
 
-linetoc_end_nop()
+end_c_nop()
 {
 return
 }
 
-linetoh_begin_simple()
+### simple -- H
+begin_h_simple()
 {
 cat EOF
 #include simpletrace.h
 EOF
-
 simple_event_num=0
 }
 
-cast_args_to_uint64_t()
+get_trace_args_simple()
 {
 local arg
 for arg in $(get_argnames $1); do
@@ -159,25 +168,22 @@ cast_args_to_uint64_t()
 done
 }
 
-linetoh_simple()
+line_h_simple()
 {
-local name args argc trace_args state
-name=$(get_name $1)
+# XXX: why 'simple' backend does not expand into 'nop' when disabled?
+local func args argc trace_args
+func=$(get_func_name $1)
 args=$(get_args $1)
 argc=$(get_argc $1)
-state=$(get_state $1)
-if [ $state = 0 ]; then
-name=${name##disable }
-fi
-
+
 trace_args=$simple_event_num
 if [ $argc -gt 0 ]
 then
-trace_args=$trace_args, $(cast_args_to_uint64_t $1)
+trace_args=$trace_args, $(get_trace_args_simple $1)
 fi
 
 cat EOF
-static inline void trace_$name($args)
+static inline void $func($args)
 {
 trace$argc($trace_args);
 }
@@ -186,7 +192,7 @@ EOF
 simple_event_num=$((simple_event_num + 1))
 }
 
-linetoh_end_simple()
+end_h_simple()
 {
 cat EOF
 #define NR_TRACE_EVENTS $simple_event_num
@@ -194,7 +200,8 @@ extern 

[Qemu-devel] [PATCH v1 4/4] trace-gen: auto-generate wrappers to call TCG trace helpers

2010-11-03 Thread Lluís
Auto-generates file trace-gen.h with instrumentable wrappers to generate calls
to TCG trace helpers.

Such wrappers are named 'trace_gen_##name', also reachable as
'trace_gen_##name##_backend' when instrumented.

Events with the gen property are also able to use TCG types on the trace event
declaration, which are gracefully handled when generating trace functions.

Only trace events with the 'gen' property are affected.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 Makefile |8 +++-
 trace-events |3 +
 tracetool|  130 ++
 3 files changed, 139 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 5975926..2831dc3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Makefile for QEMU.
 
-GENERATED_HEADERS = config-host.h trace.h trace-helper.h trace-helper.c
+GENERATED_HEADERS = config-host.h trace.h trace-helper.h trace-helper.c 
trace-gen.h
 
 ifneq ($(wildcard config-host.mak),)
 # Put the all: rule here so that config-host.mak can contain dependencies.
@@ -130,6 +130,11 @@ trace-helper.c-timestamp: $(SRC_PATH)/trace-events 
config-host.mak
 
 trace-helper.o: trace-helper.c $(GENERATED_HEADERS)
 
+trace-gen.h: trace-gen.h-timestamp
+trace-gen.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
+   $(call quiet-command,sh $(SRC_PATH)/tracetool $(TRACETOOL_EXTRA) --gen 
--$(TRACE_BACKEND) -h  $  $@,  GEN   trace-gen.h)
+   @cmp -s $@ trace-gen.h || cp $@ trace-gen.h
+
 simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
 
 version.o: $(SRC_PATH)/version.rc config-host.mak
@@ -167,6 +172,7 @@ clean:
rm -f qemu-img-cmds.h
rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
rm -f trace-helper.c trace-helper.h trace-helper.h-timestamp 
trace-helper.c-timestamp
+   rm -f trace-gen.h-timestamp trace-gen.c-timestamp
$(MAKE) -C tests clean
for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
diff --git a/trace-events b/trace-events
index 4a89d97..a54fa03 100644
--- a/trace-events
+++ b/trace-events
@@ -43,6 +43,9 @@
 #   Provide trace events suitable for using during TCG code generation.
 #   Generates TCG function helpers reachable through 'helper_trace_gen_##name'
 #   which proxy their calls onto 'trace_##name'.
+#   As an extra aid, functions named 'trace_gen_##name' are generated into
+#   trace-gen.h, which can be reched through 'trace_gen_##name##_backend' 
when
+#   the event is instrumented.
 
 # qemu-malloc.c
 disable qemu_malloc(size_t size, void *ptr) size %zu ptr %p
diff --git a/tracetool b/tracetool
index 588f442..e99da0c 100755
--- a/tracetool
+++ b/tracetool
@@ -602,6 +602,134 @@ void helper_trace_proxy_$name($args)
 EOF
 }
 
+### Gen - H
+traceto_h_gen()
+{
+ cat EOF
+#ifndef TRACE_GEN_H
+#define TRACE_GEN_H
+
+/* This file is autogenerated by tracetool, do not edit. */
+EOF
+
+convert h $1 nil
+
+if [ $had_instrument = 1 ]; then
+echo '#include trace-instrument.h'
+fi
+echo #endif /* TRACE_GEN_H */
+}
+
+line_h_gen_parse_pre()
+{
+case $3 in
+uint32_t) echo TCGv_i32 __arg_$1 = tcg_const_i32($2); ;;
+uint64_t) echo TCGv_i64 __arg_$1 = tcg_const_i64($2); ;;
+void *)   echo TCGv_ptr __arg_$1 = tcg_const_ptr((int64_t)$2); ;;
+esac
+}
+
+line_h_gen_parse_args()
+{
+case $3 in
+uint64_t) echo __arg_$1 ;;
+uint32_t) echo __arg_$1 ;;
+void *)   echo __arg_$1 ;;
+*)  echo $2   ;;
+esac
+}
+
+line_h_gen_parse_post()
+{
+case $3 in
+uint32_t) echo tcg_temp_free_i32(__arg_$1); ;;
+uint64_t) echo tcg_temp_free_i64(__arg_$1); ;;
+void *)   echo tcg_temp_free_i64(__arg_$1); ;;
+esac
+}
+ 
+line_h_gen()
+{
+local gen
+gen=$(get_property $1 gen)
+[ $gen = 1 ] || return
+
+local name args
+name=$(get_event_name $1)
+args=$(get_args $1)
+
+local gen_pre gen_post gen_args i
+gen_pre=
+gen_post=
+gen_args=
+
+local argname
+i=1
+for argname in $(get_argnames $1); do
+argname=${argname%,}
+eval __argname_$i=$argname
+i=$(($i + 1))
+done
+
+local argtypes argtype accum _pre _arg _post
+argtypes=$(get_argtypes $1)
+i=1
+accum=
+for argtype in $argtypes; do
+accum=$accum ${argtype%,}
+if [ $argtype = ${argtype%,} ]; then
+continue
+fi
+argtype=${accum# }
+accum=
+
+eval argname=\$__argname_$i
+
+_pre=$(line_h_gen_parse_pre $i $argname $argtype)
+gen_pre=$gen_pre
+$_pre
+_arg=$(line_h_gen_parse_arg $i $argname $argtype)
+gen_args=$gen_args$_arg
+_post=$(line_h_gen_parse_post $i $argname $argtype)
+gen_post=$gen_post
+$_post
+
+i=$(($i + 1))
+done
+argtype=${accum# }
+eval argname=\$__argname_$i
+
+

[Qemu-devel] [PATCH v1 2/4] trace-gen: auto-generate TCG helper routines for tracing

2010-11-03 Thread Lluís
Auto-generates file trace-helper.h to provide TCG helpers and trace-helper.c
to proxy these helpers onto trace event routines.

Only trace events with the 'gen' property are affected.

Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 .gitignore  |2 +
 Makefile|   15 
 Makefile.target |5 +--
 trace-events|5 +++
 tracetool   |   98 ++-
 5 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/.gitignore b/.gitignore
index e4a351d..758f457 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@ config-host.*
 config-target.*
 trace.h
 trace.c
+trace-helper.h
+trace-helper.c
 *-timestamp
 *-softmmu
 *-darwin-user
diff --git a/Makefile b/Makefile
index 1886317..5975926 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 # Makefile for QEMU.
 
-GENERATED_HEADERS = config-host.h trace.h
+GENERATED_HEADERS = config-host.h trace.h trace-helper.h trace-helper.c
 
 ifneq ($(wildcard config-host.mak),)
 # Put the all: rule here so that config-host.mak can contain dependencies.
@@ -118,6 +118,18 @@ trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
 
 trace.o: trace.c $(GENERATED_HEADERS)
 
+trace-helper.h: trace-helper.h-timestamp
+trace-helper.h-timestamp: $(SRC_PATH)/trace-events config-host.mak
+   $(call quiet-command,sh $(SRC_PATH)/tracetool $(TRACETOOL_EXTRA) 
--helper --$(TRACE_BACKEND) -h  $  $@,  GEN   trace-helper.h)
+   @cmp -s $@ trace-helper.h || cp $@ trace-helper.h
+
+trace-helper.c: trace-helper.c-timestamp
+trace-helper.c-timestamp: $(SRC_PATH)/trace-events config-host.mak
+   $(call quiet-command,sh $(SRC_PATH)/tracetool $(TRACETOOL_EXTRA) 
--helper --$(TRACE_BACKEND) -c  $  $@,  GEN   trace-helper.c)
+   @cmp -s $@ trace-helper.c || cp $@ trace-helper.c
+
+trace-helper.o: trace-helper.c $(GENERATED_HEADERS)
+
 simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
 
 version.o: $(SRC_PATH)/version.rc config-host.mak
@@ -154,6 +166,7 @@ clean:
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.c trace.h trace.c-timestamp trace.h-timestamp
+   rm -f trace-helper.c trace-helper.h trace-helper.h-timestamp 
trace-helper.c-timestamp
$(MAKE) -C tests clean
for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \
if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
diff --git a/Makefile.target b/Makefile.target
index 90867e7..c7e26e2 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -378,9 +378,8 @@ endif
 
 $(QEMU_PROG)-prepare: $(GENERATED_HEADERS) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB) $(QEMU_PROG)
 
-$(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB)
-   $(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) $(LIBBACKDOOR_LIB) 
$(LIBINSTRUMENT_LIB)
-
+$(QEMU_PROG): trace-helper.o $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) 
$(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
+   $(call LINK,trace-helper.o $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)) 
$(LIBBACKDOOR_LIB) $(LIBINSTRUMENT_LIB)
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/feature_to_c.sh
$(call quiet-command,rm -f $@  $(SHELL) $(SRC_PATH)/feature_to_c.sh 
$@ $(TARGET_XML_FILES),  GEN   $(TARGET_DIR)$@)
diff --git a/trace-events b/trace-events
index 3b91a1c..4a89d97 100644
--- a/trace-events
+++ b/trace-events
@@ -38,6 +38,11 @@
 #   is identified by the '--with-instrument' configure option).
 #   The original backend-specific function is still available under the name
 #   'trace_##name##_backend'.
+#
+# - gen
+#   Provide trace events suitable for using during TCG code generation.
+#   Generates TCG function helpers reachable through 'helper_trace_gen_##name'
+#   which proxy their calls onto 'trace_##name'.
 
 # qemu-malloc.c
 disable qemu_malloc(size_t size, void *ptr) size %zu ptr %p
diff --git a/tracetool b/tracetool
index 3172259..588f442 100755
--- a/tracetool
+++ b/tracetool
@@ -234,6 +234,38 @@ native_type()
 

 ### Backend code
 
+### nil -- H
+begin_h_nil()
+{
+return
+}
+
+line_h_nil()
+{
+return
+}
+
+end_h_nil()
+{
+return
+}
+
+### nil -- C
+begin_c_nil()
+{
+return
+}
+
+line_c_nil()
+{
+return
+}
+
+end_c_nil()
+{
+return
+}
+
 ### nop -- H
 begin_h_nop()
 {
@@ -507,6 +539,69 @@ line_c_regular()
 return
 }
 
+### Helper -- H
+traceto_h_helper()
+{
+echo /* This file is autogenerated by tracetool, do not edit. */
+convert h $1 nil
+}
+
+helper_h_type()
+{
+case $1 in
+void *|TCGv_ptr)   echo ptr;;
+uint32_t|TCGv_i64) echo i32;;
+uint64_t|TCGv_i32) echo i64;;
+*) echo i64;;
+esac
+}
+
+line_h_helper()
+{
+local gen
+gen=$(get_property $1 gen)
+[ $gen = 1 ] || return
+
+local name argc argtypes
+

[Qemu-devel] [PATCH v1 3/4] trace-gen: [all] include trace-helper.h on all helper.h files

2010-11-03 Thread Lluís
Signed-off-by: Lluís Vilanova vilan...@ac.upc.edu
---
 target-alpha/helper.h  |2 ++
 target-arm/helper.h|2 ++
 target-cris/helper.h   |2 ++
 target-i386/helper.h   |2 ++
 target-m68k/helper.h   |2 ++
 target-microblaze/helper.h |2 ++
 target-mips/helper.h   |2 ++
 target-ppc/helper.h|2 ++
 target-sh4/helper.h|2 ++
 target-sparc/helper.h  |2 ++
 10 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index ccf6a2a..030def3 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -123,4 +123,6 @@ DEF_HELPER_2(stl_c_raw, i64, i64, i64)
 DEF_HELPER_2(stq_c_raw, i64, i64, i64)
 #endif
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 0d1bc47..d3ba5d9 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -447,4 +447,6 @@ DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
 
 DEF_HELPER_2(set_teecr, void, env, i32)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-cris/helper.h b/target-cris/helper.h
index 093063a..620a199 100644
--- a/target-cris/helper.h
+++ b/target-cris/helper.h
@@ -23,4 +23,6 @@ DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, 
i32, i32)
 DEF_HELPER_0(evaluate_flags, void)
 DEF_HELPER_0(top_evaluate_flags, void)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-i386/helper.h b/target-i386/helper.h
index 979d94e..94d7bd1 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -217,6 +217,8 @@ DEF_HELPER_2(rclq, tl, tl, tl)
 DEF_HELPER_2(rcrq, tl, tl, tl)
 #endif
 
+#include trace-helper.h
+
 #if defined(CONFIG_BACKDOOR)
 #include backdoor/helper.h
 #endif
diff --git a/target-m68k/helper.h b/target-m68k/helper.h
index cb8a0c7..29e206b 100644
--- a/target-m68k/helper.h
+++ b/target-m68k/helper.h
@@ -51,4 +51,6 @@ DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
 DEF_HELPER_2(flush_flags, void, env, i32)
 DEF_HELPER_1(raise_exception, void, i32)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
index 11ad1b6..3606614 100644
--- a/target-microblaze/helper.h
+++ b/target-microblaze/helper.h
@@ -34,4 +34,6 @@ DEF_HELPER_2(mmu_write, void, i32, i32)
 
 DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-mips/helper.h b/target-mips/helper.h
index cb13fb2..4855b67 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -287,4 +287,6 @@ DEF_HELPER_0(rdhwr_ccres, tl)
 DEF_HELPER_1(pmon, void, int)
 DEF_HELPER_0(wait, void)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 2bf9283..c76e733 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -401,4 +401,6 @@ DEF_HELPER_2(store_601_batl, void, i32, tl)
 DEF_HELPER_2(store_601_batu, void, i32, tl)
 #endif
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-sh4/helper.h b/target-sh4/helper.h
index 4b2fcdd..daec7cd 100644
--- a/target-sh4/helper.h
+++ b/target-sh4/helper.h
@@ -50,4 +50,6 @@ DEF_HELPER_1(fsqrt_DT, i64, i64)
 DEF_HELPER_1(ftrc_FT, i32, i32)
 DEF_HELPER_1(ftrc_DT, i32, i64)
 
+#include trace-helper.h
+
 #include def-helper.h
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index 6f103e7..f2014b8 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -160,4 +160,6 @@ VIS_CMPHELPER(cmpne);
 DEF_HELPER_0(compute_psr, void);
 DEF_HELPER_0(compute_C_icc, i32);
 
+#include trace-helper.h
+
 #include def-helper.h




Re: [Qemu-devel] [PATCH 0/3] v4 Decouple block device removal from device removal

2010-11-03 Thread Ryan Harper
* Michael S. Tsirkin m...@redhat.com [2010-11-03 13:03]:
 On Wed, Nov 03, 2010 at 12:29:10PM -0500, Ryan Harper wrote:
  * Markus Armbruster arm...@redhat.com [2010-11-03 11:42]:
   Ryan Harper ry...@us.ibm.com writes:
   
* Michael S. Tsirkin m...@redhat.com [2010-11-03 02:22]:
On Tue, Nov 02, 2010 at 03:23:38PM -0500, Ryan Harper wrote:
 * Michael S. Tsirkin m...@redhat.com [2010-11-02 14:18]:
  On Tue, Nov 02, 2010 at 02:01:08PM -0500, Ryan Harper wrote:
   I like the idea of disconnect; if part of the device_del 
   method was to
   invoke a disconnect method, we could implement that for 
   block, net, etc;
   
   I'd think we'd want to send the notification, then 
   disconnect.
   Struggling with whether it's worth having some 
   reasonable timeout
   between notification and disconnect.  
  
  The problem with this is that it has no analog in real 
  world.
  In real world, you can send some notifications to the 
  guest, and you can
  remove the card.  Tying them together is what created the 
  problem in the
  first place.
  
  Timeouts can be implemented by management, maybe with a 
  nice dialog
  being shown to the user.
 
 Very true.  I'm fine with forcing a disconnect during the 
 removal path
 prior to notification.  Do we want a new disconnect method 
 at the device
 level (pci)? or just use the existing removal callback and 
 call that
 during the initial hotremov event?

Not sure what you mean by that, but I don't see a device doing 
anything
differently wrt surprise or ordered removal. So probably the 
existing
callback should do. I don't think we need to talk about 
disconnect:
since we decided we are emulating device removal, let's call it
just that.
   
   Because current the removal process depends on the guest 
   actually
   responding.  What I'm suggesting is that, in Marcus's term, and 
   what
   drive_unplug() implements, is to disconnect the host block 
   device from
   the guest device to prevent any further access to it in the case 
   the
   guest doesn't respond to the removal request made via ACPI.
   
   Very specifically, what we're suggesting instead of the 
   drive_unplug()
   command so to complete the device removal operation without 
   waiting for
   the guest to respond; that's what's going to happen if we invoke 
   the
   response callback; it will appear as if the guest responded 
   whether it
   did or not.
   
   What I was suggesting above was to instead of calling the 
   callback for
   handing the guest response was to add a device function called
   disconnect which would remove any association of host resources 
   from
   guest resources before we notified the guest.  Thinking about it 
   again
   I'm not sure this is useful, but if we're going to remove the 
   device
   without the guests knowledge, I'm not sure how useful sending the
   removal requests via ACPI is in the first place.
   
   My feeling is that I'd like to have explicit control over the 
   disconnect
   from host resources separate from the device removal *if* we're 
   going to
   retain the guest notification.  If we don't care to notify the 
   guest,
   then we can just do device removal without notifying the guest
   and be done with it.
  
  I imagine management would typically want to do this:
  1. notify guest
  2. wait a bit
  3. remove device
 
 Yes; but this argues for (1) being a separate command from (3)

Yes. Long term I think we will want a way to do that.

 unless we
 require (3) to include (1) and (2) in the qemu implementation.
 
 Currently we implement:
 
 1. device_del (attempt to remove device)
 2. notify guest
 3. if guest responds, remove device
 4. disconnect host resource from device on destruction
 
 With my drive_unplug patch we do:
 
 1. disconnect host resource from device

This is what drive_unplug does, right?
   
Correct.
   

 2. device_del (attempt to remove device)
 3. notify guest
 4. if guest responds, remove device
 
 I think we're suggesting to instead do (if we keep disconnect as 
 part of
 device_del)
 
 1. device_del (attemp to remove device)
 2. notify guest
 3. invoke device destruction callback resulting in disconnect host 
 resource from device
 4. if guest responds, invoke device destruction path a second time.

By response you mean eject?  No, this is not what I was suggesting.
   

  1   2   >