Re: [Qemu-block] [Qemu-devel] [PATCH] nvme: fix out-of-bounds access to the CMB

2018-11-21 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20181120184148.22501-1-pbonz...@redhat.com
Type: series
Subject: [Qemu-devel] [PATCH] nvme: fix out-of-bounds access to the CMB

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag] patchew/1542868372-2602-1-git-send-email-liq...@gmail.com 
-> patchew/1542868372-2602-1-git-send-email-liq...@gmail.com
Switched to a new branch 'test'
506efa4 nvme: fix out-of-bounds access to the CMB

=== OUTPUT BEGIN ===
Checking PATCH 1/1: nvme: fix out-of-bounds access to the CMB...
ERROR: space required after that ',' (ctx:VxV)
#106: FILE: tests/nvme-test.c:53:
+pdev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
 ^

total: 1 errors, 0 warnings, 99 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-block] [PATCH] scsi-disk: Fix crash if underlying host file or disk returns error.

2018-11-21 Thread Paolo Bonzini
On 21/11/18 13:47, Richard W.M. Jones wrote:
> Commit 40dce4ee6 "scsi-disk: fix rerror/werror=ignore" introduced a
> bug which causes qemu to crash with the assertion error below if the
> host file or disk returns an error:
> 
>   qemu-system-x86_64: hw/scsi/scsi-bus.c:1374: scsi_req_complete:
>   Assertion `req->status == -1' failed.
> 
> Kevin Wolf suggested this fix:
> 
>   < kwolf> Hm, should the final return false; in that patch
>actually be a return true?
>   < kwolf> Because I think he didn't intend to change anything
>except BLOCK_ERROR_ACTION_IGNORE
> 
> Signed-off-by: Richard W.M. Jones 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1804323
> ---
>  hw/scsi/scsi-disk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
> index 6eb258d3f3..0e9027c8f3 100644
> --- a/hw/scsi/scsi-disk.c
> +++ b/hw/scsi/scsi-disk.c
> @@ -482,7 +482,7 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int 
> error, bool acct_failed)
>  if (action == BLOCK_ERROR_ACTION_STOP) {
>  scsi_req_retry(&r->req);
>  }
> -return false;
> +return true;
>  }
>  
>  static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
> 

Looks good.  I was confused because now the function always returns
true.  "If an arm was returning true, the other must be returning false...".

Paolo



[Qemu-block] [PATCH] hw/block/nvme: fix bug with PCI IRQ pins on teardown

2018-11-21 Thread Logan Gunthorpe
When the submission and completion queues are being torn down
the IRQ will be asserted for the completion queue when the
submsission queue is deleted. Then when the completion queue
is deleted it stays asserted. Thus, on systems that do
not use MSI, no further interrupts can be triggered on the host.

Linux sees this as a long delay when unbinding the nvme device.
Eventually the interrupt timeout occurs and it continues.

To fix this we ensure we deassert the IRQ for a CQ when it is
deleted.

Signed-off-by: Logan Gunthorpe 
---
 hw/block/nvme.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index fc7dacb816c8..7cbed75ce5fd 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -554,6 +554,7 @@ static uint16_t nvme_del_cq(NvmeCtrl *n, NvmeCmd *cmd)
 trace_nvme_err_invalid_del_cq_notempty(qid);
 return NVME_INVALID_QUEUE_DEL;
 }
+nvme_irq_deassert(n, cq);
 trace_nvme_del_cq(qid);
 nvme_free_cq(cq, n);
 return NVME_SUCCESS;
-- 
2.19.0




[Qemu-block] encrypt in threads

2018-11-21 Thread Vladimir Sementsov-Ogievskiy
Hi Daniel!

After moving compression to threads in Qcow2 it's an obvious next step to
"threadyfy" encryption in Qcow2 too.

But it turned out to be not as simple as I assumed. If I call 
qcrypto_block_encrypt
in parallel threads with the same first argument (block), it just produce wrong
things (pattern verification fails in iotests)..

So, can you advise the way to parallelize encryption/decryption?

-- 
Best regards,
Vladimir


Re: [Qemu-block] [Qemu-devel] [PATCH] tests: fix nbd test to work correctly with raw images

2018-11-21 Thread Kevin Wolf
[ Cc: qemu-block ]

Am 20.11.2018 um 18:56 hat Daniel P. Berrangé geschrieben:
> The first qemu-io command must honour the $IMGFMT that is set rather
> than hardcoding qcow2. The qemu-nbd commands should also set $IMGFMT
> to avoid the insecure format probe warning.
> 
> Signed-off-by: Daniel P. Berrangé 

Thanks, applied to the block branch.

Kevin



Re: [Qemu-block] [PATCH v5 00/16] Don't pass flags to bdrv_reopen_queue()

2018-11-21 Thread Kevin Wolf
Am 12.11.2018 um 15:00 hat Alberto Garcia geschrieben:
> Hi all,
> 
> when reopening a BlockDriverState using bdrv_reopen() and friends the
> new options can be specified either with a QDict or with flags. Both
> methods overlap and that makes the semantics and the implementation
> unnecessarily complicated.
> 
> This series removes the 'flags' parameter from these functions, so
> from now on all option changes must be specified using a QDict. Apart
> from simplifying the API, a few bugs are fixed along the way. See the
> individual patches for more details.
> 
> This was tested with the current master (460f0236c12a86a38692c12d9bf).

Thanks, applied patch 16 to block and the rest of the series to
block-next.

Kevin



[Qemu-block] [PATCH 12/18] xen: remove 'ioreq' struct/varable/field names from dataplane/xen-qdisk.c

2018-11-21 Thread Paul Durrant
This is a purely cosmetic patch that purges the name 'ioreq' from struct,
variable and field names. (This name has been problematic for a long time
as 'ioreq' is the name used for generic I/O requests coming from Xen).
The patch replaces 'struct ioreq' with a new 'XenQdiskRequest' type and
'ioreq' field/variable names with 'request', and then does necessary
fix-up to adhere to coding style.

Function names are not modified by this patch. Yhey will be dealt with in
a subsequent patch.

No functional change.

Signed-off-by: Paul Durrant 
---
Cc: Stefan Hajnoczi 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/dataplane/xen-qdisk.c | 310 +
 1 file changed, 156 insertions(+), 154 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 2214455ff9..50a48b6f5f 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -18,7 +18,7 @@
 #include "sysemu/iothread.h"
 #include "xen-qdisk.h"
 
-struct ioreq {
+typedef struct XenQdiskRequest {
 blkif_request_t req;
 int16_t status;
 off_t start;
@@ -29,9 +29,9 @@ struct ioreq {
 int aio_inflight;
 int aio_errors;
 XenQdiskDataPlane *dataplane;
-QLIST_ENTRY(ioreq) list;
+QLIST_ENTRY(XenQdiskRequest) list;
 BlockAcctCookie acct;
-};
+} XenQdiskRequest;
 
 struct XenQdiskDataPlane {
 XenDevice *xendev;
@@ -44,9 +44,9 @@ struct XenQdiskDataPlane {
 int protocol;
 blkif_back_rings_t rings;
 int more_work;
-QLIST_HEAD(inflight_head, ioreq) inflight;
-QLIST_HEAD(finished_head, ioreq) finished;
-QLIST_HEAD(freelist_head, ioreq) freelist;
+QLIST_HEAD(inflight_head, XenQdiskRequest) inflight;
+QLIST_HEAD(finished_head, XenQdiskRequest) finished;
+QLIST_HEAD(freelist_head, XenQdiskRequest) freelist;
 int requests_total;
 int requests_inflight;
 int requests_finished;
@@ -57,68 +57,68 @@ struct XenQdiskDataPlane {
 AioContext *ctx;
 };
 
-static void ioreq_reset(struct ioreq *ioreq)
+static void ioreq_reset(XenQdiskRequest *request)
 {
-memset(&ioreq->req, 0, sizeof(ioreq->req));
-ioreq->status = 0;
-ioreq->start = 0;
-ioreq->buf = NULL;
-ioreq->size = 0;
-ioreq->presync = 0;
+memset(&request->req, 0, sizeof(request->req));
+request->status = 0;
+request->start = 0;
+request->buf = NULL;
+request->size = 0;
+request->presync = 0;
 
-ioreq->aio_inflight = 0;
-ioreq->aio_errors = 0;
+request->aio_inflight = 0;
+request->aio_errors = 0;
 
-ioreq->dataplane = NULL;
-memset(&ioreq->list, 0, sizeof(ioreq->list));
-memset(&ioreq->acct, 0, sizeof(ioreq->acct));
+request->dataplane = NULL;
+memset(&request->list, 0, sizeof(request->list));
+memset(&request->acct, 0, sizeof(request->acct));
 
-qemu_iovec_reset(&ioreq->v);
+qemu_iovec_reset(&request->v);
 }
 
-static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
 {
-struct ioreq *ioreq = NULL;
+XenQdiskRequest *request = NULL;
 
 if (QLIST_EMPTY(&dataplane->freelist)) {
 if (dataplane->requests_total >= dataplane->max_requests) {
 goto out;
 }
 /* allocate new struct */
-ioreq = g_malloc0(sizeof(*ioreq));
-ioreq->dataplane = dataplane;
+request = g_malloc0(sizeof(*request));
+request->dataplane = dataplane;
 dataplane->requests_total++;
-qemu_iovec_init(&ioreq->v, 1);
+qemu_iovec_init(&request->v, 1);
 } else {
 /* get one from freelist */
-ioreq = QLIST_FIRST(&dataplane->freelist);
-QLIST_REMOVE(ioreq, list);
+request = QLIST_FIRST(&dataplane->freelist);
+QLIST_REMOVE(request, list);
 }
-QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+QLIST_INSERT_HEAD(&dataplane->inflight, request, list);
 dataplane->requests_inflight++;
 
 out:
-return ioreq;
+return request;
 }
 
-static void ioreq_finish(struct ioreq *ioreq)
+static void ioreq_finish(XenQdiskRequest *request)
 {
-XenQdiskDataPlane *dataplane = ioreq->dataplane;
+XenQdiskDataPlane *dataplane = request->dataplane;
 
-QLIST_REMOVE(ioreq, list);
-QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+QLIST_REMOVE(request, list);
+QLIST_INSERT_HEAD(&dataplane->finished, request, list);
 dataplane->requests_inflight--;
 dataplane->requests_finished++;
 }
 
-static void ioreq_release(struct ioreq *ioreq, bool finish)
+static void ioreq_release(XenQdiskRequest *request, bool finish)
 {
-XenQdiskDataPlane *dataplane = ioreq->dataplane;
+XenQdiskDataPlane *dataplane = request->dataplane;
 
-QLIST_REMOVE(ioreq, list);
-ioreq_reset(ioreq);
-ioreq->dataplane = dataplane;
-QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
+QLIST_REMOVE(request, list);
+io

[Qemu-block] [PATCH 18/18] xen: remove the legacy 'xen_disk' backend

2018-11-21 Thread Paul Durrant
This backend has now been replaced by the 'xen-qdisk' XenDevice.

Signed-off-by: Paul Durrant 
---
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/Makefile.objs |1 -
 hw/block/xen_disk.c| 1011 
 2 files changed, 1012 deletions(-)
 delete mode 100644 hw/block/xen_disk.c

diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index bcdd36d318..d9d2f3fde5 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -4,7 +4,6 @@ common-obj-$(CONFIG_SSI_M25P80) += m25p80.o
 common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
-common-obj-$(CONFIG_XEN) += xen_disk.o
 common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
deleted file mode 100644
index 75fe55f2ae..00
--- a/hw/block/xen_disk.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*
- *  xen paravirt block device backend
- *
- *  (c) Gerd Hoffmann 
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see .
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
- */
-
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include 
-#include 
-
-#include "hw/hw.h"
-#include "hw/xen/xen-legacy-backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* - */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
-struct ioreq {
-blkif_request_t req;
-int16_t status;
-
-/* parsed request */
-off_t   start;
-QEMUIOVectorv;
-void*buf;
-size_t  size;
-int presync;
-
-/* aio status */
-int aio_inflight;
-int aio_errors;
-
-struct XenBlkDev*blkdev;
-QLIST_ENTRY(ioreq)   list;
-BlockAcctCookie acct;
-};
-
-#define MAX_RING_PAGE_ORDER 4
-
-struct XenBlkDev {
-struct XenLegacyDevicexendev;  /* must be first */
-char*params;
-char*mode;
-char*type;
-char*dev;
-char*devtype;
-booldirectiosafe;
-const char  *fileproto;
-const char  *filename;
-unsigned intring_ref[1 << MAX_RING_PAGE_ORDER];
-unsigned intnr_ring_ref;
-void*sring;
-int64_t file_blk;
-int64_t file_size;
-int protocol;
-blkif_back_rings_t  rings;
-int more_work;
-
-/* request lists */
-QLIST_HEAD(inflight_head, ioreq) inflight;
-QLIST_HEAD(finished_head, ioreq) finished;
-QLIST_HEAD(freelist_head, ioreq) freelist;
-int requests_total;
-int requests_inflight;
-int requests_finished;
-unsigned intmax_requests;
-
-gbooleanfeature_discard;
-
-/* qemu block driver */
-DriveInfo   *dinfo;
-BlockBackend*blk;
-QEMUBH  *bh;
-
-IOThread*iothread;
-AioContext  *ctx;
-};
-
-/* - */
-
-static void ioreq_reset(struct ioreq *ioreq)
-{
-memset(&ioreq->req, 0, sizeof(ioreq->req));
-ioreq->status = 0;
-ioreq->start = 0;
-ioreq->buf = NULL;
-ioreq->size = 0;
-ioreq->presync = 0;
-
-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;
-
-if (QLIST_EMPTY(&blkdev->freelist)) {
-if (blkdev->requests_total >= blkdev->max_requests) {
-goto out;
-}
-/* allocate new struct */
-ioreq = g_malloc0(sizeof(*ioreq));
-ioreq->blkdev = blkdev;
-blkdev-

[Qemu-block] [PATCH 13/18] xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-qdisk.c

2018-11-21 Thread Paul Durrant
This is a purely cosmetic patch that purges remaining use of 'blk' and
'ioreq' in local function names.

No functional change.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Stefan Hajnoczi 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/dataplane/xen-qdisk.c | 86 +-
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 50a48b6f5f..94785eeff3 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -57,7 +57,7 @@ struct XenQdiskDataPlane {
 AioContext *ctx;
 };
 
-static void ioreq_reset(XenQdiskRequest *request)
+static void reset_request(XenQdiskRequest *request)
 {
 memset(&request->req, 0, sizeof(request->req));
 request->status = 0;
@@ -76,7 +76,7 @@ static void ioreq_reset(XenQdiskRequest *request)
 qemu_iovec_reset(&request->v);
 }
 
-static XenQdiskRequest *ioreq_start(XenQdiskDataPlane *dataplane)
+static XenQdiskRequest *start_request(XenQdiskDataPlane *dataplane)
 {
 XenQdiskRequest *request = NULL;
 
@@ -101,7 +101,7 @@ out:
 return request;
 }
 
-static void ioreq_finish(XenQdiskRequest *request)
+static void finish_request(XenQdiskRequest *request)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -111,12 +111,12 @@ static void ioreq_finish(XenQdiskRequest *request)
 dataplane->requests_finished++;
 }
 
-static void ioreq_release(XenQdiskRequest *request, bool finish)
+static void release_request(XenQdiskRequest *request, bool finish)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 
 QLIST_REMOVE(request, list);
-ioreq_reset(request);
+reset_request(request);
 request->dataplane = dataplane;
 QLIST_INSERT_HEAD(&dataplane->freelist, request, list);
 if (finish) {
@@ -130,7 +130,7 @@ static void ioreq_release(XenQdiskRequest *request, bool 
finish)
  * translate request into iovec + start offset
  * do sanity checks along the way
  */
-static int ioreq_parse(XenQdiskRequest *request)
+static int parse_request(XenQdiskRequest *request)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 size_t len;
@@ -191,7 +191,7 @@ err:
 return -1;
 }
 
-static int ioreq_grant_copy(XenQdiskRequest *request)
+static int copy_request(XenQdiskRequest *request)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 XenDevice *xendev = dataplane->xendev;
@@ -240,9 +240,9 @@ static int ioreq_grant_copy(XenQdiskRequest *request)
 return 0;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request);
+static int do_aio(XenQdiskRequest *request);
 
-static void qemu_aio_complete(void *opaque, int ret)
+static void complete_aio(void *opaque, int ret)
 {
 XenQdiskRequest *request = opaque;
 XenQdiskDataPlane *dataplane = request->dataplane;
@@ -259,7 +259,7 @@ static void qemu_aio_complete(void *opaque, int ret)
 request->aio_inflight--;
 if (request->presync) {
 request->presync = 0;
-ioreq_runio_qemu_aio(request);
+do_aio(request);
 goto done;
 }
 if (request->aio_inflight > 0) {
@@ -270,7 +270,7 @@ static void qemu_aio_complete(void *opaque, int ret)
 case BLKIF_OP_READ:
 /* in case of failure request->aio_errors is increased */
 if (ret == 0) {
-ioreq_grant_copy(request);
+copy_request(request);
 }
 qemu_vfree(request->buf);
 break;
@@ -286,7 +286,7 @@ static void qemu_aio_complete(void *opaque, int ret)
 }
 
 request->status = request->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
-ioreq_finish(request);
+finish_request(request);
 
 switch (request->req.operation) {
 case BLKIF_OP_WRITE:
@@ -311,9 +311,8 @@ done:
 aio_context_release(dataplane->ctx);
 }
 
-static bool blk_split_discard(XenQdiskRequest *request,
-  blkif_sector_t sector_number,
-  uint64_t nr_sectors)
+static bool split_discard(XenQdiskRequest *request,
+  blkif_sector_t sector_number, uint64_t nr_sectors)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 int64_t byte_offset;
@@ -336,7 +335,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
 byte_chunk = byte_remaining > limit ? limit : byte_remaining;
 request->aio_inflight++;
 blk_aio_pdiscard(dataplane->blk, byte_offset, byte_chunk,
- qemu_aio_complete, request);
+ complete_aio, request);
 byte_remaining -= byte_chunk;
 byte_offset += byte_chunk;
 } while (byte_remaining > 0);
@@ -344,7 +343,7 @@ static bool blk_split_discard(XenQdiskRequest *request,
 return true;
 }
 
-static int ioreq_runio_qemu_aio(XenQdiskRequest *request)
+static int do_aio(XenQdiskRequest *request)
 {
 XenQdiskDataPlane *dataplane = request->dataplane;
 
@@ -352,14 +351,14 @@ static int

[Qemu-block] [PATCH 17/18] MAINTAINERS: add myself as a Xen maintainer

2018-11-21 Thread Paul Durrant
I have made many significant contributions to the Xen code in QEMU,
particularly the recent patches introducing a new PV device framework.
I intend to make further significant contributions, porting other PV back-
ends to the new framework with the intent of eventually removing the
legacy code. It therefore seems reasonable that I become a maintiner of
the Xen code.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Paolo Bonzini 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 5871f035c3..0b668dd205 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -382,6 +382,7 @@ Guest CPU Cores (Xen):
 X86
 M: Stefano Stabellini 
 M: Anthony Perard 
+M: Paul Durrant 
 L: xen-de...@lists.xenproject.org
 S: Supported
 F: */xen*
-- 
2.11.0




[Qemu-block] [PATCH 10/18] xen: add header and build dataplane/xen-qdisk.c

2018-11-21 Thread Paul Durrant
This patch adds the transformations necessary to get dataplane/xen-qdisk.c
to build against the new XenBus/XenDevice framework. MAINTAINERS is also
updated due to the introduction of dataplane/xen-qdisk.h.

NOTE: Existing data structure names are retained for the moment. These will
  be modified by subsequent patches. A typedef for XenQdiskDataPlane
  has been added to the header (based on the old struct XenBlkDev name
  for the moment) so that the old names don't need to leak out of the
  dataplane code.

Signed-off-by: Paul Durrant 
---
Cc: Stefan Hajnoczi 
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 MAINTAINERS  |   1 +
 hw/block/dataplane/Makefile.objs |   1 +
 hw/block/dataplane/xen-qdisk.c   | 317 +++
 hw/block/dataplane/xen-qdisk.h   |  25 +++
 4 files changed, 244 insertions(+), 100 deletions(-)
 create mode 100644 hw/block/dataplane/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4bfbfc9985..5871f035c3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -394,6 +394,7 @@ F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
+F: include/hw/block/dataplane/xen*
 F: include/hw/xen/
 F: include/sysemu/xen-mapcache.h
 
diff --git a/hw/block/dataplane/Makefile.objs b/hw/block/dataplane/Makefile.objs
index e786f66421..1c107052d1 100644
--- a/hw/block/dataplane/Makefile.objs
+++ b/hw/block/dataplane/Makefile.objs
@@ -1 +1,2 @@
 obj-y += virtio-blk.o
+obj-$(CONFIG_XEN) += xen-qdisk.o
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 8e4368e7af..b075aa975d 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -5,65 +5,56 @@
  * Based on original code (c) Gerd Hoffmann 
  */
 
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "hw/hw.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen_common.h"
+#include "hw/block/block.h"
+#include "hw/block/xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "xen-qdisk.h"
+
 struct ioreq {
-blkif_request_t req;
-int16_t status;
-
-/* parsed request */
-off_t   start;
-QEMUIOVectorv;
-void*buf;
-size_t  size;
-int presync;
-
-/* aio status */
-int aio_inflight;
-int aio_errors;
-
-struct XenBlkDev*blkdev;
-QLIST_ENTRY(ioreq)   list;
-BlockAcctCookie acct;
+blkif_request_t req;
+int16_t status;
+off_t start;
+QEMUIOVector v;
+void *buf;
+size_t size;
+int presync;
+int aio_inflight;
+int aio_errors;
+struct XenBlkDev *blkdev;
+QLIST_ENTRY(ioreq) list;
+BlockAcctCookie acct;
 };
 
-#define MAX_RING_PAGE_ORDER 4
-
 struct XenBlkDev {
-struct XenLegacyDevicexendev;  /* must be first */
-char*params;
-char*mode;
-char*type;
-char*dev;
-char*devtype;
-booldirectiosafe;
-const char  *fileproto;
-const char  *filename;
-unsigned intring_ref[1 << MAX_RING_PAGE_ORDER];
-unsigned intnr_ring_ref;
-void*sring;
-int64_t file_blk;
-int64_t file_size;
-int protocol;
-blkif_back_rings_t  rings;
-int more_work;
-
-/* request lists */
+XenDevice *xendev;
+XenEventChannel *event_channel;
+unsigned int *ring_ref;
+unsigned int nr_ring_ref;
+void *sring;
+int64_t file_blk;
+int64_t file_size;
+int protocol;
+blkif_back_rings_t rings;
+int more_work;
 QLIST_HEAD(inflight_head, ioreq) inflight;
 QLIST_HEAD(finished_head, ioreq) finished;
 QLIST_HEAD(freelist_head, ioreq) freelist;
-int requests_total;
-int requests_inflight;
-int requests_finished;
-unsigned intmax_requests;
-
-gbooleanfeature_discard;
-
-/* qemu block driver */
-DriveInfo   *dinfo;
-BlockBackend*blk;
-QEMUBH  *bh;
-
-IOThread*iothread;
-AioContext  *ctx;
+int requests_total;
+int requests_inflight;
+int requests_finished;
+unsigned int max_requests;
+BlockBackend *blk;
+QEMUBH *bh;
+IOThread *iothread;
+AioContext *ctx;
 };
 
 static void ioreq_reset(struct ioreq *ioreq)
@@ -142,7 +133,6 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
 static int ioreq_parse(struct ioreq *ioreq)
 {
 struct XenBlkDev *blkdev = ioreq->blkdev;
-struct XenLegacyDevice *xendev = &blkdev->xendev;
 size_t len;
 int i;
 
@@ -164,7 +154,8 @@ static int ioreq_parse(struct ioreq *ioreq)
 goto err;
  

[Qemu-block] [PATCH 15/18] xen: add a mechanism to automatically create XenDevice-s...

2018-11-21 Thread Paul Durrant
...that maintains compatibility with existing Xen toolstacks.

Xen toolstacks instantiate PV backends by simply writing information into
xenstore and expecting a backend implementation to be watching for this.

This patch adds a new 'xen-backend' module to allow individual XenDevice
implementations to register a creator function to be called when a tool-
stack instantiates a new backend in this way.

To support this it is also necessary to add new watchers into the XenBus
implementation to handle enumeration of new backends and also destruction
of XenDevice-s when the toolstack sets the backend 'online' key to 0.

NOTE: This patch only adds the framework. A subsequent patch will add a
  creator function for xen-qdisk.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 hw/xen/Makefile.objs |   2 +-
 hw/xen/trace-events  |   5 +
 hw/xen/xen-backend.c |  67 +
 hw/xen/xen-bus.c | 220 +++
 include/hw/xen/xen-backend.h |  24 +
 include/hw/xen/xen-bus.h |   5 +-
 include/qemu/module.h|   3 +
 7 files changed, 305 insertions(+), 21 deletions(-)
 create mode 100644 hw/xen/xen-backend.c
 create mode 100644 include/hw/xen/xen-backend.h

diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 77c0868190..84df60a928 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o xen-bus.o xen-bus-helper.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o xen-bus.o xen-bus-helper.o xen-backend.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o 
xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 94c46c2e34..5b12135083 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,11 +16,16 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_enumerate(void) ""
+xen_bus_type_enumerate(const char *type) "type: %s"
+xen_bus_backend_create(const char *type, const char *path) "type: %s path: %s"
 xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s 
key: %s token: %s"
 xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s 
key: %s token: %s"
 xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name) "type: %s name: %s"
 xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
 xen_device_backend_state(const char *type, char *name, const char *state) 
"type: %s name: %s -> %s"
+xen_device_backend_online(const char *type, char *name, bool online) "type: %s 
name: %s -> %u"
 xen_device_frontend_state(const char *type, char *name, const char *state) 
"type: %s name: %s -> %s"
+xen_device_backend_changed(const char *type, char *name) "type: %s name: %s"
 xen_device_frontend_changed(const char *type, char *name) "type: %s name: %s"
diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c
new file mode 100644
index 00..7581fd390d
--- /dev/null
+++ b/hw/xen/xen-backend.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+#include "hw/xen/xen-backend.h"
+
+typedef struct XenBackendImpl {
+const char *type;
+XenBackendDeviceCreate create;
+} XenBackendImpl;
+
+static GHashTable *xen_backend_table_get(void)
+{
+static GHashTable *table;
+
+if (table == NULL) {
+table = g_hash_table_new(g_str_hash, g_str_equal);
+}
+
+return table;
+}
+
+static void xen_backend_table_add(XenBackendImpl *impl)
+{
+g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl);
+}
+
+static XenBackendImpl *xen_backend_table_lookup(const char *type)
+{
+return g_hash_table_lookup(xen_backend_table_get(), type);
+}
+
+void xen_backend_register(const XenBackendInfo *info)
+{
+XenBackendImpl *impl = g_new0(XenBackendImpl, 1);
+
+g_assert(info->type);
+
+if (xen_backend_table_lookup(info->type)) {
+error_report("attempt to register duplicate Xen backend type '%s'",
+ info->type);
+abort();
+}
+
+if (!info->create) {
+error_report("backend type '%s' has no creator", info->type);
+abort();
+}
+
+impl->type = info->type;
+impl->create = info->create;
+
+xen_backend_table_add(impl);
+}
+
+void xen_backend_device_create(BusState *bus, const char *type,
+   const char *name, QDict *opts, Error **errp)
+{
+XenBackendImpl *impl = xen_backend_table_lookup(type);
+
+if (impl) {
+impl->create(bus, name, opts, errp);
+}
+}
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
in

[Qemu-block] [PATCH 16/18] xen: automatically create XenQdiskDevice-s

2018-11-21 Thread Paul Durrant
This patch adds a creator function for XenQdiskDevice-s so that they can
be created automatically when the Xen toolstack instantiates a new
PV backend. When the XenQdiskDevice is created this way it is also
necessary to create a drive which matches the configuration that the Xen
toolstack has written into xenstore. This drive is marked 'auto_del' so
that it will be removed when the XenQdiskDevice is destroyed. Also, for
compatibilitye with the legacy 'xen_disk' implementation, an iothread
is automatically created for the new XenQdiskDevice. This will also be
removed when he XenQdiskDevice is destroyed.

Correspondingly the legacy backend scan for 'qdisk' is removed.

After this patch is applied the legacy 'xen_disk' code is redundant. It
will be removed by a subsequent patch.

Signed-off-by: Paul Durrant 
---
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 hw/block/trace-events   |   1 +
 hw/block/xen-qdisk.c| 237 +++-
 hw/xen/xen-legacy-backend.c |   1 -
 include/hw/xen/xen-qdisk.h  |   1 +
 4 files changed, 238 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index 8b95567560..ee2ac756cf 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -133,3 +133,4 @@ xen_qdisk_realize(uint32_t disk, uint32_t partition) 
"d%up%u"
 xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_device_create(const char *name) "name: %s"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 8c88393832..00cdd8181b 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -5,9 +5,12 @@
 
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
+#include "qemu/option.h"
 #include "qapi/error.h"
 #include "qapi/visitor.h"
+#include "qapi/qmp/qdict.h"
 #include "hw/hw.h"
+#include "hw/xen/xen-backend.h"
 #include "hw/xen/xen-qdisk.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/block-backend.h"
@@ -28,6 +31,8 @@ static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
 XenQdiskVdev *vdev = &qdiskdev->vdev;
 BlockConf *conf = &qdiskdev->conf;
+IOThread *iothread = qdiskdev->auto_iothread ?
+qdiskdev->auto_iothread : qdiskdev->iothread;
 DriveInfo *dinfo;
 bool is_cdrom;
 unsigned int info;
@@ -97,7 +102,7 @@ static void xen_qdisk_realize(XenDevice *xendev, Error 
**errp)
   size / conf->logical_block_size);
 
 qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
- qdiskdev->iothread);
+ iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
@@ -228,6 +233,11 @@ static void xen_qdisk_unrealize(XenDevice *xendev, Error 
**errp)
 
 xen_qdisk_dataplane_destroy(qdiskdev->dataplane);
 qdiskdev->dataplane = NULL;
+
+if (qdiskdev->auto_iothread) {
+iothread_destroy(qdiskdev->auto_iothread);
+qdiskdev->auto_iothread = NULL;
+}
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -461,3 +471,228 @@ static void xen_qdisk_register_types(void)
 }
 
 type_init(xen_qdisk_register_types)
+
+static void xen_qdisk_drive_create(const char *id, QDict *opts,
+   Error **errp)
+{
+const char *params, *device_type, *mode, *direct_io_safe,
+*discard_enable;
+char *format = NULL;
+char *file = NULL;
+char *drive_optstr = NULL;
+QemuOpts *drive_opts;
+Error *local_err = NULL;
+
+params = qdict_get_try_str(opts, "params");
+if (params) {
+char **v = g_strsplit(params, ":", 2);
+
+if (v[1] == NULL) {
+file = g_strdup(v[0]);
+} else {
+if (strcmp(v[0], "aio") == 0) {
+format = g_strdup("raw");
+} else if (strcmp(v[0], "vhd") == 0) {
+format = g_strdup("vpc");
+} else {
+format = g_strdup(v[0]);
+}
+file = g_strdup(v[1]);
+}
+
+g_strfreev(v);
+}
+
+if (!file) {
+error_setg(errp, "no file parameter");
+return;
+}
+
+drive_optstr = g_strdup_printf("id=%s", id);
+drive_opts = drive_def(drive_optstr);
+if (!drive_opts) {
+error_setg(errp, "failed to create drive options");
+goto done;
+}
+
+qemu_opt_set(drive_opts, "file", file, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+error_prepend(errp, "failed to set 'file': ");
+goto done;
+}
+
+if (format) {
+qemu_opt_set(drive_opts, "format", format, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+error_prepend(errp, "f

[Qemu-block] [PATCH 11/18] xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk

2018-11-21 Thread Paul Durrant
This is a purely cosmetic patch that substitutes the old 'struct XenBlkDev'
name with 'XenQdiskDataPlane' and 'blkdev' field/variable names with
'dataplane', and then does necessary fix-up to adhere to coding style.

No functional change.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Stefan Hajnoczi 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/dataplane/xen-qdisk.c | 342 +
 hw/block/dataplane/xen-qdisk.h |   2 +-
 2 files changed, 179 insertions(+), 165 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index b075aa975d..2214455ff9 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -28,12 +28,12 @@ struct ioreq {
 int presync;
 int aio_inflight;
 int aio_errors;
-struct XenBlkDev *blkdev;
+XenQdiskDataPlane *dataplane;
 QLIST_ENTRY(ioreq) list;
 BlockAcctCookie acct;
 };
 
-struct XenBlkDev {
+struct XenQdiskDataPlane {
 XenDevice *xendev;
 XenEventChannel *event_channel;
 unsigned int *ring_ref;
@@ -69,33 +69,33 @@ static void ioreq_reset(struct ioreq *ioreq)
 ioreq->aio_inflight = 0;
 ioreq->aio_errors = 0;
 
-ioreq->blkdev = NULL;
+ioreq->dataplane = 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)
+static struct ioreq *ioreq_start(XenQdiskDataPlane *dataplane)
 {
 struct ioreq *ioreq = NULL;
 
-if (QLIST_EMPTY(&blkdev->freelist)) {
-if (blkdev->requests_total >= blkdev->max_requests) {
+if (QLIST_EMPTY(&dataplane->freelist)) {
+if (dataplane->requests_total >= dataplane->max_requests) {
 goto out;
 }
 /* allocate new struct */
 ioreq = g_malloc0(sizeof(*ioreq));
-ioreq->blkdev = blkdev;
-blkdev->requests_total++;
+ioreq->dataplane = dataplane;
+dataplane->requests_total++;
 qemu_iovec_init(&ioreq->v, 1);
 } else {
 /* get one from freelist */
-ioreq = QLIST_FIRST(&blkdev->freelist);
+ioreq = QLIST_FIRST(&dataplane->freelist);
 QLIST_REMOVE(ioreq, list);
 }
-QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
-blkdev->requests_inflight++;
+QLIST_INSERT_HEAD(&dataplane->inflight, ioreq, list);
+dataplane->requests_inflight++;
 
 out:
 return ioreq;
@@ -103,26 +103,26 @@ out:
 
 static void ioreq_finish(struct ioreq *ioreq)
 {
-struct XenBlkDev *blkdev = ioreq->blkdev;
+XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
 QLIST_REMOVE(ioreq, list);
-QLIST_INSERT_HEAD(&blkdev->finished, ioreq, list);
-blkdev->requests_inflight--;
-blkdev->requests_finished++;
+QLIST_INSERT_HEAD(&dataplane->finished, ioreq, list);
+dataplane->requests_inflight--;
+dataplane->requests_finished++;
 }
 
 static void ioreq_release(struct ioreq *ioreq, bool finish)
 {
-struct XenBlkDev *blkdev = ioreq->blkdev;
+XenQdiskDataPlane *dataplane = ioreq->dataplane;
 
 QLIST_REMOVE(ioreq, list);
 ioreq_reset(ioreq);
-ioreq->blkdev = blkdev;
-QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
+ioreq->dataplane = dataplane;
+QLIST_INSERT_HEAD(&dataplane->freelist, ioreq, list);
 if (finish) {
-blkdev->requests_finished--;
+dataplane->requests_finished--;
 } else {
-blkdev->requests_inflight--;
+dataplane->requests_inflight--;
 }
 }
 
@@ -132,7 +132,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
  */
 static int ioreq_parse(struct ioreq *ioreq)
 {
-struct XenBlkDev *blkdev = ioreq->blkdev;
+XenQdiskDataPlane *dataplane = ioreq->dataplane;
 size_t len;
 int i;
 
@@ -155,12 +155,12 @@ static int ioreq_parse(struct ioreq *ioreq)
 };
 
 if (ioreq->req.operation != BLKIF_OP_READ &&
-blk_is_read_only(blkdev->blk)) {
+blk_is_read_only(dataplane->blk)) {
 error_report("error: write req for ro device");
 goto err;
 }
 
-ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
+ioreq->start = ioreq->req.sector_number * dataplane->file_blk;
 for (i = 0; i < ioreq->req.nr_segments; i++) {
 if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
 error_report("error: nr_segments too big");
@@ -170,16 +170,16 @@ static int ioreq_parse(struct ioreq *ioreq)
 error_report("error: first > last sector");
 goto err;
 }
-if (ioreq->req.seg[i].last_sect * blkdev->file_blk >= XC_PAGE_SIZE) {
+if (ioreq->req.seg[i].last_sect * dataplane->file_blk >= XC_PAGE_SIZE) 
{
 error_report("error: page crossing");
 goto err;
 }
 
 len = (ioreq->req.seg[i].last_sect -
-   ioreq->req.seg[i].first_sect + 1) * blkdev->file_blk;
+   ioreq->r

[Qemu-block] [PATCH 14/18] xen: add implementations of xen-qdisk connect and disconnect functions...

2018-11-21 Thread Paul Durrant
...and wire in the dataplane.

This patch adds the remaining code to make the xen-qdisk XenDevice
functional. The parameters that a block frontend expects to find are
populated in the backend xenstore area, and the 'ring-ref' and
'event-channel' values specified in the frontend xenstore area are
mapped/bound and used to set up the dataplane.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/xen-qdisk.c   | 140 +
 hw/xen/xen-bus.c   |  12 ++--
 include/hw/xen/xen-bus.h   |   8 +++
 include/hw/xen/xen-qdisk.h |  12 
 4 files changed, 166 insertions(+), 6 deletions(-)

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 35f7b70480..8c88393832 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -9,6 +9,10 @@
 #include "qapi/visitor.h"
 #include "hw/hw.h"
 #include "hw/xen/xen-qdisk.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
+#include "sysemu/iothread.h"
+#include "dataplane/xen-qdisk.h"
 #include "trace.h"
 
 static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
@@ -23,6 +27,11 @@ static void xen_qdisk_realize(XenDevice *xendev, Error 
**errp)
 {
 XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
 XenQdiskVdev *vdev = &qdiskdev->vdev;
+BlockConf *conf = &qdiskdev->conf;
+DriveInfo *dinfo;
+bool is_cdrom;
+unsigned int info;
+int64_t size;
 
 if (!vdev->valid) {
 error_setg(errp, "vdev property not set");
@@ -30,13 +39,134 @@ static void xen_qdisk_realize(XenDevice *xendev, Error 
**errp)
 }
 
 trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+
+if (!conf->blk) {
+error_setg(errp, "drive property not set");
+return;
+}
+
+if (!blk_is_inserted(conf->blk)) {
+error_setg(errp, "device needs media, but drive is empty");
+return;
+}
+
+if (!blkconf_apply_backend_options(conf, blk_is_read_only(conf->blk),
+   false, errp)) {
+return;
+}
+
+if (!blkconf_geometry(conf, NULL, 65535, 255, 255, errp)) {
+return;
+}
+
+dinfo = blk_legacy_dinfo(conf->blk);
+is_cdrom = (dinfo && dinfo->media_cd);
+
+blkconf_blocksizes(conf);
+
+if (conf->logical_block_size > conf->physical_block_size) {
+error_setg(
+errp, "logical_block_size > physical_block_size not supported");
+return;
+}
+
+blk_set_guest_block_size(conf->blk, conf->logical_block_size);
+
+if (conf->discard_granularity > 0) {
+xen_device_backend_printf(xendev, "feature-discard", "%u", 1);
+}
+
+xen_device_backend_printf(xendev, "feature-flush-cache", "%u", 1);
+xen_device_backend_printf(xendev, "max-ring-page-order", "%u",
+  qdiskdev->max_ring_page_order);
+
+info = blk_is_read_only(conf->blk) ? VDISK_READONLY : 0;
+info |= is_cdrom ? VDISK_CDROM : 0;
+
+xen_device_backend_printf(xendev, "info", "%u", info);
+
+xen_device_frontend_printf(xendev, "virtual-device", "%u",
+   vdev->number);
+xen_device_frontend_printf(xendev, "device-type", "%s",
+   is_cdrom ? "cdrom" : "disk");
+
+size = blk_getlength(conf->blk);
+xen_device_backend_printf(xendev, "sector-size", "%u",
+  conf->logical_block_size);
+xen_device_backend_printf(xendev, "sectors", "%lu",
+  size / conf->logical_block_size);
+
+qdiskdev->dataplane = xen_qdisk_dataplane_create(xendev, conf,
+ qdiskdev->iothread);
 }
 
 static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
 {
 XenQdiskVdev *vdev = &qdiskdev->vdev;
+XenDevice *xendev = XEN_DEVICE(qdiskdev);
+unsigned int order, nr_ring_ref, *ring_ref, event_channel, protocol;
+char *str;
 
 trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+
+if (xen_device_frontend_scanf(xendev, "ring-page-order", "%u",
+  &order) != 1) {
+nr_ring_ref = 1;
+ring_ref = g_new(unsigned int, nr_ring_ref);
+
+if (xen_device_frontend_scanf(xendev, "ring-ref", "%u",
+  &ring_ref[0]) != 1) {
+error_setg(errp, "failed to read ring-ref");
+return;
+}
+} else if (order <= qdiskdev->max_ring_page_order) {
+unsigned int i;
+
+nr_ring_ref = 1 << order;
+ring_ref = g_new(unsigned int, nr_ring_ref);
+
+for (i = 0; i < nr_ring_ref; i++) {
+const char *key = g_strdup_printf("ring-ref%u", i);
+
+if (xen_device_frontend_scanf(xendev, key, "%u",
+  &ring_ref[i]) != 1) {
+error_setg(errp, "failed to read %s", key);
+g_free((gpointer)key);
+   

[Qemu-block] [PATCH 08/18] xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c

2018-11-21 Thread Paul Durrant
The new xen-qdisk XenDevice implementation requires the same core dataplane
as the legacy xen_disk implementation it will eventually replace. This
patch therefore copies the legacy xen_disk.c source module into a new
dataplane/xen-qdisk.c source module as the basis for the new dataplane and
adjusts the MAINTAINERS file accordingly.

NOTE: The duplicated code is not yet built. It is simply put into place by
  this patch (just fixing style violations) such that the
  modifications that will need to be made to the code are not
  conflated with code movement, thus making review harder.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Stefan Hajnoczi 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 MAINTAINERS|1 +
 hw/block/dataplane/xen-qdisk.c | 1019 
 2 files changed, 1020 insertions(+)
 create mode 100644 hw/block/dataplane/xen-qdisk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 10f048a503..4bfbfc9985 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -390,6 +390,7 @@ F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
 F: hw/block/xen*
+F: hw/block/dataplane/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
new file mode 100644
index 00..9fae50534e
--- /dev/null
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -0,0 +1,1019 @@
+/*
+ *  xen paravirt block device backend
+ *
+ *  (c) Gerd Hoffmann 
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; under version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, see .
+ *
+ *  Contributions after 2012-01-13 are licensed under the terms of the
+ *  GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include 
+#include 
+
+#include "hw/hw.h"
+#include "hw/xen/xen_backend.h"
+#include "xen_blkif.h"
+#include "sysemu/blockdev.h"
+#include "sysemu/iothread.h"
+#include "sysemu/block-backend.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qstring.h"
+#include "trace.h"
+
+/* - */
+
+#define BLOCK_SIZE  512
+#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
+
+struct ioreq {
+blkif_request_t req;
+int16_t status;
+
+/* parsed request */
+off_t   start;
+QEMUIOVectorv;
+void*buf;
+size_t  size;
+int presync;
+
+/* aio status */
+int aio_inflight;
+int aio_errors;
+
+struct XenBlkDev*blkdev;
+QLIST_ENTRY(ioreq)   list;
+BlockAcctCookie acct;
+};
+
+#define MAX_RING_PAGE_ORDER 4
+
+struct XenBlkDev {
+struct XenLegacyDevicexendev;  /* must be first */
+char*params;
+char*mode;
+char*type;
+char*dev;
+char*devtype;
+booldirectiosafe;
+const char  *fileproto;
+const char  *filename;
+unsigned intring_ref[1 << MAX_RING_PAGE_ORDER];
+unsigned intnr_ring_ref;
+void*sring;
+int64_t file_blk;
+int64_t file_size;
+int protocol;
+blkif_back_rings_t  rings;
+int more_work;
+
+/* request lists */
+QLIST_HEAD(inflight_head, ioreq) inflight;
+QLIST_HEAD(finished_head, ioreq) finished;
+QLIST_HEAD(freelist_head, ioreq) freelist;
+int requests_total;
+int requests_inflight;
+int requests_finished;
+unsigned intmax_requests;
+
+gbooleanfeature_discard;
+
+/* qemu block driver */
+DriveInfo   *dinfo;
+BlockBackend*blk;
+QEMUBH  *bh;
+
+IOThread*iothread;
+AioContext  *ctx;
+};
+
+/* - */
+
+static void ioreq_reset(struct ioreq *ioreq)
+{
+memset(&ioreq->req, 0, sizeof(ioreq->req));
+ioreq->status = 0;
+ioreq->start = 0;
+ioreq->buf = NULL;
+ioreq->size = 0;
+ioreq->presync = 0;
+
+ioreq->aio_inflight = 0;
+ioreq->aio_errors = 0;
+
+ioreq->blkdev = NULL;
+memset(&ioreq->list, 0, sizeof(ioreq->list));
+memset(&ioreq->acct, 0, sizeof(ioreq->

[Qemu-block] [PATCH 09/18] xen: remove unnecessary code from dataplane/xen-qdisk.c

2018-11-21 Thread Paul Durrant
Not all of the code duplicated from xen_disk.c is required as the basis for
the new dataplane implementation so this patch removes extraneous code,
along with the legacy #includes and calls to the legacy xen_pv_printf()
function. Error messages are changed to be reported using error_report().

NOTE: The code is still not yet built. Further transformations will be
  required to make it correctly interface to the new XenBus/XenDevice
  framework. They will be delivered in a subsequent patch.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Stefan Hajnoczi 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/dataplane/xen-qdisk.c | 422 ++---
 1 file changed, 13 insertions(+), 409 deletions(-)

diff --git a/hw/block/dataplane/xen-qdisk.c b/hw/block/dataplane/xen-qdisk.c
index 9fae50534e..8e4368e7af 100644
--- a/hw/block/dataplane/xen-qdisk.c
+++ b/hw/block/dataplane/xen-qdisk.c
@@ -1,45 +1,10 @@
 /*
- *  xen paravirt block device backend
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
  *
- *  (c) Gerd Hoffmann 
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; under version 2 of the License.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, see .
- *
- *  Contributions after 2012-01-13 are licensed under the terms of the
- *  GNU GPL, version 2 or (at your option) any later version.
+ * Based on original code (c) Gerd Hoffmann 
  */
 
-#include "qemu/osdep.h"
-#include "qemu/units.h"
-#include 
-#include 
-
-#include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
-#include "xen_blkif.h"
-#include "sysemu/blockdev.h"
-#include "sysemu/iothread.h"
-#include "sysemu/block-backend.h"
-#include "qapi/error.h"
-#include "qapi/qmp/qdict.h"
-#include "qapi/qmp/qstring.h"
-#include "trace.h"
-
-/* - */
-
-#define BLOCK_SIZE  512
-#define IOCB_COUNT  (BLKIF_MAX_SEGMENTS_PER_REQUEST + 2)
-
 struct ioreq {
 blkif_request_t req;
 int16_t status;
@@ -101,8 +66,6 @@ struct XenBlkDev {
 AioContext  *ctx;
 };
 
-/* - */
-
 static void ioreq_reset(struct ioreq *ioreq)
 {
 memset(&ioreq->req, 0, sizeof(ioreq->req));
@@ -183,11 +146,6 @@ static int ioreq_parse(struct ioreq *ioreq)
 size_t len;
 int i;
 
-xen_pv_printf(
-xendev, 3,
-"op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n",
-ioreq->req.operation, ioreq->req.nr_segments,
-ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number);
 switch (ioreq->req.operation) {
 case BLKIF_OP_READ:
 break;
@@ -202,28 +160,27 @@ static int ioreq_parse(struct ioreq *ioreq)
 case BLKIF_OP_DISCARD:
 return 0;
 default:
-xen_pv_printf(xendev, 0, "error: unknown operation (%d)\n",
-  ioreq->req.operation);
+error_report("error: unknown operation (%d)", ioreq->req.operation);
 goto err;
 };
 
 if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') {
-xen_pv_printf(xendev, 0, "error: write req for ro device\n");
+error_report("error: write req for ro device");
 goto err;
 }
 
 ioreq->start = ioreq->req.sector_number * blkdev->file_blk;
 for (i = 0; i < ioreq->req.nr_segments; i++) {
 if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
-xen_pv_printf(xendev, 0, "error: nr_segments too big\n");
+error_report("error: nr_segments too big");
 goto err;
 }
 if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) {
-xen_pv_printf(xendev, 0, "error: first > last sector\n");
+error_report("error: first > last sector");
 goto err;
 }
 if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) {
-xen_pv_printf(xendev, 0, "error: page crossing\n");
+error_report("error: page crossing");
 goto err;
 }
 
@@ -232,7 +189,7 @@ static int ioreq_parse(struct ioreq *ioreq)
 ioreq->size += len;
 }
 if (ioreq->start + ioreq->size > blkdev->file_size) {
-xen_pv_printf(xendev, 0, "error: access beyond end of file\n");
+error_report("error: access beyond end of file");
 goto err;
 }
 return 0;
@@ -278,8 +235,7 @@ static int ioreq_grant_copy(struct ioreq *ioreq)
 rc = xen_be_copy_grant_refs(xendev, to_domain, 

[Qemu-block] [PATCH 01/18] xen: re-name XenDevice to XenLegacyDevice...

2018-11-21 Thread Paul Durrant
...and xen_backend.h to xen-legacy-backend.h

Rather than attempting to convert the existing backend infrastructure to
be QOM compliant (which would be hard to do in an incremental fashion),
subsequent patches will introduce a completely new framework for Xen PV
backends. Hence it is necessary to re-name parts of existing code to avoid
name clashes. The re-named 'legacy' infrastructure will be removed once all
backends have been ported to the new framework.

This patch is purely cosmetic. No functional change.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Greg Kurz 
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: "Marc-André Lureau" 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: Jason Wang 
Cc: Gerd Hoffmann 
---
 hw/9pfs/xen-9p-backend.c   | 16 ++---
 hw/block/xen_disk.c| 24 +++
 hw/char/xen_console.c  | 12 ++--
 hw/display/xenfb.c | 25 
 hw/i386/xen/xen-hvm.c  |  2 +-
 hw/i386/xen/xen-mapcache.c |  2 +-
 hw/i386/xen/xen_platform.c |  2 +-
 hw/net/xen_nic.c   | 14 ++---
 hw/usb/xen-usb.c   | 25 
 hw/xen/Makefile.objs   |  2 +-
 hw/xen/xen-common.c|  2 +-
 hw/xen/{xen_backend.c => xen-legacy-backend.c} | 73 --
 hw/xen/xen_devconfig.c |  2 +-
 hw/xen/xen_pt.c|  2 +-
 hw/xen/xen_pt_config_init.c|  2 +-
 hw/xen/xen_pt_graphics.c   |  2 +-
 hw/xen/xen_pt_msi.c|  2 +-
 hw/xen/xen_pvdev.c | 20 +++---
 hw/xenpv/xen_domainbuild.c |  2 +-
 hw/xenpv/xen_machine_pv.c  |  2 +-
 .../hw/xen/{xen_backend.h => xen-legacy-backend.h} | 43 +++--
 include/hw/xen/xen_pvdev.h | 38 +--
 22 files changed, 166 insertions(+), 148 deletions(-)
 rename hw/xen/{xen_backend.c => xen-legacy-backend.c} (89%)
 rename include/hw/xen/{xen_backend.h => xen-legacy-backend.h} (61%)

diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 3f54a21c76..3859a06fe7 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -12,7 +12,7 @@
 
 #include "hw/hw.h"
 #include "hw/9pfs/9p.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-backend.h"
 #include "hw/9pfs/xen-9pfs.h"
 #include "qapi/error.h"
 #include "qemu/config-file.h"
@@ -45,7 +45,7 @@ typedef struct Xen9pfsRing {
 } Xen9pfsRing;
 
 typedef struct Xen9pfsDev {
-struct XenDevice xendev;  /* must be first */
+struct XenLegacyDevice xendev;  /* must be first */
 V9fsState state;
 char *path;
 char *security_model;
@@ -56,7 +56,7 @@ typedef struct Xen9pfsDev {
 Xen9pfsRing *rings;
 } Xen9pfsDev;
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev);
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev);
 
 static void xen_9pfs_in_sg(Xen9pfsRing *ring,
struct iovec *in_sg,
@@ -243,7 +243,7 @@ static const V9fsTransport xen_9p_transport = {
 .push_and_notify = xen_9pfs_push_and_notify,
 };
 
-static int xen_9pfs_init(struct XenDevice *xendev)
+static int xen_9pfs_init(struct XenLegacyDevice *xendev)
 {
 return 0;
 }
@@ -305,7 +305,7 @@ static void xen_9pfs_evtchn_event(void *opaque)
 qemu_bh_schedule(ring->bh);
 }
 
-static void xen_9pfs_disconnect(struct XenDevice *xendev)
+static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
 {
 Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
 int i;
@@ -321,7 +321,7 @@ static void xen_9pfs_disconnect(struct XenDevice *xendev)
 }
 }
 
-static int xen_9pfs_free(struct XenDevice *xendev)
+static int xen_9pfs_free(struct XenLegacyDevice *xendev)
 {
 Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
 int i;
@@ -354,7 +354,7 @@ static int xen_9pfs_free(struct XenDevice *xendev)
 return 0;
 }
 
-static int xen_9pfs_connect(struct XenDevice *xendev)
+static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
 {
 Error *err = NULL;
 int i;
@@ -467,7 +467,7 @@ out:
 return -1;
 }
 
-static void xen_9pfs_alloc(struct XenDevice *xendev)
+static void xen_9pfs_alloc(struct XenLegacyDevice *xendev)
 {
 xenstore_write_be_str(xendev, "versions", VERSIONS);
 xenstore_write_be_int(xendev, "max-rings", MAX_RINGS);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 36eff94f84..75fe55f2ae 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -25,7 +25,7 @@
 #include 
 
 #include "hw/hw.h"
-#include "hw/xen/xen_backend.h"
+#include "hw/xen/xen-legacy-b

[Qemu-block] [PATCH 06/18] xen: add grant table interface for XenDevice-s

2018-11-21 Thread Paul Durrant
The legacy PV backend infrastructure provides functions to map, unmap and
copy pages granted by frontends. Similar functionality will be required
by XenDevice implementations so this patch adds the necessary support.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 hw/xen/xen-bus.c | 145 +++
 include/hw/xen/xen-bus.h |  25 
 2 files changed, 170 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 99988f8568..7a152d2a2f 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -447,6 +447,138 @@ static void xen_device_frontend_destroy(XenDevice *xendev)
 g_free(xendev->frontend_path);
 }
 
+void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
+   Error **errp)
+{
+if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
+error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
+}
+}
+
+void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
+unsigned int nr_refs, int prot,
+Error **errp)
+{
+void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
+xendev->frontend_id, refs,
+prot);
+
+if (!map) {
+error_setg_errno(errp, errno,
+ "xengnttab_map_domain_grant_refs failed");
+}
+
+return map;
+}
+
+void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
+ unsigned int nr_refs, Error **errp)
+{
+if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
+error_setg_errno(errp, errno, "xengnttab_unmap failed");
+}
+}
+
+static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
+   XenDeviceGrantCopySegment segs[],
+   unsigned int nr_segs, Error **errp)
+{
+uint32_t *refs = g_new(uint32_t, nr_segs);
+int prot = to_domain ? PROT_WRITE : PROT_READ;
+void *map;
+unsigned int i;
+
+for (i = 0; i < nr_segs; i++) {
+XenDeviceGrantCopySegment *seg = &segs[i];
+
+refs[i] = to_domain ? seg->dest.foreign.ref :
+seg->source.foreign.ref;
+}
+
+map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
+  xendev->frontend_id, refs,
+  prot);
+if (!map) {
+error_setg_errno(errp, errno,
+ "xengnttab_map_domain_grant_refs failed");
+goto done;
+}
+
+for (i = 0; i < nr_segs; i++) {
+XenDeviceGrantCopySegment *seg = &segs[i];
+void *page = map + (i * XC_PAGE_SIZE);
+
+if (to_domain) {
+memcpy(page + seg->dest.foreign.offset, seg->source.virt,
+   seg->len);
+} else {
+memcpy(seg->dest.virt, page + seg->source.foreign.offset,
+   seg->len);
+}
+}
+
+if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
+error_setg_errno(errp, errno, "xengnttab_unmap failed");
+}
+
+done:
+g_free(refs);
+}
+
+void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
+XenDeviceGrantCopySegment segs[],
+unsigned int nr_segs, Error **errp)
+{
+xengnttab_grant_copy_segment_t *xengnttab_segs;
+unsigned int i;
+
+if (!xendev->feature_grant_copy) {
+compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
+return;
+}
+
+xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
+
+for (i = 0; i < nr_segs; i++) {
+XenDeviceGrantCopySegment *seg = &segs[i];
+xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
+
+if (to_domain) {
+xengnttab_seg->flags = GNTCOPY_dest_gref;
+xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
+xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
+xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
+xengnttab_seg->source.virt = seg->source.virt;
+} else {
+xengnttab_seg->flags = GNTCOPY_source_gref;
+xengnttab_seg->source.foreign.domid = xendev->frontend_id;
+xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
+xengnttab_seg->source.foreign.offset =
+seg->source.foreign.offset;
+xengnttab_seg->dest.virt = seg->dest.virt;
+}
+
+xengnttab_seg->len = seg->len;
+}
+
+if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
+error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
+goto done;
+}
+
+for (i = 0; i < nr_segs; i++) {
+xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i

[Qemu-block] [PATCH 00/18] Xen PV backend 'qdevification'

2018-11-21 Thread Paul Durrant
This series introduces a new QOM compliant framework for Xen PV backends.
This is achieved by first moving the current non-compliant framework aside,
before building up a new framework incrementally.

This series was prompted by a thread [1] started by Kevin Wolf in response
to patches against xen_disk.c posted by Tim Smith. Therefore, alongside
the patches introducing the new framework, other patches build up a QOM
compliant replacement for 'xen_disk', called 'xen-qdisk'. Patch #16 swaps
this new device into place (having establisheda mechanism to auto-
instantiate devices that is compliant with existing Xen toolstacks in
patch #15) and patch #18 then removes the old xen_disk code.

Subsequent series will port other Xen PV backends across to the new
framework.

The series is also available as a repository branch [2] on xenbits.xen.org.

[1] https://lists.gnu.org/archive/html/qemu-devel/2018-11/msg00259.html
[2] 
http://xenbits.xen.org/gitweb/?p=people/pauldu/qemu.git;a=shortlog;h=refs/heads/qom23

Paul Durrant (18):
  xen: re-name XenDevice to XenLegacyDevice...
  xen: introduce new 'XenBus' and 'XenDevice' object hierarchy
  xen: introduce 'xen-qdisk'
  xen: create xenstore areas for XenDevice-s
  xen: add xenstore watcher infratructure
  xen: add grant table interface for XenDevice-s
  xen: add event channel interface for XenDevice-s
  xen: duplicate xen_disk.c as basis of dataplane/xen-qdisk.c
  xen: remove unnecessary code from dataplane/xen-qdisk.c
  xen: add header and build dataplane/xen-qdisk.c
  xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-qdisk
  xen: remove 'ioreq' struct/varable/field names from
dataplane/xen-qdisk.c
  xen: purge 'blk' and 'ioreq' from function names in
dataplane/xen-qdisk.c
  xen: add implementations of xen-qdisk connect and disconnect
functions...
  xen: add a mechanism to automatically create XenDevice-s...
  xen: automatically create XenQdiskDevice-s
  MAINTAINERS: add myself as a Xen maintainer
  xen: remove the legacy 'xen_disk' backend

 MAINTAINERS|5 +-
 hw/9pfs/xen-9p-backend.c   |   16 +-
 hw/block/Makefile.objs |2 +-
 hw/block/dataplane/Makefile.objs   |1 +
 hw/block/dataplane/xen-qdisk.c |  756 +++
 hw/block/dataplane/xen-qdisk.h |   25 +
 hw/block/trace-events  |7 +
 hw/block/xen-qdisk.c   |  698 +
 hw/block/xen_disk.c| 1011 ---
 hw/char/xen_console.c  |   12 +-
 hw/display/xenfb.c |   25 +-
 hw/i386/xen/xen-hvm.c  |5 +-
 hw/i386/xen/xen-mapcache.c |2 +-
 hw/i386/xen/xen_platform.c |2 +-
 hw/net/xen_nic.c   |   14 +-
 hw/usb/xen-usb.c   |   25 +-
 hw/xen/Makefile.objs   |2 +-
 hw/xen/trace-events|   17 +
 hw/xen/xen-backend.c   |   67 ++
 hw/xen/xen-bus-helper.c|  152 +++
 hw/xen/xen-bus.c   | 1021 
 hw/xen/xen-common.c|2 +-
 hw/xen/{xen_backend.c => xen-legacy-backend.c} |   74 +-
 hw/xen/xen_devconfig.c |2 +-
 hw/xen/xen_pt.c|2 +-
 hw/xen/xen_pt_config_init.c|2 +-
 hw/xen/xen_pt_graphics.c   |2 +-
 hw/xen/xen_pt_msi.c|2 +-
 hw/xen/xen_pvdev.c |   20 +-
 hw/xenpv/xen_domainbuild.c |2 +-
 hw/xenpv/xen_machine_pv.c  |5 +-
 include/hw/xen/xen-backend.h   |   24 +
 include/hw/xen/xen-bus-helper.h|   31 +
 include/hw/xen/xen-bus.h   |  132 +++
 .../hw/xen/{xen_backend.h => xen-legacy-backend.h} |   43 +-
 include/hw/xen/xen-qdisk.h |   51 +
 include/hw/xen/xen_pvdev.h |   38 +-
 include/qemu/module.h  |3 +
 38 files changed, 3150 insertions(+), 1150 deletions(-)
 create mode 100644 hw/block/dataplane/xen-qdisk.c
 create mode 100644 hw/block/dataplane/xen-qdisk.h
 create mode 100644 hw/block/xen-qdisk.c
 delete mode 100644 hw/block/xen_disk.c
 create mode 100644 hw/xen/xen-backend.c
 create mode 100644 hw/xen/xen-bus-helper.c
 create mode 100644 hw/xen/xen-bus.c
 rename hw/xen/{xen_backend.c => xen-legacy-backend.c} (89%)
 create mode 100644 include/hw/xen/xen-backend.h
 create mode 100644 include/hw/xen/xen-bus-helper.h
 create mode 100644 include/h

[Qemu-block] [PATCH 03/18] xen: introduce 'xen-qdisk'

2018-11-21 Thread Paul Durrant
This patch adds a new XenDevice: 'xen-qdisk' [1]. This will eventually
replace the 'xen_disk' legacy PV backend but it is illustrative to build
up the implementation incrementally, along with the XenBus/XenDevice
framework. Subsequent patches will therefore add to this device's
implementation as new features are added to the framework.

After this patch has been applied it is possible to instantiate a new
'xen-qdisk' device with a single 'vdev' parameter, which accepts values
adhering to the Xen VBD naming scheme [2]. For example, a command-line
instantiation of a xen-qdisk can be done with an argument similar to the
following:

-device xen-qdisk,vdev=hda

The implementation of the vdev parameter formulates the appropriate VBD
number for use in the PV protocol.

[1] The name 'qdisk' as always been the name given to the QEMU
implementation of the Xen PV block protocol backend implementation
[2] 
http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/man/xen-vbd-interface.markdown.7

Signed-off-by: Paul Durrant 
---
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 MAINTAINERS|   2 +-
 hw/block/Makefile.objs |   1 +
 hw/block/trace-events  |   4 +
 hw/block/xen-qdisk.c   | 256 +
 include/hw/xen/xen-qdisk.h |  38 +++
 5 files changed, 300 insertions(+), 1 deletion(-)
 create mode 100644 hw/block/xen-qdisk.c
 create mode 100644 include/hw/xen/xen-qdisk.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1032406c56..10f048a503 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -389,7 +389,7 @@ F: hw/9pfs/xen-9p-backend.c
 F: hw/char/xen_console.c
 F: hw/display/xenfb.c
 F: hw/net/xen_nic.c
-F: hw/block/xen_*
+F: hw/block/xen*
 F: hw/xen/
 F: hw/xenpv/
 F: hw/i386/xen/
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index 53ce5751ae..bcdd36d318 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -5,6 +5,7 @@ common-obj-$(CONFIG_NAND) += nand.o
 common-obj-$(CONFIG_PFLASH_CFI01) += pflash_cfi01.o
 common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 common-obj-$(CONFIG_XEN) += xen_disk.o
+common-obj-$(CONFIG_XEN) += xen-qdisk.o
 common-obj-$(CONFIG_ECC) += ecc.o
 common-obj-$(CONFIG_ONENAND) += onenand.o
 common-obj-$(CONFIG_NVME_PCI) += nvme.o
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 335c092450..fd3c126ac1 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -127,3 +127,7 @@ xen_disk_init(char *name) "%s"
 xen_disk_connect(char *name) "%s"
 xen_disk_disconnect(char *name) "%s"
 xen_disk_free(char *name) "%s"
+
+# hw/block/xen-qdisk.c
+xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
new file mode 100644
index 00..72122073f7
--- /dev/null
+++ b/hw/block/xen-qdisk.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "hw/hw.h"
+#include "hw/xen/xen-qdisk.h"
+#include "trace.h"
+
+static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
+{
+XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+if (!vdev->valid) {
+error_setg(errp, "vdev property not set");
+return;
+}
+
+trace_xen_qdisk_realize(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
+{
+XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+}
+
+static char *disk_to_vbd_name(unsigned int disk)
+{
+unsigned int len = DIV_ROUND_UP(disk, 26);
+char *name = g_malloc0(len + 1);
+
+do {
+name[len--] = 'a' + (disk % 26);
+disk /= 26;
+} while (disk != 0);
+assert(len == 0);
+
+return name;
+}
+
+static void xen_qdisk_get_vdev(Object *obj, Visitor *v, const char *name,
+   void *opaque, Error **errp)
+{
+DeviceState *dev = DEVICE(obj);
+Property *prop = opaque;
+XenQdiskVdev *vdev = qdev_get_prop_ptr(dev, prop);
+char *str;
+
+switch (vdev->type) {
+case XEN_QDISK_VDEV_TYPE_DP:
+str = g_strdup_printf("d%lup%lu", vdev->disk, vdev->partition);
+break;
+
+case XEN_QDISK_VDEV_TYPE_XVD:
+case XEN_QDISK_VDEV_TYPE_HD:
+case XEN_QDISK_VDEV_TYPE_SD: {
+char *name = disk_to_vbd_name(vdev->disk);
+
+str = g_strdup_printf("%s%s%lu",
+  (vdev->type == XEN_QDISK_VDEV_TYPE_XVD) ?
+  "xvd" :
+  (vdev->type == XEN_QDISK_VDEV_TYPE_HD) ?
+  "hd" :
+  "sd",
+  name, vdev->partition);
+  

[Qemu-block] [PATCH 05/18] xen: add xenstore watcher infratructure

2018-11-21 Thread Paul Durrant
A Xen PV frontend communicates its state to the PV backend by writing to
the 'state' key in the frontend area in xenstore. It is therefore
necessary for a XenDevice implementation to be notified whenever the
value of this key changes.

This patch adds code to do this as follows:

- an 'fd handler' is registered on the libxenstore handle which will be
  triggered whenever a 'watch' event occurs
- primitives are added to xen-bus-helper to add or remove watch events
- a list of Notifier objects is added to XenBus to provide a mechanism
  to call the appropriate 'watch handler' when its associated event
  occurs

The xen-qisk implementation is extended with a 'frontend_changed' method,
which calls as-yet stub 'connect' and 'disconnect' functions when the
relevant frontend state transitions occur. A subsequent patch will supply
a full implementation for these functions.

Signed-off-by: Paul Durrant 
---
Cc: Kevin Wolf 
Cc: Max Reitz 
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 hw/block/trace-events   |   2 +
 hw/block/xen-qdisk.c|  56 +++
 hw/xen/trace-events |   4 +
 hw/xen/xen-bus-helper.c |  28 ++
 hw/xen/xen-bus.c| 205 +++-
 include/hw/xen/xen-bus-helper.h |   5 +
 include/hw/xen/xen-bus.h|  15 +++
 7 files changed, 313 insertions(+), 2 deletions(-)

diff --git a/hw/block/trace-events b/hw/block/trace-events
index fd3c126ac1..8b95567560 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -130,4 +130,6 @@ xen_disk_free(char *name) "%s"
 
 # hw/block/xen-qdisk.c
 xen_qdisk_realize(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_connect(uint32_t disk, uint32_t partition) "d%up%u"
+xen_qdisk_disconnect(uint32_t disk, uint32_t partition) "d%up%u"
 xen_qdisk_unrealize(uint32_t disk, uint32_t partition) "d%up%u"
diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 0859643f7d..35f7b70480 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -32,12 +32,67 @@ static void xen_qdisk_realize(XenDevice *xendev, Error 
**errp)
 trace_xen_qdisk_realize(vdev->disk, vdev->partition);
 }
 
+static void xen_qdisk_connect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+trace_xen_qdisk_connect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_disconnect(XenQdiskDevice *qdiskdev, Error **errp)
+{
+XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+trace_xen_qdisk_disconnect(vdev->disk, vdev->partition);
+}
+
+static void xen_qdisk_frontend_changed(XenDevice *xendev,
+   enum xenbus_state frontend_state,
+   Error **errp)
+{
+XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
+Error *local_err = NULL;
+
+switch (frontend_state) {
+case XenbusStateInitialised:
+case XenbusStateConnected:
+if (backend_state == XenbusStateConnected) {
+break;
+}
+
+xen_qdisk_disconnect(qdiskdev, &error_fatal);
+xen_qdisk_connect(qdiskdev, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+break;
+}
+
+xen_device_backend_set_state(xendev, XenbusStateConnected);
+break;
+
+case XenbusStateClosing:
+xen_device_backend_set_state(xendev, XenbusStateClosing);
+break;
+
+case XenbusStateClosed:
+xen_qdisk_disconnect(qdiskdev, &error_fatal);
+xen_device_backend_set_state(xendev, XenbusStateClosed);
+break;
+
+default:
+break;
+}
+}
+
 static void xen_qdisk_unrealize(XenDevice *xendev, Error **errp)
 {
 XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
 XenQdiskVdev *vdev = &qdiskdev->vdev;
 
 trace_xen_qdisk_unrealize(vdev->disk, vdev->partition);
+
+xen_qdisk_disconnect(qdiskdev, &error_fatal);
 }
 
 static char *disk_to_vbd_name(unsigned int disk)
@@ -246,6 +301,7 @@ static void xen_qdisk_class_init(ObjectClass *class, void 
*data)
 xendev_class->device = "vbd";
 xendev_class->get_name = xen_qdisk_get_name;
 xendev_class->realize = xen_qdisk_realize;
+xendev_class->frontend_changed = xen_qdisk_frontend_changed;
 xendev_class->unrealize = xen_qdisk_unrealize;
 
 dev_class->desc = "Xen Qdisk Device";
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index fa8aea1da1..94c46c2e34 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,7 +16,11 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
+xen_bus_add_watch(const char *node, const char *key, char *token) "node: %s 
key: %s token: %s"
+xen_bus_remove_watch(const char *node, const char *key, char *token) "node: %s 
key: %s token: %s"
+xen_bus_watch(const char *token) "token: %s"
 xen_device_realize(const char *type, char *name

[Qemu-block] [PATCH 04/18] xen: create xenstore areas for XenDevice-s

2018-11-21 Thread Paul Durrant
This patch adds a new source module, xen-bus-helper.c, which builds on
basic libxenstore primitives to provide functions to create (setting
permissions appropriately) and destroy xenstore areas, and functions to
'printf' and 'scanf' nodes therein. The main xen-bus code then uses
these primitives [1] to initialize and destroy the frontend and backend
areas for a XenDevice during realize and unrealize respectively.

The 'xen-qdisk' implementation is extended with a 'get_name' method that
returns the VBD number. This number is reqired to 'name' the xenstore
areas.

NOTE: An exit handler is also added to make sure the xenstore areas are
  cleaned up if QEMU terminates without devices being unrealized.

[1] The 'scanf' functions are actually not yet needed, but they will be
needed by code delivered in subsequent patches.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: Kevin Wolf 
Cc: Max Reitz 
---
 hw/block/xen-qdisk.c|  11 ++
 hw/xen/Makefile.objs|   2 +-
 hw/xen/trace-events |   6 +-
 hw/xen/xen-bus-helper.c | 124 +
 hw/xen/xen-bus.c| 288 +++-
 include/hw/xen/xen-bus-helper.h |  26 
 include/hw/xen/xen-bus.h|  12 ++
 7 files changed, 464 insertions(+), 5 deletions(-)
 create mode 100644 hw/xen/xen-bus-helper.c
 create mode 100644 include/hw/xen/xen-bus-helper.h

diff --git a/hw/block/xen-qdisk.c b/hw/block/xen-qdisk.c
index 72122073f7..0859643f7d 100644
--- a/hw/block/xen-qdisk.c
+++ b/hw/block/xen-qdisk.c
@@ -11,6 +11,14 @@
 #include "hw/xen/xen-qdisk.h"
 #include "trace.h"
 
+static char *xen_qdisk_get_name(XenDevice *xendev, Error **errp)
+{
+XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
+XenQdiskVdev *vdev = &qdiskdev->vdev;
+
+return g_strdup_printf("%lu", vdev->number);
+}
+
 static void xen_qdisk_realize(XenDevice *xendev, Error **errp)
 {
 XenQdiskDevice *qdiskdev = XEN_QDISK_DEVICE(xendev);
@@ -234,6 +242,9 @@ static void xen_qdisk_class_init(ObjectClass *class, void 
*data)
 DeviceClass *dev_class = DEVICE_CLASS(class);
 XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);
 
+xendev_class->backend = "qdisk";
+xendev_class->device = "vbd";
+xendev_class->get_name = xen_qdisk_get_name;
 xendev_class->realize = xen_qdisk_realize;
 xendev_class->unrealize = xen_qdisk_unrealize;
 
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index d9d6d7b4f9..77c0868190 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o xen-bus.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o xen-bus.o xen-bus-helper.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o 
xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index 0172cd4e26..fa8aea1da1 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -16,5 +16,7 @@ xen_domid_restrict(int err) "err: %u"
 # include/hw/xen/xen-bus.c
 xen_bus_realize(void) ""
 xen_bus_unrealize(void) ""
-xen_device_realize(const char *type) "type: %s"
-xen_device_unrealize(const char *type) "type: %s"
+xen_device_realize(const char *type, char *name) "type: %s name: %s"
+xen_device_unrealize(const char *type, char *name) "type: %s name: %s"
+xen_device_backend_state(const char *type, char *name, const char *state) 
"type: %s name: %s -> %s"
+xen_device_frontend_state(const char *type, char *name, const char *state) 
"type: %s name: %s -> %s"
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
new file mode 100644
index 00..d9ee2ed6a0
--- /dev/null
+++ b/hw/xen/xen-bus-helper.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen.h"
+#include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "qapi/error.h"
+
+struct xs_state {
+enum xenbus_state statenum;
+const char *statestr;
+};
+#define XS_STATE(state) { state, #state }
+
+static struct xs_state xs_state[] = {
+XS_STATE(XenbusStateUnknown),
+XS_STATE(XenbusStateInitialising),
+XS_STATE(XenbusStateInitWait),
+XS_STATE(XenbusStateInitialised),
+XS_STATE(XenbusStateConnected),
+XS_STATE(XenbusStateClosing),
+XS_STATE(XenbusStateClosed),
+XS_STATE(XenbusStateReconfiguring),
+XS_STATE(XenbusStateReconfigured),
+};
+
+#undef XS_STATE
+
+const char *xs_strstate(enum xenbus_state state)
+{
+unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
+if (xs_state[i].statenum == state) {
+return xs_state[i].statestr;
+}
+}
+
+return "INVALID";
+}
+
+void xs_node_create(struct

[Qemu-block] [PATCH 07/18] xen: add event channel interface for XenDevice-s

2018-11-21 Thread Paul Durrant
The legacy PV backend infrastructure provides functions to bind, unbind
and send notifications to event channnels. Similar functionality will be
required by XenDevice implementations so this patch adds the necessary
support.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
---
 hw/xen/xen-bus.c | 84 
 include/hw/xen/xen-bus.h | 16 +
 2 files changed, 100 insertions(+)

diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
index 7a152d2a2f..64c8af54b0 100644
--- a/hw/xen/xen-bus.c
+++ b/hw/xen/xen-bus.c
@@ -579,6 +579,65 @@ done:
 g_free(xengnttab_segs);
 }
 
+struct XenEventChannel {
+unsigned int local_port;
+XenEventHandler handler;
+void *opaque;
+Notifier notifier;
+};
+
+static void event_notify(Notifier *n, void *data)
+{
+XenEventChannel *channel = container_of(n, XenEventChannel, notifier);
+unsigned long port = (unsigned long)data;
+
+if (port == channel->local_port) {
+channel->handler(channel->opaque);
+}
+}
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+   unsigned int port,
+   XenEventHandler handler,
+   void *opaque, Error **errp)
+{
+XenEventChannel *channel = g_new0(XenEventChannel, 1);
+
+channel->local_port = xenevtchn_bind_interdomain(xendev->xeh,
+ xendev->frontend_id,
+ port);
+if (xendev->local_port < 0) {
+error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
+
+g_free(channel);
+return NULL;
+}
+
+channel->handler = handler;
+channel->opaque = opaque;
+channel->notifier.notify = event_notify;
+
+notifier_list_add(&xendev->event_notifiers, &channel->notifier);
+
+return channel;
+}
+
+void xen_device_notify_event_channel(XenDevice *xendev,
+ XenEventChannel *channel)
+{
+xenevtchn_notify(xendev->xeh, channel->local_port);
+}
+
+void xen_device_unbind_event_channel(XenDevice *xendev,
+ XenEventChannel *channel)
+{
+notifier_remove(&channel->notifier);
+
+xenevtchn_unbind(xendev->xeh, channel->local_port);
+
+g_free(channel);
+}
+
 static void xen_device_unrealize(DeviceState *dev, Error **errp)
 {
 XenDevice *xendev = XEN_DEVICE(dev);
@@ -602,6 +661,11 @@ static void xen_device_unrealize(DeviceState *dev, Error 
**errp)
 xen_device_frontend_destroy(xendev);
 xen_device_backend_destroy(xendev);
 
+if (xendev->xeh) {
+qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), NULL, NULL, NULL);
+xenevtchn_close(xendev->xeh);
+}
+
 if (xendev->xgth) {
 xengnttab_close(xendev->xgth);
 }
@@ -616,6 +680,16 @@ static void xen_device_exit(Notifier *n, void *data)
 xen_device_unrealize(DEVICE(xendev), &error_abort);
 }
 
+static void xen_device_event(void *opaque)
+{
+XenDevice *xendev = opaque;
+unsigned long port = xenevtchn_pending(xendev->xeh);
+
+notifier_list_notify(&xendev->event_notifiers, (void *)port);
+
+xenevtchn_unmask(xendev->xeh, port);
+}
+
 static void xen_device_realize(DeviceState *dev, Error **errp)
 {
 XenDevice *xendev = XEN_DEVICE(dev);
@@ -656,6 +730,16 @@ static void xen_device_realize(DeviceState *dev, Error 
**errp)
 xendev->feature_grant_copy =
 (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
 
+xendev->xeh = xenevtchn_open(NULL, 0);
+if (!xendev->xeh) {
+error_setg_errno(errp, errno, "failed xenevtchn_open");
+goto unrealize;
+}
+
+notifier_list_init(&xendev->event_notifiers);
+qemu_set_fd_handler(xenevtchn_fd(xendev->xeh), xen_device_event, NULL,
+xendev);
+
 xen_device_backend_create(xendev, &local_err);
 if (local_err) {
 error_propagate(errp, local_err);
diff --git a/include/hw/xen/xen-bus.h b/include/hw/xen/xen-bus.h
index db14d49027..386f6bfc93 100644
--- a/include/hw/xen/xen-bus.h
+++ b/include/hw/xen/xen-bus.h
@@ -24,6 +24,9 @@ typedef struct XenDevice {
 XenWatch *frontend_state_watch;
 xengnttab_handle *xgth;
 bool feature_grant_copy;
+xenevtchn_handle *xeh;
+xenevtchn_port_or_error_t local_port;
+NotifierList event_notifiers;
 } XenDevice;
 
 typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
@@ -102,4 +105,17 @@ void xen_device_copy_grant_refs(XenDevice *xendev, bool 
to_domain,
 XenDeviceGrantCopySegment segs[],
 unsigned int nr_segs, Error **errp);
 
+typedef struct XenEventChannel XenEventChannel;
+
+typedef void (*XenEventHandler)(void *opaque);
+
+XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
+   

[Qemu-block] [PATCH 02/18] xen: introduce new 'XenBus' and 'XenDevice' object hierarchy

2018-11-21 Thread Paul Durrant
This patch adds the basic boilerplate for a 'XenBus' object that will act
as a parent to 'XenDevice' PV backends.
A new 'XenBridge' object is also added to connect XenBus to the system bus.

The XenBus object is instantiated by a new xen_bus_init() function called
from the same sites as the legacy xen_be_init() function.

Subsequent patches will flesh-out the functionality of these objects.

Signed-off-by: Paul Durrant 
---
Cc: Stefano Stabellini 
Cc: Anthony Perard 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
---
 hw/i386/xen/xen-hvm.c |   3 ++
 hw/xen/Makefile.objs  |   2 +-
 hw/xen/trace-events   |   6 +++
 hw/xen/xen-bus.c  | 125 ++
 hw/xenpv/xen_machine_pv.c |   3 ++
 include/hw/xen/xen-bus.h  |  53 
 6 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 hw/xen/xen-bus.c
 create mode 100644 include/hw/xen/xen-bus.h

diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c
index 1d637639c7..4497f751d2 100644
--- a/hw/i386/xen/xen-hvm.c
+++ b/hw/i386/xen/xen-hvm.c
@@ -17,6 +17,7 @@
 #include "hw/i386/apic-msidef.h"
 #include "hw/xen/xen_common.h"
 #include "hw/xen/xen-legacy-backend.h"
+#include "hw/xen/xen-bus.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-misc.h"
 #include "qemu/error-report.h"
@@ -1479,6 +1480,8 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion 
**ram_memory)
 QLIST_INIT(&state->dev_list);
 device_listener_register(&state->device_listener);
 
+xen_bus_init();
+
 /* Initialize backend core & drivers */
 if (xen_be_init() != 0) {
 error_report("xen backend core setup failed");
diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs
index 3f64a44051..d9d6d7b4f9 100644
--- a/hw/xen/Makefile.objs
+++ b/hw/xen/Makefile.objs
@@ -1,5 +1,5 @@
 # xen backend driver support
-common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o
+common-obj-$(CONFIG_XEN) += xen-legacy-backend.o xen_devconfig.o xen_pvdev.o 
xen-common.o xen-bus.o
 
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o 
xen_pt_graphics.o xen_pt_msi.o
diff --git a/hw/xen/trace-events b/hw/xen/trace-events
index c7e7a3b523..0172cd4e26 100644
--- a/hw/xen/trace-events
+++ b/hw/xen/trace-events
@@ -12,3 +12,9 @@ xen_unmap_portio_range(uint32_t id, uint64_t start_addr, 
uint64_t end_addr) "id:
 xen_map_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u 
bdf: %02x.%02x.%02x"
 xen_unmap_pcidev(uint32_t id, uint8_t bus, uint8_t dev, uint8_t func) "id: %u 
bdf: %02x.%02x.%02x"
 xen_domid_restrict(int err) "err: %u"
+
+# include/hw/xen/xen-bus.c
+xen_bus_realize(void) ""
+xen_bus_unrealize(void) ""
+xen_device_realize(const char *type) "type: %s"
+xen_device_unrealize(const char *type) "type: %s"
diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c
new file mode 100644
index 00..dede2d914a
--- /dev/null
+++ b/hw/xen/xen-bus.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/sysbus.h"
+#include "hw/xen/xen-bus.h"
+#include "qapi/error.h"
+#include "trace.h"
+
+static void xen_bus_unrealize(BusState *bus, Error **errp)
+{
+trace_xen_bus_unrealize();
+}
+
+static void xen_bus_realize(BusState *bus, Error **errp)
+{
+trace_xen_bus_realize();
+}
+
+static void xen_bus_class_init(ObjectClass *class, void *data)
+{
+BusClass *bus_class = BUS_CLASS(class);
+
+bus_class->realize = xen_bus_realize;
+bus_class->unrealize = xen_bus_unrealize;
+}
+
+static const TypeInfo xen_bus_type_info = {
+.name = TYPE_XEN_BUS,
+.parent = TYPE_BUS,
+.instance_size = sizeof(XenBus),
+.class_size = sizeof(XenBusClass),
+.class_init = xen_bus_class_init,
+};
+
+static void xen_device_unrealize(DeviceState *dev, Error **errp)
+{
+XenDevice *xendev = XEN_DEVICE(dev);
+XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+const char *type = object_get_typename(OBJECT(xendev));
+Error *local_err = NULL;
+
+trace_xen_device_unrealize(type);
+
+if (xendev_class->unrealize) {
+xendev_class->unrealize(xendev, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+}
+}
+
+static void xen_device_realize(DeviceState *dev, Error **errp)
+{
+XenDevice *xendev = XEN_DEVICE(dev);
+XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
+const char *type = object_get_typename(OBJECT(xendev));
+Error *local_err = NULL;
+
+trace_xen_device_realize(type);
+
+if (xendev_class->realize) {
+xendev_class->realize(xendev, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+goto unrealize;
+}
+}
+
+return;
+
+

Re: [Qemu-block] [PATCH] scsi-disk: Fix crash if underlying host file or disk returns error.

2018-11-21 Thread Kevin Wolf
Am 21.11.2018 um 13:47 hat Richard W.M. Jones geschrieben:
> Commit 40dce4ee6 "scsi-disk: fix rerror/werror=ignore" introduced a
> bug which causes qemu to crash with the assertion error below if the
> host file or disk returns an error:
> 
>   qemu-system-x86_64: hw/scsi/scsi-bus.c:1374: scsi_req_complete:
>   Assertion `req->status == -1' failed.
> 
> Kevin Wolf suggested this fix:
> 
>   < kwolf> Hm, should the final return false; in that patch
>actually be a return true?
>   < kwolf> Because I think he didn't intend to change anything
>except BLOCK_ERROR_ACTION_IGNORE
> 
> Signed-off-by: Richard W.M. Jones 
> Buglink: https://bugs.launchpad.net/qemu/+bug/1804323

