[Qemu-devel] [PATCH] build: add needed missing libraries libm and librt

2012-02-17 Thread Roger Pau Monne
libm is used in cutils.c, but the library was not specified
when linking some binaries, throwing the following error:

cutils.o: In function `strtosz_suffix_unit':
/home/royger/xen-clean/tools/qemu-xen-dir/cutils.c:354: undefined
reference to `__isnan'
/home/royger/xen-clean/tools/qemu-xen-dir/cutils.c:357: undefined
reference to `modf'
collect2: ld returned 1 exit status

According to modf man page [0], -lm should be used when linking.

librt is used in qemu-time.c, but again the library was not specified
at link time, throwing the following error:

/home/royger/xen-clean/tools/qemu-xen-dir/qemu-timer.c:597: undefined
reference to `timer_gettime'
/home/royger/xen-clean/tools/qemu-xen-dir/qemu-timer.c:610: undefined
reference to `timer_settime'
../qemu-timer.o: In function `dynticks_start_timer':
/home/royger/xen-clean/tools/qemu-xen-dir/qemu-timer.c:565: undefined
reference to `timer_create'
../qemu-timer.o: In function `dynticks_stop_timer':
/home/royger/xen-clean/tools/qemu-xen-dir/qemu-timer.c:583: undefined
reference to `timer_delete'
collect2: ld returned 1 exit status

According to timer_getttime man page [1], -lrt should be used when
linking.

[0] http://linux.die.net/man/3/modf
[1] http://linux.die.net/man/2/timer_gettime

Signed-off-by: Roger Pau Monne 
---
 Makefile|4 ++--
 Makefile.target |2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 301c75e..e2c3cd4 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,7 @@ configure: ;
 
 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
-LIBS+=-lz $(LIBS_TOOLS)
+LIBS+=-lz -lm -lrt $(LIBS_TOOLS)
 
 ifdef BUILD_DOCS
 DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 
QMP/qmp-commands.txt
@@ -170,7 +170,7 @@ test-coroutine: test-coroutine.o qemu-timer-common.o 
async.o $(coroutine-obj-y)
 $(qapi-obj-y): $(GENERATED_HEADERS)
 qapi-dir := $(BUILD_DIR)/qapi-generated
 test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I 
$(qapi-dir)
-qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
+qemu-ga$(EXESUF): LIBS = $(LIBS_QGA) -lm
 
 $(qapi-dir)/test-qapi-types.c $(qapi-dir)/test-qapi-types.h :\
 $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
diff --git a/Makefile.target b/Makefile.target
index a111521..95d6bc0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -33,6 +33,8 @@ endif
 PROGS=$(QEMU_PROG)
 STPFILES=
 
+LIBS+=-lrt
+
 ifndef CONFIG_HAIKU
 LIBS+=-lm
 endif
-- 
1.7.9




[Qemu-devel] Status of query-netdev QMP command

2012-06-18 Thread Roger Pau Monne

Hello,

I've read from the GSoC/2010 that some work was being done creating a 
query-netdev QMP command:


http://wiki.qemu.org/Google_Summer_of_Code_2010/QMP#query-netdev

The status says that "mentor has merged it into his tree", but I cannot 
see this command anywhere upstream, and it will come really handy for 
what I'm trying to do, do someone know where this has gone?


Thanks, Roger.



Re: [Qemu-devel] Status of query-netdev QMP command

2012-06-19 Thread Roger Pau Monne

Stefan Hajnoczi wrote:

On Mon, Jun 18, 2012 at 3:19 PM, Roger Pau Monne  wrote:

I've read from the GSoC/2010 that some work was being done creating a
query-netdev QMP command:

http://wiki.qemu.org/Google_Summer_of_Code_2010/QMP#query-netdev

The status says that "mentor has merged it into his tree", but I cannot see
this command anywhere upstream, and it will come really handy for what I'm
trying to do, do someone know where this has gone?


I checked qemu.git/master and don't see it either.  The HMP "info net"
command lists the net devices but I'm not aware of a QMP equivalent.
What are you trying to do?


On Linux you can pass the name of the tap device you wish to create, and 
Qemu honors that, but on BSD systems you have no way of creating a tap 
device with a specific name, they are assigned based on the lowest free 
number (tap2 for example).


I need the query-netdev command in order to get the name of the device 
that Qemu creates, so I can use it in my scripts afterwards.


Roger.




[Qemu-devel] [PATCH RFC 2/3] xen_disk: fix memory leak

2012-12-31 Thread Roger Pau Monne
On ioreq_release the full ioreq was memset to 0, loosing all the data
and memory allocations inside the QEMUIOVector, which leads to a
memory leak. Create a new function to specifically reset ioreq.

Reported-by: Maik Wessler 
Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xen.org
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
---
 hw/xen_disk.c |   28 ++--
 1 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index a159ee5..1eb485a 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -113,6 +113,31 @@ struct XenBlkDev {
 
 /* - */
 
+static void ioreq_reset(struct ioreq *ioreq)
+{
+memset(&ioreq->req, 0, sizeof(ioreq->req));
+ioreq->status = 0;
+ioreq->start = 0;
+ioreq->presync = 0;
+ioreq->postsync = 0;
+ioreq->mapped = 0;
+
+memset(ioreq->domids, 0, sizeof(ioreq->domids));
+memset(ioreq->refs, 0, sizeof(ioreq->refs));
+ioreq->prot = 0;
+memset(ioreq->page, 0, sizeof(ioreq->page));
+ioreq->pages = NULL;
+
+ioreq->aio_inflight = 0;
+ioreq->aio_errors = 0;
+
+ioreq->blkdev = NULL;
+memset(&ioreq->list, 0, sizeof(ioreq->list));
+memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+
+qemu_iovec_reset(&ioreq->v);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -130,7 +155,6 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 /* get one from freelist */
 ioreq = QLIST_FIRST(&blkdev->freelist);
 QLIST_REMOVE(ioreq, list);
-qemu_iovec_reset(&ioreq->v);
 }
 QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
 blkdev->requests_inflight++;
@@ -154,7 +178,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 struct XenBlkDev *blkdev = ioreq->blkdev;
 
 QLIST_REMOVE(ioreq, list);
-memset(ioreq, 0, sizeof(*ioreq));
+ioreq_reset(ioreq);
 ioreq->blkdev = blkdev;
 QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
 if (finish) {
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH RFC 0/3] xen pv disk persistent grants implementation

2012-12-31 Thread Roger Pau Monne
This series contains two bug fixes for xen_disk (patches 1 & 2) and 
the implementation of the persistent grants extensions (patch 3), that 
brings a considerable speed improvement.

Thanks for the reviews, Roger.



[Qemu-devel] [PATCH RFC 1/3] xen_disk: handle disk files on ramfs/tmpfs

2012-12-31 Thread Roger Pau Monne
Files that reside on ramfs or tmpfs cannot be opened with O_DIRECT,
if first call to bdrv_open fails with errno = EINVAL, try a second
call without BDRV_O_NOCACHE.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xen.org
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
---
 hw/xen_disk.c |   16 +---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index e6bb2f2..a159ee5 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -562,7 +562,7 @@ static void blk_alloc(struct XenDevice *xendev)
 static int blk_init(struct XenDevice *xendev)
 {
 struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-int index, qflags, info = 0;
+int index, qflags, info = 0, rc;
 
 /* read xenstore entries */
 if (blkdev->params == NULL) {
@@ -625,8 +625,18 @@ static int blk_init(struct XenDevice *xendev)
 xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
 blkdev->bs = bdrv_new(blkdev->dev);
 if (blkdev->bs) {
-if (bdrv_open(blkdev->bs, blkdev->filename, qflags,
-bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) 
{
+rc = bdrv_open(blkdev->bs, blkdev->filename, qflags,
+bdrv_find_whitelisted_format(blkdev->fileproto));
+if (rc != 0 && errno == EINVAL) {
+/* Files on ramfs or tmpfs cannot be opened with O_DIRECT,
+ * remove the BDRV_O_NOCACHE flag, and try to open
+ * the file again.
+ */
+qflags &= ~BDRV_O_NOCACHE;
+rc = bdrv_open(blkdev->bs, blkdev->filename, qflags,
+bdrv_find_whitelisted_format(blkdev->fileproto));
+}
+if (rc != 0) {
 bdrv_delete(blkdev->bs);
 blkdev->bs = NULL;
 }
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH RFC 3/3] xen_disk: add persistent grant support to xen_disk backend

2012-12-31 Thread Roger Pau Monne
This protocol extension reuses the same set of grant pages for all
transactions between the front/back drivers, avoiding expensive tlb
flushes, grant table lock contention and switches between userspace
and kernel space. The full description of the protocol can be found in
the public blkif.h header.

Speed improvement with 15 guests performing I/O is ~450%.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xen.org
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
---
Performance comparison with the previous implementation can be seen in
the followign graph:

http://xenbits.xen.org/people/royger/persistent_read_qemu.png
---
 hw/xen_disk.c |  155 ++--
 1 files changed, 138 insertions(+), 17 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 1eb485a..bafeceb 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -52,6 +52,11 @@ static int max_requests = 32;
 #define BLOCK_SIZE  512
 #define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
 
+struct persistent_gnt {
+void *page;
+struct XenBlkDev *blkdev;
+};
+
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -69,6 +74,7 @@ struct ioreq {
 int prot;
 void*page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 void*pages;
+int num_unmap;
 
 /* aio status */
 int aio_inflight;
@@ -105,6 +111,12 @@ struct XenBlkDev {
 int requests_inflight;
 int requests_finished;
 
+/* Persistent grants extension */
+gbooleanfeature_persistent;
+GTree   *persistent_gnts;
+unsigned intpersistent_gnt_c;
+unsigned intmax_grants;
+
 /* qemu block driver */
 DriveInfo   *dinfo;
 BlockDriverState*bs;
@@ -138,6 +150,29 @@ static void ioreq_reset(struct ioreq *ioreq)
 qemu_iovec_reset(&ioreq->v);
 }
 
+static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+uint ua = GPOINTER_TO_UINT(a);
+uint ub = GPOINTER_TO_UINT(b);
+return (ua > ub) - (ua < ub);
+}
+
+static void destroy_grant(gpointer pgnt)
+{
+struct persistent_gnt *grant = pgnt;
+XenGnttab gnt = grant->blkdev->xendev.gnttabdev;
+
+if (xc_gnttab_munmap(gnt, grant->page, 1) != 0) {
+xen_be_printf(&grant->blkdev->xendev, 0,
+  "xc_gnttab_munmap failed: %s\n",
+  strerror(errno));
+}
+grant->blkdev->persistent_gnt_c--;
+xen_be_printf(&grant->blkdev->xendev, 3,
+  "unmapped grant %p\n", grant->page);
+g_free(grant);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -266,21 +301,21 @@ static void ioreq_unmap(struct ioreq *ioreq)
 XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
 int i;
 
-if (ioreq->v.niov == 0 || ioreq->mapped == 0) {
+if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
 return;
 }
 if (batch_maps) {
 if (!ioreq->pages) {
 return;
 }
-if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) {
+if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
 xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: 
%s\n",
   strerror(errno));
 }
-ioreq->blkdev->cnt_map -= ioreq->v.niov;
+ioreq->blkdev->cnt_map -= ioreq->num_unmap;
 ioreq->pages = NULL;
 } else {
-for (i = 0; i < ioreq->v.niov; i++) {
+for (i = 0; i < ioreq->num_unmap; i++) {
 if (!ioreq->page[i]) {
 continue;
 }
@@ -298,41 +333,107 @@ static void ioreq_unmap(struct ioreq *ioreq)
 static int ioreq_map(struct ioreq *ioreq)
 {
 XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
-int i;
+uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+int i, j, new_maps = 0;
+struct persistent_gnt *grant;
 
 if (ioreq->v.niov == 0 || ioreq->mapped == 1) {
 return 0;
 }
-if (batch_maps) {
+if (ioreq->blkdev->feature_persistent) {
+for (i = 0; i < ioreq->v.niov; i++) {
+grant = g_tree_lookup(ioreq->blkdev->persistent_gnts,
+GUINT_TO_POINTER(ioreq->refs[i]));
+
+if (grant != NULL) {
+page[i] = grant->page;
+xen_be_printf(&ioreq->blkdev->xendev, 3,
+  "using persistent-grant %" PRIu32 "\n",
+  ioreq->refs[i]);
+} else {
+/* Add the grant to the list of grants that
+ * should be mapped
+ */
+domids[new_maps] = ioreq->domids[i];
+refs[new_maps] = ioreq->refs[i];
+

[Qemu-devel] [PATCH v2 3/3] serial: poll the serial console with G_IO_HUP

2014-05-23 Thread Roger Pau Monne
On FreeBSD polling a master pty while the other end is not connected
with G_IO_OUT only results in an endless wait. This is different from
the Linux behaviour, that returns immediately. In order to demonstrate
this, I have the following example code:

http://xenbits.xen.org/people/royger/test_poll.c

When executed on Linux:

$ ./test_poll
In callback

On FreeBSD instead, the callback never gets called:

$ ./test_poll

So, in order to workaround this, poll the source with G_IO_HUP (which
makes the code behave the same way on both Linux and FreeBSD).

Signed-off-by: Roger Pau Monné 
Cc: Peter Crosthwaite 
Cc: Michael Tokarev 
Cc: "Andreas Färber" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
---
Changes since v1:
 - Fix other users of qemu_chr_fe_add_watch to use G_IO_HUP.
---
 hw/char/serial.c |2 +-
 hw/char/virtio-console.c |3 ++-
 hw/usb/redirect.c|2 +-
 monitor.c|2 +-
 4 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index f4d167f..2a2c9e5 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -246,7 +246,7 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition 
cond, void *opaque)
 serial_receive1(s, &s->tsr, 1);
 } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
 if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
-qemu_chr_fe_add_watch(s->chr, G_IO_OUT, serial_xmit, s) > 0) {
+qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, serial_xmit, s) > 
0) {
 s->tsr_retry++;
 return FALSE;
 }
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 6c8be0f..38e290a 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -69,7 +69,8 @@ static ssize_t flush_buf(VirtIOSerialPort *port,
 if (!k->is_console) {
 virtio_serial_throttle_port(port, true);
 if (!vcon->watch) {
-vcon->watch = qemu_chr_fe_add_watch(vcon->chr, G_IO_OUT,
+vcon->watch = qemu_chr_fe_add_watch(vcon->chr,
+G_IO_OUT|G_IO_HUP,
 chr_write_unblocked, vcon);
 }
 }
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 287a505..06e757d 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -284,7 +284,7 @@ static int usbredir_write(void *priv, uint8_t *data, int 
count)
 r = qemu_chr_fe_write(dev->cs, data, count);
 if (r < count) {
 if (!dev->watch) {
-dev->watch = qemu_chr_fe_add_watch(dev->cs, G_IO_OUT,
+dev->watch = qemu_chr_fe_add_watch(dev->cs, G_IO_OUT|G_IO_HUP,
usbredir_write_unblocked, dev);
 }
 if (r < 0) {
diff --git a/monitor.c b/monitor.c
index 593679a..ae1c539 100644
--- a/monitor.c
+++ b/monitor.c
@@ -304,7 +304,7 @@ void monitor_flush(Monitor *mon)
 mon->outbuf = tmp;
 }
 if (mon->watch == 0) {
-mon->watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT,
+mon->watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP,
monitor_unblocked, mon);
 }
 }
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH v2 0/3] qemu-freebsd: fixes for running Xen guests

2014-05-23 Thread Roger Pau Monne
This three patches allow FreeBSD Xen Dom0 to use Qemu (i.e., launch
HVM guests).

First patch fixes the usage of ENODATA, which doesn't exist on FreeBSD
and is replaced with ENOENT instead.

The second patch is more controversial probably, since it introduces a
FreeBSD specific version of tap_open which behaves like it's Linux
counterpart, allowing Qemu to create tap interfaces and rename them.
I've decided to just fork the function instead of adding a bunch more
of preprocessor code in the original function.

Last patch adds G_IO_HUP to calls to qemu_chr_fe_add_watch so they
behave the same way on both FreeBSD and Linux (see the commit message
for the rationale).

Thanks for the review, Roger.



[Qemu-devel] [PATCH v2 1/3] xen: fix usage of ENODATA

2014-05-23 Thread Roger Pau Monne
ENODATA doesn't exist on FreeBSD, so ENODATA errors returned by the
hypervisor are translated to ENOENT.

Also, the error code is returned in errno if the call returns -1, so
compare the error code with the value in errno instead of the value
returned by the function.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xenproject.org
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
Changes since v1:
 - Define ENODATA to ENOENT for platforms that don't have ENODATA.
---
 xen-hvm.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/xen-hvm.c b/xen-hvm.c
index a64486c..a414105 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -499,11 +499,14 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
  start_addr >> TARGET_PAGE_BITS, npages,
  bitmap);
 if (rc < 0) {
-if (rc != -ENODATA) {
+#ifndef ENODATA
+#define ENODATA  ENOENT
+#endif
+if (errno == ENODATA) {
 memory_region_set_dirty(framebuffer, 0, size);
 DPRINTF("xen: track_dirty_vram failed (0x" TARGET_FMT_plx
 ", 0x" TARGET_FMT_plx "): %s\n",
-start_addr, start_addr + size, strerror(-rc));
+start_addr, start_addr + size, strerror(errno));
 }
 return;
 }
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH v2 2/3] tap-bsd: implement a FreeBSD only version of tap_open

2014-05-23 Thread Roger Pau Monne
The current behaviour of tap_open for BSD systems differ greatly from
it's Linux counterpart. Since FreeBSD supports interface renaming and
tap device cloning by opening /dev/tap, implement a FreeBSD specific
version of tap_open that behaves like it's Linux counterpart.

This is specially important for toolstacks that use Qemu (like Xen
libxl), in order to have a unified behaviour across suported
platforms.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xenproject.org
Cc: Stefano Stabellini 
Cc: Anthony Liguori 
Cc: Stefan Hajnoczi 
---
 net/tap-bsd.c |   70 -
 1 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 90f8a02..bf91bd0 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -27,12 +27,13 @@
 #include "sysemu/sysemu.h"
 #include "qemu/error-report.h"
 
-#ifdef __NetBSD__
+#if defined(__NetBSD__) || defined(__FreeBSD__)
 #include 
 #include 
 #include 
 #endif
 
+#ifndef __FreeBSD__
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
  int vnet_hdr_required, int mq_required)
 {
@@ -108,6 +109,73 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
 return fd;
 }
 
+#else /* __FreeBSD__ */
+
+#define PATH_NET_TAP "/dev/tap"
+
+int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
+ int vnet_hdr_required, int mq_required)
+{
+int fd, s, ret;
+struct ifreq ifr;
+
+TFR(fd = open(PATH_NET_TAP, O_RDWR));
+if (fd < 0) {
+error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno));
+return -1;
+}
+
+memset(&ifr, 0, sizeof(ifr));
+
+ret = ioctl(fd, TAPGIFNAME, (void *)&ifr);
+if (ret < 0) {
+error_report("could not get tap interface name");
+goto error;
+}
+
+if (ifname[0] != '\0') {
+/* User requested the interface to have a specific name */
+s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+if (s < 0) {
+error_report("could not open socket to set interface name");
+goto error;
+}
+ifr.ifr_data = ifname;
+ret = ioctl(s, SIOCSIFNAME, (void *)&ifr);
+close(s);
+if (ret < 0) {
+error_report("could not set tap interface name");
+goto error;
+}
+} else {
+pstrcpy(ifname, ifname_size, ifr.ifr_name);
+}
+
+if (*vnet_hdr) {
+/* BSD doesn't have IFF_VNET_HDR */
+*vnet_hdr = 0;
+
+if (vnet_hdr_required && !*vnet_hdr) {
+error_report("vnet_hdr=1 requested, but no kernel "
+ "support for IFF_VNET_HDR available");
+goto error;
+}
+}
+if (mq_required) {
+error_report("mq_required requested, but not kernel support"
+ "for IFF_MULTI_QUEUE available");
+goto error;
+}
+
+fcntl(fd, F_SETFL, O_NONBLOCK);
+return fd;
+
+error:
+close(fd);
+return -1;
+}
+#endif /* __FreeBSD__ */
+
 int tap_set_sndbuf(int fd, const NetdevTapOptions *tap)
 {
 return 0;
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH] block: char devices on FreeBSD are not behind a pager

2014-10-20 Thread Roger Pau Monne
Acknowledge this and forcefully set BDRV_O_NOCACHE and O_DIRECT in order to
force QEMU to use aligned buffers.

Signed-off-by: Roger Pau Monné 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
---
 block/raw-posix.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 86ce4f2..63841dd 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -472,6 +472,18 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 }
 #endif
 }
+#ifdef __FreeBSD__
+if (S_ISCHR(st.st_mode)) {
+/*
+ * The file is a char device (disk), which on FreeBSD isn't behind
+ * a pager, so set BDRV_O_NOCACHE unconditionally. This is needed
+ * so Qemu makes sure all IO operations on the device are aligned
+ * to sector size, or else FreeBSD will reject them with EINVAL.
+ */
+bs->open_flags |= BDRV_O_NOCACHE;
+s->open_flags |= O_DIRECT;
+}
+#endif
 
 #ifdef CONFIG_XFS
 if (platform_test_xfs_fd(s->fd)) {
-- 
1.9.3 (Apple Git-50)




[Qemu-devel] [PATCH v2] block: char devices on FreeBSD are not behind a pager

2014-10-21 Thread Roger Pau Monne
Introduce a new flag to mark devices that require requests to be aligned and
replace the usage of BDRV_O_NOCACHE and O_DIRECT with this flag when
appropriate.

If a character device is used as a backend on a FreeBSD host set this flag
unconditionally.

Signed-off-by: Roger Pau Monné 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
---
Changes since v1:
 - Intead of appending BDRV_O_NOCACHE and O_DIRECT when a char dev is used
   on FreeBSD introduce a new flag that is used to mark if a device needs
   requests to be aligned.
---
 block/raw-posix.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 86ce4f2..b5361f7 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -150,6 +150,7 @@ typedef struct BDRVRawState {
 bool has_discard:1;
 bool has_write_zeroes:1;
 bool discard_zeroes:1;
+bool needs_alignement:1;
 #ifdef CONFIG_FIEMAP
 bool skip_fiemap;
 #endif
@@ -230,7 +231,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 
 /* For /dev/sg devices the alignment is not really used.
With buffered I/O, we don't have any restrictions. */
-if (bs->sg || !(s->open_flags & O_DIRECT)) {
+if (bs->sg || !s->needs_alignement) {
 bs->request_alignment = 1;
 s->buf_align = 1;
 return;
@@ -446,6 +447,8 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 
 s->has_discard = true;
 s->has_write_zeroes = true;
+if ((bs->open_flags & BDRV_O_NOCACHE) != 0)
+s->needs_alignement = true;
 
 if (fstat(s->fd, &st) < 0) {
 error_setg_errno(errp, errno, "Could not stat file");
@@ -472,6 +475,17 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 }
 #endif
 }
+#ifdef __FreeBSD__
+if (S_ISCHR(st.st_mode)) {
+/*
+ * The file is a char device (disk), which on FreeBSD isn't behind
+ * a pager, so force all requests to be aligned. This is needed
+ * so Qemu makes sure all IO operations on the device are aligned
+ * to sector size, or else FreeBSD will reject them with EINVAL.
+ */
+s->needs_alignement = true;
+}
+#endif
 
 #ifdef CONFIG_XFS
 if (platform_test_xfs_fd(s->fd)) {
@@ -1076,11 +1090,12 @@ static BlockDriverAIOCB 
*raw_aio_submit(BlockDriverState *bs,
 return NULL;
 
 /*
- * If O_DIRECT is used the buffer needs to be aligned on a sector
- * boundary.  Check if this is the case or tell the low-level
- * driver that it needs to copy the buffer.
+ * Check if the underlying device requires requests to be aligned,
+ * and if the request we are trying to submit is aligned or not.
+ * If this is the case tell the low-level driver that it needs
+ * to copy the buffer.
  */
-if ((bs->open_flags & BDRV_O_NOCACHE)) {
+if (s->needs_alignement) {
 if (!bdrv_qiov_is_aligned(bs, qiov)) {
 type |= QEMU_AIO_MISALIGNED;
 #ifdef CONFIG_LINUX_AIO
-- 
1.9.3 (Apple Git-50)




[Qemu-devel] [PATCH v3] block: char devices on FreeBSD are not behind a pager

2014-10-21 Thread Roger Pau Monne
Introduce a new flag to mark devices that require requests to be aligned and
replace the usage of BDRV_O_NOCACHE and O_DIRECT with this flag when
appropriate.

If a character device is used as a backend on a FreeBSD host set this flag
unconditionally.

Signed-off-by: Roger Pau Monné 
Reviewed-by: Max Reitz 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
---
Changes since v2:
 - s/alignement/alignment/.
 - Don't make needs_alignment a bit field.
 - Add braces to single statement conditional block.

Changes since v1:
 - Intead of appending BDRV_O_NOCACHE and O_DIRECT when a char dev is used
   on FreeBSD introduce a new flag that is used to mark if a device needs
   requests to be aligned.
---
 block/raw-posix.c | 26 +-
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 86ce4f2..afa4b01 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -150,6 +150,7 @@ typedef struct BDRVRawState {
 bool has_discard:1;
 bool has_write_zeroes:1;
 bool discard_zeroes:1;
+bool needs_alignment;
 #ifdef CONFIG_FIEMAP
 bool skip_fiemap;
 #endif
@@ -230,7 +231,7 @@ static void raw_probe_alignment(BlockDriverState *bs, int 
fd, Error **errp)
 
 /* For /dev/sg devices the alignment is not really used.
With buffered I/O, we don't have any restrictions. */
-if (bs->sg || !(s->open_flags & O_DIRECT)) {
+if (bs->sg || !s->needs_alignment) {
 bs->request_alignment = 1;
 s->buf_align = 1;
 return;
@@ -446,6 +447,9 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 
 s->has_discard = true;
 s->has_write_zeroes = true;
+if ((bs->open_flags & BDRV_O_NOCACHE) != 0) {
+s->needs_alignment = true;
+}
 
 if (fstat(s->fd, &st) < 0) {
 error_setg_errno(errp, errno, "Could not stat file");
@@ -472,6 +476,17 @@ static int raw_open_common(BlockDriverState *bs, QDict 
*options,
 }
 #endif
 }
+#ifdef __FreeBSD__
+if (S_ISCHR(st.st_mode)) {
+/*
+ * The file is a char device (disk), which on FreeBSD isn't behind
+ * a pager, so force all requests to be aligned. This is needed
+ * so QEMU makes sure all IO operations on the device are aligned
+ * to sector size, or else FreeBSD will reject them with EINVAL.
+ */
+s->needs_alignment = true;
+}
+#endif
 
 #ifdef CONFIG_XFS
 if (platform_test_xfs_fd(s->fd)) {
@@ -1076,11 +1091,12 @@ static BlockDriverAIOCB 
*raw_aio_submit(BlockDriverState *bs,
 return NULL;
 
 /*
- * If O_DIRECT is used the buffer needs to be aligned on a sector
- * boundary.  Check if this is the case or tell the low-level
- * driver that it needs to copy the buffer.
+ * Check if the underlying device requires requests to be aligned,
+ * and if the request we are trying to submit is aligned or not.
+ * If this is the case tell the low-level driver that it needs
+ * to copy the buffer.
  */
-if ((bs->open_flags & BDRV_O_NOCACHE)) {
+if (s->needs_alignment) {
 if (!bdrv_qiov_is_aligned(bs, qiov)) {
 type |= QEMU_AIO_MISALIGNED;
 #ifdef CONFIG_LINUX_AIO
-- 
1.9.3 (Apple Git-50)




[Qemu-devel] [PATCH 1/2] build: check if libm is needed in configure

2012-02-20 Thread Roger Pau Monne
Remove the hardcoded use of libm and instead rely on configure to
check for it. It is needed at least for qemu-ga and qemu-system.

Signed-off-by: Roger Pau Monne 
---
 Makefile.target |4 
 configure   |   14 ++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index a111521..1bfd419 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -33,10 +33,6 @@ endif
 PROGS=$(QEMU_PROG)
 STPFILES=
 
-ifndef CONFIG_HAIKU
-LIBS+=-lm
-endif
-
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
diff --git a/configure b/configure
index b113f60..7bcd547 100755
--- a/configure
+++ b/configure
@@ -2447,6 +2447,20 @@ elif compile_prog "" "-lrt" ; then
   LIBS="-lrt $LIBS"
 fi
 
+##
+# Do we need libm
+cat > $TMPC <
+int main(void) { double a, b; return modf(a, &b);}
+EOF
+
+if compile_prog "" "" ; then
+  :
+elif compile_prog "" "-lm" ; then
+  LIBS="-lm $LIBS"
+  libs_qga="-lm $libs_qga"
+fi
+
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
 "$aix" != "yes" -a "$haiku" != "yes" ; then
 libs_softmmu="-lutil $libs_softmmu"
-- 
1.7.9




[Qemu-devel] [PATCH 2/2] build: replace librt check function

2012-02-20 Thread Roger Pau Monne
Replace clock_gettime with timer_gettime, since at least under
uclibc 0.9.33 the clock_getttime function can be used without linking
against librt (although the manual page states the opposite).

Signed-off-by: Roger Pau Monne 
---
 configure |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 7bcd547..fb99632 100755
--- a/configure
+++ b/configure
@@ -2438,7 +2438,8 @@ fi
 cat > $TMPC <
 #include 
-int main(void) { clockid_t id; return clock_gettime(id, NULL); }
+int main(void) { timer_t tid; struct itimerspec it; \
+ return timer_gettime(tid, &it); }
 EOF
 
 if compile_prog "" "" ; then
-- 
1.7.9




[Qemu-devel] [PATCH 1/3] build: replace librt check function

2012-02-27 Thread Roger Pau Monne
Replace clock_gettime with timer_gettime, since at least under
uclibc 0.9.33 the clock_getttime function can be used without linking
against librt (although the manual page states the opposite).

Signed-off-by: Roger Pau Monne 
---
 configure |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index f9d5330..68eb3fa 100755
--- a/configure
+++ b/configure
@@ -2513,7 +2513,8 @@ fi
 cat > $TMPC <
 #include 
-int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); }
+int main(void) { timer_t tid; struct itimerspec it; \
+ return timer_gettime(tid, &it); }
 EOF
 
 if compile_prog "" "" ; then
-- 
1.7.9




[Qemu-devel] [PATCH 3/3] build: check if libm is needed in configure

2012-02-27 Thread Roger Pau Monne
Remove the hardcoded use of libm and instead rely on configure to
check for it. It is needed at least for qemu-ga and qemu-system.

Signed-off-by: Roger Pau Monne 
---
 Makefile.target |4 
 configure   |   14 ++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 68a5641..c230aff 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -42,10 +42,6 @@ PROGS+=$(QEMU_PROGW)
 endif
 STPFILES=
 
-ifndef CONFIG_HAIKU
-LIBS+=-lm
-endif
-
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
diff --git a/configure b/configure
index 790d495..b0cb175 100755
--- a/configure
+++ b/configure
@@ -2524,6 +2524,20 @@ elif compile_prog "" "-lrt" ; then
   libs_qga="-lrt $libs_qga"
 fi
 
+##
+# Do we need libm
+cat > $TMPC <
+int main(void) { double a, b; return modf(a, &b);}
+EOF
+
+if compile_prog "" "" ; then
+  :
+elif compile_prog "" "-lm" ; then
+  LIBS="-lm $LIBS"
+  libs_qga="-lm $libs_qga"
+fi
+
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
 "$aix" != "yes" -a "$haiku" != "yes" ; then
 libs_softmmu="-lutil $libs_softmmu"
-- 
1.7.9




[Qemu-devel] [PATCH 2/3] build: add librt to libs_qga

2012-02-27 Thread Roger Pau Monne
librt is needed to link qemu-ga.

Signed-off-by: Roger Pau Monne 
---
 configure |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 68eb3fa..790d495 100755
--- a/configure
+++ b/configure
@@ -2521,6 +2521,7 @@ if compile_prog "" "" ; then
   :
 elif compile_prog "" "-lrt" ; then
   LIBS="-lrt $LIBS"
+  libs_qga="-lrt $libs_qga"
 fi
 
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
-- 
1.7.9




[Qemu-devel] [PATCH 1/3] build: replace librt check function

2012-03-12 Thread Roger Pau Monne
Replace clock_gettime with timer_gettime, since at least under
uclibc 0.9.33 the clock_getttime function can be used without linking
against librt (although the manual page states the opposite).

Signed-off-by: Roger Pau Monne 
---
 configure |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index f9d5330..68eb3fa 100755
--- a/configure
+++ b/configure
@@ -2513,7 +2513,8 @@ fi
 cat > $TMPC <
 #include 
-int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); }
+int main(void) { timer_t tid; struct itimerspec it; \
+ return timer_gettime(tid, &it); }
 EOF
 
 if compile_prog "" "" ; then
-- 
1.7.9




[Qemu-devel] [PATCH 2/3] build: add librt to libs_qga

2012-03-12 Thread Roger Pau Monne
librt is needed to link qemu-ga.

Signed-off-by: Roger Pau Monne 
---
 configure |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/configure b/configure
index 68eb3fa..790d495 100755
--- a/configure
+++ b/configure
@@ -2521,6 +2521,7 @@ if compile_prog "" "" ; then
   :
 elif compile_prog "" "-lrt" ; then
   LIBS="-lrt $LIBS"
+  libs_qga="-lrt $libs_qga"
 fi
 
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
-- 
1.7.9




[Qemu-devel] [PATCH 3/3] build: check if libm is needed in configure

2012-03-12 Thread Roger Pau Monne
Remove the hardcoded use of libm and instead rely on configure to
check for it. It is needed at least for qemu-ga and qemu-system.

Signed-off-by: Roger Pau Monne 
---
 Makefile.target |4 
 configure   |   14 ++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 68a5641..c230aff 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -42,10 +42,6 @@ PROGS+=$(QEMU_PROGW)
 endif
 STPFILES=
 
-ifndef CONFIG_HAIKU
-LIBS+=-lm
-endif
-
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
diff --git a/configure b/configure
index 790d495..b0cb175 100755
--- a/configure
+++ b/configure
@@ -2524,6 +2524,20 @@ elif compile_prog "" "-lrt" ; then
   libs_qga="-lrt $libs_qga"
 fi
 
+##
+# Do we need libm
+cat > $TMPC <
+int main(void) { double a, b; return modf(a, &b);}
+EOF
+
+if compile_prog "" "" ; then
+  :
+elif compile_prog "" "-lm" ; then
+  LIBS="-lm $LIBS"
+  libs_qga="-lm $libs_qga"
+fi
+
 if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
 "$aix" != "yes" -a "$haiku" != "yes" ; then
 libs_softmmu="-lutil $libs_softmmu"
-- 
1.7.9




[Qemu-devel] [PATCH 2/2] tap-bsd: implement a FreeBSD only version of tap_open

2014-04-15 Thread Roger Pau Monne
The current behaviour of tap_open for BSD systems differ greatly from
it's Linux counterpart. Since FreeBSD supports interface renaming and
tap device cloning by opening /dev/tap, implement a FreeBSD specific
version of tap_open that behaves like it's Linux counterpart.

This is specially important for toolstacks that use Qemu (like Xen
libxl), in order to have a unified behaviour across suported
platforms.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xenproject.org
Cc: Stefano Stabellini 
Cc: Anthony Liguori 
Cc: Stefan Hajnoczi 
---
 net/tap-bsd.c |   70 -
 1 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/net/tap-bsd.c b/net/tap-bsd.c
index 90f8a02..bf91bd0 100644
--- a/net/tap-bsd.c
+++ b/net/tap-bsd.c
@@ -27,12 +27,13 @@
 #include "sysemu/sysemu.h"
 #include "qemu/error-report.h"
 
-#ifdef __NetBSD__
+#if defined(__NetBSD__) || defined(__FreeBSD__)
 #include 
 #include 
 #include 
 #endif
 
+#ifndef __FreeBSD__
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
  int vnet_hdr_required, int mq_required)
 {
@@ -108,6 +109,73 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
 return fd;
 }
 
+#else /* __FreeBSD__ */
+
+#define PATH_NET_TAP "/dev/tap"
+
+int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
+ int vnet_hdr_required, int mq_required)
+{
+int fd, s, ret;
+struct ifreq ifr;
+
+TFR(fd = open(PATH_NET_TAP, O_RDWR));
+if (fd < 0) {
+error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno));
+return -1;
+}
+
+memset(&ifr, 0, sizeof(ifr));
+
+ret = ioctl(fd, TAPGIFNAME, (void *)&ifr);
+if (ret < 0) {
+error_report("could not get tap interface name");
+goto error;
+}
+
+if (ifname[0] != '\0') {
+/* User requested the interface to have a specific name */
+s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+if (s < 0) {
+error_report("could not open socket to set interface name");
+goto error;
+}
+ifr.ifr_data = ifname;
+ret = ioctl(s, SIOCSIFNAME, (void *)&ifr);
+close(s);
+if (ret < 0) {
+error_report("could not set tap interface name");
+goto error;
+}
+} else {
+pstrcpy(ifname, ifname_size, ifr.ifr_name);
+}
+
+if (*vnet_hdr) {
+/* BSD doesn't have IFF_VNET_HDR */
+*vnet_hdr = 0;
+
+if (vnet_hdr_required && !*vnet_hdr) {
+error_report("vnet_hdr=1 requested, but no kernel "
+ "support for IFF_VNET_HDR available");
+goto error;
+}
+}
+if (mq_required) {
+error_report("mq_required requested, but not kernel support"
+ "for IFF_MULTI_QUEUE available");
+goto error;
+}
+
+fcntl(fd, F_SETFL, O_NONBLOCK);
+return fd;
+
+error:
+close(fd);
+return -1;
+}
+#endif /* __FreeBSD__ */
+
 int tap_set_sndbuf(int fd, const NetdevTapOptions *tap)
 {
 return 0;
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH 0/2] qemu-freebsd: fixes for running Xen guests

2014-04-15 Thread Roger Pau Monne
This two patches allow FreeBSD Xen Dom0 to use Qemu (i.e., launch HVM
guests).

First patch fixes the usage of ENODATA, which doesn't exist on FreeBSD
and is replaced with ENOENT instead.

The second patch is more controversial probably, since it introduces a
FreeBSD specific version of tap_open which behaves like it's Linux
counterpart, allowing Qemu to create tap interfaces and rename them.
I've decided to just fork the function instead of adding a bunch more
of preprocessor code in the original function.

Thanks for the review, Roger.



[Qemu-devel] [PATCH 1/2] xen: fix usage of ENODATA

2014-04-15 Thread Roger Pau Monne
ENODATA doesn't exist on FreeBSD, so ENODATA errors returned by the
hypervisor are translated to ENOENT.

Also, the error code is returned in errno if the call returns -1, so
compare the error code with the value in errno instead of the value
returned by the function.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xenproject.org
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 xen-all.c |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xen-all.c b/xen-all.c
index 0b4d934..4026b7b 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -499,11 +499,15 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
  start_addr >> TARGET_PAGE_BITS, npages,
  bitmap);
 if (rc < 0) {
-if (rc != -ENODATA) {
+#ifdef ENODATA
+if (errno == ENODATA) {
+#else
+if (errno == ENOENT) {
+#endif
 memory_region_set_dirty(framebuffer, 0, size);
 DPRINTF("xen: track_dirty_vram failed (0x" TARGET_FMT_plx
 ", 0x" TARGET_FMT_plx "): %s\n",
-start_addr, start_addr + size, strerror(-rc));
+start_addr, start_addr + size, strerror(errno));
 }
 return;
 }
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH] serial: poll the serial console with G_IO_HUP

2014-04-22 Thread Roger Pau Monne
On FreeBSD polling a master pty while the other end is not connected
with G_IO_OUT only results in an endless wait. This is different from
the Linux behaviour, that returns immediately. In order to demonstrate
this, I have the following example code:

http://xenbits.xen.org/people/royger/test_poll.c

When executed on Linux:

$ ./test_poll
In callback

On FreeBSD instead, the callback never gets called:

$ ./test_poll

So, in order to workaround this, poll the source with G_IO_HUP (which
makes the code behave the same way on both Linux and FreeBSD).

Signed-off-by: Roger Pau Monné 
Cc: Peter Crosthwaite 
Cc: Michael Tokarev 
Cc: "Andreas Färber" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
---
 hw/char/serial.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/char/serial.c b/hw/char/serial.c
index 6025592..ab9c40f 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -243,7 +243,7 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition 
cond, void *opaque)
 serial_receive1(s, &s->tsr, 1);
 } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
 if (s->tsr_retry >= 0 && s->tsr_retry < MAX_XMIT_RETRY &&
-qemu_chr_fe_add_watch(s->chr, G_IO_OUT, serial_xmit, s) > 0) {
+qemu_chr_fe_add_watch(s->chr, G_IO_OUT|G_IO_HUP, serial_xmit, s) > 
0) {
 s->tsr_retry++;
 return FALSE;
 }
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH] xen_disk: fix unmapping of persistent grants

2014-11-12 Thread Roger Pau Monne
This patch fixes two issues with persistent grants and the disk PV backend
(Qdisk):

 - Don't use batch mappings when using persistent grants, doing so prevents
   unmapping single grants (the whole area has to be unmapped at once).
 - Unmap persistent grants before switching to the closed state, so the
   frontend can also free them.

Signed-off-by: Roger Pau Monné 
Reported-and-Tested-by: George Dunlap 
Cc: Stefano Stabellini 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
Cc: George Dunlap 
---
 hw/block/xen_disk.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 231e9a7..1300c0a 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -43,8 +43,6 @@
 
 /* - */
 
-static int batch_maps   = 0;
-
 static int max_requests = 32;
 
 /* - */
@@ -105,6 +103,7 @@ struct XenBlkDev {
 blkif_back_rings_t  rings;
 int more_work;
 int cnt_map;
+boolbatch_maps;
 
 /* request lists */
 QLIST_HEAD(inflight_head, ioreq) inflight;
@@ -309,7 +308,7 @@ static void ioreq_unmap(struct ioreq *ioreq)
 if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
 return;
 }
-if (batch_maps) {
+if (ioreq->blkdev->batch_maps) {
 if (!ioreq->pages) {
 return;
 }
@@ -386,7 +385,7 @@ static int ioreq_map(struct ioreq *ioreq)
 new_maps = ioreq->v.niov;
 }
 
-if (batch_maps && new_maps) {
+if (ioreq->blkdev->batch_maps && new_maps) {
 ioreq->pages = xc_gnttab_map_grant_refs
 (gnt, new_maps, domids, refs, ioreq->prot);
 if (ioreq->pages == NULL) {
@@ -433,7 +432,7 @@ static int ioreq_map(struct ioreq *ioreq)
  */
 grant = g_malloc0(sizeof(*grant));
 new_maps--;
-if (batch_maps) {
+if (ioreq->blkdev->batch_maps) {
 grant->page = ioreq->pages + (new_maps) * XC_PAGE_SIZE;
 } else {
 grant->page = ioreq->page[new_maps];
@@ -718,7 +717,9 @@ static void blk_alloc(struct XenDevice *xendev)
 QLIST_INIT(&blkdev->freelist);
 blkdev->bh = qemu_bh_new(blk_bh, blkdev);
 if (xen_mode != XEN_EMULATE) {
-batch_maps = 1;
+blkdev->batch_maps = TRUE;
+} else {
+blkdev->batch_maps = FALSE;
 }
 if (xc_gnttab_set_max_grants(xendev->gnttabdev,
 MAX_GRANTS(max_requests, BLKIF_MAX_SEGMENTS_PER_REQUEST)) < 0) {
@@ -923,6 +924,13 @@ static int blk_connect(struct XenDevice *xendev)
 } else {
 blkdev->feature_persistent = !!pers;
 }
+if (blkdev->feature_persistent) {
+/*
+ * Disable batch maps, since that would prevent unmapping
+ * single persistent grants.
+ */
+blkdev->batch_maps = FALSE;
+}
 
 blkdev->protocol = BLKIF_PROTOCOL_NATIVE;
 if (blkdev->xendev.protocol) {
@@ -1000,6 +1008,16 @@ static void blk_disconnect(struct XenDevice *xendev)
 blkdev->cnt_map--;
 blkdev->sring = NULL;
 }
+
+/*
+ * Unmap persistent grants before switching to the closed state
+ * so the frontend can free them.
+ */
+if (blkdev->feature_persistent) {
+g_tree_destroy(blkdev->persistent_gnts);
+assert(blkdev->persistent_gnt_count == 0);
+blkdev->feature_persistent = FALSE;
+}
 }
 
 static int blk_free(struct XenDevice *xendev)
@@ -1011,11 +1029,6 @@ static int blk_free(struct XenDevice *xendev)
 blk_disconnect(xendev);
 }
 
-/* Free persistent grants */
-if (blkdev->feature_persistent) {
-g_tree_destroy(blkdev->persistent_gnts);
-}
-
 while (!QLIST_EMPTY(&blkdev->freelist)) {
 ioreq = QLIST_FIRST(&blkdev->freelist);
 QLIST_REMOVE(ioreq, list);
-- 
1.9.3 (Apple Git-50)




[Qemu-devel] [PATCH v2 for-xen-4.5] xen_disk: fix unmapping of persistent grants

2014-11-13 Thread Roger Pau Monne
This patch fixes two issues with persistent grants and the disk PV backend
(Qdisk):

 - Keep track of memory regions where persistent grants have been mapped
   since we need to unmap them as a whole. It is not possible to unmap a
   single grant if it has been batch-mapped.
 - Unmap persistent grants before switching to the closed state, so the
   frontend can also free them.

Signed-off-by: Roger Pau Monné 
Reported-by: George Dunlap 
Cc: Stefano Stabellini 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
Cc: George Dunlap 
Cc: Konrad Rzeszutek Wilk 
---
Xen release exception: this is obviously an important bug-fix that should be
included in 4.5. Without this fix, trying to do a block-detach of a Qdisk
from a running guest can lead to guest crash depending on the blkfront
implementation.
---
Changes since v1:
 - Instead of disabling batch mappings when using persistent grants, keep
   track of the persistently mapped regions and unmap them on disconnection.
   This prevents unmapping single persistent grants, but the current
   implementation doesn't require it.

This new version is slightly faster than the previous one, the following
test results are in IOPS from 20 runs of a block-attach, fio run,
block-detach test loop:

x batch
+ no_batch
+--+
|  +   + xx + + +  x xx x  |
|+  +   x x+  *+++   *  +x* +++x*  x xx x *|
|  |_A_M__||
||A_M___|  |
+--+
N   Min   MaxMedian   AvgStddev
x  20 52941 63822 62396  61180.15 2673.6497
+  20 49967 63849 60322   59116.9 3456.3455
Difference at 95.0% confidence
-2063.25 +/- 1977.66
-3.37242% +/- 3.23252%
(Student's t, pooled s = 3089.88)
---
 hw/block/xen_disk.c | 77 -
 1 file changed, 64 insertions(+), 13 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 231e9a7..75bdc16 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -59,6 +59,13 @@ struct PersistentGrant {
 
 typedef struct PersistentGrant PersistentGrant;
 
+struct PersistentRegion {
+void *addr;
+int num;
+};
+
+typedef struct PersistentRegion PersistentRegion;
+
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -118,6 +125,7 @@ struct XenBlkDev {
 gbooleanfeature_discard;
 gbooleanfeature_persistent;
 GTree   *persistent_gnts;
+GSList  *persistent_regions;
 unsigned intpersistent_gnt_count;
 unsigned intmax_grants;
 
@@ -164,19 +172,41 @@ static gint int_cmp(gconstpointer a, gconstpointer b, 
gpointer user_data)
 static void destroy_grant(gpointer pgnt)
 {
 PersistentGrant *grant = pgnt;
-XenGnttab gnt = grant->blkdev->xendev.gnttabdev;
 
-if (xc_gnttab_munmap(gnt, grant->page, 1) != 0) {
-xen_be_printf(&grant->blkdev->xendev, 0,
-  "xc_gnttab_munmap failed: %s\n",
-  strerror(errno));
-}
 grant->blkdev->persistent_gnt_count--;
 xen_be_printf(&grant->blkdev->xendev, 3,
-  "unmapped grant %p\n", grant->page);
+  "removed grant %p\n", grant->page);
 g_free(grant);
 }
 
+static void add_persistent_region(struct XenBlkDev *blkdev, void *addr, int 
num)
+{
+PersistentRegion *region;
+
+region = g_malloc0(sizeof(*region));
+region->addr = addr;
+region->num = num;
+blkdev->persistent_regions = g_slist_append(blkdev->persistent_regions,
+region);
+}
+
+static void remove_persistent_region(gpointer data, gpointer dev)
+{
+PersistentRegion *region = data;
+struct XenBlkDev *blkdev = dev;
+XenGnttab gnt = blkdev->xendev.gnttabdev;
+
+if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) {
+xen_be_printf(&blkdev->xendev, 0,
+  "xc_gnttab_munmap region %p failed: %s\n",
+  region->addr, strerror(errno));
+}
+xen_be_printf(&blkdev->xendev, 3,
+  "unmapped grant region %p with %d pages\n",
+  region->addr, region->num);
+g_free(region);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -421,7 +451,17 @@ static int ioreq_map(struct ioreq *ioreq)
 }
 }
 }
-if (ioreq->blkdev->feature_persistent) {
+if (ioreq->blkdev->feature_persistent && new_maps &&
+(!batch_maps || (ioreq->blkdev->persistent_gnt_count + new_maps <=
+ioreq->blkdev->max_grants))) {
+/*
+ * If we are using p

[Qemu-devel] [PATCH v3 for-xen-4.5] xen_disk: fix unmapping of persistent grants

2014-11-13 Thread Roger Pau Monne
This patch fixes two issues with persistent grants and the disk PV backend
(Qdisk):

 - Keep track of memory regions where persistent grants have been mapped
   since we need to unmap them as a whole. It is not possible to unmap a
   single grant if it has been batch-mapped. A new check has also been added
   to make sure persistent grants are only used if the whole mapped region
   can be persistently mapped in the batch_maps case.
 - Unmap persistent grants before switching to the closed state, so the
   frontend can also free them.

Signed-off-by: Roger Pau Monné 
Reported-by: George Dunlap 
Cc: Stefano Stabellini 
Cc: Kevin Wolf 
Cc: Stefan Hajnoczi 
Cc: George Dunlap 
Cc: Konrad Rzeszutek Wilk 
---
Xen release exception: this is obviously an important bug-fix that should be
included in 4.5. Without this fix, trying to do a block-detach of a Qdisk
from a running guest can lead to guest crash depending on the blkfront
implementation.
---
Changea since v2:
 - Expand the commit message to mention the newly added check.
 - Don't use persistent_regions in the !batch_maps case, we can use the
   previous implementation which works fine in that case.

Changes since v1:
 - Instead of disabling batch mappings when using persistent grants, keep
   track of the persistently mapped regions and unmap them on disconnection.
   This prevents unmapping single persistent grants, but the current
   implementation doesn't require it.

This new version is slightly faster than the previous one, the following
test results are in IOPS from 20 runs of a block-attach, fio run,
block-detach test loop:

x batch
+ no_batch
+--+
|  +   + xx + + +  x xx x  |
|+  +   x x+  *+++   *  +x* +++x*  x xx x *|
|  |_A_M__||
||A_M___|  |
+--+
N   Min   MaxMedian   AvgStddev
x  20 52941 63822 62396  61180.15 2673.6497
+  20 49967 63849 60322   59116.9 3456.3455
Difference at 95.0% confidence
-2063.25 +/- 1977.66
-3.37242% +/- 3.23252%
(Student's t, pooled s = 3089.88)
---
 hw/block/xen_disk.c | 72 -
 1 file changed, 66 insertions(+), 6 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 231e9a7..21842a0 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -59,6 +59,13 @@ struct PersistentGrant {
 
 typedef struct PersistentGrant PersistentGrant;
 
+struct PersistentRegion {
+void *addr;
+int num;
+};
+
+typedef struct PersistentRegion PersistentRegion;
+
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -118,6 +125,7 @@ struct XenBlkDev {
 gbooleanfeature_discard;
 gbooleanfeature_persistent;
 GTree   *persistent_gnts;
+GSList  *persistent_regions;
 unsigned intpersistent_gnt_count;
 unsigned intmax_grants;
 
@@ -177,6 +185,23 @@ static void destroy_grant(gpointer pgnt)
 g_free(grant);
 }
 
+static void remove_persistent_region(gpointer data, gpointer dev)
+{
+PersistentRegion *region = data;
+struct XenBlkDev *blkdev = dev;
+XenGnttab gnt = blkdev->xendev.gnttabdev;
+
+if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) {
+xen_be_printf(&blkdev->xendev, 0,
+  "xc_gnttab_munmap region %p failed: %s\n",
+  region->addr, strerror(errno));
+}
+xen_be_printf(&blkdev->xendev, 3,
+  "unmapped grant region %p with %d pages\n",
+  region->addr, region->num);
+g_free(region);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -343,6 +368,7 @@ static int ioreq_map(struct ioreq *ioreq)
 void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 int i, j, new_maps = 0;
 PersistentGrant *grant;
+PersistentRegion *region;
 /* domids and refs variables will contain the information necessary
  * to map the grants that are needed to fulfill this request.
  *
@@ -421,7 +447,22 @@ static int ioreq_map(struct ioreq *ioreq)
 }
 }
 }
-if (ioreq->blkdev->feature_persistent) {
+if (ioreq->blkdev->feature_persistent && new_maps != 0 &&
+(!batch_maps || (ioreq->blkdev->persistent_gnt_count + new_maps <=
+ioreq->blkdev->max_grants))) {
+/*
+ * If we are using persistent grants and batch mappings only
+ * add the new maps to the list of persistent grants if the whole
+ * area can be persistently mapped.
+ */
+if (batch_maps) {
+  

[Qemu-devel] [PATCH QEMU 2/2] xen: fix usage of xc_domain_create in domain builder

2015-11-13 Thread Roger Pau Monne
Due to the addition of HVMlite and the requirement to always provide a valid
xc_domain_configuration_t, xc_domain_create now always takes an arch domain
config, which can be NULL in order to mimic previous behaviour.

Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: qemu-devel@nongnu.org
---
 hw/xenpv/xen_domainbuild.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index c0ab753..a737908 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -234,7 +234,7 @@ int xen_domain_build_pv(const char *kernel, const char 
*ramdisk,
 int rc;
 
 memcpy(uuid, qemu_uuid, sizeof(uuid));
-rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid);
+rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid, NULL);
 if (rc < 0) {
 fprintf(stderr, "xen: xc_domain_create() failed\n");
 goto err;
-- 
1.9.5 (Apple Git-50.3)




[Qemu-devel] [PATCH QEMU v2 2/2] xen: fix usage of xc_domain_create in domain builder

2015-11-13 Thread Roger Pau Monne
Due to the addition of HVMlite and the requirement to always provide a valid
xc_domain_configuration_t, xc_domain_create now always takes an arch domain
config, which can be NULL in order to mimic previous behaviour.

Add a small stub called xen_domain_create that encapsulates the correct call
to xc_domain_create depending on the libxc version detected.

Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: qemu-devel@nongnu.org
---
Changes since v1:
 - Add a compat layer to support previous libxc versions.
 - Add machinery to detect current Xen unstable (4.7).
---
 configure   | 17 +
 hw/xenpv/xen_domainbuild.c  |  2 +-
 include/hw/xen/xen_common.h | 12 
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 779623a..001982f 100755
--- a/configure
+++ b/configure
@@ -1863,6 +1863,23 @@ EOF
   elif
   cat > $TMPC <
+#include 
+int main(void) {
+  xc_interface *xc = NULL;
+  xen_domain_handle_t handle;
+  xc_domain_create(xc, 0, handle, 0, NULL, NULL);
+  return 0;
+}
+EOF
+  compile_prog "" "$xen_libs"
+then
+xen_ctrl_version=470
+xen=yes
+
+  # Xen 4.6
+  elif
+  cat > $TMPC <
 #include 
 #include 
 #include 
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index c0ab753..07814f6 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -234,7 +234,7 @@ int xen_domain_build_pv(const char *kernel, const char 
*ramdisk,
 int rc;
 
 memcpy(uuid, qemu_uuid, sizeof(uuid));
-rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid);
+rc = xen_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid, NULL);
 if (rc < 0) {
 fprintf(stderr, "xen: xc_domain_create() failed\n");
 goto err;
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 5923290..e5ba732 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -417,4 +417,16 @@ static inline int xen_set_ioreq_server_state(XenXC xc, 
domid_t dom,
 
 #endif
 
+static inline int xen_domain_create(XenXC xc, uint32_t ssidref,
+xen_domain_handle_t handle, uint32_t flags,
+uint32_t *pdomid,
+xc_domain_configuration_t *config)
+{
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 470
+return xc_domain_create(xc, ssidref, handle, flags, pdomid);
+#else
+return xc_domain_create(xc, ssidref, handle, flags, pdomid, config);
+#endif
+}
+
 #endif /* QEMU_HW_XEN_COMMON_H */
-- 
1.9.5 (Apple Git-50.3)




[Qemu-devel] [PATCH QEMU v3 2/2] xen: fix usage of xc_domain_create in domain builder

2015-11-13 Thread Roger Pau Monne
Due to the addition of HVMlite and the requirement to always provide a valid
xc_domain_configuration_t, xc_domain_create now always takes an arch domain
config, which can be NULL in order to mimic previous behaviour.

Add a small stub called xen_domain_create that encapsulates the correct call
to xc_domain_create depending on the libxc version detected.

Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: qemu-devel@nongnu.org
---
Changes since v2:
 - Drop the last parameter to xen_create_domain since it's always NULL ATM
   and was causing build problems with older Xen versions.
 - Create two different inline functions instead of putting ifdefs inside of
   a single one.

Changes since v1:
 - Add a compat layer to support previous libxc versions.
 - Add machinery to detect current Xen unstable (4.7).
---
 configure   | 17 +
 hw/xenpv/xen_domainbuild.c  |  2 +-
 include/hw/xen/xen_common.h | 16 
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 779623a..001982f 100755
--- a/configure
+++ b/configure
@@ -1863,6 +1863,23 @@ EOF
   elif
   cat > $TMPC <
+#include 
+int main(void) {
+  xc_interface *xc = NULL;
+  xen_domain_handle_t handle;
+  xc_domain_create(xc, 0, handle, 0, NULL, NULL);
+  return 0;
+}
+EOF
+  compile_prog "" "$xen_libs"
+then
+xen_ctrl_version=470
+xen=yes
+
+  # Xen 4.6
+  elif
+  cat > $TMPC <
 #include 
 #include 
 #include 
diff --git a/hw/xenpv/xen_domainbuild.c b/hw/xenpv/xen_domainbuild.c
index c0ab753..ac0e5ac 100644
--- a/hw/xenpv/xen_domainbuild.c
+++ b/hw/xenpv/xen_domainbuild.c
@@ -234,7 +234,7 @@ int xen_domain_build_pv(const char *kernel, const char 
*ramdisk,
 int rc;
 
 memcpy(uuid, qemu_uuid, sizeof(uuid));
-rc = xc_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid);
+rc = xen_domain_create(xen_xc, ssidref, uuid, flags, &xen_domid);
 if (rc < 0) {
 fprintf(stderr, "xen: xc_domain_create() failed\n");
 goto err;
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index 5923290..04bf6da 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -417,4 +417,20 @@ static inline int xen_set_ioreq_server_state(XenXC xc, 
domid_t dom,
 
 #endif
 
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION < 470
+static inline int xen_domain_create(XenXC xc, uint32_t ssidref,
+xen_domain_handle_t handle, uint32_t flags,
+uint32_t *pdomid)
+{
+return xc_domain_create(xc, ssidref, handle, flags, pdomid);
+}
+#else
+static inline int xen_domain_create(XenXC xc, uint32_t ssidref,
+xen_domain_handle_t handle, uint32_t flags,
+uint32_t *pdomid)
+{
+return xc_domain_create(xc, ssidref, handle, flags, pdomid, NULL);
+}
+#endif
+
 #endif /* QEMU_HW_XEN_COMMON_H */
-- 
1.9.5 (Apple Git-50.3)




[Qemu-devel] [PATCH v2] xen_disk: add persistent grant support to xen_disk backend

2013-01-08 Thread Roger Pau Monne
This protocol extension reuses the same set of grant pages for all
transactions between the front/back drivers, avoiding expensive tlb
flushes, grant table lock contention and switches between userspace
and kernel space. The full description of the protocol can be found in
the public blkif.h header.

http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=xen/include/public/io/blkif.h

Speed improvement with 15 guests performing I/O is ~450%.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xen.org
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
---
Performance comparison with the previous implementation can be seen in
the followign graph:

http://xenbits.xen.org/people/royger/persistent_read_qemu.png
---
Changes since v1:
 * Fix coding style issues.
 * Add more comments regarding how ioreq_map works.
---
 hw/xen_disk.c |  172 +++--
 1 files changed, 155 insertions(+), 17 deletions(-)

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 1eb485a..cddd12a 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -52,6 +52,13 @@ static int max_requests = 32;
 #define BLOCK_SIZE  512
 #define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
 
+struct PersistentGrant {
+void *page;
+struct XenBlkDev *blkdev;
+};
+
+typedef struct PersistentGrant PersistentGrant;
+
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -69,6 +76,7 @@ struct ioreq {
 int prot;
 void*page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 void*pages;
+int num_unmap;
 
 /* aio status */
 int aio_inflight;
@@ -105,6 +113,12 @@ struct XenBlkDev {
 int requests_inflight;
 int requests_finished;
 
+/* Persistent grants extension */
+gbooleanfeature_persistent;
+GTree   *persistent_gnts;
+unsigned intpersistent_gnt_count;
+unsigned intmax_grants;
+
 /* qemu block driver */
 DriveInfo   *dinfo;
 BlockDriverState*bs;
@@ -138,6 +152,29 @@ static void ioreq_reset(struct ioreq *ioreq)
 qemu_iovec_reset(&ioreq->v);
 }
 
+static gint int_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
+{
+uint ua = GPOINTER_TO_UINT(a);
+uint ub = GPOINTER_TO_UINT(b);
+return (ua > ub) - (ua < ub);
+}
+
+static void destroy_grant(gpointer pgnt)
+{
+PersistentGrant *grant = pgnt;
+XenGnttab gnt = grant->blkdev->xendev.gnttabdev;
+
+if (xc_gnttab_munmap(gnt, grant->page, 1) != 0) {
+xen_be_printf(&grant->blkdev->xendev, 0,
+  "xc_gnttab_munmap failed: %s\n",
+  strerror(errno));
+}
+grant->blkdev->persistent_gnt_count--;
+xen_be_printf(&grant->blkdev->xendev, 3,
+  "unmapped grant %p\n", grant->page);
+g_free(grant);
+}
+
 static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
 {
 struct ioreq *ioreq = NULL;
@@ -266,21 +303,21 @@ static void ioreq_unmap(struct ioreq *ioreq)
 XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
 int i;
 
-if (ioreq->v.niov == 0 || ioreq->mapped == 0) {
+if (ioreq->num_unmap == 0 || ioreq->mapped == 0) {
 return;
 }
 if (batch_maps) {
 if (!ioreq->pages) {
 return;
 }
-if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->v.niov) != 0) {
+if (xc_gnttab_munmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) {
 xen_be_printf(&ioreq->blkdev->xendev, 0, "xc_gnttab_munmap failed: 
%s\n",
   strerror(errno));
 }
-ioreq->blkdev->cnt_map -= ioreq->v.niov;
+ioreq->blkdev->cnt_map -= ioreq->num_unmap;
 ioreq->pages = NULL;
 } else {
-for (i = 0; i < ioreq->v.niov; i++) {
+for (i = 0; i < ioreq->num_unmap; i++) {
 if (!ioreq->page[i]) {
 continue;
 }
@@ -298,41 +335,121 @@ static void ioreq_unmap(struct ioreq *ioreq)
 static int ioreq_map(struct ioreq *ioreq)
 {
 XenGnttab gnt = ioreq->blkdev->xendev.gnttabdev;
-int i;
+uint32_t domids[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+uint32_t refs[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+int i, j, new_maps = 0;
+PersistentGrant *grant;
+/* domids and refs variables will contain the information necessary
+ * to map the grants that are needed to fulfill this request.
+ *
+ * After mapping the needed grants, the page array will contain the
+ * memory address of each granted page in the order specified in ioreq
+ * (disregarding if it's a persistent grant or not).
+ */
 
 if (ioreq->v.niov == 0 || ioreq->mapped == 1) {
 return 0;
 }
-if (batch_maps) {
+if (ioreq->blkdev->feature_persistent) {
+for (i = 0; i < ioreq->v.niov; i++) {
+grant = g_tree_lookup(ioreq->blkdev->persistent_gnts,
+

[Qemu-devel] [PATCH] audio: fix bug in mixeng_template.h build on NetBSD

2012-05-11 Thread Roger Pau Monne
This is a bug fix for rc1, although I think this bug has been present
for a long time.

NetBSD has typedefs and defines of types, so all the types specified
in mixeng.c IN_T define (int8_t, uint8_t...) got expanded to __int8_t,
__uint8_t, and the construction of types in mixeng_template.h failed.

audio/mixeng.c:150:17: error: 'conv_natural_uint8_t_to_mono'
undeclared here (not in a function)
[...]
audio/mixeng_template.h:114:1: warning:
'conv_natural___uint8_t_to_mono' defined but not used
[...]

Undef those types, so we can safely compile. This is safe even if the
types are not defined.

Cc: Vassili Karpov (malc) 
Signed-off-by: Roger Pau Monne 
---
 audio/mixeng_template.h |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
index e644c23..33e6b61 100644
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -27,6 +27,18 @@
  * dec++'ified by Dscho
  */
 
+/*
+ * Remove definitions of types, to prevent expansion in "glue" macro.
+ * This is needed at least for NetBSD, but any operating system that
+ * has those defines will probably cause trouble.
+ */
+#undef int8_t
+#undef uint8_t
+#undef int16_t
+#undef uint16_t
+#undef int32_t
+#undef uint32_t
+
 #ifndef SIGNED
 #define HALF (IN_MAX >> 1)
 #endif
-- 
1.7.7.5 (Apple Git-26)




Re: [Qemu-devel] [PATCH] audio: fix bug in mixeng_template.h build on NetBSD

2012-05-14 Thread Roger Pau Monne

malc escribió:

On Fri, 11 May 2012, Roger Pau Monne wrote:


This is a bug fix for rc1, although I think this bug has been present
for a long time.


If there's a bug than it's within NetBSD itself, this issue has been
discussed few times (at least twice it hink) in the past, please search
the ML archives.

[..snip..]



Hello,

I've found

http://copilotco.com/mail-archives/qemu.2008/msg11157.html

and

http://lists.gnu.org/archive/html/qemu-devel/2009-09/msg00255.html

But none of them seems to reach a conclusion about how to solve this. 
The standard regarding stdint.h doesn't forbid having this types defined 
as both typedefs and preprocessor macros, so I don't think this is a 
NetBSD bug. As far as I can see, we have at least three ways of solving 
this:


 - Undef the macros.
 - Use something like concat(conv_natural_, uint8_t, _to_mono) (as done 
on the second thread I've posted).

 - Pass two separate arguments; instead of using:

#define IN_T uint8_t

use something like:

#define BSIZE 8
#define ITYPE uint

But this will probably introduce quite some modifications.

Anyway, how do you think it's best to solve this?

Regards, Roger.




[Qemu-devel] [PATCH] audio: split IN_T into two separate constants

2012-05-18 Thread Roger Pau Monne
Split IN_T into BSIZE and ITYPE, to avoid expansion if the OS has
defined macros for the intX_t and uintX_t types. The IN_T constant is
then defined in mixeng_template.h so it can be used by the
functions/macros on this header file.

This change has been tested successfully under Debian Linux and NetBSD
6.0BETA.

Cc: Vassili Karpov (malc) 
Signed-off-by: Roger Pau Monne 
---
 audio/mixeng.c  |   36 
 audio/mixeng_template.h |4 +++-
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/audio/mixeng.c b/audio/mixeng.c
index 5446be6..02a9d9f 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -33,7 +33,8 @@
 #define ENDIAN_CONVERT(v) (v)
 
 /* Signed 8 bit */
-#define IN_T int8_t
+#define BSIZE 8
+#define ITYPE int
 #define IN_MIN SCHAR_MIN
 #define IN_MAX SCHAR_MAX
 #define SIGNED
@@ -42,25 +43,29 @@
 #undef SIGNED
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 /* Unsigned 8 bit */
-#define IN_T uint8_t
+#define BSIZE 8
+#define ITYPE uint
 #define IN_MIN 0
 #define IN_MAX UCHAR_MAX
 #define SHIFT 8
 #include "mixeng_template.h"
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 #undef ENDIAN_CONVERT
 #undef ENDIAN_CONVERSION
 
 /* Signed 16 bit */
-#define IN_T int16_t
+#define BSIZE 16
+#define ITYPE int
 #define IN_MIN SHRT_MIN
 #define IN_MAX SHRT_MAX
 #define SIGNED
@@ -78,11 +83,13 @@
 #undef SIGNED
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 /* Unsigned 16 bit */
-#define IN_T uint16_t
+#define BSIZE 16
+#define ITYPE uint
 #define IN_MIN 0
 #define IN_MAX USHRT_MAX
 #define SHIFT 16
@@ -98,11 +105,13 @@
 #undef ENDIAN_CONVERSION
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 /* Signed 32 bit */
-#define IN_T int32_t
+#define BSIZE 32
+#define ITYPE int
 #define IN_MIN INT32_MIN
 #define IN_MAX INT32_MAX
 #define SIGNED
@@ -120,11 +129,13 @@
 #undef SIGNED
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 /* Unsigned 32 bit */
-#define IN_T uint32_t
+#define BSIZE 32
+#define ITYPE uint
 #define IN_MIN 0
 #define IN_MAX UINT32_MAX
 #define SHIFT 32
@@ -140,7 +151,8 @@
 #undef ENDIAN_CONVERSION
 #undef IN_MAX
 #undef IN_MIN
-#undef IN_T
+#undef BSIZE
+#undef ITYPE
 #undef SHIFT
 
 t_sample *mixeng_conv[2][2][2][3] = {
diff --git a/audio/mixeng_template.h b/audio/mixeng_template.h
index e644c23..30849a6 100644
--- a/audio/mixeng_template.h
+++ b/audio/mixeng_template.h
@@ -31,7 +31,8 @@
 #define HALF (IN_MAX >> 1)
 #endif
 
-#define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
+#define ET glue (ENDIAN_CONVERSION, glue (glue (glue (_, ITYPE), BSIZE), _t))
+#define IN_T glue (glue (ITYPE, BSIZE), _t)
 
 #ifdef FLOAT_MIXENG
 static mixeng_real inline glue (conv_, ET) (IN_T v)
@@ -150,3 +151,4 @@ static void glue (glue (clip_, ET), _from_mono)
 
 #undef ET
 #undef HALF
+#undef IN_T
-- 
1.7.7.5 (Apple Git-26)




Re: [Qemu-devel] [PATCH] audio: split IN_T into two separate constants

2012-05-18 Thread Roger Pau Monne

malc wrote:

On Fri, 18 May 2012, Roger Pau Monne wrote:


Split IN_T into BSIZE and ITYPE, to avoid expansion if the OS has
defined macros for the intX_t and uintX_t types. The IN_T constant is
then defined in mixeng_template.h so it can be used by the
functions/macros on this header file.

This change has been tested successfully under Debian Linux and NetBSD
6.0BETA.



Applied.


Thanks!




[Qemu-devel] [PATCH] qemu-xen: make use of xenstore relative paths

2013-09-18 Thread Roger Pau Monne
Qemu has several hardcoded xenstore paths that are only valid on Dom0.
Attempts to launch a Qemu instance (to act as a userspace backend for
PV disks) will fail because Qemu is not able to access those paths
when running on a domain different than Dom0.

Instead make the xenstore paths relative to the domain where Qemu is
actually running.

Signed-off-by: Roger Pau Monné 
Cc: xen-de...@lists.xenproject.org
Cc: Anthony PERARD 
Cc: Stefano Stabellini 
---
 hw/xen_backend.c |   19 ++-
 xen-all.c|2 +-
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index 008cdb3..e220606 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -205,7 +205,6 @@ static struct XenDevice *xen_be_get_xendev(const char 
*type, int dom, int dev,
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
-char *dom0;
 
 xendev = xen_be_find_xendev(type, dom, dev);
 if (xendev) {
@@ -219,12 +218,10 @@ static struct XenDevice *xen_be_get_xendev(const char 
*type, int dom, int dev,
 xendev->dev   = dev;
 xendev->ops   = ops;
 
-dom0 = xs_get_domain_path(xenstore, 0);
-snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
- dom0, xendev->type, xendev->dom, xendev->dev);
+snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d",
+ xendev->type, xendev->dom, xendev->dev);
 snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
  xendev->type, xendev->dev);
-free(dom0);
 
 xendev->debug  = debug;
 xendev->local_port = -1;
@@ -570,14 +567,12 @@ static int xenstore_scan(const char *type, int dom, 
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
 char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
-char **dev = NULL, *dom0;
+char **dev = NULL;
 unsigned int cdev, j;
 
 /* setup watch */
-dom0 = xs_get_domain_path(xenstore, 0);
 snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
-snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
-free(dom0);
+snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 if (!xs_watch(xenstore, path, token)) {
 xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", 
path);
 return -1;
@@ -603,12 +598,10 @@ static void xenstore_update_be(char *watch, char *type, 
int dom,
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
-char path[XEN_BUFSIZE], *dom0, *bepath;
+char path[XEN_BUFSIZE], *bepath;
 unsigned int len, dev;
 
-dom0 = xs_get_domain_path(xenstore, 0);
-len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
-free(dom0);
+len = snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 if (strncmp(path, watch, len) != 0) {
 return;
 }
diff --git a/xen-all.c b/xen-all.c
index 15be8ed..99666f9 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -967,7 +967,7 @@ static void xenstore_record_dm_state(struct xs_handle *xs, 
const char *state)
 exit(1);
 }
 
-snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", 
xen_domid);
+snprintf(path, sizeof (path), "device-model/%u/state", xen_domid);
 if (!xs_write(xs, XBT_NULL, path, state, strlen(state))) {
 fprintf(stderr, "error recording dm state\n");
 exit(1);
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH v2] qemu/xen: make use of xenstore relative paths

2013-09-27 Thread Roger Pau Monne
Qemu has several hardcoded xenstore paths that are only valid on Dom0.
Attempts to launch a Qemu instance (to act as a userspace backend for
PV disks) will fail because Qemu is not able to access those paths
when running on a domain different than Dom0.

Instead make the xenstore paths relative to the domain where Qemu is
actually running.

Signed-off-by: Roger Pau Monné 
Reviewed-by: Anthony PERARD 
Cc: xen-de...@lists.xenproject.org
Cc: Anthony PERARD 
Cc: Stefano Stabellini 
---
Changes since v1:
 * Update paths to match upstream Qemu.
---
 hw/xen/xen_backend.c |   19 ++-
 xen-all.c|2 +-
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index d82ce5d..197795f 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -205,7 +205,6 @@ static struct XenDevice *xen_be_get_xendev(const char 
*type, int dom, int dev,
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
-char *dom0;
 
 xendev = xen_be_find_xendev(type, dom, dev);
 if (xendev) {
@@ -219,12 +218,10 @@ static struct XenDevice *xen_be_get_xendev(const char 
*type, int dom, int dev,
 xendev->dev   = dev;
 xendev->ops   = ops;
 
-dom0 = xs_get_domain_path(xenstore, 0);
-snprintf(xendev->be, sizeof(xendev->be), "%s/backend/%s/%d/%d",
- dom0, xendev->type, xendev->dom, xendev->dev);
+snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d",
+ xendev->type, xendev->dom, xendev->dev);
 snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
  xendev->type, xendev->dev);
-free(dom0);
 
 xendev->debug  = debug;
 xendev->local_port = -1;
@@ -570,14 +567,12 @@ static int xenstore_scan(const char *type, int dom, 
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
 char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
-char **dev = NULL, *dom0;
+char **dev = NULL;
 unsigned int cdev, j;
 
 /* setup watch */
-dom0 = xs_get_domain_path(xenstore, 0);
 snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
-snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
-free(dom0);
+snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 if (!xs_watch(xenstore, path, token)) {
 xen_be_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", 
path);
 return -1;
@@ -603,12 +598,10 @@ static void xenstore_update_be(char *watch, char *type, 
int dom,
struct XenDevOps *ops)
 {
 struct XenDevice *xendev;
-char path[XEN_BUFSIZE], *dom0, *bepath;
+char path[XEN_BUFSIZE], *bepath;
 unsigned int len, dev;
 
-dom0 = xs_get_domain_path(xenstore, 0);
-len = snprintf(path, sizeof(path), "%s/backend/%s/%d", dom0, type, dom);
-free(dom0);
+len = snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 if (strncmp(path, watch, len) != 0) {
 return;
 }
diff --git a/xen-all.c b/xen-all.c
index 839f14f..0504c45 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -948,7 +948,7 @@ static void xenstore_record_dm_state(struct xs_handle *xs, 
const char *state)
 exit(1);
 }
 
-snprintf(path, sizeof (path), "/local/domain/0/device-model/%u/state", 
xen_domid);
+snprintf(path, sizeof (path), "device-model/%u/state", xen_domid);
 if (!xs_write(xs, XBT_NULL, path, state, strlen(state))) {
 fprintf(stderr, "error recording dm state\n");
 exit(1);
-- 
1.7.7.5 (Apple Git-26)




[Qemu-devel] [PATCH] xen-mapcache: use MAP_FIXED flag so the mmap address hint is always honored

2019-03-15 Thread Roger Pau Monne
Or if it's not possible to honor the hinted address an error is returned
instead. This makes it easier to spot the actual failure, instead of
failing later on when the caller of xen_remap_bucket realizes the
mapping has not been created at the requested address.

Also note that at least on FreeBSD using MAP_FIXED will cause mmap to
try harder to honor the passed address.

Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: Igor Druzhinin 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: xen-de...@lists.xenproject.org
---
 hw/i386/xen/xen-mapcache.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 349f72d00c..0e2870b320 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -185,8 +185,14 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 }
 
 if (!dummy) {
+/*
+ * If the caller has requested the mapping at a specific address use
+ * MAP_FIXED to make sure it's honored. Note that with MAP_FIXED at
+ * least FreeBSD will try harder to honor the passed address.
+ */
 vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
-   PROT_READ | PROT_WRITE, 0,
+   PROT_READ | PROT_WRITE,
+   vaddr ? MAP_FIXED : 0,
nb_pfn, pfns, err);
 if (vaddr_base == NULL) {
 perror("xenforeignmemory_map2");
-- 
2.17.2 (Apple Git-113)




Re: [Qemu-devel] [PATCH 1/3] xen-disk: only advertize feature-persistent if grant copy is not available

2017-06-21 Thread Roger Pau Monne
On Wed, Jun 21, 2017 at 11:40:00AM +0100, Paul Durrant wrote:
> > -Original Message-
> > From: Qemu-devel [mailto:qemu-devel-
> > bounces+paul.durrant=citrix@nongnu.org] On Behalf Of Paul Durrant
> > Sent: 21 June 2017 10:36
> > To: Roger Pau Monne ; Stefano Stabellini
> > 
> > Cc: Kevin Wolf ; qemu-bl...@nongnu.org; qemu-
> > de...@nongnu.org; Max Reitz ; Anthony Perard
> > ; xen-de...@lists.xenproject.org
> > Subject: Re: [Qemu-devel] [PATCH 1/3] xen-disk: only advertize feature-
> > persistent if grant copy is not available
> > 
> > > -Original Message-
> > > From: Roger Pau Monne
> > > Sent: 21 June 2017 10:18
> > > To: Stefano Stabellini 
> > > Cc: Paul Durrant ; xen-
> > de...@lists.xenproject.org;
> > > qemu-devel@nongnu.org; qemu-bl...@nongnu.org; Anthony Perard
> > > ; Kevin Wolf ; Max
> > Reitz
> > > 
> > > Subject: Re: [PATCH 1/3] xen-disk: only advertize feature-persistent if
> > grant
> > > copy is not available
> > >
> > > On Tue, Jun 20, 2017 at 03:19:33PM -0700, Stefano Stabellini wrote:
> > > > On Tue, 20 Jun 2017, Paul Durrant wrote:
> > > > > If grant copy is available then it will always be used in preference 
> > > > > to
> > > > > persistent maps. In this case feature-persistent should not be
> > advertized
> > > > > to the frontend, otherwise it may needlessly copy data into 
> > > > > persistently
> > > > > granted buffers.
> > > > >
> > > > > Signed-off-by: Paul Durrant 
> > > >
> > > > CC'ing Roger.
> > > >
> > > > It is true that using feature-persistent together with grant copies is a
> > > > a very bad idea.
> > > >
> > > > But this change enstablishes an explicit preference of
> > > > feature_grant_copy over feature-persistent in the xen_disk backend. It
> > > > is not obvious to me that it should be the case.
> > > >
> > > > Why is feature_grant_copy (without feature-persistent) better than
> > > > feature-persistent (without feature_grant_copy)? Shouldn't we simply
> > > > avoid grant copies to copy data to persistent grants?
> > >
> > > When using persistent grants the frontend must always copy data from
> > > the buffer to the persistent grant, there's no way to avoid this.
> > >
> > > Using grant_copy we move the copy from the frontend to the backend,
> > > which means the CPU time of the copy is accounted to the backend. This
> > > is not ideal, but IMHO it's better than persistent grants because it
> > > avoids keeping a pool of mapped grants that consume memory and make
> > > the code more complex.
> > >
> > > Do you have some performance data showing the difference between
> > > persistent grants vs grant copy?
> > >
> > 
> > No, but I can get some :-)
> > 
> > For a little background... I've been trying to push throughput of fio 
> > running in
> > a debian stretch guest on my skull canyon NUC. When I started out, I was
> > getting ~100MBbs. When I finished, with this patch, the IOThreads one, the
> > multi-page ring one and a bit of hackery to turn off all the aio flushes 
> > that
> > seem to occur even if the image is opened with O_DIRECT, I was getting
> > ~960Mbps... which is about line rate for the SSD in the in NUC.
> > 
> > So, I'll force use of persistent grants on and see what sort of throughput I
> > get.
> 
> A quick test with grant copy forced off (causing persistent grants to be 
> used)... My VM is debian stretch using a 16 page shared ring from blkfront. 
> The image backing xvdb is a fully inflated 10G qcow2.
> 
> root@dhcp-237-70:~# fio --randrepeat=1 --ioengine=libaio --direct=0 
> --gtod_reduce=1 --name=test --filename=/dev/xvdb --bs=512k --iodepth=64 
> --size=10G --readwrite=randwrite --ramp_time=4
> test: (g=0): rw=randwrite, bs=512K-512K/512K-512K/512K-512K, ioengine=libaio, 
> iodepth=64
> fio-2.16
> Starting 1 process
> Jobs: 1 (f=1): [w(1)] [70.6% done] [0KB/539.4MB/0KB /s] [0/1078/0 iops] [eta 
> 00m:05s]
> test: (groupid=0, jobs=1): err= 0: pid=633: Wed Jun 21 06:26:06 2017
>   write: io=6146.6MB, bw=795905KB/s, iops=1546, runt=  7908msec
>   cpu  : usr=2.07%, sys=34.00%, ctx=4490, majf=0, minf=1
>   IO depths: 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.3%, >=64=166.9%
>  submit: 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0

[Qemu-devel] [PATCH QEMU] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
When a MSIX interrupt is bound to a guest using
xc_domain_update_msi_irq (XEN_DOMCTL_bind_pt_irq) the interrupt is
left masked by default.

This causes problems with guests that first configure interrupts and
clean the per-entry MSIX table mask bit and afterwards enable MSIX
globally. In such scenario the Xen internal msixtbl handlers would not
detect the unmasking of MSIX entries because vectors are not yet
registered since MSIX is not enabled, and vectors would be left
masked.

Introduce a new flag in the gflags field to signal Xen whether a MSIX
interrupt should be unmasked after being bound.

Signed-off-by: Roger Pau Monné 
Reported-by: Andreas Kinzler 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Jan Beulich 
Cc: qemu-devel@nongnu.org
---
 hw/xen/xen_pt_msi.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index ff9a79f5d2..c00ac2fd7d 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -24,6 +24,7 @@
 #define XEN_PT_GFLAGS_SHIFT_DM 9
 #define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
 #define XEN_PT_GFLAGSSHIFT_TRG_MODE   15
+#define XEN_PT_GFLAGSSHIFT_UNMASKED   16
 
 #define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
 
@@ -155,7 +156,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
int pirq,
bool is_msix,
int msix_entry,
-   int *old_pirq)
+   int *old_pirq,
+   bool masked)
 {
 PCIDevice *d = &s->dev;
 uint8_t gvec = msi_vector(data);
@@ -171,6 +173,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
 table_addr = s->msix->mmio_base_addr;
 }
 
+gflags |= masked ? 0 : (1u << XEN_PT_GFLAGSSHIFT_UNMASKED);
+
 rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
   pirq, gflags, table_addr);
 
@@ -274,7 +278,7 @@ int xen_pt_msi_update(XenPCIPassthroughState *s)
 {
 XenPTMSI *msi = s->msi;
 return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
-   false, 0, &msi->pirq);
+   false, 0, &msi->pirq, false);
 }
 
 void xen_pt_msi_disable(XenPCIPassthroughState *s)
@@ -355,7 +359,8 @@ static int xen_pt_msix_update_one(XenPCIPassthroughState 
*s, int entry_nr,
 }
 
 rc = msi_msix_update(s, entry->addr, entry->data, pirq, true,
- entry_nr, &entry->pirq);
+ entry_nr, &entry->pirq,
+ vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT);
 
 if (!rc) {
 entry->updated = false;
-- 
2.11.0 (Apple Git-81)




Re: [Qemu-devel] [PATCH QEMU] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
On Thu, Aug 24, 2017 at 03:54:21AM -0600, Jan Beulich wrote:
> >>> On 24.08.17 at 11:47,  wrote:
> > @@ -274,7 +278,7 @@ int xen_pt_msi_update(XenPCIPassthroughState *s)
> >  {
> >  XenPTMSI *msi = s->msi;
> >  return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
> > -   false, 0, &msi->pirq);
> > +   false, 0, &msi->pirq, false);
> >  }
> 
> I don't think this is correct when the device has mask bits.

Right, I thought I modified this. I've already changed
pt_irq_create_bind so that the original behavior is keep if the unmask
bit is not set. In this case this should be 'true' in order to keep
the previous behavior, which was correct for MSI.

It also makes me wonder whether it would be better to change the name
of the parameter to "unmask", so that false -> no change to mask, true
-> unconditionally unmask.

Thanks, Roger.



Re: [Qemu-devel] [PATCH QEMU] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
On Thu, Aug 24, 2017 at 04:13:58AM -0600, Jan Beulich wrote:
> >>> On 24.08.17 at 12:06,  wrote:
> > On Thu, Aug 24, 2017 at 03:54:21AM -0600, Jan Beulich wrote:
> >> >>> On 24.08.17 at 11:47,  wrote:
> >> > @@ -274,7 +278,7 @@ int xen_pt_msi_update(XenPCIPassthroughState *s)
> >> >  {
> >> >  XenPTMSI *msi = s->msi;
> >> >  return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
> >> > -   false, 0, &msi->pirq);
> >> > +   false, 0, &msi->pirq, false);
> >> >  }
> >> 
> >> I don't think this is correct when the device has mask bits.
> > 
> > Right, I thought I modified this. I've already changed
> > pt_irq_create_bind so that the original behavior is keep if the unmask
> > bit is not set. In this case this should be 'true' in order to keep
> > the previous behavior, which was correct for MSI.
> 
> Wouldn't you want to pass the state of the mask bit here,
> rather than uniformly hard coding true or false?

Yes, I think so. I've overlooked the MSI code because I thought we
allowed QEMU to directly write to the mask register, but that's not
true, it's trapped by Xen.

Thanks, Roger.



[Qemu-devel] [PATCH QEMU v2] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
When a MSI interrupt is bound to a guest using
xc_domain_update_msi_irq (XEN_DOMCTL_bind_pt_irq) the interrupt is
left masked by default.

This causes problems with guests that first configure interrupts and
clean the per-entry MSIX table mask bit and afterwards enable MSIX
globally. In such scenario the Xen internal msixtbl handlers would not
detect the unmasking of MSIX entries because vectors are not yet
registered since MSIX is not enabled, and vectors would be left
masked.

Introduce a new flag in the gflags field to signal Xen whether a MSI
interrupt should be unmasked after being bound.

This also requires to track the mask register for MSI interrupts, so
QEMU can also notify to Xen whether the MSI interrupt should be bound
masked or unmasked

Signed-off-by: Roger Pau Monné 
Reported-by: Andreas Kinzler 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Jan Beulich 
Cc: qemu-devel@nongnu.org
---
Changes since v1:
 - Track MSI mask bits.
 - Notify Xen of whether MSI interrupts should be unmasked after
   binding, instead of hardcoding it.
---
 hw/xen/xen_pt.h |  1 +
 hw/xen/xen_pt_config_init.c | 19 +--
 hw/xen/xen_pt_msi.c | 13 ++---
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea1..aa39a9aa5f 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -180,6 +180,7 @@ typedef struct XenPTMSI {
 uint32_t addr_hi;  /* guest message upper address */
 uint16_t data; /* guest message data */
 uint32_t ctrl_offset; /* saved control offset */
+uint32_t mask; /* guest mask bits */
 int pirq;  /* guest pirq corresponding */
 bool initialized;  /* when guest MSI is initialized */
 bool mapped;   /* when pirq is mapped */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 1f04ec5eec..9c724eeb62 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1315,6 +1315,21 @@ static int 
xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
 return 0;
 }
 
+static int xen_pt_mask_reg_write(XenPCIPassthroughState *s, XenPTReg 
*cfg_entry,
+ uint32_t *val, uint32_t dev_value,
+ uint32_t valid_mask)
+{
+int rc;
+
+rc = xen_pt_long_reg_write(s, cfg_entry, val, dev_value, valid_mask);
+if (rc)
+return rc;
+
+s->msi->mask = *val;
+
+return 0;
+}
+
 /* MSI Capability Structure reg static information table */
 static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 /* Next Pointer reg */
@@ -1393,7 +1408,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
 {
@@ -1404,7 +1419,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
 {
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index ff9a79f5d2..6d1e3bdeb4 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -24,6 +24,7 @@
 #define XEN_PT_GFLAGS_SHIFT_DM 9
 #define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
 #define XEN_PT_GFLAGSSHIFT_TRG_MODE   15
+#define XEN_PT_GFLAGSSHIFT_UNMASKED   16
 
 #define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
 
@@ -155,7 +156,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
int pirq,
bool is_msix,
int msix_entry,
-   int *old_pirq)
+   int *old_pirq,
+   bool masked)
 {
 PCIDevice *d = &s->dev;
 uint8_t gvec = msi_vector(data);
@@ -171,6 +173,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
 table_addr = s->msix->mmio_base_addr;
 }
 
+gflags |= masked ? 0 : (1u << XEN_PT_GFLAGSSHIFT_UNMASKED);
+
 rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
   pirq, gflags, table_addr);
 
@@ -273,8 +277,10 @@ int xen_pt_msi_setup(XenPCIPassthroughState *s)
 int xen_pt_msi_update(XenPCIPassthroughState *s)
 {
 XenPTMSI *msi = s->msi;
+
+/* Current MSI emulation in QEMU only supports 1 vector */
 return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
-   false, 0, &msi->pirq);
+   false, 0, &msi->pirq, msi->mask & 1);
 }
 
 void xen_pt_msi_disable(XenPCIPassthroughState *s)
@@ -355,7 +361,8 @@ static int xen_pt_msix_update_one(XenPCIP

Re: [Qemu-devel] [PATCH QEMU v2] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
On Thu, Aug 24, 2017 at 07:09:08AM -0600, Jan Beulich wrote:
> >>> On 24.08.17 at 14:19,  wrote:
> > When a MSI interrupt is bound to a guest using
> > xc_domain_update_msi_irq (XEN_DOMCTL_bind_pt_irq) the interrupt is
> > left masked by default.
> > 
> > This causes problems with guests that first configure interrupts and
> > clean the per-entry MSIX table mask bit and afterwards enable MSIX
> > globally. In such scenario the Xen internal msixtbl handlers would not
> > detect the unmasking of MSIX entries because vectors are not yet
> > registered since MSIX is not enabled, and vectors would be left
> > masked.
> > 
> > Introduce a new flag in the gflags field to signal Xen whether a MSI
> > interrupt should be unmasked after being bound.
> > 
> > This also requires to track the mask register for MSI interrupts, so
> > QEMU can also notify to Xen whether the MSI interrupt should be bound
> > masked or unmasked
> > 
> > Signed-off-by: Roger Pau Monné 
> > Reported-by: Andreas Kinzler 
> 
> Reviewed-by: Jan Beulich 

Thanks, Roger.



[Qemu-devel] [PATCH QEMU v3] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
When a MSI interrupt is bound to a guest using
xc_domain_update_msi_irq (XEN_DOMCTL_bind_pt_irq) the interrupt is
left masked by default.

This causes problems with guests that first configure interrupts and
clean the per-entry MSIX table mask bit and afterwards enable MSIX
globally. In such scenario the Xen internal msixtbl handlers would not
detect the unmasking of MSIX entries because vectors are not yet
registered since MSIX is not enabled, and vectors would be left
masked.

Introduce a new flag in the gflags field to signal Xen whether a MSI
interrupt should be unmasked after being bound.

This also requires to track the mask register for MSI interrupts, so
QEMU can also notify to Xen whether the MSI interrupt should be bound
masked or unmasked

Signed-off-by: Roger Pau Monné 
Reviewed-by: Jan Beulich 
Reported-by: Andreas Kinzler 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Jan Beulich 
Cc: qemu-devel@nongnu.org
---
Changes since v2:
 - Fix coding style.

Changes since v1:
 - Track MSI mask bits.
 - Notify Xen of whether MSI interrupts should be unmasked after
   binding, instead of hardcoding it.
---
 hw/xen/xen_pt.h |  1 +
 hw/xen/xen_pt_config_init.c | 19 +--
 hw/xen/xen_pt_msi.c | 13 ++---
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea1..aa39a9aa5f 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -180,6 +180,7 @@ typedef struct XenPTMSI {
 uint32_t addr_hi;  /* guest message upper address */
 uint16_t data; /* guest message data */
 uint32_t ctrl_offset; /* saved control offset */
+uint32_t mask; /* guest mask bits */
 int pirq;  /* guest pirq corresponding */
 bool initialized;  /* when guest MSI is initialized */
 bool mapped;   /* when pirq is mapped */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 1f04ec5eec..9c724eeb62 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1315,6 +1315,21 @@ static int 
xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
 return 0;
 }
 
+static int xen_pt_mask_reg_write(XenPCIPassthroughState *s, XenPTReg 
*cfg_entry,
+ uint32_t *val, uint32_t dev_value,
+ uint32_t valid_mask)
+{
+int rc;
+
+rc = xen_pt_long_reg_write(s, cfg_entry, val, dev_value, valid_mask);
+if (rc)
+return rc;
+
+s->msi->mask = *val;
+
+return 0;
+}
+
 /* MSI Capability Structure reg static information table */
 static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 /* Next Pointer reg */
@@ -1393,7 +1408,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
 {
@@ -1404,7 +1419,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
 {
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index ff9a79f5d2..6d1e3bdeb4 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -24,6 +24,7 @@
 #define XEN_PT_GFLAGS_SHIFT_DM 9
 #define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
 #define XEN_PT_GFLAGSSHIFT_TRG_MODE   15
+#define XEN_PT_GFLAGSSHIFT_UNMASKED   16
 
 #define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
 
@@ -155,7 +156,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
int pirq,
bool is_msix,
int msix_entry,
-   int *old_pirq)
+   int *old_pirq,
+   bool masked)
 {
 PCIDevice *d = &s->dev;
 uint8_t gvec = msi_vector(data);
@@ -171,6 +173,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
 table_addr = s->msix->mmio_base_addr;
 }
 
+gflags |= masked ? 0 : (1u << XEN_PT_GFLAGSSHIFT_UNMASKED);
+
 rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
   pirq, gflags, table_addr);
 
@@ -273,8 +277,10 @@ int xen_pt_msi_setup(XenPCIPassthroughState *s)
 int xen_pt_msi_update(XenPCIPassthroughState *s)
 {
 XenPTMSI *msi = s->msi;
+
+/* Current MSI emulation in QEMU only supports 1 vector */
 return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
-   false, 0, &msi->pirq);
+   false, 0, &msi->pirq, msi->mask & 1);
 }
 
 void xen_pt_msi_disable(XenPCIPassthroughState

[Qemu-devel] [PATCH QEMU v4] xen/pt: allow QEMU to request MSI unmasking at bind time

2017-08-24 Thread Roger Pau Monne
When a MSI interrupt is bound to a guest using
xc_domain_update_msi_irq (XEN_DOMCTL_bind_pt_irq) the interrupt is
left masked by default.

This causes problems with guests that first configure interrupts and
clean the per-entry MSIX table mask bit and afterwards enable MSIX
globally. In such scenario the Xen internal msixtbl handlers would not
detect the unmasking of MSIX entries because vectors are not yet
registered since MSIX is not enabled, and vectors would be left
masked.

Introduce a new flag in the gflags field to signal Xen whether a MSI
interrupt should be unmasked after being bound.

This also requires to track the mask register for MSI interrupts, so
QEMU can also notify to Xen whether the MSI interrupt should be bound
masked or unmasked

Signed-off-by: Roger Pau Monné 
Reviewed-by: Jan Beulich 
Reported-by: Andreas Kinzler 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Jan Beulich 
Cc: qemu-devel@nongnu.org
---
Changes since v2:
 - Fix coding style.

Changes since v1:
 - Track MSI mask bits.
 - Notify Xen of whether MSI interrupts should be unmasked after
   binding, instead of hardcoding it.
---
 hw/xen/xen_pt.h |  1 +
 hw/xen/xen_pt_config_init.c | 20 ++--
 hw/xen/xen_pt_msi.c | 13 ++---
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea1..aa39a9aa5f 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -180,6 +180,7 @@ typedef struct XenPTMSI {
 uint32_t addr_hi;  /* guest message upper address */
 uint16_t data; /* guest message data */
 uint32_t ctrl_offset; /* saved control offset */
+uint32_t mask; /* guest mask bits */
 int pirq;  /* guest pirq corresponding */
 bool initialized;  /* when guest MSI is initialized */
 bool mapped;   /* when pirq is mapped */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 1f04ec5eec..a3ce33e78b 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -1315,6 +1315,22 @@ static int 
xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
 return 0;
 }
 
+static int xen_pt_mask_reg_write(XenPCIPassthroughState *s, XenPTReg 
*cfg_entry,
+ uint32_t *val, uint32_t dev_value,
+ uint32_t valid_mask)
+{
+int rc;
+
+rc = xen_pt_long_reg_write(s, cfg_entry, val, dev_value, valid_mask);
+if (rc) {
+return rc;
+}
+
+s->msi->mask = *val;
+
+return 0;
+}
+
 /* MSI Capability Structure reg static information table */
 static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 /* Next Pointer reg */
@@ -1393,7 +1409,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
 {
@@ -1404,7 +1420,7 @@ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
 .emu_mask   = 0x,
 .init   = xen_pt_mask_reg_init,
 .u.dw.read  = xen_pt_long_reg_read,
-.u.dw.write = xen_pt_long_reg_write,
+.u.dw.write = xen_pt_mask_reg_write,
 },
 /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
 {
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index ff9a79f5d2..6d1e3bdeb4 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -24,6 +24,7 @@
 #define XEN_PT_GFLAGS_SHIFT_DM 9
 #define XEN_PT_GFLAGSSHIFT_DELIV_MODE 12
 #define XEN_PT_GFLAGSSHIFT_TRG_MODE   15
+#define XEN_PT_GFLAGSSHIFT_UNMASKED   16
 
 #define latch(fld) latch[PCI_MSIX_ENTRY_##fld / sizeof(uint32_t)]
 
@@ -155,7 +156,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
int pirq,
bool is_msix,
int msix_entry,
-   int *old_pirq)
+   int *old_pirq,
+   bool masked)
 {
 PCIDevice *d = &s->dev;
 uint8_t gvec = msi_vector(data);
@@ -171,6 +173,8 @@ static int msi_msix_update(XenPCIPassthroughState *s,
 table_addr = s->msix->mmio_base_addr;
 }
 
+gflags |= masked ? 0 : (1u << XEN_PT_GFLAGSSHIFT_UNMASKED);
+
 rc = xc_domain_update_msi_irq(xen_xc, xen_domid, gvec,
   pirq, gflags, table_addr);
 
@@ -273,8 +277,10 @@ int xen_pt_msi_setup(XenPCIPassthroughState *s)
 int xen_pt_msi_update(XenPCIPassthroughState *s)
 {
 XenPTMSI *msi = s->msi;
+
+/* Current MSI emulation in QEMU only supports 1 vector */
 return msi_msix_update(s, msi_addr64(msi), msi->data, msi->pirq,
-   false, 0, &msi->pirq);
+   false, 0, &msi->pirq, msi->mask & 1);
 }
 
 void xen_pt_msi_disable(XenPCIPassth

[PATCH] qemu-user: fix build with LLVM lld 10

2020-03-26 Thread Roger Pau Monne
lld 10.0.0 introduced a new linker option --image-base equivalent to
the GNU -Ttext-segment one, hence use it when available.

This fixes the build of QEMU on systems using lld 10 or greater.

Signed-off-by: Dimitry Andric 
Signed-off-by: Roger Pau Monné 
---
Cc: Laurent Vivier 
Cc: Richard Henderson 
Cc: "Philippe Mathieu-Daudé" 
Cc: Paolo Bonzini 
Cc: "Daniel P. Berrangé" 
---
 configure | 42 +++---
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/configure b/configure
index da09c35895..92d57d84fa 100755
--- a/configure
+++ b/configure
@@ -6514,27 +6514,31 @@ if ( [ "$linux_user" = yes ] || [ "$bsd_user" = yes ] ) 
&& [ "$pie" = no ]; then
 cat > $TMPC &1; then
-error_exit \
-"We need to link the QEMU user mode binaries at a" \
-"specific text address. Unfortunately your linker" \
-"doesn't support either the -Ttext-segment option or" \
-"printing the default linker script with --verbose." \
-"If you don't want the user mode binaries, pass the" \
-"--disable-user option to configure."
-  fi
+  textseg_ldflags="-Wl,-Ttext-segment=$textseg_addr"
+  if ! compile_prog "" "$textseg_ldflags"; then
+# In case ld does not support -Ttext-segment, edit the default linker
+# script via sed to set the .text start addr.  This is needed on 
FreeBSD
+# at least.
+if ! $ld --verbose >/dev/null 2>&1; then
+  error_exit \
+  "We need to link the QEMU user mode binaries at a" \
+  "specific text address. Unfortunately your linker" \
+  "doesn't support either the --image-base or -Ttext-segment" \
+  "options or printing the default linker script with" \
+  "--verbose. If you don't want the user mode binaries," \
+  "pass the --disable-user option to configure."
+fi
 
-  $ld --verbose | sed \
--e '1,/==/d' \
--e '/==/,$d' \
--e "s/[.] = [0-9a-fx]* [+] SIZEOF_HEADERS/. = $textseg_addr + 
SIZEOF_HEADERS/" \
--e "s/__executable_start = [0-9a-fx]*/__executable_start = 
$textseg_addr/" > config-host.ld
-  textseg_ldflags="-Wl,-T../config-host.ld"
+$ld --verbose | sed \
+  -e '1,/==/d' \
+  -e '/==/,$d' \
+  -e "s/[.] = [0-9a-fx]* [+] SIZEOF_HEADERS/. = $textseg_addr + 
SIZEOF_HEADERS/" \
+  -e "s/__executable_start = [0-9a-fx]*/__executable_start = 
$textseg_addr/" > config-host.ld
+textseg_ldflags="-Wl,-T../config-host.ld"
+  fi
 fi
   fi
 fi
-- 
2.26.0




[PATCH] xen: fix build without pci passthrough

2020-05-04 Thread Roger Pau Monne
has_igd_gfx_passthru is only available when QEMU is built with
CONFIG_XEN_PCI_PASSTHROUGH, and hence shouldn't be used in common
code without checking if it's available.

Fixes: 46472d82322d0 ('xen: convert "-machine igd-passthru" to an accelerator 
property')
Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: xen-de...@lists.xenproject.org
---
 hw/xen/xen-common.c | 4 
 hw/xen/xen_pt.h | 7 +++
 2 files changed, 11 insertions(+)

diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index a15070f7f6..c800862419 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -127,6 +127,7 @@ static void xen_change_state_handler(void *opaque, int 
running,
 }
 }
 
+#ifdef CONFIG_XEN_PCI_PASSTHROUGH
 static bool xen_get_igd_gfx_passthru(Object *obj, Error **errp)
 {
 return has_igd_gfx_passthru;
@@ -136,6 +137,7 @@ static void xen_set_igd_gfx_passthru(Object *obj, bool 
value, Error **errp)
 {
 has_igd_gfx_passthru = value;
 }
+#endif
 
 static void xen_setup_post(MachineState *ms, AccelState *accel)
 {
@@ -197,11 +199,13 @@ static void xen_accel_class_init(ObjectClass *oc, void 
*data)
 
 compat_props_add(ac->compat_props, compat, G_N_ELEMENTS(compat));
 
+#ifdef CONFIG_XEN_PCI_PASSTHROUGH
 object_class_property_add_bool(oc, "igd-passthru",
 xen_get_igd_gfx_passthru, xen_set_igd_gfx_passthru,
 &error_abort);
 object_class_property_set_description(oc, "igd-passthru",
 "Set on/off to enable/disable igd passthrou", &error_abort);
+#endif
 }
 
 #define TYPE_XEN_ACCEL ACCEL_CLASS_NAME("xen")
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 179775db7b..660dd8a008 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -1,6 +1,7 @@
 #ifndef XEN_PT_H
 #define XEN_PT_H
 
+#include "qemu/osdep.h"
 #include "hw/xen/xen_common.h"
 #include "hw/pci/pci.h"
 #include "xen-host-pci-device.h"
@@ -322,7 +323,13 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
 unsigned int domain,
 unsigned int bus, unsigned int 
slot,
 unsigned int function);
+
+#ifdef CONFIG_XEN_PCI_PASSTHROUGH
 extern bool has_igd_gfx_passthru;
+#else
+# define has_igd_gfx_passthru false
+#endif
+
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
 return (has_igd_gfx_passthru
-- 
2.26.2




[PATCH v2] xen: fix build without pci passthrough

2020-05-19 Thread Roger Pau Monne
has_igd_gfx_passthru is only available when QEMU is built with
CONFIG_XEN_PCI_PASSTHROUGH, and hence shouldn't be used in common
code without checking if it's available.

Fixes: 46472d82322d0 ('xen: convert "-machine igd-passthru" to an accelerator 
property')
Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: xen-de...@lists.xenproject.org
---
Changes since v1:
 - Do not include osdep in header file.
 - Always add the setters/getters of igd-passthru, report an error
   when attempting to set igd-passthru without built in
   pci-passthrough support.
---
 hw/xen/xen-common.c | 4 
 hw/xen/xen_pt.h | 6 ++
 2 files changed, 10 insertions(+)

diff --git a/hw/xen/xen-common.c b/hw/xen/xen-common.c
index 70564cc952..d758770da0 100644
--- a/hw/xen/xen-common.c
+++ b/hw/xen/xen-common.c
@@ -134,7 +134,11 @@ static bool xen_get_igd_gfx_passthru(Object *obj, Error 
**errp)
 
 static void xen_set_igd_gfx_passthru(Object *obj, bool value, Error **errp)
 {
+#ifdef CONFIG_XEN_PCI_PASSTHROUGH
 has_igd_gfx_passthru = value;
+#else
+error_setg(errp, "Xen PCI passthrough support not built in");
+#endif
 }
 
 static void xen_setup_post(MachineState *ms, AccelState *accel)
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 179775db7b..7430235a27 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -322,7 +322,13 @@ extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
 unsigned int domain,
 unsigned int bus, unsigned int 
slot,
 unsigned int function);
+
+#ifdef CONFIG_XEN_PCI_PASSTHROUGH
 extern bool has_igd_gfx_passthru;
+#else
+# define has_igd_gfx_passthru false
+#endif
+
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
 return (has_igd_gfx_passthru
-- 
2.26.2




[Qemu-devel] [PATCH v2] xen-mapcache: use MAP_FIXED flag so the mmap address hint is always honored

2019-03-18 Thread Roger Pau Monne
Or if it's not possible to honor the hinted address an error is returned
instead. This makes it easier to spot the actual failure, instead of
failing later on when the caller of xen_remap_bucket realizes the
mapping has not been created at the requested address.

Also note that at least on FreeBSD using MAP_FIXED will cause mmap to
try harder to honor the passed address.

Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: Igor Druzhinin 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: xen-de...@lists.xenproject.org
---
Changes since v1:
 - Use MAP_FIXED for the dummy mmap call also if a specific virtual
   address is requested.
---
 hw/i386/xen/xen-mapcache.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 349f72d00c..23de5517db 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -185,8 +185,13 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 }
 
 if (!dummy) {
+/*
+ * If the caller has requested the mapping at a specific address use
+ * MAP_FIXED to make sure it's honored.
+ */
 vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
-   PROT_READ | PROT_WRITE, 0,
+   PROT_READ | PROT_WRITE,
+   vaddr ? MAP_FIXED : 0,
nb_pfn, pfns, err);
 if (vaddr_base == NULL) {
 perror("xenforeignmemory_map2");
@@ -198,7 +203,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
  * mapping immediately due to certain circumstances (i.e. on resume 
now)
  */
 vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE,
-  MAP_ANON | MAP_SHARED, -1, 0);
+  MAP_ANON | MAP_SHARED | (vaddr ? MAP_FIXED : 0),
+  -1, 0);
 if (vaddr_base == MAP_FAILED) {
 perror("mmap");
 exit(-1);
-- 
2.17.2 (Apple Git-113)




[Qemu-devel] [PATCH v3] xen-mapcache: use MAP_FIXED flag so the mmap address hint is always honored

2019-03-18 Thread Roger Pau Monne
Or if it's not possible to honor the hinted address an error is returned
instead. This makes it easier to spot the actual failure, instead of
failing later on when the caller of xen_remap_bucket realizes the
mapping has not been created at the requested address.

Also note that at least on FreeBSD using MAP_FIXED will cause mmap to
try harder to honor the passed address.

Signed-off-by: Roger Pau Monné 
Reviewed-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paul Durrant 
Cc: Igor Druzhinin 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: xen-de...@lists.xenproject.org
---
Changes since v2:
 - Move comment position.

Changes since v1:
 - Use MAP_FIXED for the dummy mmap call also if a specific virtual
   address is requested.
---
 hw/i386/xen/xen-mapcache.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/i386/xen/xen-mapcache.c b/hw/i386/xen/xen-mapcache.c
index 349f72d00c..254759f776 100644
--- a/hw/i386/xen/xen-mapcache.c
+++ b/hw/i386/xen/xen-mapcache.c
@@ -184,9 +184,14 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
 }
 
+/*
+ * If the caller has requested the mapping at a specific address use
+ * MAP_FIXED to make sure it's honored.
+ */
 if (!dummy) {
 vaddr_base = xenforeignmemory_map2(xen_fmem, xen_domid, vaddr,
-   PROT_READ | PROT_WRITE, 0,
+   PROT_READ | PROT_WRITE,
+   vaddr ? MAP_FIXED : 0,
nb_pfn, pfns, err);
 if (vaddr_base == NULL) {
 perror("xenforeignmemory_map2");
@@ -198,7 +203,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
  * mapping immediately due to certain circumstances (i.e. on resume 
now)
  */
 vaddr_base = mmap(vaddr, size, PROT_READ | PROT_WRITE,
-  MAP_ANON | MAP_SHARED, -1, 0);
+  MAP_ANON | MAP_SHARED | (vaddr ? MAP_FIXED : 0),
+  -1, 0);
 if (vaddr_base == MAP_FAILED) {
 perror("mmap");
 exit(-1);
-- 
2.17.2 (Apple Git-113)




[PATCH 0/2] xen: error handling and FreeBSD compatibility fixes

2025-01-07 Thread Roger Pau Monne
Hello,

First patch fixes some error handling paths that incorrectly used
error_prepend() in the Xen console driver.  Second patch removes usage
of the 'm' character in scanf directives, as it's not supported on
FreeBSD (see usages of "%ms").

Thanks, Roger.

Roger Pau Monné (2):
  xen/console: fix error handling in xen_console_device_create()
  xen: do not use '%ms' scanf specifier

 hw/char/xen_console.c | 15 +++
 hw/xen/xen-bus.c  |  7 +--
 2 files changed, 16 insertions(+), 6 deletions(-)
-- 
2.46.0




[PATCH 2/2] xen: do not use '%ms' scanf specifier

2025-01-07 Thread Roger Pau Monne
The 'm' parameter used to request auto-allocation of the destination variable
is not supported on FreeBSD, and as such leads to failures to parse.

What's more, the current usage of '%ms' with xs_node_scanf() is pointless, as
it just leads to a double allocation of the same string.  Instead use
qemu_xen_xs_read() to read the whole xenstore node.

Fixes: a783f8ad4ec9 ('xen: add a mechanism to automatically create 
XenDevice-s...')
Fixes: 9b7737469080 ('hw/xen: update Xen console to XenDevice model')
Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
Cc: Paul Durrant 
Cc: "Edgar E. Iglesias" 
Cc: "Marc-André Lureau" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
---
 hw/char/xen_console.c | 11 +--
 hw/xen/xen-bus.c  |  7 +--
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index af706c7ef440..18afd214c2f6 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -531,6 +531,7 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 const char *name = xen_backend_get_name(backend);
 unsigned long number;
 char *fe = NULL, *type = NULL, *output = NULL;
+const char *node_path;
 char label[32];
 XenDevice *xendev = NULL;
 XenConsole *con;
@@ -550,7 +551,10 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 goto fail;
 }
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) {
+node_path = g_strdup_printf("%s/type", fe);
+type = qemu_xen_xs_read(xsh, XBT_NULL, node_path, NULL);
+g_free(node_path);
+if (!type) {
 error_setg(errp, "failed to read console device type: ");
 goto fail;
 }
@@ -568,7 +572,10 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 
 snprintf(label, sizeof(label), "xencons%ld", number);
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) 
{
+node_path = g_strdup_printf("%s/output", fe);
+output = qemu_xen_xs_read(xsh, XBT_NULL, node_path, NULL);
+g_free(node_path);
+if (!output) {
 /*
  * FIXME: sure we want to support implicit
  * muxed monitors here?
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index adfc4efad035..9be807649e77 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -142,6 +142,7 @@ again:
 
 opts = qdict_new();
 for (i = 0; i < n; i++) {
+const char *node_path;
 char *val;
 
 /*
@@ -156,8 +157,10 @@ again:
 !strcmp(key[i], "hotplug-status"))
 continue;
 
-if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
-  &val) == 1) {
+node_path = g_strdup_printf("%s/%s", path, key[i]);
+val = qemu_xen_xs_read(xenbus->xsh, tid, node_path, NULL);
+g_free(node_path);
+if (val) {
 qdict_put_str(opts, key[i], val);
 free(val);
 }
-- 
2.46.0




[PATCH 1/2] xen/console: fix error handling in xen_console_device_create()

2025-01-07 Thread Roger Pau Monne
The usage of error_prepend() in some of the error contexts of
xen_console_device_create() is incorrect, as `errp` hasn't been initialized.
This leads to the following segmentation fault on error paths resulting from
xenstore reads:

Program terminated with signal SIGSEGV, Segmentation fault.
Address not mapped to object.
fmt=0x15c4dfeade42 "failed to read console device type: ", 
ap=0x15cd0165ab50)
at ../qemu-xen-dir-remote/util/error.c:142
142 g_string_append(newmsg, (*errp)->msg);
[...]
(gdb) bt
(errp=0x15cd0165ae10, fmt=0x15c4dfeade42 "failed to read console device 
type: ", ap=0x15cd0165ab50) at ../qemu-xen-dir-remote/util/error.c:142
(errp=0x15cd0165ae10, fmt=0x15c4dfeade42 "failed to read console device 
type: ")
at ../qemu-xen-dir-remote/util/error.c:152
(backend=0x43944de00660, opts=0x43944c929000, errp=0x15cd0165ae10)
at ../qemu-xen-dir-remote/hw/char/xen_console.c:555

Replace usages of error_prepend() with error_setg() where appropriate.

Fixes: 9b7737469080 ('hw/xen: update Xen console to XenDevice model')
Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
Cc: Paul Durrant 
Cc: "Edgar E. Iglesias" 
Cc: "Marc-André Lureau" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
---
 hw/char/xen_console.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index ef0c2912efa1..af706c7ef440 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -551,7 +551,7 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 }
 
 if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) {
-error_prepend(errp, "failed to read console device type: ");
+error_setg(errp, "failed to read console device type: ");
 goto fail;
 }
 
@@ -582,7 +582,7 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 } else if (number) {
 cd = serial_hd(number);
 if (!cd) {
-error_prepend(errp, "console: No serial device #%ld found: ",
+error_setg(errp, "console: No serial device #%ld found: ",
   number);
 goto fail;
 }
-- 
2.46.0




[PATCH v2 2/2] xen: do not use '%ms' scanf specifier

2025-01-10 Thread Roger Pau Monne
The 'm' parameter used to request auto-allocation of the destination variable
is not supported on FreeBSD, and as such leads to failures to parse.

What's more, the current usage of '%ms' with xs_node_scanf() is pointless, as
it just leads to a double allocation of the same string.  Instead use
xs_node_read() to read the whole xenstore node.

Fixes: a783f8ad4ec9 ('xen: add a mechanism to automatically create 
XenDevice-s...')
Fixes: 9b7737469080 ('hw/xen: update Xen console to XenDevice model')
Signed-off-by: Roger Pau Monné 
---
Changes since v2:
 - New version of xs_node_read().
 - Fix usage of %ms in xen-block.c

Changes since v1:
 - Introduce xs_node_read() helper.
 - Merge with errp fixes.
---
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
Cc: Paul Durrant 
Cc: "Edgar E. Iglesias" 
Cc: Kevin Wolf 
Cc: Hanna Reitz 
Cc: "Marc-André Lureau" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
Cc: qemu-bl...@nongnu.org
---
 hw/block/xen-block.c |  3 ++-
 hw/char/xen_console.c|  6 --
 hw/xen/xen-bus.c | 14 --
 include/hw/xen/xen-bus.h |  1 +
 4 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index 306d38927cf4..034a18b70e28 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -239,7 +239,8 @@ static void xen_block_connect(XenDevice *xendev, Error 
**errp)
 return;
 }
 
-if (xen_device_frontend_scanf(xendev, "protocol", "%ms", &str) != 1) {
+str = xen_device_frontend_read(xendev, "protocol");
+if (!str) {
 /* x86 defaults to the 32-bit protocol even for 64-bit guests. */
 if (object_dynamic_cast(OBJECT(qdev_get_machine()), "x86-machine")) {
 protocol = BLKIF_PROTOCOL_X86_32;
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index ef0c2912efa1..989e75fef88f 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -550,7 +550,8 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 goto fail;
 }
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) {
+type = xs_node_read(xsh, XBT_NULL, NULL, errp, "%s/%s", fe, "type");
+if (!type) {
 error_prepend(errp, "failed to read console device type: ");
 goto fail;
 }
@@ -568,7 +569,8 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 
 snprintf(label, sizeof(label), "xencons%ld", number);
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) 
{
+output = xs_node_read(xsh, XBT_NULL, NULL, errp, "%s/%s", fe, "output");
+if (output) {
 /*
  * FIXME: sure we want to support implicit
  * muxed monitors here?
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index adfc4efad035..85b92cded4e2 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -156,8 +156,8 @@ again:
 !strcmp(key[i], "hotplug-status"))
 continue;
 
-if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
-  &val) == 1) {
+val = xs_node_read(xenbus->xsh, tid, NULL, NULL, "%s/%s", path, 
key[i]);
+if (val) {
 qdict_put_str(opts, key[i], val);
 free(val);
 }
@@ -650,6 +650,16 @@ int xen_device_frontend_scanf(XenDevice *xendev, const 
char *key,
 return rc;
 }
 
+char *xen_device_frontend_read(XenDevice *xendev, const char *key)
+{
+XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
+
+g_assert(xenbus->xsh);
+
+return xs_node_read(xenbus->xsh, XBT_NULL, NULL, NULL, "%s/%s",
+xendev->frontend_path, key);;
+}
+
 static void xen_device_frontend_set_state(XenDevice *xendev,
   enum xenbus_state state,
   bool publish)
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index 38d40afa3798..2adb2af83919 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -91,6 +91,7 @@ void xen_device_frontend_printf(XenDevice *xendev, const char 
*key,
 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
   const char *fmt, ...)
 G_GNUC_SCANF(3, 4);
+char *xen_device_frontend_read(XenDevice *xendev, const char *key);
 
 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
Error **errp);
-- 
2.46.0




[PATCH v2 1/2] hw/xen: Add xs_node_read() helper function

2025-01-10 Thread Roger Pau Monne
From: David Woodhouse 

This returns the full contents of the node, having created the node path
from the printf-style format string provided in its arguments.

This will save various callers from having to do so for themselves (and
from using xs_node_scanf() with the non-portable %ms format string.

Signed-off-by: David Woodhouse 
[remove double newline and constify trace parameters]
Signed-off-by: Roger Pau Monné 
---
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
Cc: Paul Durrant 
Cc: "Edgar E. Iglesias" 
Cc: xen-de...@lists.xenproject.org
---
 hw/xen/trace-events |  1 +
 hw/xen/xen-bus-helper.c | 22 ++
 include/hw/xen/xen-bus-helper.h |  4 
 3 files changed, 27 insertions(+)

diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index a07fe41c6d3b..461dee7b239f 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -39,6 +39,7 @@ xs_node_create(const char *node) "%s"
 xs_node_destroy(const char *node) "%s"
 xs_node_vprintf(char *path, char *value) "%s %s"
 xs_node_vscanf(char *path, char *value) "%s %s"
+xs_node_read(const char *path, const char *value) "%s %s"
 xs_node_watch(char *path) "%s"
 xs_node_unwatch(char *path) "%s"
 
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
index b2b2cc9c5d5e..0fba7946c55e 100644
--- a/hw/xen/xen-bus-helper.c
+++ b/hw/xen/xen-bus-helper.c
@@ -142,6 +142,28 @@ int xs_node_scanf(struct qemu_xs_handle *h,  
xs_transaction_t tid,
 return rc;
 }
 
+char *xs_node_read(struct qemu_xs_handle *h, xs_transaction_t tid,
+   unsigned int *len, Error **errp,
+   const char *node_fmt, ...)
+{
+char *path, *value;
+va_list ap;
+
+va_start(ap, node_fmt);
+path = g_strdup_vprintf(node_fmt, ap);
+va_end(ap);
+
+value = qemu_xen_xs_read(h, tid, path, len);
+trace_xs_node_read(path, value);
+if (!value) {
+error_setg_errno(errp, errno, "failed to read from '%s'", path);
+}
+
+g_free(path);
+
+return value;
+}
+
 struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node,
 const char *key, xs_watch_fn fn,
 void *opaque, Error **errp)
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
index d8dcc2f0107d..6478d25be5e6 100644
--- a/include/hw/xen/xen-bus-helper.h
+++ b/include/hw/xen/xen-bus-helper.h
@@ -37,6 +37,10 @@ int xs_node_scanf(struct qemu_xs_handle *h,  
xs_transaction_t tid,
   const char *node, const char *key, Error **errp,
   const char *fmt, ...)
 G_GNUC_SCANF(6, 7);
+char *xs_node_read(struct qemu_xs_handle *h, xs_transaction_t tid,
+   unsigned int *len, Error **errp,
+   const char *node_fmt, ...)
+G_GNUC_PRINTF(5, 6);
 
 /* Watch node/key unless node is empty, in which case watch key */
 struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node,
-- 
2.46.0




[PATCH v2 0/2] xen: error handling and FreeBSD compatibility fixes

2025-01-10 Thread Roger Pau Monne
Hello,

First patch from David introduces a new helper to fetch xenstore nodes,
while second patch removes the usage of scanf related functions with the
"%ms" format specifier, as it's not supported by the FreeBSD scanf libc
implementation.

Thanks, Roger.

David Woodhouse (1):
  hw/xen: Add xs_node_read() helper function

Roger Pau Monné (1):
  xen: do not use '%ms' scanf specifier

 hw/block/xen-block.c|  3 ++-
 hw/char/xen_console.c   | 14 --
 hw/xen/trace-events |  1 +
 hw/xen/xen-bus-helper.c | 22 ++
 hw/xen/xen-bus.c| 14 --
 include/hw/xen/xen-bus-helper.h |  4 
 include/hw/xen/xen-bus.h|  1 +
 7 files changed, 50 insertions(+), 9 deletions(-)

-- 
2.46.0




[PATCH v2] xen: do not use '%ms' scanf specifier

2025-01-09 Thread Roger Pau Monne
The 'm' parameter used to request auto-allocation of the destination variable
is not supported on FreeBSD, and as such leads to failures to parse.

What's more, the current usage of '%ms' with xs_node_scanf() is pointless, as
it just leads to a double allocation of the same string.  Instead introduce and
use xs_node_read() to read the whole xenstore node.

Additionally fix the errors paths to not use error_prepend(), as that could
lead to a segmentation fault because xs_node_scanf() only initializes errp when
returning a value smaller than 0:

Program terminated with signal SIGSEGV, Segmentation fault.
Address not mapped to object.
fmt=0x15c4dfeade42 "failed to read console device type: ", 
ap=0x15cd0165ab50)
at ../qemu-xen-dir-remote/util/error.c:142
142 g_string_append(newmsg, (*errp)->msg);
[...]
(gdb) bt
(errp=0x15cd0165ae10, fmt=0x15c4dfeade42 "failed to read console device 
type: ", ap=0x15cd0165ab50) at ../qemu-xen-dir-remote/util/error.c:142
(errp=0x15cd0165ae10, fmt=0x15c4dfeade42 "failed to read console device 
type: ")
at ../qemu-xen-dir-remote/util/error.c:152
(backend=0x43944de00660, opts=0x43944c929000, errp=0x15cd0165ae10)
at ../qemu-xen-dir-remote/hw/char/xen_console.c:555

With the change to use xs_node_read() instead of xs_node_scanf() errp will
never be initialized, and hence error_setg() should be used unconditionally.

Fixes: a783f8ad4ec9 ('xen: add a mechanism to automatically create 
XenDevice-s...')
Fixes: 9b7737469080 ('hw/xen: update Xen console to XenDevice model')
Signed-off-by: Roger Pau Monné 
---
Changes since v1:
 - Introduce xs_node_read() helper.
 - Merge with errp fixes.
---
Cc: Stefano Stabellini 
Cc: Anthony PERARD 
Cc: Paul Durrant 
Cc: "Edgar E. Iglesias" 
Cc: "Marc-André Lureau" 
Cc: Paolo Bonzini 
Cc: xen-de...@lists.xenproject.org
---
 hw/char/xen_console.c   | 12 +++-
 hw/xen/xen-bus-helper.c | 12 
 hw/xen/xen-bus.c|  4 ++--
 include/hw/xen/xen-bus-helper.h |  2 ++
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index ef0c2912efa1..a3591df1af2e 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -550,8 +550,9 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 goto fail;
 }
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) {
-error_prepend(errp, "failed to read console device type: ");
+type = xs_node_read(xsh, XBT_NULL, fe, "type");
+if (!type) {
+error_setg(errp, "failed to read console device type");
 goto fail;
 }
 
@@ -568,7 +569,8 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 
 snprintf(label, sizeof(label), "xencons%ld", number);
 
-if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) 
{
+output = xs_node_read(xsh, XBT_NULL, fe, "output");
+if (!output) {
 /*
  * FIXME: sure we want to support implicit
  * muxed monitors here?
@@ -582,8 +584,8 @@ static void xen_console_device_create(XenBackendInstance 
*backend,
 } else if (number) {
 cd = serial_hd(number);
 if (!cd) {
-error_prepend(errp, "console: No serial device #%ld found: ",
-  number);
+error_setg(errp, "console: No serial device #%ld found",
+   number);
 goto fail;
 }
 } else {
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
index b2b2cc9c5d5e..115c5b1a8ce8 100644
--- a/hw/xen/xen-bus-helper.c
+++ b/hw/xen/xen-bus-helper.c
@@ -142,6 +142,18 @@ int xs_node_scanf(struct qemu_xs_handle *h,  
xs_transaction_t tid,
 return rc;
 }
 
+char *xs_node_read(struct qemu_xs_handle *h, xs_transaction_t tid,
+   const char *node, const char *key)
+{
+char *path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key)
+ : g_strdup(key);
+char *value = qemu_xen_xs_read(h, tid, path, NULL);
+
+g_free(path);
+
+return value;
+}
+
 struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node,
 const char *key, xs_watch_fn fn,
 void *opaque, Error **errp)
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index adfc4efad035..aaede5d9ecb2 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -156,8 +156,8 @@ again:
 !strcmp(key[i], "hotplug-status"))
 continue;
 
-if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
-  &val) == 1) {
+val = xs_node_read(xenbus->xsh, tid, path, key[i]);
+if (val) {
 qdict_put_str(opts, key[i], val);
 free(val);
 }
diff --git a/include/hw/xen/xen-bus-helper.h b/include/hw/xen/xen-bus-helper.h
index d8dcc2f0107d..79f0787332ed 100644
--- a/include/h