Thanks, applied to the block branch.

Kevin



Re: [Qemu-block] [Qemu-devel] [PATCH] iotests: Skip 233 if certtool not installed

2018-11-21 Thread Wainer dos Santos Moschetta




On 11/20/2018 08:52 PM, Eric Blake wrote:

The use of TLS while building qemu is optional. While the
'certtool' binary should be available on every platform that
supports building against TLS, that does not imply that the
developer has installed it.  Make the test gracefully skip
in that case.

Reported-by: Kevin Wolf 
Signed-off-by: Eric Blake 


Reviewed-by: Wainer dos Santos Moschetta 


---

On Fedora, libvirt requires libtls-utils to be present, but not qemu.

I'm fine if Kevin wants to pick this up in a pull request related
to iotests in general; if not, I'll do a pull request through my
NBD tree in time for -rc3.

  tests/qemu-iotests/common.tls | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/tests/qemu-iotests/common.tls b/tests/qemu-iotests/common.tls
index 39f17c1b999..eae81789bbc 100644
--- a/tests/qemu-iotests/common.tls
+++ b/tests/qemu-iotests/common.tls
@@ -31,6 +31,9 @@ tls_x509_cleanup()

  tls_x509_init()
  {
+(certtool --help) >/dev/null 2>&1 || \
+   _notrun "certtool utility not found, skipping test"
+
  mkdir -p "${tls_dir}"

  # use a fixed key so we don't waste system entropy on





[Qemu-block] [PATCH] scsi-disk: Fix crash if underlying host file or disk returns error.

2018-11-21 Thread Richard W.M. Jones
Commit 40dce4ee6 "scsi-disk: fix rerror/werror=ignore" introduced a
bug which causes qemu to crash with the assertion error below if the
host file or disk returns an error:

  qemu-system-x86_64: hw/scsi/scsi-bus.c:1374: scsi_req_complete:
  Assertion `req->status == -1' failed.

Kevin Wolf suggested this fix:

  < kwolf> Hm, should the final return false; in that patch
   actually be a return true?
  < kwolf> Because I think he didn't intend to change anything
   except BLOCK_ERROR_ACTION_IGNORE

Signed-off-by: Richard W.M. Jones 
Buglink: https://bugs.launchpad.net/qemu/+bug/1804323
---
 hw/scsi/scsi-disk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 6eb258d3f3..0e9027c8f3 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -482,7 +482,7 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, 
bool acct_failed)
 if (action == BLOCK_ERROR_ACTION_STOP) {
 scsi_req_retry(&r->req);
 }
-return false;
+return true;
 }
 
 static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
-- 
2.19.0.rc0




Re: [Qemu-block] [PATCH for-next? 0/2] qemu-img: Minor fixes to an amend error path

2018-11-21 Thread Kevin Wolf
Am 19.11.2018 um 11:19 hat Max Reitz geschrieben:
> One of the amend error paths has two issues that are fixed by this
> series.  Since they are relatively minor and have been present in 3.0
> already, I think there is no need to get them into 3.1.  OTOH they are
> bug fixes, so they could go into 3.1 if you, dear reader, insist.

Thanks, applied to the block branch (looks like the dear reader
insists).

Kevin



Re: [Qemu-block] [PATCH] iotests: Skip 233 if certtool not installed

2018-11-21 Thread Kevin Wolf
Am 20.11.2018 um 23:52 hat Eric Blake geschrieben:
> The use of TLS while building qemu is optional. While the
> 'certtool' binary should be available on every platform that
> supports building against TLS, that does not imply that the
> developer has installed it.  Make the test gracefully skip
> in that case.
> 
> Reported-by: Kevin Wolf 
> Signed-off-by: Eric Blake 

Thanks, applied to the block branch.

Kevin



Re: [Qemu-block] [PATCH] iotests: Skip 233 if certtool not installed

2018-11-21 Thread Daniel P . Berrangé
On Tue, Nov 20, 2018 at 04:52:41PM -0600, Eric Blake wrote:
> The use of TLS while building qemu is optional. While the
> 'certtool' binary should be available on every platform that
> supports building against TLS, that does not imply that the
> developer has installed it.  Make the test gracefully skip
> in that case.
> 
> Reported-by: Kevin Wolf 
> Signed-off-by: Eric Blake 
> ---
> 
> On Fedora, libvirt requires libtls-utils to be present, but not qemu.
> 
> I'm fine if Kevin wants to pick this up in a pull request related
> to iotests in general; if not, I'll do a pull request through my
> NBD tree in time for -rc3.
> 
>  tests/qemu-iotests/common.tls | 3 +++
>  1 file changed, 3 insertions(+)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-block] [PATCH 6/6] tests: exercise NBD server in TLS mode

2018-11-21 Thread Daniel P . Berrangé
On Tue, Nov 20, 2018 at 12:22:39PM -0600, Eric Blake wrote:
> On 11/20/18 11:53 AM, Daniel P. Berrangé wrote:
> 
> > > > > +echo
> > > > > +echo "== preparing TLS creds =="
> > > > > +
> > > > > +tls_x509_create_root_ca "ca1"
> > > > > +tls_x509_create_root_ca "ca2"
> > > > > +tls_x509_create_server "ca1" "server1"
> > > > > +tls_x509_create_client "ca1" "client1"
> > > > > +tls_x509_create_client "ca2" "client2"
> > > > 
> > > > Looks like we can't blindly assume that certtool exists. This test case
> > > > fails for me, starting with the following diff:
> > > 
> > > Looks like we'll need a followup patch to skip the test if certtool is not
> > > found. (I already did the same in common.nbd if 'ss' was not found; so it
> > > should be easy to copy...)
> > 
> > FWIW certtool is part of gnutls-utils and is available on every platform
> > that QEMU officially supports as a build target.
> 
> Ported to the build target != installed on the build machine. The failure is
> happening on machines that do not have all the build prerequisites (since it
> should still be possible to configure qemu to build without TLS, right?)

Yes, I just assumed that the iotests could expect a fully featured install

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|