Re: [Qemu-devel] [PATCH v6 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"

2016-11-14 Thread Markus Armbruster
Fam Zheng  writes:

> On Mon, 11/14 15:07, Stefan Hajnoczi wrote:
>> On Mon, Nov 07, 2016 at 04:59:44PM -0800, Ashish Mittal wrote:
>> > diff --git a/block/vxhs.c b/block/vxhs.c
>> > new file mode 100644
>> > index 000..8913e8f
>> > --- /dev/null
>> > +++ b/block/vxhs.c
>> > @@ -0,0 +1,689 @@
>> > +/*
>> > + * QEMU Block driver for Veritas HyperScale (VxHS)
>> > + *
>> > + * This work is licensed under the terms of the GNU GPL, version 2 or 
>> > later.
>> > + * See the COPYING file in the top-level directory.
>> > + *
>> > + */
>> > +
>> > +#include "qemu/osdep.h"
>> > +#include "block/block_int.h"
>> > +#include 
>> 
>> Please move system headers (<>) above user headers ("").  This way you
>> can be sure the system header isn't affected by any macros defined by
>> user headers.
>
> Yes, but still after "qemu/osdep.h", which prepares necessary bits for any 
> other
> headers.

Yes, osdep.h must come first.  See also scripts/clean-includes.



Re: [Qemu-devel] [PATCH] mttcg: Move tb lock asserts under DEBUG_LOCKING

2016-11-14 Thread Richard Henderson

On 11/15/2016 06:41 AM, Pranith Kumar wrote:

Move the asserts in tb_lock/unlock() to DEBUG_LOCKING to avoid the
assert checking overhead in normal builds.


I know DEBUG_LOCKING already exists in translate-all.c, but I think both this 
and the old ought to be using CONFIG_DEBUG_TCG, so that it is regularly enabled.


At which point you might as well use tcg_debug_assert instead of these wrappers 
around g_assert.



r~



[Qemu-devel] [PULL V3 3/3] docs: fix COLO architecture diagram

2016-11-14 Thread Jason Wang
From: Zhang Chen 

Fix COLO-Proxy part of COLO architecture diagram

Signed-off-by: Zhang Chen 
Reviewed-by: zhanghailiang 
Signed-off-by: Jason Wang 
---
 docs/COLO-FT.txt | 72 +---
 1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt
index 6282938..e289be2 100644
--- a/docs/COLO-FT.txt
+++ b/docs/COLO-FT.txt
@@ -41,41 +41,43 @@ identical responses to all client requests. Once the 
differences in the outputs
 are detected between the PVM and SVM, COLO withholds transmission of the
 outbound packets until it has successfully synchronized the PVM state to the 
SVM.
 
-   Primary Node
Secondary Node
- ++  +---+   ++  
++
- ||  |   HeartBeat   |<->|   HeartBeat|  | 
   |
- | Primary VM |  +---|---+   +---|+  
|Secondary VM|
- ||  |   |   | 
   |
- ||  +---|---+   +---|+  | 
   |
- ||  |QEMU   +---v+  |   |QEMU  +v---+|  | 
   |
- ||  |   |Failover|  |   |  |Failover||  | 
   |
- ||  |   ++  |   |  ++|  | 
   |
- ||  |   +---+   |   |   +---+|  | 
   |
- ||  |   | VM Checkpoint |-->| VM Checkpoint ||  | 
   |
- ||  |   +---+   |   |   +---+|  | 
   |
- ||  |   |   ||  | 
   |
- 
|Requests<---^-->Requests|
- |Responses--\ /--|--\  
/Responses|
- ||  |   | |  |  |   |   |  | |  | 
   |
- ||  | +---+ | |  |  |   |   |  |  ++ |  | 
   |
- ||  | | COLO disk | | |  |  |   |   |  |  | COLO disk  | |  | 
   |
- ||  | |   Manager |-|-|--|--|--|->| Manager| |  | 
   |
- ||  | +|--+ | |  |  |   |   |  |  +---|+ |  | 
   |
- ||  |  || |  |  |   |   |  |  |  |  | 
   |
- ++  +--||-|--|--+   +---|--|--|--+  
++
-|| |  |  |  |  |
- +-+| +--v-v--|--+   +---|--v---+  |
+-+
- |  VM Monitor || |  COLO Proxy  |   |COLO Proxy|  || 
VM Monitor  |
- | || |(compare packet)  |   | (adjust sequence)|  ||  
   |
- +-+| +--|^--+   +--+  |
+-+
-||||
- +--|||--+   
+-|--+
- |   Kernel |||  |   |   Kernel|   
   |
- +--|||--+   
+-|--+
-||||
- +--v+  +v|--+   +--+ 
+v-+
- |   Storage |  |External Network|   | External Network | |   
Storage|
- +---+  ++   +--+ 
+--+
+  Primary Node
Secondary Node
+++  +---+   ++  
++
+||  |   HeartBeat   +<->+   HeartBeat|  |  
  |
+| Primary VM |  +---+---+   +---++  
|Secondary VM|
+||  |   |   |  
  |
+||  +---|---+   +---|+  |  
  |
+||  |QEMU   +---v+  |   |QEMU  +v---+|  |  
  |
+||  |   |Failover|  |   |  |Failover||  |  
  |
+||  |   ++  |   |  ++|  |  
  |
+||  |   +---+   |   |   +---+|  |  
  |
+||  |   | VM Checkpoint +-->+ VM Checkpoint 

[Qemu-devel] [PULL V3 2/3] net: fix sending of data with -net socket, listen backend

2016-11-14 Thread Jason Wang
From: "Daniel P. Berrange" 

The use of -net socket,listen was broken in the following
commit

  commit 16a3df403b10c4ac347159e39005fd520b2648bb
  Author: Zhang Chen 
  Date:   Fri May 13 15:35:19 2016 +0800

net/net: Add SocketReadState for reuse codes

This function is from net/socket.c, move it to net.c and net.h.
Add SocketReadState to make others reuse net_fill_rstate().
suggestion from jason.

This refactored the state out of NetSocketState into a
separate SocketReadState. This refactoring requires
that a callback is provided to be triggered upon
completion of a packet receive from the guest.

The patch only registered this callback in the codepaths
hit by -net socket,connect, not -net socket,listen. So
as a result packets sent by the guest in the latter case
get dropped on the floor.

This bug is hidden because net_fill_rstate() silently
does nothing if the callback is not set.

This patch adds in the middle callback registration
and also adds an assert so that QEMU aborts if there
are any other codepaths hit which are missing the
callback.

Signed-off-by: Daniel P. Berrange 
Reviewed-by: Zhang Chen 
Signed-off-by: Jason Wang 
---
 net/net.c| 5 ++---
 net/socket.c | 1 +
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/net.c b/net/net.c
index ec984bf..939fe31 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1653,9 +1653,8 @@ int net_fill_rstate(SocketReadState *rs, const uint8_t 
*buf, int size)
 if (rs->index >= rs->packet_len) {
 rs->index = 0;
 rs->state = 0;
-if (rs->finalize) {
-rs->finalize(rs);
-}
+assert(rs->finalize);
+rs->finalize(rs);
 }
 break;
 }
diff --git a/net/socket.c b/net/socket.c
index 982c8de..fe3547b 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -511,6 +511,7 @@ static int net_socket_listen_init(NetClientState *peer,
 s->fd = -1;
 s->listen_fd = ret;
 s->nc.link_down = true;
+net_socket_rs_init(>rs, net_socket_rs_finalize);
 
 qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
 qapi_free_SocketAddress(saddr);
-- 
2.7.4




[Qemu-devel] [PULL V3 0/3] Net patches

2016-11-14 Thread Jason Wang
The following changes since commit 682df581c65ed2c1b9e77093e332214ecaa1ee93:

  Merge remote-tracking branch 'jsnow/tags/ide-pull-request' into staging 
(2016-11-14 17:07:16 +)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to a38299bf431a891c0a21a77199e7148c0983413e:

  docs: fix COLO architecture diagram (2016-11-15 15:36:21 +0800)



Changes from V1:
- no change, V1 misses the list
Changes from V2:
- drop record/replay network support
- add a new patch that fixes the COLO proxy parts in the doc


Daniel P. Berrange (1):
  net: fix sending of data with -net socket, listen backend

Yuri Benditovich (1):
  net: skip virtio-net config of deleted nic's peers

Zhang Chen (1):
  docs: fix COLO architecture diagram

 docs/COLO-FT.txt| 72 +++--
 hw/net/virtio-net.c |  4 +++
 net/net.c   |  5 ++--
 net/socket.c|  1 +
 4 files changed, 44 insertions(+), 38 deletions(-)




[Qemu-devel] [PULL V3 1/3] net: skip virtio-net config of deleted nic's peers

2016-11-14 Thread Jason Wang
From: Yuri Benditovich 

https://bugzilla.redhat.com/show_bug.cgi?id=1373816
qemu core dump happens during repetitive unpug-plug
with multiple queues and Windows RSS-capable guest.
If back-end delete requested during virtio-net device
initialization, driver still can try configure the device
for multiple queues. The virtio-net device is expected
to be removed as soon as the initialization is done.

Signed-off-by: Yuri Benditovich 
Signed-off-by: Jason Wang 
---
 hw/net/virtio-net.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 06bfe4b..77a4fae 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -508,6 +508,10 @@ static void virtio_net_set_queues(VirtIONet *n)
 int i;
 int r;
 
+if (n->nic->peer_deleted) {
+return;
+}
+
 for (i = 0; i < n->max_queues; i++) {
 if (i < n->curr_queues) {
 r = peer_attach(n, i);
-- 
2.7.4




Re: [Qemu-devel] [PATCH] docs: fix COLO architecture diagram

2016-11-14 Thread Jason Wang



On 2016年11月01日 11:38, Zhang Chen wrote:

Fix COLO-Proxy part of COLO architecture diagram

Signed-off-by: Zhang Chen 
---
  docs/COLO-FT.txt | 72 +---
  1 file changed, 37 insertions(+), 35 deletions(-)

diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt
index 6282938..e289be2 100644
--- a/docs/COLO-FT.txt
+++ b/docs/COLO-FT.txt
@@ -41,41 +41,43 @@ identical responses to all client requests. Once the 
differences in the outputs
  are detected between the PVM and SVM, COLO withholds transmission of the
  outbound packets until it has successfully synchronized the PVM state to the 
SVM.
  
-   Primary NodeSecondary Node

- ++  +---+   ++  
++
- ||  |   HeartBeat   |<->|   HeartBeat|  | 
   |
- | Primary VM |  +---|---+   +---|+  
|Secondary VM|
- ||  |   |   | 
   |
- ||  +---|---+   +---|+  | 
   |
- ||  |QEMU   +---v+  |   |QEMU  +v---+|  | 
   |
- ||  |   |Failover|  |   |  |Failover||  | 
   |
- ||  |   ++  |   |  ++|  | 
   |
- ||  |   +---+   |   |   +---+|  | 
   |
- ||  |   | VM Checkpoint |-->| VM Checkpoint ||  | 
   |
- ||  |   +---+   |   |   +---+|  | 
   |
- ||  |   |   ||  | 
   |
- 
|Requests<---^-->Requests|
- |Responses--\ /--|--\  
/Responses|
- ||  |   | |  |  |   |   |  | |  | 
   |
- ||  | +---+ | |  |  |   |   |  |  ++ |  | 
   |
- ||  | | COLO disk | | |  |  |   |   |  |  | COLO disk  | |  | 
   |
- ||  | |   Manager |-|-|--|--|--|->| Manager| |  | 
   |
- ||  | +|--+ | |  |  |   |   |  |  +---|+ |  | 
   |
- ||  |  || |  |  |   |   |  |  |  |  | 
   |
- ++  +--||-|--|--+   +---|--|--|--+  
++
-|| |  |  |  |  |
- +-+| +--v-v--|--+   +---|--v---+  |
+-+
- |  VM Monitor || |  COLO Proxy  |   |COLO Proxy|  || 
VM Monitor  |
- | || |(compare packet)  |   | (adjust sequence)|  ||  
   |
- +-+| +--|^--+   +--+  |
+-+
-||||
- +--|||--+   
+-|--+
- |   Kernel |||  |   |   Kernel|   
   |
- +--|||--+   
+-|--+
-||||
- +--v+  +v|--+   +--+ 
+v-+
- |   Storage |  |External Network|   | External Network | |   
Storage|
- +---+  ++   +--+ 
+--+
+  Primary Node
Secondary Node
+++  +---+   ++  
++
+||  |   HeartBeat   +<->+   HeartBeat|  |  
  |
+| Primary VM |  +---+---+   +---++  
|Secondary VM|
+||  |   |   |  
  |
+||  +---|---+   +---|+  |  
  |
+||  |QEMU   +---v+  |   |QEMU  +v---+|  |  
  |
+||  |   |Failover|  |   |  |Failover||  |  
  |
+||  |   ++  |   |  ++|  |  
  |
+||  |   +---+   |   |   +---+|  |  
  |
+||  |   | VM Checkpoint +-->+ VM Checkpoint ||  |  
  |
+||  |   +---+   |   |   +---+|  |  
 

Re: [Qemu-devel] [PATCH v11 10/22] vfio iommu type1: Add support for mediated devices

2016-11-14 Thread Alexey Kardashevskiy
On 15/11/16 17:33, Kirti Wankhede wrote:
> 
> 
> On 11/15/2016 10:47 AM, Alexey Kardashevskiy wrote:
>> On 08/11/16 17:52, Alexey Kardashevskiy wrote:
>>> On 05/11/16 08:10, Kirti Wankhede wrote:
 VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
 Mediated device only uses IOMMU APIs, the underlying hardware can be
 managed by an IOMMU domain.

 Aim of this change is:
 - To use most of the code of TYPE1 IOMMU driver for mediated devices
 - To support direct assigned device and mediated device in single module

 This change adds pin and unpin support for mediated device to TYPE1 IOMMU
 backend module. More details:
 - vfio_pin_pages() callback here uses task and address space of vfio_dma,
   that is, of the process who mapped that iova range.
 - Added pfn_list tracking logic to address space structure. All pages
   pinned through this interface are trached in its address space.
 - Pinned pages list is used to verify unpinning request and to unpin
   remaining pages while detaching the group for that device.
 - Page accounting is updated to account in its address space where the
   pages are pinned/unpinned.
 -  Accouting for mdev device is only done if there is no iommu capable
   domain in the container. When there is a direct device assigned to the
   container and that domain is iommu capable, all pages are already pinned
   during DMA_MAP.
 - Page accouting is updated on hot plug and unplug mdev device and pass
   through device.

 Tested by assigning below combinations of devices to a single VM:
 - GPU pass through only
>>>
>>> This does not require this patchset, right?
>>>
> 
> Sorry I missed this earlier.
> This testing is required for this patch, because this patch touches code
> that is used for direct device assignment. Also for page accounting, all
> cases are considered i.e. when there is only pass through device in a
> container, when there is pass through device + vGPU device in a
> container. Also have to test that pages are pinned properly when device
> is hotplugged. In that case vfio_iommu_replay() is called to take
> necessary action.

So in this particular test you are only testing that the patchset did not
break the already existing functionality, is that correct?


> 
 - vGPU device only
>>>
>>> Out of curiosity - how exactly did you test this? The exact GPU, how to
>>> create vGPU, what was the QEMU command line and the guest does with this
>>> passed device? Thanks.
>>
>> ping?
>>
> 
> I'm testing this code with M60, with custom changes in our driver.


Is this shared anywhere? What does the mediated driver do? Can Tesla K80 do
the same thing, or [10de:15fe] (whatever its name is)?


> Steps how to create mediated device are listed in
> Documentation/vfio-mediated-device.txt for sample mtty driver. Same
> steps I'm following for GPU. Quoting those steps here for you:


Nah, I saw this, I was wondering about actual hardware :) Like when you say
"tested with vGPU" - I am wondering what is passed to the guest and how the
guest is actually using it.


> 
> 2. Create a mediated device by using the dummy device that you created
> in the
>previous step.
> 
># echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" >  \
> 
> /sys/devices/virtual/mtty/mtty/mdev_supported_types/mtty-2/create
> 
> 3. Add parameters to qemu-kvm.
> 
>-device vfio-pci,\
> sysfsdev=/sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001




-- 
Alexey



[Qemu-devel] [PATCH v1 13/18] block/pcache: inflight readahead request waiting for aio read

2016-11-14 Thread Pavel Butsykin
If there was a cache hit, but the status of the node is NODE_STATUS_INFLIGHT,
then this means that a readahead request for this node is in flight. In this 
case,
we can wait for the completion of the readahead request, and then copy the
data. It allows us even more to optimize aio read requests.

Signed-off-by: Pavel Butsykin 
---
 block/pcache.c | 73 +++---
 1 file changed, 65 insertions(+), 8 deletions(-)

diff --git a/block/pcache.c b/block/pcache.c
index 0f918d0..55d1061 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -67,9 +67,15 @@ typedef struct BDRVPCacheState {
 uint64_t readahead_size;
 } BDRVPCacheState;
 
+typedef struct ACBLinkEntry {
+QTAILQ_ENTRY(ACBLinkEntry) entry;
+struct PCacheAIOCBRead *acb;
+} ACBLinkEntry;
+
 typedef struct PCacheNode {
 RBCacheNode common;
 uint8_t *data;
+QTAILQ_HEAD(, ACBLinkEntry) wait_list;
 enum {
 NODE_STATUS_NEW   = 0,
 NODE_STATUS_INFLIGHT  = 1,
@@ -94,6 +100,7 @@ typedef struct PCacheAIOCBRead {
 uint64_t offset;
 uint64_t bytes;
 QEMUIOVector *qiov;
+int ref;
 int ret;
 } PCacheAIOCBRead;
 
@@ -147,18 +154,49 @@ static void read_cache_data(PCacheAIOCBRead *acb, 
PCacheNode *node,
 assert(copy == size);
 }
 
+static void pcache_aio_read(PCacheAIOCBRead *acb, PCacheNode *node)
+{
+ACBLinkEntry *link;
+
+if (node->status == NODE_STATUS_COMPLETED) {
+read_cache_data(acb, node, acb->offset, acb->bytes);
+return;
+}
+
+assert(node->status == NODE_STATUS_INFLIGHT ||
+   node->status == NODE_STATUS_REMOVE);
+
+link = g_malloc(sizeof(*link));
+link->acb = acb;
+
+QTAILQ_INSERT_HEAD(>wait_list, link, entry);
+acb->ref++;
+}
+
+static void aio_read_complete(PCacheAIOCBRead *acb, int ret)
+{
+if (ret < 0 && acb->ret == 0) {
+acb->ret = ret;
+}
+
+assert(acb->ref > 0);
+if (--acb->ref == 0) {
+qemu_coroutine_enter(acb->co);
+}
+}
+
 static void pcache_aio_read_cb(void *opaque, int ret)
 {
 PCacheAIOCBRead *acb = opaque;
 
-acb->ret = ret;
-qemu_coroutine_enter(acb->co);
+aio_read_complete(acb, ret);
 }
 
 static void pcache_aio_readahead_cb(void *opaque, int ret)
 {
 PCacheAIOCBReadahead *acb = opaque;
 PCacheNode *node = acb->node;
+ACBLinkEntry *link, *next;
 
 assert(node->status == NODE_STATUS_INFLIGHT ||
node->status == NODE_STATUS_REMOVE);
@@ -171,6 +209,20 @@ static void pcache_aio_readahead_cb(void *opaque, int ret)
 rbcache_remove(s->cache, >common);
 }
 }
+
+QTAILQ_FOREACH_SAFE(link, >wait_list, entry, next) {
+PCacheAIOCBRead *acb_read = link->acb;
+
+QTAILQ_REMOVE(>wait_list, link, entry);
+g_free(link);
+
+if (ret == 0) {
+read_cache_data(acb_read, node, acb_read->offset, acb_read->bytes);
+}
+
+aio_read_complete(acb_read, ret);
+}
+
 pcache_node_unref(node);
 
 qemu_coroutine_enter(acb->co);
@@ -254,6 +306,7 @@ static RBCacheNode *pcache_node_alloc(uint64_t offset, 
uint64_t bytes,
 node->data = g_malloc(bytes);
 node->status = NODE_STATUS_NEW;
 node->ref = 1;
+QTAILQ_INIT(>wait_list);
 
 return >common;
 }
@@ -379,7 +432,7 @@ static int pcache_lookup_data(PCacheAIOCBRead *acb)
 BDRVPCacheState *s = acb->bs->opaque;
 
 PCacheNode *node = rbcache_search(s->cache, acb->offset, acb->bytes);
-if (node == NULL || node->status != NODE_STATUS_COMPLETED) {
+if (node == NULL) {
 return CACHE_MISS;
 }
 
@@ -387,7 +440,7 @@ static int pcache_lookup_data(PCacheAIOCBRead *acb)
 if (node->common.offset <= acb->offset &&
 node->common.offset + node->common.bytes >= acb->offset + acb->bytes)
 {
-read_cache_data(acb, node, acb->offset, acb->bytes);
+pcache_aio_read(acb, node);
 return CACHE_HIT;
 }
 
@@ -405,6 +458,7 @@ static coroutine_fn int pcache_co_preadv(BlockDriverState 
*bs, uint64_t offset,
 .offset = offset,
 .bytes = bytes,
 .qiov = qiov,
+.ref = 1,
 };
 int status;
 
@@ -417,14 +471,17 @@ static coroutine_fn int pcache_co_preadv(BlockDriverState 
*bs, uint64_t offset,
 update_req_stats(s->req_stats, offset, bytes);
 
 status = pcache_lookup_data();
-if (status == CACHE_HIT) {
-return 0;
+if (status == CACHE_MISS || status == PARTIAL_CACHE_HIT) {
+bdrv_aio_preadv(bs->file, offset, qiov, bytes,
+pcache_aio_read_cb, );
 }
 
-bdrv_aio_preadv(bs->file, offset, qiov, bytes, pcache_aio_read_cb, );
-
 pcache_readahead_request();
 
+if (status == CACHE_HIT && --acb.ref == 0) {
+return 0;
+}
+
 out:
 qemu_coroutine_yield();
 
-- 
2.10.1




[Qemu-devel] [PATCH v1 07/18] block/pcache: skip large aio read

2016-11-14 Thread Pavel Butsykin
This change will allow more efficient use of cache memory and filter the case
for which the pcache isn't efficient.  We skip requests that are not required in
the optimization and thereby reducing the number of unnecessary readaheads.

Add pcache-max-aio-size open parameter.

Signed-off-by: Pavel Butsykin 
---
 block/pcache.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/block/pcache.c b/block/pcache.c
index 60b1f93..bfc7e97 100644
--- a/block/pcache.c
+++ b/block/pcache.c
@@ -16,6 +16,7 @@
 #include "qemu/rbcache.h"
 
 #define PCACHE_OPT_STATS_SIZE "pcache-stats-size"
+#define PCACHE_OPT_MAX_AIO_SIZE "pcache-max-aio-size"
 
 static QemuOptsList runtime_opts = {
 .name = "pcache",
@@ -31,15 +32,23 @@ static QemuOptsList runtime_opts = {
 .type = QEMU_OPT_SIZE,
 .help = "Total volume of requests for statistics",
 },
+{
+.name = PCACHE_OPT_MAX_AIO_SIZE,
+.type = QEMU_OPT_SIZE,
+.help = "Maximum size of aio which is handled by pcache",
+},
 { /* end of list */ }
 },
 };
 
+#define KB_BITS 10
 #define MB_BITS 20
 #define PCACHE_DEFAULT_STATS_SIZE (3 << MB_BITS)
+#define PCACHE_DEFAULT_MAX_AIO_SIZE (64 << KB_BITS)
 
 typedef struct BDRVPCacheState {
 RBCache *req_stats;
+uint64_t max_aio_size;
 } BDRVPCacheState;
 
 typedef struct PCacheAIOCB {
@@ -64,7 +73,9 @@ static coroutine_fn int pcache_co_preadv(BlockDriverState 
*bs, uint64_t offset,
 .co = qemu_coroutine_self(),
 };
 
-rbcache_search_and_insert(s->req_stats, offset, bytes);
+if (s->max_aio_size >= bytes) {
+rbcache_search_and_insert(s->req_stats, offset, bytes);
+}
 
 bdrv_aio_preadv(bs->file, offset, qiov, bytes, pcache_aio_cb, );
 
@@ -93,6 +104,9 @@ static void pcache_state_init(QemuOpts *opts, 
BDRVPCacheState *s)
 uint64_t stats_size = qemu_opt_get_size(opts, PCACHE_OPT_STATS_SIZE,
 PCACHE_DEFAULT_STATS_SIZE);
 s->req_stats = rbcache_create(NULL, NULL, stats_size, RBCACHE_FIFO, s);
+
+s->max_aio_size = qemu_opt_get_size(opts, PCACHE_OPT_MAX_AIO_SIZE,
+PCACHE_DEFAULT_MAX_AIO_SIZE);
 }
 
 static int pcache_file_open(BlockDriverState *bs, QDict *options, int flags,
-- 
2.10.1




[Qemu-devel] [PATCH v1 04/18] util/rbcache: range-based cache core

2016-11-14 Thread Pavel Butsykin
RBCache provides functionality to cache the data from block devices
(basically). The range here is used as the main key for searching and storing
data. The cache is based on red-black trees, so basic operations search,
insert, delete are performed for O(log n).

It is important to note that QEMU usually does not require a data cache, but
in reality, there are already some cases where a cache of small amounts can
increase performance, so as the data structure was selected red-black trees,
this is a fairly simple data structure and show high efficiency on a small
number of elements. Therefore, when the minimum range is 512 bytes, the
recommended size of the cache memory no more than 8-16mb.  Also note
that this cache implementation allows to store ranges of different lengths
without alignment.

Generic cache core can easily be used to implement different caching policies at
the block level, such as read-ahed. Also it can be used in some special cases,
for example for caching data in qcow2 when sequential allocating writes to image
with backing file.

Signed-off-by: Pavel Butsykin 
---
 MAINTAINERS|   6 ++
 include/qemu/rbcache.h | 105 +
 util/Makefile.objs |   1 +
 util/rbcache.c | 246 +
 4 files changed, 358 insertions(+)
 create mode 100644 include/qemu/rbcache.h
 create mode 100644 util/rbcache.c

diff --git a/MAINTAINERS b/MAINTAINERS
index ddf797b..cb74802 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1365,6 +1365,12 @@ F: include/qemu/rbtree.h
 F: include/qemu/rbtree_augmented.h
 F: util/rbtree.c
 
+Range-Based Cache
+M: Denis V. Lunev 
+S: Supported
+F: include/qemu/rbcache.h
+F: util/rbcache.c
+
 UUID
 M: Fam Zheng 
 S: Supported
diff --git a/include/qemu/rbcache.h b/include/qemu/rbcache.h
new file mode 100644
index 000..c8f0a9f
--- /dev/null
+++ b/include/qemu/rbcache.h
@@ -0,0 +1,105 @@
+/*
+ * QEMU Range-Based Cache core
+ *
+ * Copyright (C) 2015-2016 Parallels IP Holdings GmbH. All rights reserved.
+ *
+ * Author: Pavel Butsykin 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later.  See the COPYING file in the top-level directory.
+ */
+
+#ifndef RBCACHE_H
+#define RBCACHE_H
+
+#include "qemu/rbtree.h"
+#include "qemu/queue.h"
+
+typedef struct RBCacheNode {
+struct RbNode rb_node;
+uint64_t offset;
+uint64_t bytes;
+QTAILQ_ENTRY(RBCacheNode) entry;
+} RBCacheNode;
+
+typedef struct RBCache RBCache;
+
+typedef RBCacheNode *RBNodeAlloc(uint64_t offset, uint64_t bytes, void 
*opaque);
+typedef void RBNodeFree(RBCacheNode *node, void *opaque);
+
+
+enum eviction_type {
+RBCACHE_FIFO,
+RBCACHE_LRU,
+};
+
+/**
+ * rbcache_search:
+ * @rbcache: the cache object.
+ * @offset: the start of the range.
+ * @bytes: the size of the range.
+ *
+ * Returns the node corresponding to the range(offset, bytes),
+ * or NULL if the node was not found.
+ */
+void *rbcache_search(RBCache *rbcache, uint64_t offset, uint64_t bytes);
+
+/**
+ * rbcache_insert:
+ * @rbcache: the cache object.
+ * @node: a new node for the cache.
+ *
+ * Returns the new node, or old node if the node already exists.
+ */
+void *rbcache_insert(RBCache *rbcache, RBCacheNode *node);
+
+/**
+ * rbcache_search_and_insert:
+ * @rbcache: the cache object.
+ * @offset: the start of the range.
+ * @bytes: the size of the range.
+ *
+ * rbcache_search_and_insert() is like rbcache_insert(), except that a new node
+ * is allocated inside the function. Returns the new node, or old node if the
+ * node already exists.
+ */
+void *rbcache_search_and_insert(RBCache *rbcache, uint64_t offset,
+uint64_t byte);
+
+/**
+ * rbcache_remove:
+ * @rbcache: the cache object.
+ * @node: the node to remove.
+ *
+ * Removes the cached range owned by the node.
+ */
+void rbcache_remove(RBCache *rbcache, RBCacheNode *node);
+
+RBCacheNode *rbcache_node_alloc(RBCache *rbcache, uint64_t offset,
+uint64_t bytes);
+
+void rbcache_node_free(RBCache *rbcache, RBCacheNode *node);
+
+/**
+ * rbcache_create:
+ * @alloc: callback to allocation node, allows to upgrade allocate and expand
+ * the capabilities of the node.
+ * @free: callback to release node, must be used together with alloc callback.
+ * @limit_size: maximum cache size in bytes.
+ * @eviction_type: method of memory limitation
+ * @opaque: the opaque pointer to pass to the callback.
+ *
+ * Returns the cache object.
+ */
+RBCache *rbcache_create(RBNodeAlloc *alloc, RBNodeFree *free,
+uint64_t limit_size, int eviction_type, void *opaque);
+
+/**
+ * rbcache_destroy:
+ * @rbcache: the cache object.
+ *
+ * Cleanup the cache object created with rbcache_create().
+ */
+void rbcache_destroy(RBCache *rbcache);
+
+#endif /* RBCACHE_H */
diff --git a/util/Makefile.objs b/util/Makefile.objs

Re: [Qemu-devel] [PATCH v12 12/22] vfio: Add notifier callback to parent's ops structure of mdev

2016-11-14 Thread Jike Song
On 11/14/2016 11:42 PM, Kirti Wankhede wrote:
> Add a notifier calback to parent's ops structure of mdev device so that per
> device notifer for vfio module is registered through vfio_mdev module.
> 
> Signed-off-by: Kirti Wankhede 
> Signed-off-by: Neo Jia 
> Change-Id: Iafa6f1721aecdd6e50eb93b153b5621e6d29b637
> ---
>  drivers/vfio/mdev/vfio_mdev.c | 19 +++
>  include/linux/mdev.h  |  9 +
>  2 files changed, 28 insertions(+)
> 
> diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
> index ffc36758cb84..1694b1635607 100644
> --- a/drivers/vfio/mdev/vfio_mdev.c
> +++ b/drivers/vfio/mdev/vfio_mdev.c
> @@ -24,6 +24,15 @@
>  #define DRIVER_AUTHOR   "NVIDIA Corporation"
>  #define DRIVER_DESC "VFIO based driver for Mediated device"
>  
> +static int vfio_mdev_notifier(struct notifier_block *nb, unsigned long 
> action,
> +   void *data)
> +{
> + struct mdev_device *mdev = container_of(nb, struct mdev_device, nb);
> + struct parent_device *parent = mdev->parent;
> +
> + return parent->ops->notifier(mdev, action, data);
> +}
> +
>  static int vfio_mdev_open(void *device_data)
>  {
>   struct mdev_device *mdev = device_data;
> @@ -40,6 +49,11 @@ static int vfio_mdev_open(void *device_data)
>   if (ret)
>   module_put(THIS_MODULE);
>  
> + if (likely(parent->ops->notifier)) {
> + mdev->nb.notifier_call = vfio_mdev_notifier;
> + if (vfio_register_notifier(>dev, >nb))
> + pr_err("Failed to register notifier for mdev\n");
> + }

Hi Kirti,

Could you please move the notifier registration before parent->ops->open()?
as you might know, I'm extending your vfio_register_notifier to also include
the attaching/detaching events of vfio_group and kvm.  Basically if vfio_group
not attached to any kvm instance, the parent->ops->open() should return -ENODEV
to indicate the failure, but to know whether kvm is available in open(), the
notifier registration should be earlier.

Of course I can call vfio_register_notifier() from an earlier place to
workaround it, but it doesn't seem a canonical way.

--
Thanks,
Jike

>   return ret;
>  }
>  
> @@ -48,6 +62,11 @@ static void vfio_mdev_release(void *device_data)
>   struct mdev_device *mdev = device_data;
>   struct parent_device *parent = mdev->parent;
>  
> + if (likely(parent->ops->notifier)) {
> + if (vfio_unregister_notifier(>dev, >nb))
> + pr_err("Failed to unregister notifier for mdev\n");
> + }
> +
>   if (likely(parent->ops->release))
>   parent->ops->release(mdev);
>  
> diff --git a/include/linux/mdev.h b/include/linux/mdev.h
> index 4900cc472364..665afe0a4c31 100644
> --- a/include/linux/mdev.h
> +++ b/include/linux/mdev.h
> @@ -37,6 +37,7 @@ struct mdev_device {
>   struct kref ref;
>   struct list_headnext;
>   struct kobject  *type_kobj;
> + struct notifier_block   nb;
>  };
>  
>  /**
> @@ -85,6 +86,12 @@ struct mdev_device {
>   * @mmap:mmap callback
>   *   @mdev: mediated device structure
>   *   @vma: vma structure
> + * @notifer: Notifier callback, currently only for
> + *   VFIO_IOMMU_NOTIFY_DMA_UNMAP action notified duing
> + *   DMA_UNMAP call on mapped iova range.
> + *   @mdev: mediated device structure
> + *   @action: Action for which notifier is called
> + *   @data: Data associated with the notifier
>   * Parent device that support mediated device should be registered with mdev
>   * module with parent_ops structure.
>   **/
> @@ -106,6 +113,8 @@ struct parent_ops {
>   ssize_t (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
>unsigned long arg);
>   int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
> + int (*notifier)(struct mdev_device *mdev, unsigned long action,
> + void *data);
>  };
>  
>  /* interface for exporting mdev supported type attributes */
> 



Re: [Qemu-devel] [PATCH v11 10/22] vfio iommu type1: Add support for mediated devices

2016-11-14 Thread Kirti Wankhede


On 11/15/2016 10:47 AM, Alexey Kardashevskiy wrote:
> On 08/11/16 17:52, Alexey Kardashevskiy wrote:
>> On 05/11/16 08:10, Kirti Wankhede wrote:
>>> VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
>>> Mediated device only uses IOMMU APIs, the underlying hardware can be
>>> managed by an IOMMU domain.
>>>
>>> Aim of this change is:
>>> - To use most of the code of TYPE1 IOMMU driver for mediated devices
>>> - To support direct assigned device and mediated device in single module
>>>
>>> This change adds pin and unpin support for mediated device to TYPE1 IOMMU
>>> backend module. More details:
>>> - vfio_pin_pages() callback here uses task and address space of vfio_dma,
>>>   that is, of the process who mapped that iova range.
>>> - Added pfn_list tracking logic to address space structure. All pages
>>>   pinned through this interface are trached in its address space.
>>> - Pinned pages list is used to verify unpinning request and to unpin
>>>   remaining pages while detaching the group for that device.
>>> - Page accounting is updated to account in its address space where the
>>>   pages are pinned/unpinned.
>>> -  Accouting for mdev device is only done if there is no iommu capable
>>>   domain in the container. When there is a direct device assigned to the
>>>   container and that domain is iommu capable, all pages are already pinned
>>>   during DMA_MAP.
>>> - Page accouting is updated on hot plug and unplug mdev device and pass
>>>   through device.
>>>
>>> Tested by assigning below combinations of devices to a single VM:
>>> - GPU pass through only
>>
>> This does not require this patchset, right?
>>

Sorry I missed this earlier.
This testing is required for this patch, because this patch touches code
that is used for direct device assignment. Also for page accounting, all
cases are considered i.e. when there is only pass through device in a
container, when there is pass through device + vGPU device in a
container. Also have to test that pages are pinned properly when device
is hotplugged. In that case vfio_iommu_replay() is called to take
necessary action.

>>> - vGPU device only
>>
>> Out of curiosity - how exactly did you test this? The exact GPU, how to
>> create vGPU, what was the QEMU command line and the guest does with this
>> passed device? Thanks.
> 
> ping?
> 

I'm testing this code with M60, with custom changes in our driver.
Steps how to create mediated device are listed in
Documentation/vfio-mediated-device.txt for sample mtty driver. Same
steps I'm following for GPU. Quoting those steps here for you:

2. Create a mediated device by using the dummy device that you created
in the
   previous step.

   # echo "83b8f4f2-509f-382f-3c1e-e6bfe0fa1001" >  \

/sys/devices/virtual/mtty/mtty/mdev_supported_types/mtty-2/create

3. Add parameters to qemu-kvm.

   -device vfio-pci,\
sysfsdev=/sys/bus/mdev/devices/83b8f4f2-509f-382f-3c1e-e6bfe0fa1001


Thanks,
Kirti




Re: [Qemu-devel] [PATCH 2/3] qemu: Implement virtio-pstore device

2016-11-14 Thread Namhyung Kim
On Fri, Nov 11, 2016 at 12:50:03AM +0200, Michael S. Tsirkin wrote:
> On Fri, Sep 16, 2016 at 07:05:47PM +0900, Namhyung Kim wrote:
> > On Tue, Sep 13, 2016 at 06:57:10PM +0300, Michael S. Tsirkin wrote:
> > > On Sat, Aug 20, 2016 at 05:07:43PM +0900, Namhyung Kim wrote:
> > > > +
> > > > +/* the index should match to the type value */
> > > > +static const char *virtio_pstore_file_prefix[] = {
> > > > +"unknown-",/* VIRTIO_PSTORE_TYPE_UNKNOWN */
> > > 
> > > Is there value in treating everything unexpected as "unknown"
> > > and rotating them as if they were logs?
> > > It might be better to treat everything that's not known
> > > as guest error.
> > 
> > I was thinking about the version mismatch between the kernel and qemu.
> > I'd like to make the device can deal with a new kernel version which
> > might implement a new pstore message type.  It will be saved as
> > unknown but the kernel can read it properly later.
> 
> Well it'll have a different prefix. E.g. if kernel has
> two different types they will end up in the same
> file, hardly what was wanted.

Right, I think it needs to add 'type' info to the filename for unknown
type.

Thanks,
Namhyung



Re: [Qemu-devel] [PATCH v2] qapi-schema: clarify 'colo' state for MigrationStatus

2016-11-14 Thread Hailiang Zhang

On 2016/11/14 21:54, Stefan Hajnoczi wrote:

On Mon, Nov 14, 2016 at 10:36:45AM +0800, Hailiang Zhang wrote:

ping ?

Anyone pick this up?


The original patch that added these lines went through Amit Shah and
David Gilbert.  I have CCed them.



Great, thanks :)


Stefan






Re: [Qemu-devel] [PATCH 1/3] virtio: Basic implementation of virtio pstore driver

2016-11-14 Thread Namhyung Kim
On Tue, Nov 15, 2016 at 07:06:28AM +0200, Michael S. Tsirkin wrote:
> On Tue, Nov 15, 2016 at 01:50:21PM +0900, Namhyung Kim wrote:
> > On Thu, Nov 10, 2016 at 06:39:55PM +0200, Michael S. Tsirkin wrote:
> > [SNIP]
> > > > +struct virtio_pstore_fileinfo {
> > > > +   __virtio64  id;
> > > > +   __virtio32  count;
> > > > +   __virtio16  type;
> > > > +   __virtio16  unused;
> > > > +   __virtio32  flags;
> > > > +   __virtio32  len;
> > > > +   __virtio64  time_sec;
> > > > +   __virtio32  time_nsec;
> > > > +   __virtio32  reserved;
> > > > +};
> > > > +
> > > > +struct virtio_pstore_config {
> > > > +   __virtio32  bufsize;
> > > > +};
> > > > +
> > > 
> > > What exactly does each field mean? I'm especially
> > > interested in time fields - maintaining a consistent
> > > time between host and guest is not a simple problem.
> > 
> > These are required by pstore and will be used to create corresponding
> > files in the pstore filesystem.  The time fields are for mtime and
> > ctime and, I think, it's just a hint for user and doesn't require
> > strict consistency.
> 
> Pls add documentation. I would just drop hints for now.

Well, I'll add docmentation.  But I think just dropping might not good
since they all have host time and it's helpful to know their relative
difference in guest.

Thanks,
Namhyung



Re: [Qemu-devel] [PATCH v12 09/22] vfio iommu type1: Add task structure to vfio_dma

2016-11-14 Thread Alexey Kardashevskiy
On 15/11/16 02:42, Kirti Wankhede wrote:
> Add task structure to vfio_dma structure.
> During DMA_UNMAP, same task who mapped it or other task who shares same
> address space is allowed to unmap, otherwise unmap fails.
> QEMU maps few iova ranges initially, then fork threads and from the child
> thread calls DMA_UNMAP on previously mapped iova. Since child shares same
> address space, DMA_UNMAP is successful.

Please add few words why you reference task instead of mm. afaict you only
use mm. Thanks.


> 
> Signed-off-by: Kirti Wankhede 
> Signed-off-by: Neo Jia 
> Change-Id: I7600f1bea6b384fd589fa72421ccf031bcfd9ac5
> ---
>  drivers/vfio/vfio_iommu_type1.c | 137 
> +---
>  1 file changed, 86 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index ffe2026f1341..50aca95cf61e 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -36,6 +36,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define DRIVER_VERSION  "0.2"
>  #define DRIVER_AUTHOR   "Alex Williamson "
> @@ -75,6 +76,7 @@ struct vfio_dma {
>   unsigned long   vaddr;  /* Process virtual addr */
>   size_t  size;   /* Map size (bytes) */
>   int prot;   /* IOMMU_READ/WRITE */
> + struct task_struct  *task;
>  };
>  
>  struct vfio_group {
> @@ -277,41 +279,47 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned 
> long vaddr,
>   * the iommu can only map chunks of consecutive pfns anyway, so get the
>   * first page and all consecutive pages with the same locking.
>   */
> -static long vfio_pin_pages_remote(unsigned long vaddr, long npage,
> -   int prot, unsigned long *pfn_base)
> +static long vfio_pin_pages_remote(struct vfio_dma *dma, unsigned long vaddr,
> +   long npage, int prot, unsigned long *pfn_base)
>  {
> - unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
> - bool lock_cap = capable(CAP_IPC_LOCK);
> + unsigned long limit;
> + bool lock_cap = ns_capable(task_active_pid_ns(dma->task)->user_ns,
> +CAP_IPC_LOCK);
> + struct mm_struct *mm;
>   long ret, i;
>   bool rsvd;
>  
> - if (!current->mm)
> + mm = get_task_mm(dma->task);
> + if (!mm)
>   return -ENODEV;
>  
> - ret = vaddr_get_pfn(current->mm, vaddr, prot, pfn_base);
> + ret = vaddr_get_pfn(mm, vaddr, prot, pfn_base);
>   if (ret)
> - return ret;
> + goto pin_pg_remote_exit;
>  
>   rsvd = is_invalid_reserved_pfn(*pfn_base);
> + limit = task_rlimit(dma->task, RLIMIT_MEMLOCK) >> PAGE_SHIFT;
>  
> - if (!rsvd && !lock_cap && current->mm->locked_vm + 1 > limit) {
> + if (!rsvd && !lock_cap && mm->locked_vm + 1 > limit) {
>   put_pfn(*pfn_base, prot);
>   pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__,
>   limit << PAGE_SHIFT);
> - return -ENOMEM;
> + ret = -ENOMEM;
> + goto pin_pg_remote_exit;
>   }
>  
>   if (unlikely(disable_hugepages)) {
>   if (!rsvd)
> - vfio_lock_acct(current, 1);
> - return 1;
> + vfio_lock_acct(dma->task, 1);
> + ret = 1;
> + goto pin_pg_remote_exit;
>   }
>  
>   /* Lock all the consecutive pages from pfn_base */
>   for (i = 1, vaddr += PAGE_SIZE; i < npage; i++, vaddr += PAGE_SIZE) {
>   unsigned long pfn = 0;
>  
> - ret = vaddr_get_pfn(current->mm, vaddr, prot, );
> + ret = vaddr_get_pfn(mm, vaddr, prot, );
>   if (ret)
>   break;
>  
> @@ -321,8 +329,7 @@ static long vfio_pin_pages_remote(unsigned long vaddr, 
> long npage,
>   break;
>   }
>  
> - if (!rsvd && !lock_cap &&
> - current->mm->locked_vm + i + 1 > limit) {
> + if (!rsvd && !lock_cap && mm->locked_vm + i + 1 > limit) {
>   put_pfn(pfn, prot);
>   pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
>   __func__, limit << PAGE_SHIFT);
> @@ -331,13 +338,16 @@ static long vfio_pin_pages_remote(unsigned long vaddr, 
> long npage,
>   }
>  
>   if (!rsvd)
> - vfio_lock_acct(current, i);
> + vfio_lock_acct(dma->task, i);
> + ret = i;
>  
> - return i;
> +pin_pg_remote_exit:
> + mmput(mm);
> + return ret;
>  }
>  
> -static long vfio_unpin_pages_remote(unsigned long pfn, long npage,
> - int prot, bool do_accounting)
> +static long vfio_unpin_pages_remote(struct vfio_dma *dma, unsigned long pfn,
> +   

Re: [Qemu-devel] [PATCH v11 10/22] vfio iommu type1: Add support for mediated devices

2016-11-14 Thread Alexey Kardashevskiy
On 08/11/16 17:52, Alexey Kardashevskiy wrote:
> On 05/11/16 08:10, Kirti Wankhede wrote:
>> VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
>> Mediated device only uses IOMMU APIs, the underlying hardware can be
>> managed by an IOMMU domain.
>>
>> Aim of this change is:
>> - To use most of the code of TYPE1 IOMMU driver for mediated devices
>> - To support direct assigned device and mediated device in single module
>>
>> This change adds pin and unpin support for mediated device to TYPE1 IOMMU
>> backend module. More details:
>> - vfio_pin_pages() callback here uses task and address space of vfio_dma,
>>   that is, of the process who mapped that iova range.
>> - Added pfn_list tracking logic to address space structure. All pages
>>   pinned through this interface are trached in its address space.
>> - Pinned pages list is used to verify unpinning request and to unpin
>>   remaining pages while detaching the group for that device.
>> - Page accounting is updated to account in its address space where the
>>   pages are pinned/unpinned.
>> -  Accouting for mdev device is only done if there is no iommu capable
>>   domain in the container. When there is a direct device assigned to the
>>   container and that domain is iommu capable, all pages are already pinned
>>   during DMA_MAP.
>> - Page accouting is updated on hot plug and unplug mdev device and pass
>>   through device.
>>
>> Tested by assigning below combinations of devices to a single VM:
>> - GPU pass through only
> 
> This does not require this patchset, right?
> 
>> - vGPU device only
> 
> Out of curiosity - how exactly did you test this? The exact GPU, how to
> create vGPU, what was the QEMU command line and the guest does with this
> passed device? Thanks.


ping?


-- 
Alexey



Re: [Qemu-devel] [PATCH] vfio: avoid adding same iommu mr for notify

2016-11-14 Thread Alexey Kardashevskiy
On 15/11/16 11:59, Peter Xu wrote:
> When one IOMMU memory region is splitted into multiple memory sections,


Out of curiosity - when does this happen?


> vfio will register multiple same notifiers to a vIOMMU for the same
> region. That's not sensible. What we need is to register one IOMMU
> notifier for each IOMMU region, not per section.
> 
> Solution is simple - we traverse the container->giommu_list, and skip
> the registration if memory region is already registered.
> 
> To make vfio's region_add() short, vfio_listener_region_add_iommu() is
> introduced.
> 
> Signed-off-by: Peter Xu 
> ---
>  hw/vfio/common.c | 56 
> +++-
>  1 file changed, 35 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 801578b..5279fd1 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -360,6 +360,40 @@ out:
>  rcu_read_unlock();
>  }
>  
> +static void vfio_listener_region_add_iommu(VFIOContainer *container,
> +   MemoryRegionSection *section,
> +   hwaddr iova,
> +   hwaddr end)
> +{
> +VFIOGuestIOMMU *giommu;
> +
> +QLIST_FOREACH(giommu, >giommu_list, giommu_next) {
> +if (giommu->iommu == section->mr) {
> +/* We have already registered with this MR, skip */
> +return;
> +}
> +}
> +
> +trace_vfio_listener_region_add_iommu(iova, end);
> +
> +/*
> + * FIXME: For VFIO iommu types which have KVM acceleration to
> + * avoid bouncing all map/unmaps through qemu this way, this
> + * would be the right place to wire that up (tell the KVM
> + * device emulation the VFIO iommu handles to use).
> + */
> +giommu = g_malloc0(sizeof(*giommu));
> +giommu->iommu = section->mr;
> +giommu->iommu_offset = section->offset_within_address_space -
> +section->offset_within_region;
> +giommu->container = container;
> +giommu->n.notify = vfio_iommu_map_notify;
> +giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
> +QLIST_INSERT_HEAD(>giommu_list, giommu, giommu_next);
> +memory_region_register_iommu_notifier(giommu->iommu, >n);
> +memory_region_iommu_replay(giommu->iommu, >n, false);
> +}
> +
>  static void vfio_listener_region_add(MemoryListener *listener,
>   MemoryRegionSection *section)
>  {
> @@ -439,27 +473,7 @@ static void vfio_listener_region_add(MemoryListener 
> *listener,
>  memory_region_ref(section->mr);
>  
>  if (memory_region_is_iommu(section->mr)) {
> -VFIOGuestIOMMU *giommu;
> -
> -trace_vfio_listener_region_add_iommu(iova, end);
> -/*
> - * FIXME: For VFIO iommu types which have KVM acceleration to
> - * avoid bouncing all map/unmaps through qemu this way, this
> - * would be the right place to wire that up (tell the KVM
> - * device emulation the VFIO iommu handles to use).
> - */
> -giommu = g_malloc0(sizeof(*giommu));
> -giommu->iommu = section->mr;
> -giommu->iommu_offset = section->offset_within_address_space -
> -   section->offset_within_region;
> -giommu->container = container;
> -giommu->n.notify = vfio_iommu_map_notify;
> -giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
> -QLIST_INSERT_HEAD(>giommu_list, giommu, giommu_next);
> -
> -memory_region_register_iommu_notifier(giommu->iommu, >n);
> -memory_region_iommu_replay(giommu->iommu, >n, false);
> -
> +vfio_listener_region_add_iommu(container, section, iova, end);
>  return;
>  }
>  
> 


-- 
Alexey



Re: [Qemu-devel] [PATCH v2 0/4] ppc/pnv: XSCOM fixes and unit tests

2016-11-14 Thread Cédric Le Goater
On 11/15/2016 12:11 AM, David Gibson wrote:
> On Mon, Nov 14, 2016 at 10:12:54AM +0100, Cédric Le Goater wrote:
>> Hello,
>>
>> Here is a little serie adding some fixes for the XSCOM registers of
>> the POWER9 cores and a unit test. 
>>
>> Changes since v1 :
>>
>>  - fixed pnv_xscom_addr() for 32bit host systems
>>  - replace hweight_long() by ctpop64()
>>
>> Tested on a 32-bit LE system and on 64-bit LE and BE systems.
> 
> Applied to ppc-for-2.8.
> 
> I fixed a trivial nit in 4/4 - you had a 5 space indent, instead of a
> 4 space indent in one place.

yes. I need to automate the checkpatch step in some ways when I send 
patches.

Thanks for doing that.

C.




Re: [Qemu-devel] [PATCH 1/3] virtio: Basic implementation of virtio pstore driver

2016-11-14 Thread Michael S. Tsirkin
On Tue, Nov 15, 2016 at 01:50:21PM +0900, Namhyung Kim wrote:
> Hi Michael,
> 
> On Thu, Nov 10, 2016 at 06:39:55PM +0200, Michael S. Tsirkin wrote:
> > On Sat, Aug 20, 2016 at 05:07:42PM +0900, Namhyung Kim wrote:
> > > The virtio pstore driver provides interface to the pstore subsystem so
> > > that the guest kernel's log/dump message can be saved on the host
> > > machine.  Users can access the log file directly on the host, or on the
> > > guest at the next boot using pstore filesystem.  It currently deals with
> > > kernel log (printk) buffer only, but we can extend it to have other
> > > information (like ftrace dump) later.
> > > 
> > > It supports legacy PCI device using single order-2 page buffer.
> > 
> > Do you mean a legacy virtio device? I don't see why
> > you would want to support pre-1.0 mode.
> > If you drop that, you can drop all cpu_to_virtio things
> > and just use __le accessors.
> 
> I was thinking about the kvmtools which lacks 1.0 support AFAIK.

Unless kvmtools wants to be left behind it has to go 1.0.

>  But
> I think it'd be better to always use __le type anyway.  Will change.
> 
> 
> > 
> > > It uses
> > > two virtqueues - one for (sync) read and another for (async) write.
> > > Since it cannot wait for write finished, it supports up to 128
> > > concurrent IO.  The buffer size is configurable now.
> > > 
> > > Cc: Paolo Bonzini 
> > > Cc: Radim Krčmář 
> > > Cc: "Michael S. Tsirkin" 
> > > Cc: Anthony Liguori 
> > > Cc: Anton Vorontsov 
> > > Cc: Colin Cross 
> > > Cc: Kees Cook 
> > > Cc: Tony Luck 
> > > Cc: Steven Rostedt 
> > > Cc: Ingo Molnar 
> > > Cc: Minchan Kim 
> > > Cc: k...@vger.kernel.org
> > > Cc: qemu-devel@nongnu.org
> > > Cc: virtualizat...@lists.linux-foundation.org
> > > Signed-off-by: Namhyung Kim 
> > > ---
> > >  drivers/virtio/Kconfig |  10 +
> > >  drivers/virtio/Makefile|   1 +
> > >  drivers/virtio/virtio_pstore.c | 417 
> > > +
> > >  include/uapi/linux/Kbuild  |   1 +
> > >  include/uapi/linux/virtio_ids.h|   1 +
> > >  include/uapi/linux/virtio_pstore.h |  74 +++
> > >  6 files changed, 504 insertions(+)
> > >  create mode 100644 drivers/virtio/virtio_pstore.c
> > >  create mode 100644 include/uapi/linux/virtio_pstore.h
> > > 
> > > diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> > > index 77590320d44c..8f0e6c796c12 100644
> > > --- a/drivers/virtio/Kconfig
> > > +++ b/drivers/virtio/Kconfig
> > > @@ -58,6 +58,16 @@ config VIRTIO_INPUT
> > >  
> > >If unsure, say M.
> > >  
> > > +config VIRTIO_PSTORE
> > > + tristate "Virtio pstore driver"
> > > + depends on VIRTIO
> > > + depends on PSTORE
> > > + ---help---
> > > +  This driver supports virtio pstore devices to save/restore
> > > +  panic and oops messages on the host.
> > > +
> > > +  If unsure, say M.
> > > +
> > >   config VIRTIO_MMIO
> > >   tristate "Platform bus driver for memory mapped virtio devices"
> > >   depends on HAS_IOMEM && HAS_DMA
> > > diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
> > > index 41e30e3dc842..bee68cb26d48 100644
> > > --- a/drivers/virtio/Makefile
> > > +++ b/drivers/virtio/Makefile
> > > @@ -5,3 +5,4 @@ virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
> > >  virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
> > >  obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
> > >  obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
> > > +obj-$(CONFIG_VIRTIO_PSTORE) += virtio_pstore.o
> > > diff --git a/drivers/virtio/virtio_pstore.c 
> > > b/drivers/virtio/virtio_pstore.c
> > > new file mode 100644
> > > index ..0a63c7db4278
> > > --- /dev/null
> > > +++ b/drivers/virtio/virtio_pstore.c
> > > @@ -0,0 +1,417 @@
> > > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > > +
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +#include 
> > > +
> > > +#define VIRT_PSTORE_ORDER2
> > > +#define VIRT_PSTORE_BUFSIZE  (4096 << VIRT_PSTORE_ORDER)
> > > +#define VIRT_PSTORE_NR_REQ   128
> > > +
> > > +struct virtio_pstore {
> > > + struct virtio_device*vdev;
> > > + struct virtqueue*vq[2];
> > 
> > I'd add named fields instead of an array here, vq[0]
> > vq[1] all over the place is hard to read.
> 
> Will change.
> 
> > 
> > > + struct pstore_info   pstore;
> > > + struct virtio_pstore_req req[VIRT_PSTORE_NR_REQ];
> > > + struct virtio_pstore_res res[VIRT_PSTORE_NR_REQ];
> > > + unsigned int req_id;
> > > +
> > > + /* Waiting for host to ack */
> > > + wait_queue_head_t   acked;
> > > + int failed;
> > > +};
> > > +
> > > +#define TYPE_TABLE_ENTRY(_entry) \
> > > + { 

Re: [Qemu-devel] [PATCH 1/3] virtio: Basic implementation of virtio pstore driver

2016-11-14 Thread Namhyung Kim
Hi Michael,

On Thu, Nov 10, 2016 at 06:39:55PM +0200, Michael S. Tsirkin wrote:
> On Sat, Aug 20, 2016 at 05:07:42PM +0900, Namhyung Kim wrote:
> > The virtio pstore driver provides interface to the pstore subsystem so
> > that the guest kernel's log/dump message can be saved on the host
> > machine.  Users can access the log file directly on the host, or on the
> > guest at the next boot using pstore filesystem.  It currently deals with
> > kernel log (printk) buffer only, but we can extend it to have other
> > information (like ftrace dump) later.
> > 
> > It supports legacy PCI device using single order-2 page buffer.
> 
> Do you mean a legacy virtio device? I don't see why
> you would want to support pre-1.0 mode.
> If you drop that, you can drop all cpu_to_virtio things
> and just use __le accessors.

I was thinking about the kvmtools which lacks 1.0 support AFAIK.  But
I think it'd be better to always use __le type anyway.  Will change.


> 
> > It uses
> > two virtqueues - one for (sync) read and another for (async) write.
> > Since it cannot wait for write finished, it supports up to 128
> > concurrent IO.  The buffer size is configurable now.
> > 
> > Cc: Paolo Bonzini 
> > Cc: Radim Krčmář 
> > Cc: "Michael S. Tsirkin" 
> > Cc: Anthony Liguori 
> > Cc: Anton Vorontsov 
> > Cc: Colin Cross 
> > Cc: Kees Cook 
> > Cc: Tony Luck 
> > Cc: Steven Rostedt 
> > Cc: Ingo Molnar 
> > Cc: Minchan Kim 
> > Cc: k...@vger.kernel.org
> > Cc: qemu-devel@nongnu.org
> > Cc: virtualizat...@lists.linux-foundation.org
> > Signed-off-by: Namhyung Kim 
> > ---
> >  drivers/virtio/Kconfig |  10 +
> >  drivers/virtio/Makefile|   1 +
> >  drivers/virtio/virtio_pstore.c | 417 
> > +
> >  include/uapi/linux/Kbuild  |   1 +
> >  include/uapi/linux/virtio_ids.h|   1 +
> >  include/uapi/linux/virtio_pstore.h |  74 +++
> >  6 files changed, 504 insertions(+)
> >  create mode 100644 drivers/virtio/virtio_pstore.c
> >  create mode 100644 include/uapi/linux/virtio_pstore.h
> > 
> > diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> > index 77590320d44c..8f0e6c796c12 100644
> > --- a/drivers/virtio/Kconfig
> > +++ b/drivers/virtio/Kconfig
> > @@ -58,6 +58,16 @@ config VIRTIO_INPUT
> >  
> >  If unsure, say M.
> >  
> > +config VIRTIO_PSTORE
> > +   tristate "Virtio pstore driver"
> > +   depends on VIRTIO
> > +   depends on PSTORE
> > +   ---help---
> > +This driver supports virtio pstore devices to save/restore
> > +panic and oops messages on the host.
> > +
> > +If unsure, say M.
> > +
> >   config VIRTIO_MMIO
> > tristate "Platform bus driver for memory mapped virtio devices"
> > depends on HAS_IOMEM && HAS_DMA
> > diff --git a/drivers/virtio/Makefile b/drivers/virtio/Makefile
> > index 41e30e3dc842..bee68cb26d48 100644
> > --- a/drivers/virtio/Makefile
> > +++ b/drivers/virtio/Makefile
> > @@ -5,3 +5,4 @@ virtio_pci-y := virtio_pci_modern.o virtio_pci_common.o
> >  virtio_pci-$(CONFIG_VIRTIO_PCI_LEGACY) += virtio_pci_legacy.o
> >  obj-$(CONFIG_VIRTIO_BALLOON) += virtio_balloon.o
> >  obj-$(CONFIG_VIRTIO_INPUT) += virtio_input.o
> > +obj-$(CONFIG_VIRTIO_PSTORE) += virtio_pstore.o
> > diff --git a/drivers/virtio/virtio_pstore.c b/drivers/virtio/virtio_pstore.c
> > new file mode 100644
> > index ..0a63c7db4278
> > --- /dev/null
> > +++ b/drivers/virtio/virtio_pstore.c
> > @@ -0,0 +1,417 @@
> > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define VIRT_PSTORE_ORDER2
> > +#define VIRT_PSTORE_BUFSIZE  (4096 << VIRT_PSTORE_ORDER)
> > +#define VIRT_PSTORE_NR_REQ   128
> > +
> > +struct virtio_pstore {
> > +   struct virtio_device*vdev;
> > +   struct virtqueue*vq[2];
> 
> I'd add named fields instead of an array here, vq[0]
> vq[1] all over the place is hard to read.

Will change.

> 
> > +   struct pstore_info   pstore;
> > +   struct virtio_pstore_req req[VIRT_PSTORE_NR_REQ];
> > +   struct virtio_pstore_res res[VIRT_PSTORE_NR_REQ];
> > +   unsigned int req_id;
> > +
> > +   /* Waiting for host to ack */
> > +   wait_queue_head_t   acked;
> > +   int failed;
> > +};
> > +
> > +#define TYPE_TABLE_ENTRY(_entry)   \
> > +   { PSTORE_TYPE_##_entry, VIRTIO_PSTORE_TYPE_##_entry }
> > +
> > +struct type_table {
> > +   int pstore;
> > +   u16 virtio;
> > +} type_table[] = {
> > +   TYPE_TABLE_ENTRY(DMESG),
> > +};
> > +
> > +#undef TYPE_TABLE_ENTRY
> 
> let's avoid macros for now pls. In fact, I would just open-code this
> in to_virtio_type below. We can always change our minds 

[Qemu-devel] [PULL for-2.8 13/13] mirror: do not flush every time the disks are synced

2016-11-14 Thread Jeff Cody
From: Paolo Bonzini 

This puts a huge strain on the disks when there are many concurrent
migrations.  With this patch we only flush twice: just before issuing
the event, and just before pivoting to the destination.  If management
will complete the job close to the BLOCK_JOB_READY event, the cost of
the second flush should be small anyway.

Signed-off-by: Paolo Bonzini 
Message-id: 20161109162008.27287-2-pbonz...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/mirror.c | 40 +---
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/block/mirror.c b/block/mirror.c
index 62ac87f..301ba92 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -615,6 +615,20 @@ static int coroutine_fn mirror_dirty_init(MirrorBlockJob 
*s)
 return 0;
 }
 
+/* Called when going out of the streaming phase to flush the bulk of the
+ * data to the medium, or just before completing.
+ */
+static int mirror_flush(MirrorBlockJob *s)
+{
+int ret = blk_flush(s->target);
+if (ret < 0) {
+if (mirror_error_action(s, false, -ret) == BLOCK_ERROR_ACTION_REPORT) {
+s->ret = ret;
+}
+}
+return ret;
+}
+
 static void coroutine_fn mirror_run(void *opaque)
 {
 MirrorBlockJob *s = opaque;
@@ -727,27 +741,23 @@ static void coroutine_fn mirror_run(void *opaque)
 should_complete = false;
 if (s->in_flight == 0 && cnt == 0) {
 trace_mirror_before_flush(s);
-ret = blk_flush(s->target);
-if (ret < 0) {
-if (mirror_error_action(s, false, -ret) ==
-BLOCK_ERROR_ACTION_REPORT) {
-goto immediate_exit;
+if (!s->synced) {
+if (mirror_flush(s) < 0) {
+/* Go check s->ret.  */
+continue;
 }
-} else {
 /* We're out of the streaming phase.  From now on, if the job
  * is cancelled we will actually complete all pending I/O and
  * report completion.  This way, block-job-cancel will leave
  * the target in a consistent state.
  */
-if (!s->synced) {
-block_job_event_ready(>common);
-s->synced = true;
-}
-
-should_complete = s->should_complete ||
-block_job_is_cancelled(>common);
-cnt = bdrv_get_dirty_count(s->dirty_bitmap);
+block_job_event_ready(>common);
+s->synced = true;
 }
+
+should_complete = s->should_complete ||
+block_job_is_cancelled(>common);
+cnt = bdrv_get_dirty_count(s->dirty_bitmap);
 }
 
 if (cnt == 0 && should_complete) {
@@ -765,7 +775,7 @@ static void coroutine_fn mirror_run(void *opaque)
 
 bdrv_drained_begin(bs);
 cnt = bdrv_get_dirty_count(s->dirty_bitmap);
-if (cnt > 0) {
+if (cnt > 0 || mirror_flush(s) < 0) {
 bdrv_drained_end(bs);
 continue;
 }
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 10/13] block/curl: Fix return value from curl_read_cb

2016-11-14 Thread Jeff Cody
From: Max Reitz 

While commit 38bbc0a580f9f10570b1d1b5d3e92f0e6feb2970 is correct in that
the callback is supposed to return the number of bytes handled; what it
does not mention is that libcurl will throw an error if the callback did
not "handle" all of the data passed to it.

Therefore, if the callback receives some data that it cannot handle
(either because the receive buffer has not been set up yet or because it
would not fit into the receive buffer) and we have to ignore it, we
still have to report that the data has been handled.

Obviously, this should not happen normally. But it does happen at least
for FTP connections where some data (that we do not expect) may be
generated when the connection is established.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Message-id: 20161025025431.24714-3-mre...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/curl.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 1d19e64..7a7e831 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -211,12 +211,13 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t 
nmemb, void *opaque)
 
 DPRINTF("CURL: Just reading %zd bytes\n", realsize);
 
-if (!s || !s->orig_buf)
-return 0;
+if (!s || !s->orig_buf) {
+goto read_end;
+}
 
 if (s->buf_off >= s->buf_len) {
 /* buffer full, read nothing */
-return 0;
+goto read_end;
 }
 realsize = MIN(realsize, s->buf_len - s->buf_off);
 memcpy(s->orig_buf + s->buf_off, ptr, realsize);
@@ -237,7 +238,9 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t 
nmemb, void *opaque)
 }
 }
 
-return realsize;
+read_end:
+/* curl will error out if we do not return this value */
+return size * nmemb;
 }
 
 static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len,
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 12/13] block/curl: Do not wait for data beyond EOF

2016-11-14 Thread Jeff Cody
From: Max Reitz 

libcurl will only give us as much data as there is, not more. The block
layer will deny requests beyond the end of file for us; but since this
block driver is still using a sector-based interface, we can still get
in trouble if the file size is not a multiple of 512.

While we have already made sure not to attempt transfers beyond the end
of the file, we are currently still trying to receive data from there if
the original request exceeds the file size. This patch fixes this issue
and invokes qemu_iovec_memset() on the iovec's tail.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20161025025431.24714-5-mre...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/curl.c | 32 +++-
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 273f329..0404c1b 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -252,8 +252,17 @@ static size_t curl_read_cb(void *ptr, size_t size, size_t 
nmemb, void *opaque)
 continue;
 
 if ((s->buf_off >= acb->end)) {
+size_t request_length = acb->nb_sectors * BDRV_SECTOR_SIZE;
+
 qemu_iovec_from_buf(acb->qiov, 0, s->orig_buf + acb->start,
 acb->end - acb->start);
+
+if (acb->end - acb->start < request_length) {
+size_t offset = acb->end - acb->start;
+qemu_iovec_memset(acb->qiov, offset, 0,
+  request_length - offset);
+}
+
 acb->common.cb(acb->common.opaque, 0);
 qemu_aio_unref(acb);
 s->acb[i] = NULL;
@@ -270,6 +279,8 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, 
size_t len,
 {
 int i;
 size_t end = start + len;
+size_t clamped_end = MIN(end, s->len);
+size_t clamped_len = clamped_end - start;
 
 for (i=0; istates[i];
@@ -284,12 +295,15 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, 
size_t len,
 // Does the existing buffer cover our section?
 if ((start >= state->buf_start) &&
 (start <= buf_end) &&
-(end >= state->buf_start) &&
-(end <= buf_end))
+(clamped_end >= state->buf_start) &&
+(clamped_end <= buf_end))
 {
 char *buf = state->orig_buf + (start - state->buf_start);
 
-qemu_iovec_from_buf(acb->qiov, 0, buf, len);
+qemu_iovec_from_buf(acb->qiov, 0, buf, clamped_len);
+if (clamped_len < len) {
+qemu_iovec_memset(acb->qiov, clamped_len, 0, len - 
clamped_len);
+}
 acb->common.cb(acb->common.opaque, 0);
 
 return FIND_RET_OK;
@@ -299,13 +313,13 @@ static int curl_find_buf(BDRVCURLState *s, size_t start, 
size_t len,
 if (state->in_use &&
 (start >= state->buf_start) &&
 (start <= buf_fend) &&
-(end >= state->buf_start) &&
-(end <= buf_fend))
+(clamped_end >= state->buf_start) &&
+(clamped_end <= buf_fend))
 {
 int j;
 
 acb->start = start - state->buf_start;
-acb->end = acb->start + len;
+acb->end = acb->start + clamped_len;
 
 for (j=0; jacb[j]) {
@@ -798,13 +812,13 @@ static void curl_readv_bh_cb(void *p)
 }
 
 acb->start = 0;
-acb->end = (acb->nb_sectors * BDRV_SECTOR_SIZE);
+acb->end = MIN(acb->nb_sectors * BDRV_SECTOR_SIZE, s->len - start);
 
 state->buf_off = 0;
 g_free(state->orig_buf);
 state->buf_start = start;
-state->buf_len = acb->end + s->readahead_size;
-end = MIN(start + state->buf_len, s->len) - 1;
+state->buf_len = MIN(acb->end + s->readahead_size, s->len - start);
+end = start + state->buf_len - 1;
 state->orig_buf = g_try_malloc(state->buf_len);
 if (state->buf_len && state->orig_buf == NULL) {
 curl_clean_state(state);
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 05/13] blockjob: refactor backup_start as backup_job_create

2016-11-14 Thread Jeff Cody
From: John Snow 

Refactor backup_start as backup_job_create, which only creates the job,
but does not automatically start it. The old interface, 'backup_start',
is not kept in favor of limiting the number of nearly-identical interfaces
that would have to be edited to keep up with QAPI changes in the future.

Callers that wish to synchronously start the backup_block_job can
instead just call block_job_start immediately after calling
backup_job_create.

Transactions are updated to use the new interface, calling block_job_start
only during the .commit phase, which helps prevent race conditions where
jobs may finish before we even finish building the transaction. This may
happen, for instance, during empty block backup jobs.

Reported-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: John Snow 
Message-id: 1478587839-9834-6-git-send-email-js...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/backup.c| 26 ---
 block/replication.c   | 12 ---
 blockdev.c| 81 ++-
 include/block/block_int.h | 23 +++---
 4 files changed, 85 insertions(+), 57 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index ae1b99a..ea38733 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -543,7 +543,7 @@ static const BlockJobDriver backup_job_driver = {
 .drain  = backup_drain,
 };
 
-void backup_start(const char *job_id, BlockDriverState *bs,
+BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
   BlockDriverState *target, int64_t speed,
   MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
   bool compress,
@@ -563,52 +563,52 @@ void backup_start(const char *job_id, BlockDriverState 
*bs,
 
 if (bs == target) {
 error_setg(errp, "Source and target cannot be the same");
-return;
+return NULL;
 }
 
 if (!bdrv_is_inserted(bs)) {
 error_setg(errp, "Device is not inserted: %s",
bdrv_get_device_name(bs));
-return;
+return NULL;
 }
 
 if (!bdrv_is_inserted(target)) {
 error_setg(errp, "Device is not inserted: %s",
bdrv_get_device_name(target));
-return;
+return NULL;
 }
 
 if (compress && target->drv->bdrv_co_pwritev_compressed == NULL) {
 error_setg(errp, "Compression is not supported for this drive %s",
bdrv_get_device_name(target));
-return;
+return NULL;
 }
 
 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
-return;
+return NULL;
 }
 
 if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
-return;
+return NULL;
 }
 
 if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {
 if (!sync_bitmap) {
 error_setg(errp, "must provide a valid bitmap name for "
  "\"incremental\" sync mode");
-return;
+return NULL;
 }
 
 /* Create a new bitmap, and freeze/disable this one. */
 if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) {
-return;
+return NULL;
 }
 } else if (sync_bitmap) {
 error_setg(errp,
"a sync_bitmap was provided to backup_run, "
"but received an incompatible sync_mode (%s)",
MirrorSyncMode_lookup[sync_mode]);
-return;
+return NULL;
 }
 
 len = bdrv_getlength(bs);
@@ -655,8 +655,8 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 block_job_add_bdrv(>common, target);
 job->common.len = len;
 block_job_txn_add_job(txn, >common);
-block_job_start(>common);
-return;
+
+return >common;
 
  error:
 if (sync_bitmap) {
@@ -666,4 +666,6 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 backup_clean(>common);
 block_job_unref(>common);
 }
+
+return NULL;
 }
diff --git a/block/replication.c b/block/replication.c
index d5e2b0f..729dd12 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -421,6 +421,7 @@ static void replication_start(ReplicationState *rs, 
ReplicationMode mode,
 int64_t active_length, hidden_length, disk_length;
 AioContext *aio_context;
 Error *local_err = NULL;
+BlockJob *job;
 
 aio_context = bdrv_get_aio_context(bs);
 aio_context_acquire(aio_context);
@@ -508,17 +509,18 @@ static void replication_start(ReplicationState *rs, 
ReplicationMode mode,
 bdrv_op_block_all(top_bs, s->blocker);
 bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
 
-backup_start(NULL, s->secondary_disk->bs, s->hidden_disk->bs, 0,
- MIRROR_SYNC_MODE_NONE, NULL, false,
- BLOCKDEV_ON_ERROR_REPORT, 

[Qemu-devel] [PULL for-2.8 11/13] block/curl: Remember all sockets

2016-11-14 Thread Jeff Cody
From: Max Reitz 

For some connection types (like FTP, generally), more than one socket
may be used (in FTP's case: control vs. data stream). As of commit
838ef602498b8d1985a231a06f5e328e2946a81d ("curl: Eliminate unnecessary
use of curl_multi_socket_all"), we have to remember all of the sockets
used by libcurl, but in fact we only did that for a single one. Since
one libcurl connection may use multiple sockets, however, we have to
remember them all.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Message-id: 20161025025431.24714-4-mre...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/curl.c | 47 +--
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 7a7e831..273f329 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -103,12 +103,17 @@ typedef struct CURLAIOCB {
 size_t end;
 } CURLAIOCB;
 
+typedef struct CURLSocket {
+int fd;
+QLIST_ENTRY(CURLSocket) next;
+} CURLSocket;
+
 typedef struct CURLState
 {
 struct BDRVCURLState *s;
 CURLAIOCB *acb[CURL_NUM_ACB];
 CURL *curl;
-curl_socket_t sock_fd;
+QLIST_HEAD(, CURLSocket) sockets;
 char *orig_buf;
 size_t buf_start;
 size_t buf_off;
@@ -162,10 +167,27 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int 
action,
 {
 BDRVCURLState *s;
 CURLState *state = NULL;
+CURLSocket *socket;
+
 curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **));
-state->sock_fd = fd;
 s = state->s;
 
+QLIST_FOREACH(socket, >sockets, next) {
+if (socket->fd == fd) {
+if (action == CURL_POLL_REMOVE) {
+QLIST_REMOVE(socket, next);
+g_free(socket);
+}
+break;
+}
+}
+if (!socket) {
+socket = g_new0(CURLSocket, 1);
+socket->fd = fd;
+QLIST_INSERT_HEAD(>sockets, socket, next);
+}
+socket = NULL;
+
 DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, (int)fd);
 switch (action) {
 case CURL_POLL_IN:
@@ -353,6 +375,7 @@ static void curl_multi_check_completion(BDRVCURLState *s)
 static void curl_multi_do(void *arg)
 {
 CURLState *s = (CURLState *)arg;
+CURLSocket *socket, *next_socket;
 int running;
 int r;
 
@@ -360,10 +383,13 @@ static void curl_multi_do(void *arg)
 return;
 }
 
-do {
-r = curl_multi_socket_action(s->s->multi, s->sock_fd, 0, );
-} while(r == CURLM_CALL_MULTI_PERFORM);
-
+/* Need to use _SAFE because curl_multi_socket_action() may trigger
+ * curl_sock_cb() which might modify this list */
+QLIST_FOREACH_SAFE(socket, >sockets, next, next_socket) {
+do {
+r = curl_multi_socket_action(s->s->multi, socket->fd, 0, );
+} while (r == CURLM_CALL_MULTI_PERFORM);
+}
 }
 
 static void curl_multi_read(void *arg)
@@ -467,6 +493,7 @@ static CURLState *curl_init_state(BlockDriverState *bs, 
BDRVCURLState *s)
 #endif
 }
 
+QLIST_INIT(>sockets);
 state->s = s;
 
 return state;
@@ -476,6 +503,14 @@ static void curl_clean_state(CURLState *s)
 {
 if (s->s->multi)
 curl_multi_remove_handle(s->s->multi, s->curl);
+
+while (!QLIST_EMPTY(>sockets)) {
+CURLSocket *socket = QLIST_FIRST(>sockets);
+
+QLIST_REMOVE(socket, next);
+g_free(socket);
+}
+
 s->in_use = 0;
 }
 
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 07/13] qemu-iotests: avoid spurious failure on test 109

2016-11-14 Thread Jeff Cody
From: Paolo Bonzini 

In some cases it is possible that query-io-status is called just
before the job is completed, causing

-{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, 
"event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, 
"offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not 
permitted"}}
-{"return": []}
+{"return": [{"io-status": "ok", "device": "src", "busy": true, "len": 
31457280, "offset": OFFSET, "paused": false, "speed": 0, "ready": false, 
"type": "mirror"}]}

Assert that the completeion event eventually happens.

Signed-off-by: Paolo Bonzini 
Message-id: 20161109162008.27287-1-pbonz...@redhat.com
Reviewed-by: Jeff Cody 
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/109 | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index 280ed27..927151a 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -62,6 +62,9 @@ function run_qemu()
 "return"
 
 _send_qemu_cmd $QEMU_HANDLE '' "$qmp_event"
+if test "$qmp_event" = BLOCK_JOB_ERROR; then
+_send_qemu_cmd $QEMU_HANDLE '' "BLOCK_JOB_COMPLETED"
+fi
 _send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return"
 _cleanup_qemu
 }
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 09/13] block/curl: Use BDRV_SECTOR_SIZE

2016-11-14 Thread Jeff Cody
From: Max Reitz 

Currently, curl defines its own constant SECTOR_SIZE. There is no
advantage over using the global BDRV_SECTOR_SIZE, so drop it.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Message-id: 20161025025431.24714-2-mre...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/curl.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index ba8adae..1d19e64 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -72,7 +72,6 @@ static CURLMcode __curl_multi_socket_action(CURLM 
*multi_handle,
 
 #define CURL_NUM_STATES 8
 #define CURL_NUM_ACB8
-#define SECTOR_SIZE 512
 #define READ_AHEAD_DEFAULT (256 * 1024)
 #define CURL_TIMEOUT_DEFAULT 5
 #define CURL_TIMEOUT_MAX 1
@@ -737,12 +736,12 @@ static void curl_readv_bh_cb(void *p)
 CURLAIOCB *acb = p;
 BDRVCURLState *s = acb->common.bs->opaque;
 
-size_t start = acb->sector_num * SECTOR_SIZE;
+size_t start = acb->sector_num * BDRV_SECTOR_SIZE;
 size_t end;
 
 // In case we have the requested data already (e.g. read-ahead),
 // we can just call the callback and be done.
-switch (curl_find_buf(s, start, acb->nb_sectors * SECTOR_SIZE, acb)) {
+switch (curl_find_buf(s, start, acb->nb_sectors * BDRV_SECTOR_SIZE, acb)) {
 case FIND_RET_OK:
 qemu_aio_unref(acb);
 // fall through
@@ -761,7 +760,7 @@ static void curl_readv_bh_cb(void *p)
 }
 
 acb->start = 0;
-acb->end = (acb->nb_sectors * SECTOR_SIZE);
+acb->end = (acb->nb_sectors * BDRV_SECTOR_SIZE);
 
 state->buf_off = 0;
 g_free(state->orig_buf);
@@ -778,8 +777,8 @@ static void curl_readv_bh_cb(void *p)
 state->acb[0] = acb;
 
 snprintf(state->range, 127, "%zd-%zd", start, end);
-DPRINTF("CURL (AIO): Reading %d at %zd (%s)\n",
-(acb->nb_sectors * SECTOR_SIZE), start, state->range);
+DPRINTF("CURL (AIO): Reading %llu at %zd (%s)\n",
+(acb->nb_sectors * BDRV_SECTOR_SIZE), start, state->range);
 curl_easy_setopt(state->curl, CURLOPT_RANGE, state->range);
 
 curl_multi_add_handle(s->multi, state->curl);
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 08/13] block/curl: Drop TFTP "support"

2016-11-14 Thread Jeff Cody
From: Max Reitz 

Because TFTP does not support byte ranges, it was never usable with our
curl block driver. Since apparently nobody has ever complained loudly
enough for someone to take care of the issue until now, it seems
reasonable to assume that nobody has ever actually used it.

Therefore, it should be safe to just drop it from curl's protocol list.

[Jeff Cody: Below is additional summary pulled, with some rewording,
from followup emails between Max and Markus, to explain what
worked and what didn't]

TFTP would sometimes work, to a limited extent, for images <= the curl
"readahead" size, so long as reads started at offset zero.  By default,
that readahead size is 256KB.

Reads starting at a non-zero offset would also have returned data from a
zero offset.  It can become more complicated still, with mixed reads at
zero offset and non-zero offsets, due to data buffering.

In short, TFTP could only have worked before in very specific scenarios
with unrealistic expectations and constraints.

Signed-off-by: Max Reitz 
Reviewed-by: Kevin Wolf 
Reviewed-by: Jeff Cody 
Message-id: 20161102175539.4375-4-mre...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/curl.c  | 20 +---
 docs/qmp-commands.txt |  2 +-
 qapi/block-core.json  |  7 +++
 qemu-options.hx   |  6 +++---
 4 files changed, 8 insertions(+), 27 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index e5eaa7b..ba8adae 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -68,8 +68,7 @@ static CURLMcode __curl_multi_socket_action(CURLM 
*multi_handle,
 #endif
 
 #define PROTOCOLS (CURLPROTO_HTTP | CURLPROTO_HTTPS | \
-   CURLPROTO_FTP | CURLPROTO_FTPS | \
-   CURLPROTO_TFTP)
+   CURLPROTO_FTP | CURLPROTO_FTPS)
 
 #define CURL_NUM_STATES 8
 #define CURL_NUM_ACB8
@@ -886,29 +885,12 @@ static BlockDriver bdrv_ftps = {
 .bdrv_attach_aio_context= curl_attach_aio_context,
 };
 
-static BlockDriver bdrv_tftp = {
-.format_name= "tftp",
-.protocol_name  = "tftp",
-
-.instance_size  = sizeof(BDRVCURLState),
-.bdrv_parse_filename= curl_parse_filename,
-.bdrv_file_open = curl_open,
-.bdrv_close = curl_close,
-.bdrv_getlength = curl_getlength,
-
-.bdrv_aio_readv = curl_aio_readv,
-
-.bdrv_detach_aio_context= curl_detach_aio_context,
-.bdrv_attach_aio_context= curl_attach_aio_context,
-};
-
 static void curl_block_init(void)
 {
 bdrv_register(_http);
 bdrv_register(_https);
 bdrv_register(_ftp);
 bdrv_register(_ftps);
-bdrv_register(_tftp);
 }
 
 block_init(curl_block_init);
diff --git a/docs/qmp-commands.txt b/docs/qmp-commands.txt
index 6afa872..abf210a 100644
--- a/docs/qmp-commands.txt
+++ b/docs/qmp-commands.txt
@@ -1803,7 +1803,7 @@ Each json-object contain the following:
 "file", "file", "ftp", "ftps", "host_cdrom",
 "host_device", "http", "https",
 "nbd", "parallels", "qcow", "qcow2", "raw",
-"tftp", "vdi", "vmdk", "vpc", "vvfat"
+"vdi", "vmdk", "vpc", "vvfat"
  - "backing_file": backing file name (json-string, optional)
  - "backing_file_depth": number of files in the backing file chain 
(json-int)
  - "encrypted": true if encrypted, false otherwise (json-bool)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index bcd3b9e..c29bef7 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -243,12 +243,12 @@
 #   0.14.0 this can be: 'blkdebug', 'bochs', 'cloop', 'cow', 'dmg',
 #   'file', 'file', 'ftp', 'ftps', 'host_cdrom', 'host_device',
 #   'http', 'https', 'luks', 'nbd', 'parallels', 'qcow',
-#   'qcow2', 'raw', 'tftp', 'vdi', 'vmdk', 'vpc', 'vvfat'
+#   'qcow2', 'raw', 'vdi', 'vmdk', 'vpc', 'vvfat'
 #   2.2: 'archipelago' added, 'cow' dropped
 #   2.3: 'host_floppy' deprecated
 #   2.5: 'host_floppy' dropped
 #   2.6: 'luks' added
-#   2.8: 'replication' added
+#   2.8: 'replication' added, 'tftp' dropped
 #
 # @backing_file: #optional the name of the backing file (for copy-on-write)
 #
@@ -1723,7 +1723,7 @@
 'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom',
 'host_device', 'http', 'https', 'luks', 'nbd', 'nfs', 'null-aio',
 'null-co', 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw',
-'replication', 'ssh', 'tftp', 'vdi', 'vhdx', 'vmdk', 'vpc',
+'replication', 'ssh', 'vdi', 'vhdx', 'vmdk', 'vpc',
 'vvfat' ] }
 
 ##
@@ -2410,7 +2410,6 @@
   'replication':'BlockdevOptionsReplication',
 # TODO sheepdog: Wait for structured options
   'ssh':

[Qemu-devel] [PULL for-2.8 03/13] blockjob: add .start field

2016-11-14 Thread Jeff Cody
From: John Snow 

Add an explicit start field to specify the entrypoint. We already have
ownership of the coroutine itself AND managing the lifetime of the
coroutine, let's take control of creation of the coroutine, too.

This will allow us to delay creation of the actual coroutine until we
know we'll actually start a BlockJob in block_job_start. This avoids
the sticky question of how to "un-create" a Coroutine that hasn't been
started yet.

Signed-off-by: John Snow 
Reviewed-by: Kevin Wolf 
Message-id: 1478587839-9834-4-git-send-email-js...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/backup.c   | 25 +
 block/commit.c   |  3 ++-
 block/mirror.c   |  4 +++-
 block/stream.c   |  3 ++-
 include/block/blockjob_int.h |  3 +++
 5 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 734a24c..4ed4494 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -323,17 +323,6 @@ static void backup_drain(BlockJob *job)
 }
 }
 
-static const BlockJobDriver backup_job_driver = {
-.instance_size  = sizeof(BackupBlockJob),
-.job_type   = BLOCK_JOB_TYPE_BACKUP,
-.set_speed  = backup_set_speed,
-.commit = backup_commit,
-.abort  = backup_abort,
-.clean  = backup_clean,
-.attached_aio_context   = backup_attached_aio_context,
-.drain  = backup_drain,
-};
-
 static BlockErrorAction backup_error_action(BackupBlockJob *job,
 bool read, int error)
 {
@@ -542,6 +531,18 @@ static void coroutine_fn backup_run(void *opaque)
 block_job_defer_to_main_loop(>common, backup_complete, data);
 }
 
+static const BlockJobDriver backup_job_driver = {
+.instance_size  = sizeof(BackupBlockJob),
+.job_type   = BLOCK_JOB_TYPE_BACKUP,
+.start  = backup_run,
+.set_speed  = backup_set_speed,
+.commit = backup_commit,
+.abort  = backup_abort,
+.clean  = backup_clean,
+.attached_aio_context   = backup_attached_aio_context,
+.drain  = backup_drain,
+};
+
 void backup_start(const char *job_id, BlockDriverState *bs,
   BlockDriverState *target, int64_t speed,
   MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
@@ -653,7 +654,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 
 block_job_add_bdrv(>common, target);
 job->common.len = len;
-job->common.co = qemu_coroutine_create(backup_run, job);
+job->common.co = qemu_coroutine_create(job->common.driver->start, job);
 block_job_txn_add_job(txn, >common);
 qemu_coroutine_enter(job->common.co);
 return;
diff --git a/block/commit.c b/block/commit.c
index e1eda89..20d27e2 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -205,6 +205,7 @@ static const BlockJobDriver commit_job_driver = {
 .instance_size = sizeof(CommitBlockJob),
 .job_type  = BLOCK_JOB_TYPE_COMMIT,
 .set_speed = commit_set_speed,
+.start = commit_run,
 };
 
 void commit_start(const char *job_id, BlockDriverState *bs,
@@ -288,7 +289,7 @@ void commit_start(const char *job_id, BlockDriverState *bs,
 s->backing_file_str = g_strdup(backing_file_str);
 
 s->on_error = on_error;
-s->common.co = qemu_coroutine_create(commit_run, s);
+s->common.co = qemu_coroutine_create(s->common.driver->start, s);
 
 trace_commit_start(bs, base, top, s, s->common.co);
 qemu_coroutine_enter(s->common.co);
diff --git a/block/mirror.c b/block/mirror.c
index b2c1fb8..659e09c 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -920,6 +920,7 @@ static const BlockJobDriver mirror_job_driver = {
 .instance_size  = sizeof(MirrorBlockJob),
 .job_type   = BLOCK_JOB_TYPE_MIRROR,
 .set_speed  = mirror_set_speed,
+.start  = mirror_run,
 .complete   = mirror_complete,
 .pause  = mirror_pause,
 .attached_aio_context   = mirror_attached_aio_context,
@@ -930,6 +931,7 @@ static const BlockJobDriver commit_active_job_driver = {
 .instance_size  = sizeof(MirrorBlockJob),
 .job_type   = BLOCK_JOB_TYPE_COMMIT,
 .set_speed  = mirror_set_speed,
+.start  = mirror_run,
 .complete   = mirror_complete,
 .pause  = mirror_pause,
 .attached_aio_context   = mirror_attached_aio_context,
@@ -1007,7 +1009,7 @@ static void mirror_start_job(const char *job_id, 
BlockDriverState *bs,
 }
 }
 
-s->common.co = qemu_coroutine_create(mirror_run, s);
+s->common.co = qemu_coroutine_create(s->common.driver->start, s);
 trace_mirror_start(bs, 

[Qemu-devel] [PULL for-2.8 06/13] iotests: add transactional failure race test

2016-11-14 Thread Jeff Cody
From: John Snow 

Add a regression test for the case found by Vladimir.

Reported-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: John Snow 
Reviewed-by: Kevin Wolf 
Message-id: 1478587839-9834-7-git-send-email-js...@redhat.com
Signed-off-by: Jeff Cody 
---
 tests/qemu-iotests/124 | 53 ++
 tests/qemu-iotests/124.out |  4 ++--
 2 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index f06938e..d0d2c2b 100644
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -395,19 +395,7 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 self.check_backups()
 
 
-def test_transaction_failure(self):
-'''Test: Verify backups made from a transaction that partially fails.
-
-Add a second drive with its own unique pattern, and add a bitmap to 
each
-drive. Use blkdebug to interfere with the backup on just one drive and
-attempt to create a coherent incremental backup across both drives.
-
-verify a failure in one but not both, then delete the failed stubs and
-re-run the same transaction.
-
-verify that both incrementals are created successfully.
-'''
-
+def do_transaction_failure_test(self, race=False):
 # Create a second drive, with pattern:
 drive1 = self.add_node('drive1')
 self.img_create(drive1['file'], drive1['fmt'])
@@ -451,9 +439,10 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 self.assertFalse(self.vm.get_qmp_events(wait=False))
 
 # Emulate some writes
-self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
-  ('0xfe', '16M', '256k'),
-  ('0x64', '32736k', '64k')))
+if not race:
+self.hmp_io_writes(drive0['id'], (('0xab', 0, 512),
+  ('0xfe', '16M', '256k'),
+  ('0x64', '32736k', '64k')))
 self.hmp_io_writes(drive1['id'], (('0xba', 0, 512),
   ('0xef', '16M', '256k'),
   ('0x46', '32736k', '64k')))
@@ -463,7 +452,8 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 target1 = self.prepare_backup(dr1bm0)
 
 # Ask for a new incremental backup per-each drive,
-# expecting drive1's backup to fail:
+# expecting drive1's backup to fail. In the 'race' test,
+# we expect drive1 to attempt to cancel the empty drive0 job.
 transaction = [
 transaction_drive_backup(drive0['id'], target0, sync='incremental',
  format=drive0['fmt'], mode='existing',
@@ -488,9 +478,15 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 self.assert_no_active_block_jobs()
 
 # Delete drive0's successful target and eliminate our record of the
-# unsuccessful drive1 target. Then re-run the same transaction.
+# unsuccessful drive1 target.
 dr0bm0.del_target()
 dr1bm0.del_target()
+if race:
+# Don't re-run the transaction, we only wanted to test the race.
+self.vm.shutdown()
+return
+
+# Re-run the same transaction:
 target0 = self.prepare_backup(dr0bm0)
 target1 = self.prepare_backup(dr1bm0)
 
@@ -511,6 +507,27 @@ class TestIncrementalBackup(TestIncrementalBackupBase):
 self.vm.shutdown()
 self.check_backups()
 
+def test_transaction_failure(self):
+'''Test: Verify backups made from a transaction that partially fails.
+
+Add a second drive with its own unique pattern, and add a bitmap to 
each
+drive. Use blkdebug to interfere with the backup on just one drive and
+attempt to create a coherent incremental backup across both drives.
+
+verify a failure in one but not both, then delete the failed stubs and
+re-run the same transaction.
+
+verify that both incrementals are created successfully.
+'''
+self.do_transaction_failure_test()
+
+def test_transaction_failure_race(self):
+'''Test: Verify that transactions with jobs that have no data to
+transfer do not cause race conditions in the cancellation of the entire
+transaction job group.
+'''
+self.do_transaction_failure_test(race=True)
+
 
 def test_sync_dirty_bitmap_missing(self):
 self.assert_no_active_block_jobs()
diff --git a/tests/qemu-iotests/124.out b/tests/qemu-iotests/124.out
index 36376be..e56cae0 100644
--- a/tests/qemu-iotests/124.out
+++ b/tests/qemu-iotests/124.out
@@ -1,5 +1,5 @@
-..
+...
 --
-Ran 10 tests

[Qemu-devel] [PULL for-2.8 04/13] blockjob: add block_job_start

2016-11-14 Thread Jeff Cody
From: John Snow 

Instead of automatically starting jobs at creation time via backup_start
et al, we'd like to return a job object pointer that can be started
manually at later point in time.

For now, add the block_job_start mechanism and start the jobs
automatically as we have been doing, with conversions job-by-job coming
in later patches.

Of note: cancellation of unstarted jobs will perform all the normal
cleanup as if the job had started, particularly abort and clean. The
only difference is that we will not emit any events, because the job
never actually started.

Signed-off-by: John Snow 
Message-id: 1478587839-9834-5-git-send-email-js...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/backup.c|  3 +--
 block/commit.c|  5 ++---
 block/mirror.c|  5 ++---
 block/stream.c|  5 ++---
 block/trace-events|  6 +++---
 blockjob.c| 54 ---
 include/block/blockjob.h  |  9 
 tests/test-blockjob-txn.c | 12 +--
 8 files changed, 67 insertions(+), 32 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 4ed4494..ae1b99a 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -654,9 +654,8 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 
 block_job_add_bdrv(>common, target);
 job->common.len = len;
-job->common.co = qemu_coroutine_create(job->common.driver->start, job);
 block_job_txn_add_job(txn, >common);
-qemu_coroutine_enter(job->common.co);
+block_job_start(>common);
 return;
 
  error:
diff --git a/block/commit.c b/block/commit.c
index 20d27e2..c284e85 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -289,10 +289,9 @@ void commit_start(const char *job_id, BlockDriverState *bs,
 s->backing_file_str = g_strdup(backing_file_str);
 
 s->on_error = on_error;
-s->common.co = qemu_coroutine_create(s->common.driver->start, s);
 
-trace_commit_start(bs, base, top, s, s->common.co);
-qemu_coroutine_enter(s->common.co);
+trace_commit_start(bs, base, top, s);
+block_job_start(>common);
 }
 
 
diff --git a/block/mirror.c b/block/mirror.c
index 659e09c..62ac87f 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1009,9 +1009,8 @@ static void mirror_start_job(const char *job_id, 
BlockDriverState *bs,
 }
 }
 
-s->common.co = qemu_coroutine_create(s->common.driver->start, s);
-trace_mirror_start(bs, s, s->common.co, opaque);
-qemu_coroutine_enter(s->common.co);
+trace_mirror_start(bs, s, opaque);
+block_job_start(>common);
 }
 
 void mirror_start(const char *job_id, BlockDriverState *bs,
diff --git a/block/stream.c b/block/stream.c
index 92309ff..1523ba7 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -255,7 +255,6 @@ void stream_start(const char *job_id, BlockDriverState *bs,
 s->bs_flags = orig_bs_flags;
 
 s->on_error = on_error;
-s->common.co = qemu_coroutine_create(s->common.driver->start, s);
-trace_stream_start(bs, base, s, s->common.co);
-qemu_coroutine_enter(s->common.co);
+trace_stream_start(bs, base, s);
+block_job_start(>common);
 }
diff --git a/block/trace-events b/block/trace-events
index 882c903..cfc05f2 100644
--- a/block/trace-events
+++ b/block/trace-events
@@ -19,14 +19,14 @@ bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned 
int bytes, int64_t c
 
 # block/stream.c
 stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int 
is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-stream_start(void *bs, void *base, void *s, void *co) "bs %p base %p s %p co 
%p"
+stream_start(void *bs, void *base, void *s) "bs %p base %p s %p"
 
 # block/commit.c
 commit_one_iteration(void *s, int64_t sector_num, int nb_sectors, int 
is_allocated) "s %p sector_num %"PRId64" nb_sectors %d is_allocated %d"
-commit_start(void *bs, void *base, void *top, void *s, void *co) "bs %p base 
%p top %p s %p co %p"
+commit_start(void *bs, void *base, void *top, void *s) "bs %p base %p top %p s 
%p"
 
 # block/mirror.c
-mirror_start(void *bs, void *s, void *co, void *opaque) "bs %p s %p co %p 
opaque %p"
+mirror_start(void *bs, void *s, void *opaque) "bs %p s %p opaque %p"
 mirror_restart_iter(void *s, int64_t cnt) "s %p dirty count %"PRId64
 mirror_before_flush(void *s) "s %p"
 mirror_before_drain(void *s, int64_t cnt) "s %p dirty count %"PRId64
diff --git a/blockjob.c b/blockjob.c
index e3c458c..513620c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -174,7 +174,9 @@ void *block_job_create(const char *job_id, const 
BlockJobDriver *driver,
 job->blk   = blk;
 job->cb= cb;
 job->opaque= opaque;
-job->busy  = true;
+job->busy  = false;
+job->paused= true;
+job->pause_count   = 1;
 job->refcnt= 1;
 bs->job = job;
 
@@ -202,6 +204,23 @@ bool block_job_is_internal(BlockJob *job)
 

[Qemu-devel] [PULL for-2.8 01/13] blockjob: fix dead pointer in txn list

2016-11-14 Thread Jeff Cody
From: Vladimir Sementsov-Ogievskiy 

Though it is not intended to be reached through normal circumstances,
if we do not gracefully deconstruct the transaction QLIST, we may wind
up with stale pointers in the list.

The rest of this series attempts to address the underlying issues,
but this should fix list inconsistencies.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Tested-by: John Snow 
Reviewed-by: John Snow 
Reviewed-by: Eric Blake 
Reviewed-by: Kevin Wolf 
Signed-off-by: John Snow 
Message-id: 1478587839-9834-2-git-send-email-js...@redhat.com
[Rewrote commit message. --js]
Signed-off-by: John Snow 
Reviewed-by: Eric Blake 
Reviewed-by: Kevin Wolf 

Signed-off-by: John Snow 
Signed-off-by: Jeff Cody 
---
 blockjob.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/blockjob.c b/blockjob.c
index 4aa14a4..4d0ef53 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -256,6 +256,7 @@ static void block_job_completed_single(BlockJob *job)
 }
 
 if (job->txn) {
+QLIST_REMOVE(job, txn_list);
 block_job_txn_unref(job->txn);
 }
 block_job_unref(job);
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 02/13] blockjob: add .clean property

2016-11-14 Thread Jeff Cody
From: John Snow 

Cleaning up after we have deferred to the main thread but before the
transaction has converged can be dangerous and result in deadlocks
if the job cleanup invokes any BH polling loops.

A job may attempt to begin cleaning up, but may induce another job to
enter its cleanup routine. The second job, part of our same transaction,
will block waiting for the first job to finish, so neither job may now
make progress.

To rectify this, allow jobs to register a cleanup operation that will
always run regardless of if the job was in a transaction or not, and
if the transaction job group completed successfully or not.

Move sensitive cleanup to this callback instead which is guaranteed to
be run only after the transaction has converged, which removes sensitive
timing constraints from said cleanup.

Furthermore, in future patches these cleanup operations will be performed
regardless of whether or not we actually started the job. Therefore,
cleanup callbacks should essentially confine themselves to undoing create
operations, e.g. setup actions taken in what is now backup_start.

Reported-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: John Snow 
Reviewed-by: Kevin Wolf 
Message-id: 1478587839-9834-3-git-send-email-js...@redhat.com
Signed-off-by: Jeff Cody 
---
 block/backup.c   | 15 ++-
 blockjob.c   |  3 +++
 include/block/blockjob_int.h |  8 
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 7b5d8a3..734a24c 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -242,6 +242,14 @@ static void backup_abort(BlockJob *job)
 }
 }
 
+static void backup_clean(BlockJob *job)
+{
+BackupBlockJob *s = container_of(job, BackupBlockJob, common);
+assert(s->target);
+blk_unref(s->target);
+s->target = NULL;
+}
+
 static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
 {
 BackupBlockJob *s = container_of(job, BackupBlockJob, common);
@@ -321,6 +329,7 @@ static const BlockJobDriver backup_job_driver = {
 .set_speed  = backup_set_speed,
 .commit = backup_commit,
 .abort  = backup_abort,
+.clean  = backup_clean,
 .attached_aio_context   = backup_attached_aio_context,
 .drain  = backup_drain,
 };
@@ -343,12 +352,8 @@ typedef struct {
 
 static void backup_complete(BlockJob *job, void *opaque)
 {
-BackupBlockJob *s = container_of(job, BackupBlockJob, common);
 BackupCompleteData *data = opaque;
 
-blk_unref(s->target);
-s->target = NULL;
-
 block_job_completed(job, data->ret);
 g_free(data);
 }
@@ -658,7 +663,7 @@ void backup_start(const char *job_id, BlockDriverState *bs,
 bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);
 }
 if (job) {
-blk_unref(job->target);
+backup_clean(>common);
 block_job_unref(>common);
 }
 }
diff --git a/blockjob.c b/blockjob.c
index 4d0ef53..e3c458c 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -241,6 +241,9 @@ static void block_job_completed_single(BlockJob *job)
 job->driver->abort(job);
 }
 }
+if (job->driver->clean) {
+job->driver->clean(job);
+}
 
 if (job->cb) {
 job->cb(job->opaque, job->ret);
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index 40275e4..60d91a0 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -74,6 +74,14 @@ struct BlockJobDriver {
 void (*abort)(BlockJob *job);
 
 /**
+ * If the callback is not NULL, it will be invoked after a call to either
+ * .commit() or .abort(). Regardless of which callback is invoked after
+ * completion, .clean() will always be called, even if the job does not
+ * belong to a transaction group.
+ */
+void (*clean)(BlockJob *job);
+
+/**
  * If the callback is not NULL, it will be invoked when the job transitions
  * into the paused state.  Paused jobs must not perform any asynchronous
  * I/O or event loop activity.  This callback is used to quiesce jobs.
-- 
2.7.4




[Qemu-devel] [PULL for-2.8 00/13] Block patches for 2.8

2016-11-14 Thread Jeff Cody
The following changes since commit 682df581c65ed2c1b9e77093e332214ecaa1ee93:

  Merge remote-tracking branch 'jsnow/tags/ide-pull-request' into staging 
(2016-11-14 17:07:16 +)

are available in the git repository at:

  https://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request

for you to fetch changes up to bdffb31d8eece1cbd4d88f136daccfe1f93a1bf6:

  mirror: do not flush every time the disks are synced (2016-11-14 22:49:26 
-0500)


Block patches for 2.8


John Snow (5):
  blockjob: add .clean property
  blockjob: add .start field
  blockjob: add block_job_start
  blockjob: refactor backup_start as backup_job_create
  iotests: add transactional failure race test

Max Reitz (5):
  block/curl: Drop TFTP "support"
  block/curl: Use BDRV_SECTOR_SIZE
  block/curl: Fix return value from curl_read_cb
  block/curl: Remember all sockets
  block/curl: Do not wait for data beyond EOF

Paolo Bonzini (2):
  qemu-iotests: avoid spurious failure on test 109
  mirror: do not flush every time the disks are synced

Vladimir Sementsov-Ogievskiy (1):
  blockjob: fix dead pointer in txn list

 block/backup.c   |  63 +--
 block/commit.c   |   6 +--
 block/curl.c | 119 +++
 block/mirror.c   |  47 ++---
 block/replication.c  |  12 +++--
 block/stream.c   |   6 +--
 block/trace-events   |   6 +--
 blockdev.c   |  81 ++---
 blockjob.c   |  58 -
 docs/qmp-commands.txt|   2 +-
 include/block/block_int.h|  23 +
 include/block/blockjob.h |   9 
 include/block/blockjob_int.h |  11 
 qapi/block-core.json |   7 ++-
 qemu-options.hx  |   6 +--
 tests/qemu-iotests/109   |   3 ++
 tests/qemu-iotests/124   |  53 ---
 tests/qemu-iotests/124.out   |   4 +-
 tests/test-blockjob-txn.c|  12 ++---
 19 files changed, 339 insertions(+), 189 deletions(-)

-- 
2.7.4




Re: [Qemu-devel] [PATCH for-2.8] mirror: do not flush every time the disks are synced

2016-11-14 Thread Jeff Cody
On Wed, Nov 09, 2016 at 05:01:31PM -0500, Paolo Bonzini wrote:
> 
> 
> - Original Message -
> > From: "Jeff Cody" 
> > To: "Paolo Bonzini" 
> > Cc: qemu-devel@nongnu.org, qemu-bl...@nongnu.org, js...@redhat.com
> > Sent: Wednesday, November 9, 2016 7:38:26 PM
> > Subject: Re: [PATCH for-2.8] mirror: do not flush every time the disks are 
> > synced
> > 
> > On Wed, Nov 09, 2016 at 05:20:08PM +0100, Paolo Bonzini wrote:
> > > This puts a huge strain on the disks when there are many concurrent
> > > migrations.  With this patch we only flush twice: just before issuing
> > > the event, and just before pivoting to the destination.  If management
> > > will complete the job close to the BLOCK_JOB_READY event, the cost of
> > > the second flush should be small anyway.
> > > 
> > > Signed-off-by: Paolo Bonzini 
> > > ---
> > >  block/mirror.c | 40 +---
> > >  1 file changed, 25 insertions(+), 15 deletions(-)
> > > 
> > > diff --git a/block/mirror.c b/block/mirror.c
> > > index b2c1fb8..3ec281c 100644
> > > --- a/block/mirror.c
> > > +++ b/block/mirror.c
> > > @@ -615,6 +615,20 @@ static int coroutine_fn
> > > mirror_dirty_init(MirrorBlockJob *s)
> > >  return 0;
> > >  }
> > >  
> > > +/* Called when going out of the streaming phase to flush the bulk of the
> > > + * data to the medium, or just before completing.
> > > + */
> > > +static int mirror_flush(MirrorBlockJob *s)
> > > +{
> > > +int ret = blk_flush(s->target);
> > > +if (ret < 0) {
> > > +if (mirror_error_action(s, false, -ret) ==
> > > BLOCK_ERROR_ACTION_REPORT) {
> > > +s->ret = ret;
> > > +}
> > > +}
> > > +return ret;
> > > +}
> > > +
> > >  static void coroutine_fn mirror_run(void *opaque)
> > >  {
> > >  MirrorBlockJob *s = opaque;
> > > @@ -727,27 +741,23 @@ static void coroutine_fn mirror_run(void *opaque)
> > >  should_complete = false;
> > >  if (s->in_flight == 0 && cnt == 0) {
> > >  trace_mirror_before_flush(s);
> > > -ret = blk_flush(s->target);
> > > -if (ret < 0) {
> > > -if (mirror_error_action(s, false, -ret) ==
> > > -BLOCK_ERROR_ACTION_REPORT) {
> > > -goto immediate_exit;
> > > +if (!s->synced) {
> > > +if (mirror_flush(s) < 0) {
> > > +/* Go check s->ret.  */
> > > +continue;
> > 
> > I think this would be easier to follow, if rather than popping back up to
> > the top of the loop to do error checking, to just do the error cleanup like
> > normal, e.g.:
> > 
> > > @@ -765,7 +775,7 @@ static void coroutine_fn mirror_run(void *opaque)
> > >  
> > >  bdrv_drained_begin(bs);
> > >  cnt = bdrv_get_dirty_count(s->dirty_bitmap);
> > > -if (cnt > 0) {
> > > +if (cnt > 0 || mirror_flush(s) < 0) {
> > >  bdrv_drained_end(bs);
> > >  continue;
> > 
> > Bah, that continue paradigm is used here from before this patch.  Could I
> > convince you to change this too?
> 
> I tried but I could not really write it in a way that looked nice, so I at
> least made both calls to mirror_flush look the same. :(
> 
> The problem is that the cnt > 0 really needs to be a 
> bdrv_drained_end+continue,
> while the mirror_flush case would be a bdrv_drained_end+goto immediate_exit.
> 
> Paolo

Very well :)

Applied to my block branch:

git://github.com/codyprime/qemu-kvm-jtc.git block

-Jeff



Re: [Qemu-devel] [PATCH 0/4] block/curl: Fix FTP

2016-11-14 Thread Jeff Cody
On Wed, Oct 26, 2016 at 10:44:02AM +0100, Richard W.M. Jones wrote:
> As well as testing patch 2 on its own, I also tested all 4 patches
> together on top of current qemu from git.
> 
> In summary, it seems to work fine and doesn't break http or https as
> far as I can tell.
> 
> Rich.
> 
> $ http_proxy= LIBGUESTFS_BACKEND=direct 
> LIBGUESTFS_HV=~/d/qemu/x86_64-softmmu/qemu-system-x86_64 guestfish -a 
> http://onuma.home.annexia.org/media/installers/Fedora-23-Cloud-x86_64/Fedora-Cloud-Base-23-20151030.x86_64.qcow2
>  --ro -i
> 
> Welcome to guestfish, the guest filesystem shell for
> editing virtual machine filesystems and disk images.
> 
> Type: 'help' for help on commands
>   'man' to read the manual
>   'quit' to quit the shell
> 
> Operating system: Fedora 23 (Cloud Edition)
> /dev/sda1 mounted on /
> 
> > ll /
> total 84
> dr-xr-xr-x. 18 root root  4096 Oct 30  2015 .
> drwxr-xr-x  19 root root  4096 Oct 26 09:42 ..
> lrwxrwxrwx.  1 root root 7 Sep 10  2015 bin -> usr/bin
> dr-xr-xr-x.  5 root root  4096 Oct 30  2015 boot
> drwxr-xr-x.  2 root root  4096 Oct 30  2015 dev
> drwxr-xr-x. 68 root root  4096 Oct 30  2015 etc
> drwxr-xr-x.  2 root root  4096 Oct 30  2015 home
> lrwxrwxrwx.  1 root root 7 Sep 10  2015 lib -> usr/lib
> lrwxrwxrwx.  1 root root 9 Sep 10  2015 lib64 -> usr/lib64
> drwx--.  2 root root 16384 Oct 30  2015 lost+found
> drwxr-xr-x.  2 root root  4096 Sep 10  2015 media
> drwxr-xr-x.  2 root root  4096 Sep 10  2015 mnt
> drwxr-xr-x.  2 root root  4096 Sep 10  2015 opt
> drwxr-xr-x.  2 root root  4096 Oct 30  2015 proc
> dr-xr-x---.  2 root root  4096 Oct 30  2015 root
> drwxr-xr-x.  2 root root  4096 Oct 30  2015 run
> lrwxrwxrwx.  1 root root 8 Sep 10  2015 sbin -> usr/sbin
> drwxr-xr-x.  2 root root  4096 Sep 10  2015 srv
> drwxr-xr-x.  2 root root  4096 Oct 30  2015 sys
> drwxrwxrwt.  7 root root  4096 Oct 30  2015 tmp
> drwxr-xr-x. 12 root root  4096 Oct 30  2015 usr
> drwxr-xr-x. 18 root root  4096 Oct 30  2015 var
> 
> > find / | wc -l
> 26532
> > exit
> 
> $ http_proxy= https_proxy= LIBGUESTFS_BACKEND=direct 
> LIBGUESTFS_HV=~/d/qemu/x86_64-softmmu/qemu-system-x86_64 guestfish -a 
> https://download.fedoraproject.org/pub/fedora/linux/releases/24/CloudImages/x86_64/images/Fedora-Cloud-Base-24-1.2.x86_64.qcow2
>  --ro -i
> 
> Welcome to guestfish, the guest filesystem shell for
> editing virtual machine filesystems and disk images.
> 
> Type: 'help' for help on commands
>   'man' to read the manual
>   'quit' to quit the shell
> 
> Operating system: Fedora 24 (Cloud Edition)
> /dev/sda1 mounted on /
> 
> > ll /
> total 84
> dr-xr-xr-x. 18 root root  4096 Jun 14 16:24 .
> drwxr-xr-x  19 root root  4096 Oct 26 09:42 ..
> lrwxrwxrwx.  1 root root 7 Feb  3  2016 bin -> usr/bin
> dr-xr-xr-x.  4 root root  4096 Jun 14 16:24 boot
> drwxr-xr-x.  2 root root  4096 Jun 14 16:20 dev
> drwxr-xr-x. 67 root root  4096 Jun 14 16:25 etc
> drwxr-xr-x.  2 root root  4096 Jun 14 16:24 home
> lrwxrwxrwx.  1 root root 7 Feb  3  2016 lib -> usr/lib
> lrwxrwxrwx.  1 root root 9 Feb  3  2016 lib64 -> usr/lib64
> drwx--.  2 root root 16384 Jun 14 16:20 lost+found
> drwxr-xr-x.  2 root root  4096 Feb  3  2016 media
> drwxr-xr-x.  2 root root  4096 Feb  3  2016 mnt
> drwxr-xr-x.  2 root root  4096 Feb  3  2016 opt
> drwxr-xr-x.  2 root root  4096 Jun 14 16:20 proc
> dr-xr-x---.  2 root root  4096 Jun 14 16:26 root
> drwxr-xr-x.  2 root root  4096 Jun 14 16:20 run
> lrwxrwxrwx.  1 root root 8 Feb  3  2016 sbin -> usr/sbin
> drwxr-xr-x.  2 root root  4096 Feb  3  2016 srv
> drwxr-xr-x.  2 root root  4096 Jun 14 16:20 sys
> drwxrwxrwt.  7 root root  4096 Jun 14 16:26 tmp
> drwxr-xr-x. 12 root root  4096 Jun 14 16:20 usr
> drwxr-xr-x. 19 root root  4096 Jun 14 16:20 var
> 
> > find / | wc -l
> 25817
> > 
> 
> 
> -- 
> Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
> Read my programming and virtualization blog: http://rwmj.wordpress.com
> libguestfs lets you edit virtual machines.  Supports shell scripting,
> bindings from many languages.  http://libguestfs.org
> 

Thanks,

Applied to my block branch:

git://github.com/codyprime/qemu-kvm-jtc.git block

-Jeff



Re: [Qemu-devel] [PULL V2 0/3] Net patches

2016-11-14 Thread Jason Wang



On 2016年11月15日 00:40, Stefan Hajnoczi wrote:

On Mon, Nov 14, 2016 at 10:54:23AM +0800, Jason Wang wrote:

Pavel Dovgalyuk (1):
   record/replay: add network support

QEMU is in soft freeze.  The policy has changed this release and only
bug fixes are being accepted during soft freeze.  Please don't include
new features.

http://qemu-project.org/Planning/SoftFeatureFreeze

Please submit a new version without this patch or explain why it is a
necessary bug fix for -rc0.

Thanks,
Stefan


Will drop this patch.

Thanks



Re: [Qemu-devel] [PULL V2 0/3] Net patches

2016-11-14 Thread Jason Wang



On 2016年11月14日 14:46, Zhang Chen wrote:

Hi~ Jason~

Can you pick up this patch?

[PATCH] docs: fix COLO architecture diagram


Thanks

Zhang Chen 


Will have a look at this and pick it.

Thanks



[Qemu-devel] [PULL 19/19] boot-serial-test: Add a test for the powernv machine

2016-11-14 Thread David Gibson
From: Thomas Huth 

The new powernv machine ships with a firmware that outputs
some text to the serial console, so we can automatically
test this machine type in the boot-serial tester, too.
And to get some (very limited) test coverage for the new
POWER9 CPU emulation, too, this test is also started with
"-cpu POWER9".

Signed-off-by: Thomas Huth 
Reviewed-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 tests/boot-serial-test.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c
index d98c564..44c82e5 100644
--- a/tests/boot-serial-test.c
+++ b/tests/boot-serial-test.c
@@ -29,6 +29,7 @@ static testdef_t tests[] = {
 { "ppc64", "ppce500", "", "U-Boot" },
 { "ppc64", "prep", "", "Open Hack'Ware BIOS" },
 { "ppc64", "pseries", "", "Open Firmware" },
+{ "ppc64", "powernv", "-cpu POWER9", "SkiBoot" },
 { "i386", "isapc", "-cpu qemu32 -device sga", "SGABIOS" },
 { "i386", "pc", "-device sga", "SGABIOS" },
 { "i386", "q35", "-device sga", "SGABIOS" },
-- 
2.7.4




[Qemu-devel] [PULL 15/19] ppc/pnv: add a 'xscom_core_base' field to PnvChipClass

2016-11-14 Thread David Gibson
From: Cédric Le Goater 

The XSCOM addresses for the core registers are encoded in a slightly
different way on POWER8 and POWER9.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c   | 8 +++-
 include/hw/ppc/pnv.h   | 1 +
 include/hw/ppc/pnv_xscom.h | 5 ++---
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 6af3424..e777958 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -521,6 +521,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, 
void *data)
 k->cores_mask = POWER8E_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
 k->xscom_base = 0x003fc00ull;
+k->xscom_core_base = 0x1000ull;
 dc->desc = "PowerNV Chip POWER8E";
 }
 
@@ -542,6 +543,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, 
void *data)
 k->cores_mask = POWER8_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
 k->xscom_base = 0x003fc00ull;
+k->xscom_core_base = 0x1000ull;
 dc->desc = "PowerNV Chip POWER8";
 }
 
@@ -563,6 +565,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass 
*klass, void *data)
 k->cores_mask = POWER8_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p8;
 k->xscom_base = 0x003fc00ull;
+k->xscom_core_base = 0x1000ull;
 dc->desc = "PowerNV Chip POWER8NVL";
 }
 
@@ -584,6 +587,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, 
void *data)
 k->cores_mask = POWER9_CORE_MASK;
 k->core_pir = pnv_chip_core_pir_p9;
 k->xscom_base = 0x00603fcull;
+k->xscom_core_base = 0x0ull;
 dc->desc = "PowerNV Chip POWER9";
 }
 
@@ -691,7 +695,9 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp)
 object_unref(OBJECT(pnv_core));
 
 /* Each core has an XSCOM MMIO region */
-pnv_xscom_add_subregion(chip, PNV_XSCOM_EX_CORE_BASE(core_hwid),
+pnv_xscom_add_subregion(chip,
+PNV_XSCOM_EX_CORE_BASE(pcc->xscom_core_base,
+   core_hwid),
 _CORE(pnv_core)->xscom_regs);
 i++;
 }
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 7bee658..df98a72 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -69,6 +69,7 @@ typedef struct PnvChipClass {
 uint64_t cores_mask;
 
 hwaddr   xscom_base;
+hwaddr   xscom_core_base;
 
 uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id);
 } PnvChipClass;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index 41a5127..0faa184 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -40,7 +40,7 @@ typedef struct PnvXScomInterfaceClass {
 } PnvXScomInterfaceClass;
 
 /*
- * Layout of the XSCOM PCB addresses of EX core 1
+ * Layout of the XSCOM PCB addresses of EX core 1 (POWER 8)
  *
  *   GPIO0x1100
  *   SCOM0x1101
@@ -54,8 +54,7 @@ typedef struct PnvXScomInterfaceClass {
  *   PCB SLAVE   0x110F
  */
 
-#define PNV_XSCOM_EX_BASE 0x1000
-#define PNV_XSCOM_EX_CORE_BASE(i) (PNV_XSCOM_EX_BASE | (((uint64_t)i) << 24))
+#define PNV_XSCOM_EX_CORE_BASE(base, i) (base | (((uint64_t)i) << 24))
 #define PNV_XSCOM_EX_CORE_SIZE0x10
 
 #define PNV_XSCOM_LPC_BASE0xb0020
-- 
2.7.4




[Qemu-devel] [PULL 18/19] tests: add XSCOM tests for the PowerNV machine

2016-11-14 Thread David Gibson
Add a couple of tests on the XSCOM bus of the PowerNV machine for the
the POWER8 and POWER9 CPUs. The first tests reads the CFAM identifier
of the chip. The second test goes further in the XSCOM address space
and reaches the cores to read their DTS registers.

Signed-off-by: Cédric Le Goater 
[dwg: Fixed an incorrect indentation, and a Makefile problem]]
Signed-off-by: David Gibson 
---
 tests/Makefile.include |   2 +
 tests/pnv-xscom-test.c | 140 +
 2 files changed, 142 insertions(+)
 create mode 100644 tests/pnv-xscom-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index de51634..e98d3b6 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -270,6 +270,7 @@ gcov-files-ppc64-y = ppc64-softmmu/hw/ppc/spapr_pci.c
 check-qtest-ppc64-y += tests/endianness-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
 check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
+check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF)
 check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
 check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
 check-qtest-ppc64-y += tests/boot-serial-test$(EXESUF)
@@ -644,6 +645,7 @@ tests/e1000-test$(EXESUF): tests/e1000-test.o
 tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y)
 tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
 tests/pcnet-test$(EXESUF): tests/pcnet-test.o
+tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o
 tests/eepro100-test$(EXESUF): tests/eepro100-test.o
 tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
 tests/ne2000-test$(EXESUF): tests/ne2000-test.o
diff --git a/tests/pnv-xscom-test.c b/tests/pnv-xscom-test.c
new file mode 100644
index 000..5951da1
--- /dev/null
+++ b/tests/pnv-xscom-test.c
@@ -0,0 +1,140 @@
+/*
+ * QTest testcase for PowerNV XSCOM bus
+ *
+ * Copyright (c) 2016, IBM Corporation.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+
+#include "libqtest.h"
+
+typedef enum PnvChipType {
+PNV_CHIP_POWER8E, /* AKA Murano (default) */
+PNV_CHIP_POWER8,  /* AKA Venice */
+PNV_CHIP_POWER8NVL,   /* AKA Naples */
+PNV_CHIP_POWER9,  /* AKA Nimbus */
+} PnvChipType;
+
+typedef struct PnvChip {
+PnvChipType chip_type;
+const char *cpu_model;
+uint64_txscom_base;
+uint64_txscom_core_base;
+uint64_tcfam_id;
+uint32_tfirst_core;
+} PnvChip;
+
+static const PnvChip pnv_chips[] = {
+{
+.chip_type  = PNV_CHIP_POWER8,
+.cpu_model  = "POWER8",
+.xscom_base = 0x0003fc00ull,
+.xscom_core_base = 0x1000ull,
+.cfam_id= 0x220ea0498000ull,
+.first_core = 0x1,
+}, {
+.chip_type  = PNV_CHIP_POWER8NVL,
+.cpu_model  = "POWER8NVL",
+.xscom_base = 0x0003fc00ull,
+.xscom_core_base = 0x1000ull,
+.cfam_id= 0x120d30498000ull,
+.first_core = 0x1,
+}, {
+.chip_type  = PNV_CHIP_POWER9,
+.cpu_model  = "POWER9",
+.xscom_base = 0x000603fcull,
+.xscom_core_base = 0x0ull,
+.cfam_id= 0x100d10498000ull,
+.first_core = 0x20,
+},
+};
+
+static uint64_t pnv_xscom_addr(const PnvChip *chip, uint32_t pcba)
+{
+uint64_t addr = chip->xscom_base;
+
+if (chip->chip_type == PNV_CHIP_POWER9) {
+addr |= ((uint64_t) pcba << 3);
+} else {
+addr |= (((uint64_t) pcba << 4) & ~0xffull) |
+(((uint64_t) pcba << 3) & 0x78);
+}
+return addr;
+}
+
+static uint64_t pnv_xscom_read(const PnvChip *chip, uint32_t pcba)
+{
+return readq(pnv_xscom_addr(chip, pcba));
+}
+
+static void test_xscom_cfam_id(const PnvChip *chip)
+{
+uint64_t f000f = pnv_xscom_read(chip, 0xf000f);
+
+g_assert_cmphex(f000f, ==, chip->cfam_id);
+}
+
+static void test_cfam_id(const void *data)
+{
+char *args;
+const PnvChip *chip = data;
+
+args = g_strdup_printf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
+
+qtest_start(args);
+test_xscom_cfam_id(chip);
+qtest_quit(global_qtest);
+
+g_free(args);
+}
+
+#define PNV_XSCOM_EX_CORE_BASE(chip, i) \
+((chip)->xscom_core_base | (((uint64_t)i) << 24))
+#define PNV_XSCOM_EX_DTS_RESULT0 0x5
+
+static void test_xscom_core(const PnvChip *chip)
+{
+uint32_t first_core_dts0 =
+PNV_XSCOM_EX_CORE_BASE(chip, chip->first_core) |
+PNV_XSCOM_EX_DTS_RESULT0;
+uint64_t dts0 = pnv_xscom_read(chip, first_core_dts0);
+
+g_assert_cmphex(dts0, ==, 0x26f024f023full);
+}
+
+static void test_core(const void *data)
+{
+char *args;
+const PnvChip *chip = data;
+
+args = g_strdup_printf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
+
+qtest_start(args);
+test_xscom_core(chip);
+

[Qemu-devel] [PULL 10/19] target-ppc: Implement bcdcfz. instruction

2016-11-14 Thread David Gibson
From: Jose Ricardo Ziviani 

bcdcfz. converts from Zoned numeric format to BCD. Zoned format uses
a byte to represent a digit where the most significant nibble is 0x3
or 0xf, depending on the preferred signal.

Signed-off-by: Jose Ricardo Ziviani 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  1 +
 target-ppc/int_helper.c | 44 +
 target-ppc/translate/vmx-impl.inc.c |  7 ++
 3 files changed, 52 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 180c5d0..b083c08 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -380,6 +380,7 @@ DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
 DEF_HELPER_3(bcdcfn, i32, avr, avr, i32)
 DEF_HELPER_3(bcdctn, i32, avr, avr, i32)
+DEF_HELPER_3(bcdcfz, i32, avr, avr, i32)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index d4106a9..2aacc94 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2787,6 +2787,50 @@ uint32_t helper_bcdctn(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 return cr;
 }
 
+uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
+{
+int i;
+int cr = 0;
+int invalid = 0;
+int zone_digit = 0;
+int zone_lead = ps ? 0xF : 0x3;
+int digit = 0;
+ppc_avr_t ret = { .u64 = { 0, 0 } };
+int sgnb = b->u8[BCD_DIG_BYTE(0)] >> 4;
+
+if (unlikely((sgnb < 0xA) && ps)) {
+invalid = 1;
+}
+
+for (i = 0; i < 16; i++) {
+zone_digit = (i * 2) ? b->u8[BCD_DIG_BYTE(i * 2)] >> 4 : zone_lead;
+digit = b->u8[BCD_DIG_BYTE(i * 2)] & 0xF;
+if (unlikely(zone_digit != zone_lead || digit > 0x9)) {
+invalid = 1;
+break;
+}
+
+bcd_put_digit(, digit, i + 1);
+}
+
+if ((ps && (sgnb == 0xB || sgnb == 0xD)) ||
+(!ps && (sgnb & 0x4))) {
+bcd_put_digit(, BCD_NEG_PREF, 0);
+} else {
+bcd_put_digit(, BCD_PLUS_PREF_1, 0);
+}
+
+cr = bcd_cmp_zero();
+
+if (unlikely(invalid)) {
+cr = 1 << CRF_SO;
+}
+
+*r = ret;
+
+return cr;
+}
+
 void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
 {
 int i;
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index 795e55c..d9e3eb6 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -987,6 +987,7 @@ GEN_BCD(bcdadd)
 GEN_BCD(bcdsub)
 GEN_BCD2(bcdcfn)
 GEN_BCD2(bcdctn)
+GEN_BCD2(bcdcfz)
 
 static void gen_xpnd04_1(DisasContext *ctx)
 {
@@ -994,6 +995,9 @@ static void gen_xpnd04_1(DisasContext *ctx)
 case 5:
 gen_bcdctn(ctx);
 break;
+case 6:
+gen_bcdcfz(ctx);
+break;
 case 7:
 gen_bcdcfn(ctx);
 break;
@@ -1006,6 +1010,9 @@ static void gen_xpnd04_1(DisasContext *ctx)
 static void gen_xpnd04_2(DisasContext *ctx)
 {
 switch (opc4(ctx->opcode)) {
+case 6:
+gen_bcdcfz(ctx);
+break;
 case 7:
 gen_bcdcfn(ctx);
 break;
-- 
2.7.4




[Qemu-devel] [PULL 11/19] target-ppc: Implement bcdctz. instruction

2016-11-14 Thread David Gibson
From: Jose Ricardo Ziviani 

bcdctz. converts from BCD to Zoned numeric format. Zoned format uses
a byte to represent a digit where the most significant nibble is 0x3
or 0xf, depending on the preferred signal.

Signed-off-by: Jose Ricardo Ziviani 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  1 +
 target-ppc/int_helper.c | 43 +
 target-ppc/translate/vmx-impl.inc.c |  7 ++
 3 files changed, 51 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index b083c08..da00f0a 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -381,6 +381,7 @@ DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
 DEF_HELPER_3(bcdcfn, i32, avr, avr, i32)
 DEF_HELPER_3(bcdctn, i32, avr, avr, i32)
 DEF_HELPER_3(bcdcfz, i32, avr, avr, i32)
+DEF_HELPER_3(bcdctz, i32, avr, avr, i32)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 2aacc94..9ac204a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2831,6 +2831,49 @@ uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 return cr;
 }
 
+uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
+{
+int i;
+int cr = 0;
+uint8_t digit = 0;
+int sgnb = bcd_get_sgn(b);
+int zone_lead = (ps) ? 0xF0 : 0x30;
+int invalid = (sgnb == 0);
+ppc_avr_t ret = { .u64 = { 0, 0 } };
+
+int ox_flag = ((b->u64[HI_IDX] >> 4) != 0);
+
+for (i = 0; i < 16; i++) {
+digit = bcd_get_digit(b, i + 1, );
+
+if (unlikely(invalid)) {
+break;
+}
+
+ret.u8[BCD_DIG_BYTE(i * 2)] = zone_lead + digit;
+}
+
+if (ps) {
+bcd_put_digit(, (sgnb == 1) ? 0xC : 0xD, 1);
+} else {
+bcd_put_digit(, (sgnb == 1) ? 0x3 : 0x7, 1);
+}
+
+cr = bcd_cmp_zero(b);
+
+if (ox_flag) {
+cr |= 1 << CRF_SO;
+}
+
+if (unlikely(invalid)) {
+cr = 1 << CRF_SO;
+}
+
+*r = ret;
+
+return cr;
+}
+
 void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
 {
 int i;
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index d9e3eb6..7143eb3 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -988,10 +988,14 @@ GEN_BCD(bcdsub)
 GEN_BCD2(bcdcfn)
 GEN_BCD2(bcdctn)
 GEN_BCD2(bcdcfz)
+GEN_BCD2(bcdctz)
 
 static void gen_xpnd04_1(DisasContext *ctx)
 {
 switch (opc4(ctx->opcode)) {
+case 4:
+gen_bcdctz(ctx);
+break;
 case 5:
 gen_bcdctn(ctx);
 break;
@@ -1010,6 +1014,9 @@ static void gen_xpnd04_1(DisasContext *ctx)
 static void gen_xpnd04_2(DisasContext *ctx)
 {
 switch (opc4(ctx->opcode)) {
+case 4:
+gen_bcdctz(ctx);
+break;
 case 6:
 gen_bcdcfz(ctx);
 break;
-- 
2.7.4




[Qemu-devel] [PULL 12/19] spapr: Fix migration of PCI host bridges from qemu-2.7

2016-11-14 Thread David Gibson
daa2369 "spapr_pci: Add a 64-bit MMIO window" subtly broke migration from
qemu-2.7 to the current version.  It split the device's MMIO window into
two pieces for 32-bit and 64-bit MMIO.

The patch included backwards compatibility code to convert the old property
into the new format.  However, the property value was also transferred in
the migration stream and compared with a (probably unwise) VMSTATE_EQUAL.
So, the "raw" value from 2.7 is compared to the new style converted value
from (pre-)2.8 giving a mismatch and migration failure.

Although it would be technically possible to fix this in a way allowing
backwards migration, that would leave an ugly legacy around indefinitely.
This patch takes the simpler approach of bumping the migration version,
dropping the unwise VMSTATE_EQUAL (and some equally unwise ones around it)
and ignoring them on an incoming migration.

Signed-off-by: David Gibson 
Reviewed-by: Alexey Kardashevskiy 
---
 hw/ppc/spapr_pci.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 7cde30e..f9661b7 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1658,19 +1658,25 @@ static int spapr_pci_post_load(void *opaque, int 
version_id)
 return 0;
 }
 
+static bool version_before_3(void *opaque, int version_id)
+{
+return version_id < 3;
+}
+
 static const VMStateDescription vmstate_spapr_pci = {
 .name = "spapr_pci",
-.version_id = 2,
+.version_id = 3,
 .minimum_version_id = 2,
 .pre_save = spapr_pci_pre_save,
 .post_load = spapr_pci_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINT64_EQUAL(buid, sPAPRPHBState),
-VMSTATE_UINT32_EQUAL(dma_liobn[0], sPAPRPHBState),
-VMSTATE_UINT64_EQUAL(mem_win_addr, sPAPRPHBState),
-VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState),
-VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState),
-VMSTATE_UINT64_EQUAL(io_win_size, sPAPRPHBState),
+VMSTATE_UNUSED_TEST(version_before_3,
+sizeof(uint32_t) /* dma_liobn[0] */
++ sizeof(uint64_t) /* mem_win_addr */
++ sizeof(uint64_t) /* mem_win_size */
++ sizeof(uint64_t) /* io_win_addr */
++ sizeof(uint64_t) /* io_win_size */),
 VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
  vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
 VMSTATE_INT32(msi_devs_num, sPAPRPHBState),
-- 
2.7.4




[Qemu-devel] [PULL 09/19] target-ppc: Implement bcdctn. instruction

2016-11-14 Thread David Gibson
From: Jose Ricardo Ziviani 

bcdctn. converts from BCD to National numeric format. National format
uses a byte to represent a digit where the most significant nibble is
always 0x3 and the least sign. nibbles is the digit itself.

Signed-off-by: Jose Ricardo Ziviani 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  1 +
 target-ppc/int_helper.c | 43 +
 target-ppc/translate/vmx-impl.inc.c |  4 
 3 files changed, 48 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 5e88e4e..180c5d0 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -379,6 +379,7 @@ DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr)
 DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
 DEF_HELPER_3(bcdcfn, i32, avr, avr, i32)
+DEF_HELPER_3(bcdctn, i32, avr, avr, i32)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index c79d3ec..d4106a9 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2578,6 +2578,15 @@ static uint16_t get_national_digit(ppc_avr_t *reg, int n)
 #endif
 }
 
+static void set_national_digit(ppc_avr_t *reg, uint8_t val, int n)
+{
+#if defined(HOST_WORDS_BIGENDIAN)
+reg->u16[8 - n] = val;
+#else
+reg->u16[n] = val;
+#endif
+}
+
 static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
 {
 int i;
@@ -2744,6 +2753,40 @@ uint32_t helper_bcdcfn(ppc_avr_t *r, ppc_avr_t *b, 
uint32_t ps)
 return cr;
 }
 
+uint32_t helper_bcdctn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
+{
+int i;
+int cr = 0;
+int sgnb = bcd_get_sgn(b);
+int invalid = (sgnb == 0);
+ppc_avr_t ret = { .u64 = { 0, 0 } };
+
+int ox_flag = (b->u64[HI_IDX] != 0) || ((b->u64[LO_IDX] >> 32) != 0);
+
+for (i = 1; i < 8; i++) {
+set_national_digit(, 0x30 + bcd_get_digit(b, i, ), i);
+
+if (unlikely(invalid)) {
+break;
+}
+}
+set_national_digit(, (sgnb == -1) ? NATIONAL_NEG : NATIONAL_PLUS, 0);
+
+cr = bcd_cmp_zero(b);
+
+if (ox_flag) {
+cr |= 1 << CRF_SO;
+}
+
+if (unlikely(invalid)) {
+cr = 1 << CRF_SO;
+}
+
+*r = ret;
+
+return cr;
+}
+
 void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
 {
 int i;
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index 90448e9..795e55c 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -986,10 +986,14 @@ static void gen_##op(DisasContext *ctx) \
 GEN_BCD(bcdadd)
 GEN_BCD(bcdsub)
 GEN_BCD2(bcdcfn)
+GEN_BCD2(bcdctn)
 
 static void gen_xpnd04_1(DisasContext *ctx)
 {
 switch (opc4(ctx->opcode)) {
+case 5:
+gen_bcdctn(ctx);
+break;
 case 7:
 gen_bcdcfn(ctx);
 break;
-- 
2.7.4




[Qemu-devel] [PULL 17/19] ppc/pnv: Fix fatal bug on 32-bit hosts

2016-11-14 Thread David Gibson
If the pnv machine type is compiled on a 32-bit host, the unsigned long
(host) type is 32-bit.  This means that the hweight_long() used to
calculate the number of allowed cores only considers the low 32 bits of
the cores_mask variable, and can thus return 0 in some circumstances.

This corrects the bug.

Signed-off-by: David Gibson 
Suggested-by: Richard Henderson 
[clg: replaced hweight_long() by ctpop64() ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index e777958..9df7b25 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -620,7 +620,7 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error 
**errp)
 chip->cores_mask &= pcc->cores_mask;
 
 /* now that we have a sane layout, let check the number of cores */
-cores_max = hweight_long(chip->cores_mask);
+cores_max = ctpop64(chip->cores_mask);
 if (chip->nr_cores > cores_max) {
 error_setg(errp, "warning: too many cores for chip ! Limit is %d",
cores_max);
-- 
2.7.4




[Qemu-devel] [PULL 05/19] powernv: CPU compatibility modes don't make sense for powernv

2016-11-14 Thread David Gibson
powernv has some code (derived from the spapr equivalent) used in device
tree generation which depends on the CPU's compatibility mode / logical
PVR.  However, compatibility modes don't make sense on powernv - at least
not as a property controlled by the host - because the guest in powernv
has full hypervisor level access to the virtual system, and so owns the
PCR (Processor Compatibility Register) which implements compatiblity modes.

Note: the new logic doesn't take into account kvmppc_smt_threads() like the
old version did.  However, if core->nr_threads exceeds kvmppc_smt_threads()
then things will already be broken and clamping the value in the device
tree isn't going to save us.

Signed-off-by: David Gibson 
Reviewed-by: Greg Kurz 
Reviewed-by: Thomas Huth 
---
 hw/ppc/pnv.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 82276e0..6af3424 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip *chip, PnvCore 
*pc, void *fdt)
 CPUState *cs = CPU(DEVICE(pc->threads));
 DeviceClass *dc = DEVICE_GET_CLASS(cs);
 PowerPCCPU *cpu = POWERPC_CPU(cs);
-int smt_threads = ppc_get_compat_smt_threads(cpu);
+int smt_threads = CPU_CORE(pc)->nr_threads;
 CPUPPCState *env = >env;
 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 uint32_t servers_prop[smt_threads];
@@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip *chip, 
PnvCore *pc, void *fdt)
 _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
pa_features, sizeof(pa_features;
 
-if (cpu->cpu_version) {
-_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu->cpu_version)));
-}
-
 /* Build interrupt servers properties */
 for (i = 0; i < smt_threads; i++) {
 servers_prop[i] = cpu_to_be32(pc->pir + i);
-- 
2.7.4




[Qemu-devel] [PULL 06/19] ppc/pnv: fix compile breakage on old gcc

2016-11-14 Thread David Gibson
From: Cédric Le Goater 

PnvChip is defined twice and this can confuse old compilers :

  CC  ppc64-softmmu/hw/ppc/pnv_xscom.o
In file included from qemu.git/hw/ppc/pnv.c:29:
qemu.git/include/hw/ppc/pnv.h:60: error: redefinition of typedef ‘PnvChip’
qemu.git/include/hw/ppc/pnv_xscom.h:24: note: previous declaration of ‘PnvChip’ 
was here
make[1]: *** [hw/ppc/pnv.o] Error 1
make[1]: *** Waiting for unfinished jobs

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_core.c  | 1 +
 hw/ppc/pnv_lpc.c   | 3 ++-
 hw/ppc/pnv_xscom.c | 2 +-
 include/hw/ppc/pnv.h   | 1 -
 include/hw/ppc/pnv_xscom.h | 2 --
 5 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 2acda96..76ce854 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -24,6 +24,7 @@
 #include "hw/ppc/ppc.h"
 #include "hw/ppc/pnv.h"
 #include "hw/ppc/pnv_core.h"
+#include "hw/ppc/pnv_xscom.h"
 
 static void powernv_cpu_reset(void *opaque)
 {
diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c
index 00dbd8b..0e2117f 100644
--- a/hw/ppc/pnv_lpc.c
+++ b/hw/ppc/pnv_lpc.c
@@ -23,8 +23,9 @@
 #include "qapi/error.h"
 #include "qemu/log.h"
 
-#include "hw/ppc/pnv_lpc.h"
 #include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_lpc.h"
+#include "hw/ppc/pnv_xscom.h"
 #include "hw/ppc/fdt.h"
 
 #include 
diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index 5aaa264..f466461 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -25,8 +25,8 @@
 #include "hw/sysbus.h"
 
 #include "hw/ppc/fdt.h"
-#include "hw/ppc/pnv_xscom.h"
 #include "hw/ppc/pnv.h"
+#include "hw/ppc/pnv_xscom.h"
 
 #include 
 
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index 02ac1c5..7bee658 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -21,7 +21,6 @@
 
 #include "hw/boards.h"
 #include "hw/sysbus.h"
-#include "hw/ppc/pnv_xscom.h"
 #include "hw/ppc/pnv_lpc.h"
 
 #define TYPE_PNV_CHIP "powernv-chip"
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index c0a2fbb..41a5127 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -21,8 +21,6 @@
 
 #include "qom/object.h"
 
-typedef struct PnvChip PnvChip;
-
 typedef struct PnvXScomInterface {
 Object parent;
 } PnvXScomInterface;
-- 
2.7.4




[Qemu-devel] [PULL 08/19] target-ppc: Implement bcdcfn. instruction

2016-11-14 Thread David Gibson
From: Jose Ricardo Ziviani 

bcdcfn. converts from National numeric format to BCD. National format
uses a byte to represent a digit where the most significant nibble is
always 0x3 and the least sign. nibbles is the digit itself.

Signed-off-by: Jose Ricardo Ziviani 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  1 +
 target-ppc/int_helper.c | 56 +
 target-ppc/translate/vmx-impl.inc.c | 55 
 target-ppc/translate/vmx-ops.inc.c  |  4 +--
 4 files changed, 114 insertions(+), 2 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 201a8cf..5e88e4e 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -378,6 +378,7 @@ DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr)
 
 DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
+DEF_HELPER_3(bcdcfn, i32, avr, avr, i32)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 92684cf..c79d3ec 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2492,6 +2492,8 @@ void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, 
ppc_avr_t *b, ppc_avr_t *c)
 #define BCD_NEG_PREF0xD
 #define BCD_NEG_ALT 0xB
 #define BCD_PLUS_ALT_2  0xE
+#define NATIONAL_PLUS   0x2B
+#define NATIONAL_NEG0x2D
 
 #if defined(HOST_WORDS_BIGENDIAN)
 #define BCD_DIG_BYTE(n) (15 - (n/2))
@@ -2558,6 +2560,24 @@ static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, 
int n)
 }
 }
 
+static int bcd_cmp_zero(ppc_avr_t *bcd)
+{
+if (bcd->u64[HI_IDX] == 0 && (bcd->u64[LO_IDX] >> 4) == 0) {
+return 1 << CRF_EQ;
+} else {
+return (bcd_get_sgn(bcd) == 1) ? 1 << CRF_GT : 1 << CRF_LT;
+}
+}
+
+static uint16_t get_national_digit(ppc_avr_t *reg, int n)
+{
+#if defined(HOST_WORDS_BIGENDIAN)
+return reg->u16[8 - n];
+#else
+return reg->u16[n];
+#endif
+}
+
 static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
 {
 int i;
@@ -2688,6 +2708,42 @@ uint32_t helper_bcdsub(ppc_avr_t *r,  ppc_avr_t *a, 
ppc_avr_t *b, uint32_t ps)
 return helper_bcdadd(r, a, , ps);
 }
 
+uint32_t helper_bcdcfn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
+{
+int i;
+int cr = 0;
+uint16_t national = 0;
+uint16_t sgnb = get_national_digit(b, 0);
+ppc_avr_t ret = { .u64 = { 0, 0 } };
+int invalid = (sgnb != NATIONAL_PLUS && sgnb != NATIONAL_NEG);
+
+for (i = 1; i < 8; i++) {
+national = get_national_digit(b, i);
+if (unlikely(national < 0x30 || national > 0x39)) {
+invalid = 1;
+break;
+}
+
+bcd_put_digit(, national & 0xf, i);
+}
+
+if (sgnb == NATIONAL_PLUS) {
+bcd_put_digit(, (ps == 0) ? BCD_PLUS_PREF_1 : BCD_PLUS_PREF_2, 0);
+} else {
+bcd_put_digit(, BCD_NEG_PREF, 0);
+}
+
+cr = bcd_cmp_zero();
+
+if (unlikely(invalid)) {
+cr = 1 << CRF_SO;
+}
+
+*r = ret;
+
+return cr;
+}
+
 void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
 {
 int i;
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index e1d0897..90448e9 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -960,8 +960,61 @@ static void gen_##op(DisasContext *ctx) \
 tcg_temp_free_i32(ps);  \
 }
 
+#define GEN_BCD2(op)\
+static void gen_##op(DisasContext *ctx) \
+{   \
+TCGv_ptr rd, rb;\
+TCGv_i32 ps;\
+\
+if (unlikely(!ctx->altivec_enabled)) {  \
+gen_exception(ctx, POWERPC_EXCP_VPU);   \
+return; \
+}   \
+\
+rb = gen_avr_ptr(rB(ctx->opcode));  \
+rd = gen_avr_ptr(rD(ctx->opcode));  \
+\
+ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
+\
+gen_helper_##op(cpu_crf[6], rd, rb, ps);\
+\
+tcg_temp_free_ptr(rb);  \
+tcg_temp_free_ptr(rd);  \
+tcg_temp_free_i32(ps);  \
+}
+
 GEN_BCD(bcdadd)
 GEN_BCD(bcdsub)
+GEN_BCD2(bcdcfn)
+
+static void gen_xpnd04_1(DisasContext *ctx)
+{
+switch (opc4(ctx->opcode)) {
+case 7:
+gen_bcdcfn(ctx);
+break;
+default:
+gen_invalid(ctx);
+ 

[Qemu-devel] [PULL 02/19] target-ppc: add vrldnmi and vrlwmi instructions

2016-11-14 Thread David Gibson
From: "Gautham R. Shenoy" 

vrldmi: Vector Rotate Left Dword then Mask Insert
vrlwmi: Vector Rotate Left Word then Mask Insert

Signed-off-by: Gautham R. Shenoy 
Signed-off-by: Bharata B Rao 
( use extract[32,64] and rol[32,64], introduce mask helpers in
  internal.h )
Signed-off-by: Nikunj A Dadhania 
Signed-off-by: David Gibson 
---
 disas/ppc.c |  2 ++
 target-ppc/helper.h |  2 ++
 target-ppc/int_helper.c | 23 +
 target-ppc/internal.h   | 50 +
 target-ppc/translate.c  | 29 +
 target-ppc/translate/vmx-impl.inc.c |  6 +
 target-ppc/translate/vmx-ops.inc.c  |  4 +--
 7 files changed, 86 insertions(+), 30 deletions(-)
 create mode 100644 target-ppc/internal.h

diff --git a/disas/ppc.c b/disas/ppc.c
index 052cebe..32f0d8d 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -2286,6 +2286,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "vrlh",  VX(4,   68), VX_MASK,   PPCVEC, { VD, VA, VB } },
 { "vrlw",  VX(4,  132), VX_MASK,   PPCVEC, { VD, VA, VB } },
 { "vrsqrtefp", VX(4,  330), VX_MASK,   PPCVEC, { VD, VB } },
+{ "vrldmi",VX(4,  197), VX_MASK,PPCVEC, { VD, VA, VB } },
+{ "vrlwmi",VX(4,  133), VX_MASK,PPCVEC, { VD, VA, VB} },
 { "vsel",  VXA(4,  42), VXA_MASK,  PPCVEC, { VD, VA, VB, VC } },
 { "vsl",   VX(4,  452), VX_MASK,   PPCVEC, { VD, VA, VB } },
 { "vslb",  VX(4,  260), VX_MASK,   PPCVEC, { VD, VA, VB } },
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 3916b2e..ac94f8a 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -325,6 +325,8 @@ DEF_HELPER_4(vmaxfp, void, env, avr, avr, avr)
 DEF_HELPER_4(vminfp, void, env, avr, avr, avr)
 DEF_HELPER_3(vrefp, void, env, avr, avr)
 DEF_HELPER_3(vrsqrtefp, void, env, avr, avr)
+DEF_HELPER_3(vrlwmi, void, avr, avr, avr)
+DEF_HELPER_3(vrldmi, void, avr, avr, avr)
 DEF_HELPER_5(vmaddfp, void, env, avr, avr, avr, avr)
 DEF_HELPER_5(vnmsubfp, void, env, avr, avr, avr, avr)
 DEF_HELPER_3(vexptefp, void, env, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index dca4798..e96dfe4 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -18,6 +18,7 @@
  */
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "internal.h"
 #include "exec/exec-all.h"
 #include "qemu/host-utils.h"
 #include "exec/helper-proto.h"
@@ -1717,6 +1718,28 @@ void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, 
ppc_avr_t *b)
 }
 }
 
+#define VRLMI(name, size, element)\
+void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)  \
+{ \
+int i;\
+for (i = 0; i < ARRAY_SIZE(r->element); i++) {\
+uint##size##_t src1 = a->element[i];  \
+uint##size##_t src2 = b->element[i];  \
+uint##size##_t src3 = r->element[i];  \
+uint##size##_t begin, end, shift, mask, rot_val;  \
+  \
+shift = extract##size(src2, 0, 6);\
+end   = extract##size(src2, 8, 6);\
+begin = extract##size(src2, 16, 6);   \
+rot_val = rol##size(src1, shift); \
+mask = mask_u##size(begin, end);  \
+r->element[i] = (rot_val & mask) | (src3 & ~mask);\
+} \
+}
+
+VRLMI(vrldmi, 64, u64);
+VRLMI(vrlwmi, 32, u32);
+
 void helper_vsel(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
  ppc_avr_t *c)
 {
diff --git a/target-ppc/internal.h b/target-ppc/internal.h
new file mode 100644
index 000..1ff4896
--- /dev/null
+++ b/target-ppc/internal.h
@@ -0,0 +1,50 @@
+/*
+ *  PowerPC interal definitions for qemu.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; 

[Qemu-devel] [PULL 16/19] ppc/pnv: fix xscom address translation for POWER9

2016-11-14 Thread David Gibson
From: Cédric Le Goater 

High addresses can overflow the uint32_t pcba variable after the 8byte
shift.

Signed-off-by: Cédric Le Goater 
Signed-off-by: David Gibson 
---
 hw/ppc/pnv_xscom.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/pnv_xscom.c b/hw/ppc/pnv_xscom.c
index f466461..8da2718 100644
--- a/hw/ppc/pnv_xscom.c
+++ b/hw/ppc/pnv_xscom.c
@@ -124,8 +124,8 @@ static uint64_t xscom_read(void *opaque, hwaddr addr, 
unsigned width)
 goto complete;
 }
 
-val = address_space_ldq(>xscom_as, pcba << 3, MEMTXATTRS_UNSPECIFIED,
-);
+val = address_space_ldq(>xscom_as, (uint64_t) pcba << 3,
+MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
 qemu_log_mask(LOG_GUEST_ERROR, "XSCOM read failed at @0x%"
   HWADDR_PRIx " pcba=0x%08x\n", addr, pcba);
@@ -150,8 +150,8 @@ static void xscom_write(void *opaque, hwaddr addr, uint64_t 
val,
 goto complete;
 }
 
-address_space_stq(>xscom_as, pcba << 3, val, MEMTXATTRS_UNSPECIFIED,
-  );
+address_space_stq(>xscom_as, (uint64_t) pcba << 3, val,
+  MEMTXATTRS_UNSPECIFIED, );
 if (result != MEMTX_OK) {
 qemu_log_mask(LOG_GUEST_ERROR, "XSCOM write failed at @0x%"
   HWADDR_PRIx " pcba=0x%08x data=0x%" PRIx64 "\n",
-- 
2.7.4




[Qemu-devel] [PULL 03/19] target-ppc: add vrldnm and vrlwnm instructions

2016-11-14 Thread David Gibson
From: Bharata B Rao 

vrldnm: Vector Rotate Left Doubleword then AND with Mask
vrlwnm: Vector Rotate Left Word then AND with Mask

Signed-off-by: Bharata B Rao 
Signed-off-by: Nikunj A Dadhania 
Reviewed-by: David Gibson 
Signed-off-by: David Gibson 
---
 disas/ppc.c |  2 ++
 target-ppc/helper.h |  2 ++
 target-ppc/int_helper.c | 14 ++
 target-ppc/translate/vmx-impl.inc.c |  6 ++
 target-ppc/translate/vmx-ops.inc.c  |  4 ++--
 5 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/disas/ppc.c b/disas/ppc.c
index 32f0d8d..bd05623 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -2287,7 +2287,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 { "vrlw",  VX(4,  132), VX_MASK,   PPCVEC, { VD, VA, VB } },
 { "vrsqrtefp", VX(4,  330), VX_MASK,   PPCVEC, { VD, VB } },
 { "vrldmi",VX(4,  197), VX_MASK,PPCVEC, { VD, VA, VB } },
+{ "vrldnm",VX(4,  453), VX_MASK,PPCVEC, { VD, VA, VB } },
 { "vrlwmi",VX(4,  133), VX_MASK,PPCVEC, { VD, VA, VB} },
+{ "vrlwnm",VX(4,  389), VX_MASK,PPCVEC, { VD, VA, VB } },
 { "vsel",  VXA(4,  42), VXA_MASK,  PPCVEC, { VD, VA, VB, VC } },
 { "vsl",   VX(4,  452), VX_MASK,   PPCVEC, { VD, VA, VB } },
 { "vslb",  VX(4,  260), VX_MASK,   PPCVEC, { VD, VA, VB } },
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ac94f8a..5fa2469 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -327,6 +327,8 @@ DEF_HELPER_3(vrefp, void, env, avr, avr)
 DEF_HELPER_3(vrsqrtefp, void, env, avr, avr)
 DEF_HELPER_3(vrlwmi, void, avr, avr, avr)
 DEF_HELPER_3(vrldmi, void, avr, avr, avr)
+DEF_HELPER_3(vrldnm, void, avr, avr, avr)
+DEF_HELPER_3(vrlwnm, void, avr, avr, avr)
 DEF_HELPER_5(vmaddfp, void, env, avr, avr, avr, avr)
 DEF_HELPER_5(vnmsubfp, void, env, avr, avr, avr, avr)
 DEF_HELPER_3(vexptefp, void, env, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index e96dfe4..8237bf5 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1718,7 +1718,7 @@ void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, 
ppc_avr_t *b)
 }
 }
 
-#define VRLMI(name, size, element)\
+#define VRLMI(name, size, element, insert)\
 void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)  \
 { \
 int i;\
@@ -1733,12 +1733,18 @@ void helper_##name(ppc_avr_t *r, ppc_avr_t *a, 
ppc_avr_t *b)  \
 begin = extract##size(src2, 16, 6);   \
 rot_val = rol##size(src1, shift); \
 mask = mask_u##size(begin, end);  \
-r->element[i] = (rot_val & mask) | (src3 & ~mask);\
+if (insert) { \
+r->element[i] = (rot_val & mask) | (src3 & ~mask);\
+} else {  \
+r->element[i] = (rot_val & mask); \
+} \
 } \
 }
 
-VRLMI(vrldmi, 64, u64);
-VRLMI(vrlwmi, 32, u32);
+VRLMI(vrldmi, 64, u64, 1);
+VRLMI(vrlwmi, 32, u32, 1);
+VRLMI(vrldnm, 64, u64, 0);
+VRLMI(vrlwnm, 32, u32, 0);
 
 void helper_vsel(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
  ppc_avr_t *c)
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index fdfbd6a..500c43f 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -442,6 +442,9 @@ GEN_VXFORM(vmulesw, 4, 14);
 GEN_VXFORM(vslb, 2, 4);
 GEN_VXFORM(vslh, 2, 5);
 GEN_VXFORM(vslw, 2, 6);
+GEN_VXFORM(vrlwnm, 2, 6);
+GEN_VXFORM_DUAL(vslw, PPC_ALTIVEC, PPC_NONE, \
+vrlwnm, PPC_NONE, PPC2_ISA300)
 GEN_VXFORM(vsld, 2, 23);
 GEN_VXFORM(vsrb, 2, 8);
 GEN_VXFORM(vsrh, 2, 9);
@@ -496,6 +499,9 @@ GEN_VXFORM(vrldmi, 2, 3);
 GEN_VXFORM_DUAL(vrld, PPC_NONE, PPC2_ALTIVEC_207, \
 vrldmi, PPC_NONE, PPC2_ISA300)
 GEN_VXFORM(vsl, 2, 7);
+GEN_VXFORM(vrldnm, 2, 7);
+GEN_VXFORM_DUAL(vsl, PPC_ALTIVEC, PPC_NONE, \
+vrldnm, PPC_NONE, PPC2_ISA300)
 GEN_VXFORM(vsr, 2, 11);
 GEN_VXFORM_ENV(vpkuhum, 7, 0);
 GEN_VXFORM_ENV(vpkuwum, 7, 1);
diff --git a/target-ppc/translate/vmx-ops.inc.c 
b/target-ppc/translate/vmx-ops.inc.c
index 76b3593..a5ad4d4 100644
--- a/target-ppc/translate/vmx-ops.inc.c
+++ b/target-ppc/translate/vmx-ops.inc.c
@@ -107,7 +107,7 @@ GEN_VXFORM(vmulesh, 4, 13),
 

[Qemu-devel] [PULL 13/19] FU exceptions should carry a cause (IC)

2016-11-14 Thread David Gibson
From: Balbir Singh 

As per the ISA we need a cause and executing a tabort r9 in libc
for example causes a EXCP_FU exception, we don't wire up the
IC (cause) when we post the exception. The cause is required
for the kernel to do the right thing. The fix applies only to 64
bit ppc targets.

Signed-off-by: Balbir singh 
Signed-off-by: David Gibson 
---
 target-ppc/excp_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index 808760b..93369d4 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -427,6 +427,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 case POWERPC_EXCP_VPU:   /* Vector unavailable exception */
 case POWERPC_EXCP_VSXU:   /* VSX unavailable exception   */
 case POWERPC_EXCP_FU: /* Facility unavailable exception  */
+#ifdef TARGET_PPC64
+env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
+#endif
 break;
 case POWERPC_EXCP_PIT:   /* Programmable interval timer interrupt*/
 LOG_EXCP("PIT exception\n");
-- 
2.7.4




[Qemu-devel] [PULL 14/19] spapr-vty: Fix bad assert() statement

2016-11-14 Thread David Gibson
From: Thomas Huth 

When using the serial console in the GTK interface of QEMU (and
QEMU has been compiled with CONFIG_VTE), it is possible to trigger
the assert() statement in vty_receive() in spapr_vty.c by pasting
a chunk of text with length > 16 into the QEMU window.
Most of the other serial backends seem to simply drop characters
that they can not handle, so I think we should also do the same in
spapr-vty to fix this issue.

Buglink: https://bugs.launchpad.net/qemu/+bug/1639322
Signed-off-by: Thomas Huth 
Signed-off-by: David Gibson 
---
 hw/char/spapr_vty.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index 31822fe..06b9b39 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -1,4 +1,5 @@
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
@@ -37,7 +38,15 @@ static void vty_receive(void *opaque, const uint8_t *buf, 
int size)
 qemu_irq_pulse(spapr_vio_qirq(>sdev));
 }
 for (i = 0; i < size; i++) {
-assert((dev->in - dev->out) < VTERM_BUFSIZE);
+if (dev->in - dev->out >= VTERM_BUFSIZE) {
+static bool reported;
+if (!reported) {
+error_report("VTY input buffer exhausted - characters dropped."
+ " (input size = %i)", size);
+reported = true;
+}
+break;
+}
 dev->buf[dev->in++ % VTERM_BUFSIZE] = buf[i];
 }
 }
-- 
2.7.4




[Qemu-devel] [PULL 07/19] ppc: Remove some stub POWER6 models

2016-11-14 Thread David Gibson
The CPU model table includes stub (commented out) definitions for
CPU_POWERPC_POWER6_5 and CPU_POWERPC_POWER6A.  These are not real cpu
models, but represent the POWER6 in some compatiblity modes.  If we ever
do implement POWER6 (unlikely), we'll implement its compatibility modes in
a different way (similar to what we do for POWER7 and POWER8).  So these
stub definitions can be removed.

Signed-off-by: David Gibson 
Reviewed-by: Thomas Huth 
---
 target-ppc/cpu-models.c | 4 
 target-ppc/cpu-models.h | 2 --
 2 files changed, 6 deletions(-)

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 901cf40..506dee1 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1130,10 +1130,6 @@
 #if defined(TODO)
 POWERPC_DEF("POWER6",CPU_POWERPC_POWER6, POWER6,
 "POWER6")
-POWERPC_DEF("POWER6_5",  CPU_POWERPC_POWER6_5,   POWER5,
-"POWER6 running in POWER5 mode")
-POWERPC_DEF("POWER6A",   CPU_POWERPC_POWER6A,POWER6,
-"POWER6A")
 #endif
 POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23, POWER7,
 "POWER7 v2.3")
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 7d9e6a2..aafbbd7 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -549,8 +549,6 @@ enum {
 CPU_POWERPC_POWER5 = 0x003A0203,
 CPU_POWERPC_POWER5P_v21= 0x003B0201,
 CPU_POWERPC_POWER6 = 0x003E,
-CPU_POWERPC_POWER6_5   = 0x0F01, /* POWER6 in POWER5 mode */
-CPU_POWERPC_POWER6A= 0x0F02,
 CPU_POWERPC_POWER_SERVER_MASK  = 0x,
 CPU_POWERPC_POWER7_BASE= 0x003F,
 CPU_POWERPC_POWER7_v23 = 0x003F0203,
-- 
2.7.4




[Qemu-devel] [PULL 01/19] bitops: fix rol/ror when shift is zero

2016-11-14 Thread David Gibson
From: Nikunj A Dadhania 

All the variants for rol/ror have a bug in case where the shift == 0.
For example rol32, would generate:

return (word << 0) | (word >> 32);

Which though works, would be flagged as a runtime error on clang's
sanitizer.

Suggested-by: Richard Henderson 
Signed-off-by: Nikunj A Dadhania 
Reviewed-by: Richard Henderson 
Signed-off-by: David Gibson 
---
 include/qemu/bitops.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 98fb005..1881284 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -218,7 +218,7 @@ static inline unsigned long hweight_long(unsigned long w)
  */
 static inline uint8_t rol8(uint8_t word, unsigned int shift)
 {
-return (word << shift) | (word >> (8 - shift));
+return (word << shift) | (word >> ((8 - shift) & 7));
 }
 
 /**
@@ -228,7 +228,7 @@ static inline uint8_t rol8(uint8_t word, unsigned int shift)
  */
 static inline uint8_t ror8(uint8_t word, unsigned int shift)
 {
-return (word >> shift) | (word << (8 - shift));
+return (word >> shift) | (word << ((8 - shift) & 7));
 }
 
 /**
@@ -238,7 +238,7 @@ static inline uint8_t ror8(uint8_t word, unsigned int shift)
  */
 static inline uint16_t rol16(uint16_t word, unsigned int shift)
 {
-return (word << shift) | (word >> (16 - shift));
+return (word << shift) | (word >> ((16 - shift) & 15));
 }
 
 /**
@@ -248,7 +248,7 @@ static inline uint16_t rol16(uint16_t word, unsigned int 
shift)
  */
 static inline uint16_t ror16(uint16_t word, unsigned int shift)
 {
-return (word >> shift) | (word << (16 - shift));
+return (word >> shift) | (word << ((16 - shift) & 15));
 }
 
 /**
@@ -258,7 +258,7 @@ static inline uint16_t ror16(uint16_t word, unsigned int 
shift)
  */
 static inline uint32_t rol32(uint32_t word, unsigned int shift)
 {
-return (word << shift) | (word >> (32 - shift));
+return (word << shift) | (word >> ((32 - shift) & 31));
 }
 
 /**
@@ -268,7 +268,7 @@ static inline uint32_t rol32(uint32_t word, unsigned int 
shift)
  */
 static inline uint32_t ror32(uint32_t word, unsigned int shift)
 {
-return (word >> shift) | (word << (32 - shift));
+return (word >> shift) | (word << ((32 - shift) & 31));
 }
 
 /**
@@ -278,7 +278,7 @@ static inline uint32_t ror32(uint32_t word, unsigned int 
shift)
  */
 static inline uint64_t rol64(uint64_t word, unsigned int shift)
 {
-return (word << shift) | (word >> (64 - shift));
+return (word << shift) | (word >> ((64 - shift) & 63));
 }
 
 /**
@@ -288,7 +288,7 @@ static inline uint64_t rol64(uint64_t word, unsigned int 
shift)
  */
 static inline uint64_t ror64(uint64_t word, unsigned int shift)
 {
-return (word >> shift) | (word << (64 - shift));
+return (word >> shift) | (word << ((64 - shift) & 63));
 }
 
 /**
-- 
2.7.4




[Qemu-devel] [PULL 04/19] target-ppc: add vprtyb[w/d/q] instructions

2016-11-14 Thread David Gibson
From: Ankit Kumar 

Add following POWER ISA 3.0 instructions.
vprtybw: Vector Parity Byte Word
vprtybd: Vector Parity Byte Double Word
vprtybq: Vector Parity Byte Quad Word

Signed-off-by: Ankit Kumar 
Signed-off-by: Nikunj A Dadhania 
Signed-off-by: David Gibson 
---
 target-ppc/helper.h |  3 +++
 target-ppc/int_helper.c | 34 ++
 target-ppc/translate/vmx-impl.inc.c |  3 +++
 target-ppc/translate/vmx-ops.inc.c  |  4 
 4 files changed, 44 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 5fa2469..201a8cf 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -223,6 +223,9 @@ DEF_HELPER_3(vsro, void, avr, avr, avr)
 DEF_HELPER_3(vsrv, void, avr, avr, avr)
 DEF_HELPER_3(vslv, void, avr, avr, avr)
 DEF_HELPER_3(vaddcuw, void, avr, avr, avr)
+DEF_HELPER_2(vprtybw, void, avr, avr)
+DEF_HELPER_2(vprtybd, void, avr, avr)
+DEF_HELPER_2(vprtybq, void, avr, avr)
 DEF_HELPER_3(vsubcuw, void, avr, avr, avr)
 DEF_HELPER_2(lvsl, void, avr, tl)
 DEF_HELPER_2(lvsr, void, avr, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 8237bf5..92684cf 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -528,6 +528,40 @@ void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t 
*b)
 }
 }
 
+/* vprtybw */
+void helper_vprtybw(ppc_avr_t *r, ppc_avr_t *b)
+{
+int i;
+for (i = 0; i < ARRAY_SIZE(r->u32); i++) {
+uint64_t res = b->u32[i] ^ (b->u32[i] >> 16);
+res ^= res >> 8;
+r->u32[i] = res & 1;
+}
+}
+
+/* vprtybd */
+void helper_vprtybd(ppc_avr_t *r, ppc_avr_t *b)
+{
+int i;
+for (i = 0; i < ARRAY_SIZE(r->u64); i++) {
+uint64_t res = b->u64[i] ^ (b->u64[i] >> 32);
+res ^= res >> 16;
+res ^= res >> 8;
+r->u64[i] = res & 1;
+}
+}
+
+/* vprtybq */
+void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b)
+{
+uint64_t res = b->u64[0] ^ b->u64[1];
+res ^= res >> 32;
+res ^= res >> 16;
+res ^= res >> 8;
+r->u64[LO_IDX] = res & 1;
+r->u64[HI_IDX] = 0;
+}
+
 #define VARITH_DO(name, op, element)\
 void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
 {   \
diff --git a/target-ppc/translate/vmx-impl.inc.c 
b/target-ppc/translate/vmx-impl.inc.c
index 500c43f..e1d0897 100644
--- a/target-ppc/translate/vmx-impl.inc.c
+++ b/target-ppc/translate/vmx-impl.inc.c
@@ -705,6 +705,9 @@ GEN_VXFORM_NOA_ENV(vrfim, 5, 11);
 GEN_VXFORM_NOA_ENV(vrfin, 5, 8);
 GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
 GEN_VXFORM_NOA_ENV(vrfiz, 5, 9);
+GEN_VXFORM_NOA(vprtybw, 1, 24);
+GEN_VXFORM_NOA(vprtybd, 1, 24);
+GEN_VXFORM_NOA(vprtybq, 1, 24);
 
 #define GEN_VXFORM_SIMM(name, opc2, opc3)   \
 static void glue(gen_, name)(DisasContext *ctx)
 \
diff --git a/target-ppc/translate/vmx-ops.inc.c 
b/target-ppc/translate/vmx-ops.inc.c
index a5ad4d4..c631780 100644
--- a/target-ppc/translate/vmx-ops.inc.c
+++ b/target-ppc/translate/vmx-ops.inc.c
@@ -122,6 +122,10 @@ GEN_VXFORM_300(vslv, 2, 29),
 GEN_VXFORM(vslo, 6, 16),
 GEN_VXFORM(vsro, 6, 17),
 GEN_VXFORM(vaddcuw, 0, 6),
+GEN_HANDLER_E_2(vprtybw, 0x4, 0x1, 0x18, 8, 0, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E_2(vprtybd, 0x4, 0x1, 0x18, 9, 0, PPC_NONE, PPC2_ISA300),
+GEN_HANDLER_E_2(vprtybq, 0x4, 0x1, 0x18, 10, 0, PPC_NONE, PPC2_ISA300),
+
 GEN_VXFORM(vsubcuw, 0, 22),
 GEN_VXFORM_DUAL(vaddubs, vmul10uq, 0, 8, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM_DUAL(vadduhs, vmul10euq, 0, 9, PPC_ALTIVEC, PPC_NONE),
-- 
2.7.4




[Qemu-devel] [PULL 00/19] ppc-for-2.8 queue 20161115

2016-11-14 Thread David Gibson
The following changes since commit 682df581c65ed2c1b9e77093e332214ecaa1ee93:

  Merge remote-tracking branch 'jsnow/tags/ide-pull-request' into staging 
(2016-11-14 17:07:16 +)

are available in the git repository at:

  git://github.com/dgibson/qemu.git tags/ppc-for-2.8-20161115

for you to fetch changes up to 859c397e57a4c0f8be2e2be011892b7d81b72e8c:

  boot-serial-test: Add a test for the powernv machine (2016-11-15 11:45:01 
+1100)


ppc patch queue 2016-11-15

Latest set of ppc and spapr related patches.  Highlights are:
   * More POWER9 instructions
   * Fix some subtle outstanding bugs
   * Add some extra tests

One patch affects bitops.h, so isn't strictly ppc related.


Ankit Kumar (1):
  target-ppc: add vprtyb[w/d/q] instructions

Balbir Singh (1):
  FU exceptions should carry a cause (IC)

Bharata B Rao (1):
  target-ppc: add vrldnm and vrlwnm instructions

Cédric Le Goater (3):
  ppc/pnv: fix compile breakage on old gcc
  ppc/pnv: add a 'xscom_core_base' field to PnvChipClass
  ppc/pnv: fix xscom address translation for POWER9

David Gibson (5):
  powernv: CPU compatibility modes don't make sense for powernv
  ppc: Remove some stub POWER6 models
  spapr: Fix migration of PCI host bridges from qemu-2.7
  ppc/pnv: Fix fatal bug on 32-bit hosts
  tests: add XSCOM tests for the PowerNV machine

Gautham R. Shenoy (1):
  target-ppc: add vrldnmi and vrlwmi instructions

Jose Ricardo Ziviani (4):
  target-ppc: Implement bcdcfn. instruction
  target-ppc: Implement bcdctn. instruction
  target-ppc: Implement bcdcfz. instruction
  target-ppc: Implement bcdctz. instruction

Nikunj A Dadhania (1):
  bitops: fix rol/ror when shift is zero

Thomas Huth (2):
  spapr-vty: Fix bad assert() statement
  boot-serial-test: Add a test for the powernv machine

 disas/ppc.c |   4 +
 hw/char/spapr_vty.c |  11 +-
 hw/ppc/pnv.c|  16 ++-
 hw/ppc/pnv_core.c   |   1 +
 hw/ppc/pnv_lpc.c|   3 +-
 hw/ppc/pnv_xscom.c  |  10 +-
 hw/ppc/spapr_pci.c  |  18 ++-
 include/hw/ppc/pnv.h|   2 +-
 include/hw/ppc/pnv_xscom.h  |   7 +-
 include/qemu/bitops.h   |  16 +--
 target-ppc/cpu-models.c |   4 -
 target-ppc/cpu-models.h |   2 -
 target-ppc/excp_helper.c|   3 +
 target-ppc/helper.h |  11 ++
 target-ppc/int_helper.c | 249 
 target-ppc/internal.h   |  50 
 target-ppc/translate.c  |  29 +
 target-ppc/translate/vmx-impl.inc.c |  88 +
 target-ppc/translate/vmx-ops.inc.c  |  16 ++-
 tests/Makefile.include  |   2 +
 tests/boot-serial-test.c|   1 +
 tests/pnv-xscom-test.c  | 140 
 22 files changed, 609 insertions(+), 74 deletions(-)
 create mode 100644 target-ppc/internal.h
 create mode 100644 tests/pnv-xscom-test.c



[Qemu-devel] [PATCH v2 3/3] 9pfs: add cleanup operation for proxy backend driver

2016-11-14 Thread Li Qiang
In the init operation of proxy backend dirver, it allocates a
V9fsProxy struct and some other resources. We should free these
resources when the 9pfs device is unrealized. This is what this
patch does.

Signed-off-by: Li Qiang 
---
 hw/9pfs/9p-proxy.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index f2417b7..4b22f57 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -1168,9 +1168,19 @@ static int proxy_init(FsContext *ctx)
 return 0;
 }
 
+static void proxy_cleanup(FsContext *ctx)
+{
+V9fsProxy *proxy = ctx->private;
+close(proxy->sockfd);
+g_free(proxy->in_iovec.iov_base);
+g_free(proxy->out_iovec.iov_base);
+g_free(proxy);
+}
+
 FileOperations proxy_ops = {
 .parse_opts   = proxy_parse_opts,
 .init = proxy_init,
+.cleanup  = proxy_cleanup,
 .lstat= proxy_lstat,
 .readlink = proxy_readlink,
 .close= proxy_close,
-- 
1.8.3.1




[Qemu-devel] [PATCH v2 1/3] 9pfs: add cleanup operation in FileOperations

2016-11-14 Thread Li Qiang
Currently, the backend of VirtFS doesn't have a cleanup
function. This will lead resource leak issues if the backed
driver allocates resources. This patch addresses this issue.

Signed-off-by: Li Qiang 
---

Changes since the v1:
-move the cleanup stuff above calls to g_free
-add cleanup call in the error path of realize if init was called

 fsdev/file-op-9p.h | 1 +
 hw/9pfs/9p.c   | 6 ++
 2 files changed, 7 insertions(+)

diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index 6db9fea..a56dc84 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -100,6 +100,7 @@ struct FileOperations
 {
 int (*parse_opts)(QemuOpts *, struct FsDriverEntry *);
 int (*init)(struct FsContext *);
+void (*cleanup)(struct FsContext *);
 int (*lstat)(FsContext *, V9fsPath *, struct stat *);
 ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t);
 int (*chmod)(FsContext *, V9fsPath *, FsCred *);
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index f7e14ac..70361a2 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3521,6 +3521,9 @@ int v9fs_device_realize_common(V9fsState *s, Error **errp)
 rc = 0;
 out:
 if (rc) {
+if (s->ops->cleanup && s->ctx.private) {
+s->ops->cleanup(>ctx);
+}
 g_free(s->ctx.fs_root);
 g_free(s->tag);
 v9fs_path_free();
@@ -3530,6 +3533,9 @@ out:
 
 void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
 {
+if (s->ops->cleanup) {
+s->ops->cleanup(>ctx);
+}
 g_free(s->tag);
 g_free(s->ctx.fs_root);
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v2 0/3] 9pfs: add cleanup operation in handle/proxy backend

2016-11-14 Thread Li Qiang
Currently, the backend of VirtFS doesn't have a cleanup
function. This will leak some resources in handle and proxy
backend driver. This patchset addresses this issue.

Li Qiang (3):
  9pfs: add cleanup operation in FileOperations
  9pfs: add cleanup operation for handle backend driver
  9pfs: add cleanup operation for proxy backend driver

 fsdev/file-op-9p.h  |  1 +
 hw/9pfs/9p-handle.c |  8 
 hw/9pfs/9p-proxy.c  | 10 ++
 hw/9pfs/9p.c|  6 ++
 4 files changed, 25 insertions(+)

-- 
1.8.3.1




[Qemu-devel] [PATCH v2 2/3] 9pfs: add cleanup operation for handle backend driver

2016-11-14 Thread Li Qiang
In the init operation of handle backend dirver, it allocates a
handle_data struct and opens a mount file. We should free these
resources when the 9pfs device is unrealized. This is what this
patch does.

Signed-off-by: Li Qiang 
---
 hw/9pfs/9p-handle.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index 3d77594..9b50f40 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -649,6 +649,13 @@ out:
 return ret;
 }
 
+static void handle_cleanup(FsContext *ctx)
+{
+struct handle_data *data = ctx->private;
+close(data->mountfd);
+g_free(data);
+}
+
 static int handle_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
 {
 const char *sec_model = qemu_opt_get(opts, "security_model");
@@ -671,6 +678,7 @@ static int handle_parse_opts(QemuOpts *opts, struct 
FsDriverEntry *fse)
 FileOperations handle_ops = {
 .parse_opts   = handle_parse_opts,
 .init = handle_init,
+.cleanup  = handle_cleanup,
 .lstat= handle_lstat,
 .readlink = handle_readlink,
 .close= handle_close,
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v6 1/2] block/vxhs.c: Add support for a new block device type called "vxhs"

2016-11-14 Thread Fam Zheng
On Mon, 11/14 13:06, Eric Blake wrote:
> So I guess you have to determine if libqnio is something that should
> compile completely independent from qemu, or whether it is so closely
> tied to the rest of qemu that it should follow qemu conventions.

The question is on include directives in block/vxhs.c, not libnqio library
header, so qemu conventions apply.

Fam

> 
> -- 
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 






Re: [Qemu-devel] [PATCH] hw/misc/ivshmem:fix misconfig of not_legacy_32bit

2016-11-14 Thread Gonglei (Arei)




Regards,
-Gonglei


> -Original Message-
> From: Zhuangyanying
> Sent: Monday, November 14, 2016 8:35 PM
> To: pbonz...@redhat.com; arm...@redhat.com
> Cc: qemu-devel@nongnu.org; Gonglei (Arei); Huangweidong (C);
> Zhuangyanying
> Subject: [PATCH] hw/misc/ivshmem:fix misconfig of not_legacy_32bit
> 
> From: ZhuangYanying 
> 
> After "ivshmem: Split ivshmem-plain, ivshmem-doorbell off ivshmem",
> ivshmem_64bit renamed to not_legacy_32bit, and changed the
> implementation of this property.
> Then use64 = not_legacy_32bit = 1, then PCI attribute configuration ~
> PCI_BASE_ADDRESS_MEM_TYPE_64 (default for ivshmem), the actual use is
> the legacy model, can not support greater than or equal 1G mapping, which is
> the opposite of configuration requirements.
> 
> Signed-off-by: ann.zhuangyany...@huawei.com
> ---
> Recently, I tested ivshmem, found that use64, that is not_legacy_32bit
> implementation is odd, or even the opposite.
> Previous use64 = ivshmem_64bit = 1, then attr |=
> PCI_BASE_ADDRESS_MEM_TYPE_64, then ivshmem support 1G and above
> packaged into bar2, presented to the virtual machine.
> But after "ivshmem: Split ivshmem-plain, ivshmem-doorbell off ivshmem",
> PCI_BASE_ADDRESS_MEM_TYPE_64 is configured while not_legacy_32bit = 0,
> that is the legacy model.
> ---
>  hw/misc/ivshmem.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 

Reviewed-by: Gonglei 

I find that there isn't a maintainer to maintain ivshmem.c:

# ./scripts/get_maintainer.pl -f hw/misc/ivshmem.c 
get_maintainer.pl: No maintainers found, printing recent contributors.
get_maintainer.pl: Do not blindly cc: them on patches!  Use common sense.

"Marc-André Lureau"  (commit_signer:39/49=80%)
Markus Armbruster  (commit_signer:37/49=76%)
Paolo Bonzini  (commit_signer:14/49=29%)
"Michael S. Tsirkin"  (commit_signer:6/49=12%)

Who can pick up this obvious bugfix for QEMU-2.8?

+ Marc and Michael.

Regards,
-Gonglei

> diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
> index 230e51b..b71acf6 100644
> --- a/hw/misc/ivshmem.c
> +++ b/hw/misc/ivshmem.c
> @@ -858,7 +858,7 @@ static void ivshmem_common_realize(PCIDevice *dev,
> Error **errp)
>  pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
>   >ivshmem_mmio);
> 
> -if (!s->not_legacy_32bit) {
> +if (s->not_legacy_32bit) {
>  attr |= PCI_BASE_ADDRESS_MEM_TYPE_64;
>  }
> 
> @@ -1033,6 +1033,7 @@ static const VMStateDescription
> ivshmem_plain_vmsd = {
> 
>  static Property ivshmem_plain_properties[] = {
>  DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master,
> ON_OFF_AUTO_OFF),
> +DEFINE_PROP_UINT32("use64", IVShmemState, not_legacy_32bit, 1),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> 
> @@ -1107,6 +1108,7 @@ static Property ivshmem_doorbell_properties[] = {
>  DEFINE_PROP_BIT("ioeventfd", IVShmemState, features,
> IVSHMEM_IOEVENTFD,
>  true),
>  DEFINE_PROP_ON_OFF_AUTO("master", IVShmemState, master,
> ON_OFF_AUTO_OFF),
> +DEFINE_PROP_UINT32("use64", IVShmemState, not_legacy_32bit, 1),
>  DEFINE_PROP_END_OF_LIST(),
>  };
> 
> --
> 1.8.3.1
> 




[Qemu-devel] [PATCH v2] hw/isa/lpc_ich9: inject SMI on all VCPUs if APM_STS == 'Q'

2016-11-14 Thread Laszlo Ersek
The generic edk2 SMM infrastructure prefers
EFI_SMM_CONTROL2_PROTOCOL.Trigger() to inject an SMI on each processor. If
Trigger() only brings the current processor into SMM, then edk2 handles it
in the following ways:

(1) If Trigger() is executed by the BSP (which is guaranteed before
ExitBootServices(), but is not necessarily true at runtime), then:

(a) If edk2 has been configured for "traditional" SMM synchronization,
then the BSP sends directed SMIs to the APs with APIC delivery,
bringing them into SMM individually. Then the BSP runs the SMI
handler / dispatcher.

(b) If edk2 has been configured for "relaxed" SMM synchronization,
then the APs that are not already in SMM are not brought in, and
the BSP runs the SMI handler / dispatcher.

(2) If Trigger() is executed by an AP (which is possible after
ExitBootServices(), and can be forced e.g. by "taskset -c 1
efibootmgr"), then the AP in question brings in the BSP with a
directed SMI, and the BSP runs the SMI handler / dispatcher.

The smaller problem with (1a) and (2) is that the BSP and AP
synchronization is slow. For example, the "taskset -c 1 efibootmgr"
command from (2) can take more than 3 seconds to complete, because
efibootmgr accesses non-volatile UEFI variables intensively.

The larger problem is that QEMU's current behavior diverges from the
behavior usually seen on physical hardware, and that keeps exposing
obscure corner cases, race conditions and other instabilities in edk2,
which generally expects / prefers a software SMI to affect all CPUs at
once.

Therefore introduce a special APM_STS value (0x51) that causes QEMU to
inject the SMI on all VCPUs. OVMF's EFI_SMM_CONTROL2_PROTOCOL.Trigger()
can utilize this to accommodate edk2's preference about "broadcast" SMI.

SeaBIOS uses values 0x00 and 0x01 for APM_STS (called PORT_SMI_STATUS in
the SeaBIOS code), so this change should be transparent to it.

While the original posting of this patch

only intended to speed up (2), based on our recent "stress testing" of SMM
this patch actually provides functional improvements. (There are no code
changes relative to the original posting.)

Cc: "Michael S. Tsirkin" 
Cc: Paolo Bonzini 
Also-suggested-by: Paolo Bonzini 
Signed-off-by: Laszlo Ersek 
---
 hw/isa/lpc_ich9.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 10d1ee8b9310..f2fe644fdaa4 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -372,6 +372,8 @@ void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled)
 
 /* APM */
 
+#define QEMU_ICH9_APM_STS_BROADCAST_SMI 'Q'
+
 static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 {
 ICH9LPCState *lpc = arg;
@@ -386,7 +388,15 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
 
 /* SMI_EN = PMBASE + 30. SMI control and enable register */
 if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
-cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
+if (lpc->apm.apms == QEMU_ICH9_APM_STS_BROADCAST_SMI) {
+CPUState *cs;
+
+CPU_FOREACH(cs) {
+cpu_interrupt(cs, CPU_INTERRUPT_SMI);
+}
+} else {
+cpu_interrupt(current_cpu, CPU_INTERRUPT_SMI);
+}
 }
 }
 
-- 
2.9.2




[Qemu-devel] [PATCH] 9pfs: adjust the order of resource cleanup in device unrealize

2016-11-14 Thread Li Qiang
From: Li Qiang 

Unrealize should undo things that were set during realize in
reverse order. This is what this patch does.

Signed-off-by: Li Qiang 
---
 hw/9pfs/9p.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index aea7e9d..f7e14ac 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -3530,8 +3530,8 @@ out:
 
 void v9fs_device_unrealize_common(V9fsState *s, Error **errp)
 {
-g_free(s->ctx.fs_root);
 g_free(s->tag);
+g_free(s->ctx.fs_root);
 }
 
 typedef struct VirtfsCoResetData {
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH 2/4] hw/misc: add a TMP42{1, 2, 3} device model

2016-11-14 Thread Andrew Jeffery
On Mon, 2016-11-14 at 08:14 +0100, Cédric Le Goater wrote:
> > Given the starting point of the tmp105 code the patch looks okay, but I
> > was a bit thrown by the use of the 'len' member as what I'd consider an
> > index. For instance we reset len to zero in tmp421_event() after
> > populating buf, and then the data in buf is presumably sent out on a
> > recv transaction which again starts incrementing len. len is also
> > incremented when we don't interact with buf, e.g. when we instead
> > assign to pointer. It feels like it could be prone to bugs, and
> > 'cb5ef3fa1871 tmp105: Fix I2C protocol bug' suggests that might not be
> > an unreasonable feeling.
> > 
> > But given the code already exists in tmp105 maybe it's fine?
> 
> So, I took my time to check this but yes, I think the code is fine.

Yes, from memory it was okay, just not as obvious as I'd hoped it to
be.

> 
> However, tmp421 does not need to support 2 bytes writes so we can
> simplify tmp421_tx() :
> 
> static int tmp421_tx(I2CSlave *i2c, uint8_t data)
> {
>     TMP421State *s = TMP421(i2c);
> 
>     if (s->len == 0) {
>     /* first byte is the register pointer for a read or write
>  * operation */
>     s->pointer = data;
>     s->len++;
>     } else if (s->len == 1) {
>     /* second byte is the data to write. The device only supports
>  * one byte writes */
>     s->buf[0] = data;
>     tmp421_write(s);
>     }
> 
>     return 0;
> }
> 
> and tmp421 needs to support 2 bytes reads, so we need to extend a bit 
> tmp421_read() when the temperatures are are. Linux does not use it 
> so I guess we should use a command line tool to test.

Okay.

> 
> I will send an updated patch for the TMP42{1,2,3} device with a larger 
> patchset I am working on for Aspeed support. That is for 2.9.
> 

Okay, I'll review again then.

Thanks,

Andrew

> Thanks,
> 
> C. 

signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH] vfio: avoid adding same iommu mr for notify

2016-11-14 Thread Peter Xu
On Mon, Nov 14, 2016 at 07:59:28PM -0500, Peter Xu wrote:
> When one IOMMU memory region is splitted into multiple memory sections,
> vfio will register multiple same notifiers to a vIOMMU for the same
> region. That's not sensible. What we need is to register one IOMMU
> notifier for each IOMMU region, not per section.
> 
> Solution is simple - we traverse the container->giommu_list, and skip
> the registration if memory region is already registered.
> 
> To make vfio's region_add() short, vfio_listener_region_add_iommu() is
> introduced.
> 
> Signed-off-by: Peter Xu 

This patch will solve Aviv's issue that vfio_map_notify() will dump
many error messages when device assignments are enabled with Intel
vIOMMU.

Alex, could you help verify whether this is the one that you
suggested? I'd be glad to add your suggestted-by if you won't
disagree.

Thanks,

-- peterx



[Qemu-devel] [PATCH] vfio: avoid adding same iommu mr for notify

2016-11-14 Thread Peter Xu
When one IOMMU memory region is splitted into multiple memory sections,
vfio will register multiple same notifiers to a vIOMMU for the same
region. That's not sensible. What we need is to register one IOMMU
notifier for each IOMMU region, not per section.

Solution is simple - we traverse the container->giommu_list, and skip
the registration if memory region is already registered.

To make vfio's region_add() short, vfio_listener_region_add_iommu() is
introduced.

Signed-off-by: Peter Xu 
---
 hw/vfio/common.c | 56 +++-
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 801578b..5279fd1 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -360,6 +360,40 @@ out:
 rcu_read_unlock();
 }
 
+static void vfio_listener_region_add_iommu(VFIOContainer *container,
+   MemoryRegionSection *section,
+   hwaddr iova,
+   hwaddr end)
+{
+VFIOGuestIOMMU *giommu;
+
+QLIST_FOREACH(giommu, >giommu_list, giommu_next) {
+if (giommu->iommu == section->mr) {
+/* We have already registered with this MR, skip */
+return;
+}
+}
+
+trace_vfio_listener_region_add_iommu(iova, end);
+
+/*
+ * FIXME: For VFIO iommu types which have KVM acceleration to
+ * avoid bouncing all map/unmaps through qemu this way, this
+ * would be the right place to wire that up (tell the KVM
+ * device emulation the VFIO iommu handles to use).
+ */
+giommu = g_malloc0(sizeof(*giommu));
+giommu->iommu = section->mr;
+giommu->iommu_offset = section->offset_within_address_space -
+section->offset_within_region;
+giommu->container = container;
+giommu->n.notify = vfio_iommu_map_notify;
+giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
+QLIST_INSERT_HEAD(>giommu_list, giommu, giommu_next);
+memory_region_register_iommu_notifier(giommu->iommu, >n);
+memory_region_iommu_replay(giommu->iommu, >n, false);
+}
+
 static void vfio_listener_region_add(MemoryListener *listener,
  MemoryRegionSection *section)
 {
@@ -439,27 +473,7 @@ static void vfio_listener_region_add(MemoryListener 
*listener,
 memory_region_ref(section->mr);
 
 if (memory_region_is_iommu(section->mr)) {
-VFIOGuestIOMMU *giommu;
-
-trace_vfio_listener_region_add_iommu(iova, end);
-/*
- * FIXME: For VFIO iommu types which have KVM acceleration to
- * avoid bouncing all map/unmaps through qemu this way, this
- * would be the right place to wire that up (tell the KVM
- * device emulation the VFIO iommu handles to use).
- */
-giommu = g_malloc0(sizeof(*giommu));
-giommu->iommu = section->mr;
-giommu->iommu_offset = section->offset_within_address_space -
-   section->offset_within_region;
-giommu->container = container;
-giommu->n.notify = vfio_iommu_map_notify;
-giommu->n.notifier_flags = IOMMU_NOTIFIER_ALL;
-QLIST_INSERT_HEAD(>giommu_list, giommu, giommu_next);
-
-memory_region_register_iommu_notifier(giommu->iommu, >n);
-memory_region_iommu_replay(giommu->iommu, >n, false);
-
+vfio_listener_region_add_iommu(container, section, iova, end);
 return;
 }
 
-- 
2.7.4




Re: [Qemu-devel] [PATCH 04/21] tests: add hbitmap iter test

2016-11-14 Thread John Snow



On 11/09/2016 01:17 PM, Vladimir Sementsov-Ogievskiy wrote:

Test that hbitmap iter is resistant to bitmap resetting.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Denis V. Lunev 
Reviewed-by: Max Reitz 


Reviewed-by: John Snow 


---
 tests/test-hbitmap.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
index 9b7495c..c76d2b5 100644
--- a/tests/test-hbitmap.c
+++ b/tests/test-hbitmap.c
@@ -898,6 +898,22 @@ static void hbitmap_test_add(const char *testpath,
hbitmap_test_teardown);
 }

+static void test_hbitmap_iter_and_reset(TestHBitmapData *data,
+const void *unused)
+{
+HBitmapIter hbi;
+
+hbitmap_test_init(data, L1 * 2, 0);
+hbitmap_set(data->hb, 0, data->size);
+
+hbitmap_iter_init(, data->hb, BITS_PER_LONG - 1);
+
+hbitmap_iter_next();
+
+hbitmap_reset_all(data->hb);
+hbitmap_iter_next();
+}
+
 int main(int argc, char **argv)
 {
 g_test_init(, , NULL);
@@ -955,6 +971,9 @@ int main(int argc, char **argv)
  test_hbitmap_serialize_part);
 hbitmap_test_add("/hbitmap/serialize/zeroes",
  test_hbitmap_serialize_zeroes);
+
+hbitmap_test_add("/hbitmap/iter/iter_and_reset",
+ test_hbitmap_iter_and_reset);
 g_test_run();

 return 0;



--
—js



Re: [Qemu-devel] [PATCH v12 11/22] vfio iommu: Add blocking notifier to notify DMA_UNMAP

2016-11-14 Thread Alex Williamson
On Mon, 14 Nov 2016 21:12:25 +0530
Kirti Wankhede  wrote:

> Added blocking notifier to IOMMU TYPE1 driver to notify vendor drivers
> about DMA_UNMAP.
> Exported two APIs vfio_register_notifier() and vfio_unregister_notifier().
> Notifier should be registered, if external user wants to use
> vfio_pin_pages()/vfio_unpin_pages() APIs to pin/unpin pages.
> Vendor driver should use VFIO_IOMMU_NOTIFY_DMA_UNMAP action to invalidate
> mappings.
> 
> Signed-off-by: Kirti Wankhede 
> Signed-off-by: Neo Jia 
> Change-Id: I5910d0024d6be87f3e8d3e0ca0eaeaaa0b17f271
> ---
>  drivers/vfio/vfio.c | 73 
> +
>  drivers/vfio/vfio_iommu_type1.c | 60 ++---
>  include/linux/vfio.h| 11 +++
>  3 files changed, 132 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
> index 7dcfbca2016a..388a3cbddbd9 100644
> --- a/drivers/vfio/vfio.c
> +++ b/drivers/vfio/vfio.c
> @@ -1902,6 +1902,79 @@ err_unpin_pages:
>  }
>  EXPORT_SYMBOL(vfio_unpin_pages);
>  
> +int vfio_register_notifier(struct device *dev, struct notifier_block *nb)
> +{
> + struct vfio_container *container;
> + struct vfio_group *group;
> + struct vfio_iommu_driver *driver;
> + ssize_t ret;
> +
> + if (!dev || !nb)
> + return -EINVAL;
> +
> + group = vfio_group_get_from_dev(dev);
> + if (IS_ERR(group))
> + return PTR_ERR(group);
> +
> + ret = vfio_group_add_container_user(group);
> + if (ret)
> + goto err_register_nb;
> +
> + container = group->container;
> + down_read(>group_lock);
> +
> + driver = container->iommu_driver;
> + if (likely(driver && driver->ops->register_notifier))
> + ret = driver->ops->register_notifier(container->iommu_data, nb);
> + else
> + ret = -ENOTTY;
> +
> + up_read(>group_lock);
> + vfio_group_try_dissolve_container(group);
> +
> +err_register_nb:
> + vfio_group_put(group);
> + return ret;
> +}
> +EXPORT_SYMBOL(vfio_register_notifier);
> +
> +int vfio_unregister_notifier(struct device *dev, struct notifier_block *nb)
> +{
> + struct vfio_container *container;
> + struct vfio_group *group;
> + struct vfio_iommu_driver *driver;
> + ssize_t ret;
> +
> + if (!dev || !nb)
> + return -EINVAL;
> +
> + group = vfio_group_get_from_dev(dev);
> + if (IS_ERR(group))
> + return PTR_ERR(group);
> +
> + ret = vfio_group_add_container_user(group);
> + if (ret)
> + goto err_unregister_nb;
> +
> + container = group->container;
> + down_read(>group_lock);
> +
> + driver = container->iommu_driver;
> + if (likely(driver && driver->ops->unregister_notifier))
> + ret = driver->ops->unregister_notifier(container->iommu_data,
> +nb);
> + else
> + ret = -ENOTTY;
> +
> + up_read(>group_lock);
> + vfio_group_try_dissolve_container(group);
> +
> +err_unregister_nb:
> + vfio_group_put(group);
> + return ret;
> +}
> +EXPORT_SYMBOL(vfio_unregister_notifier);
> +
>  /**
>   * Module/class support
>   */
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 2697d874dd35..7e034e7c5ea5 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -38,6 +38,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define DRIVER_VERSION  "0.2"
>  #define DRIVER_AUTHOR   "Alex Williamson "
> @@ -60,6 +61,7 @@ struct vfio_iommu {
>   struct vfio_domain  *external_domain; /* domain for external user */
>   struct mutexlock;
>   struct rb_root  dma_list;
> + struct blocking_notifier_head notifier;
>   boolv2;
>   boolnesting;
>  };
> @@ -568,7 +570,8 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data,
>  
>   mutex_lock(>lock);
>  
> - if (!iommu->external_domain) {
> + /* Fail if notifier list is empty */
> + if ((!iommu->external_domain) || (!iommu->notifier.head)) {
>   ret = -EINVAL;
>   goto pin_done;
>   }
> @@ -854,15 +857,29 @@ static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
>   if (dma->task->mm != current->mm)
>   break;
>   unmapped += dma->size;
> +
> + mutex_unlock(>lock);
> + if (iommu->external_domain && !RB_EMPTY_ROOT(>pfn_list)) {
> + struct vfio_iommu_type1_dma_unmap nb_unmap;
> +
> + nb_unmap.iova = dma->iova;
> + nb_unmap.size = dma->size;
> + blocking_notifier_call_chain(>notifier,
> + VFIO_IOMMU_NOTIFY_DMA_UNMAP,
> +  

Re: [Qemu-devel] [PATCH 03/21] hbitmap: improve dirty iter

2016-11-14 Thread John Snow



On 11/09/2016 01:17 PM, Vladimir Sementsov-Ogievskiy wrote:

Make dirty iter resistant to resetting bits in corresponding HBitmap.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Max Reitz 
---
 include/qemu/hbitmap.h | 25 +++--
 util/hbitmap.c | 23 ++-
 2 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index eb46475..594f6f8 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -243,10 +243,8 @@ void hbitmap_free(HBitmap *hb);
  * the lowest-numbered bit that is set in @hb, starting at @first.
  *
  * Concurrent setting of bits is acceptable, and will at worst cause the
- * iteration to miss some of those bits.  Resetting bits before the current
- * position of the iterator is also okay.  However, concurrent resetting of
- * bits can lead to unexpected behavior if the iterator has not yet reached
- * those bits.
+ * iteration to miss some of those bits. Concurrent resetting of bits is OK,
+ * too.
  */


Minor bikeshed: I might remove "too" because the concurrent resetting of 
bits is perfectly ok in /contrast/ to the concurrent setting of bits, 
which has undesirable side-effects.


I may simply strongly word this as:

"The concurrent resetting of bits is OK."

It's not worth a rewrite on its own.

Reviewed-by: John Snow 


 void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first);

@@ -285,24 +283,7 @@ void hbitmap_free_meta(HBitmap *hb);
  * Return the next bit that is set in @hbi's associated HBitmap,
  * or -1 if all remaining bits are zero.
  */
-static inline int64_t hbitmap_iter_next(HBitmapIter *hbi)
-{
-unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1];
-int64_t item;
-
-if (cur == 0) {
-cur = hbitmap_iter_skip_words(hbi);
-if (cur == 0) {
-return -1;
-}
-}
-
-/* The next call will resume work from the next bit.  */
-hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1);
-item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur);
-
-return item << hbi->granularity;
-}
+int64_t hbitmap_iter_next(HBitmapIter *hbi);

 /**
  * hbitmap_iter_next_word:
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 5d1a21c..48d8b2d 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -106,8 +106,9 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi)

 unsigned long cur;
 do {
-cur = hbi->cur[--i];
+i--;
 pos >>= BITS_PER_LEVEL;
+cur = hbi->cur[i] & hb->levels[i][pos];
 } while (cur == 0);

 /* Check for end of iteration.  We always use fewer than BITS_PER_LONG
@@ -139,6 +140,26 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi)
 return cur;
 }

+int64_t hbitmap_iter_next(HBitmapIter *hbi)
+{
+unsigned long cur = hbi->cur[HBITMAP_LEVELS - 1] &
+hbi->hb->levels[HBITMAP_LEVELS - 1][hbi->pos];
+int64_t item;
+
+if (cur == 0) {
+cur = hbitmap_iter_skip_words(hbi);
+if (cur == 0) {
+return -1;
+}
+}
+
+/* The next call will resume work from the next bit.  */
+hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1);
+item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ctzl(cur);
+
+return item << hbi->granularity;
+}
+
 void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap *hb, uint64_t first)
 {
 unsigned i, bit;





Re: [Qemu-devel] [PATCH v2 0/4] ppc/pnv: XSCOM fixes and unit tests

2016-11-14 Thread David Gibson
On Mon, Nov 14, 2016 at 10:12:54AM +0100, Cédric Le Goater wrote:
> Hello,
> 
> Here is a little serie adding some fixes for the XSCOM registers of
> the POWER9 cores and a unit test. 
> 
> Changes since v1 :
> 
>  - fixed pnv_xscom_addr() for 32bit host systems
>  - replace hweight_long() by ctpop64()
> 
> Tested on a 32-bit LE system and on 64-bit LE and BE systems.

Applied to ppc-for-2.8.

I fixed a trivial nit in 4/4 - you had a 5 space indent, instead of a
4 space indent in one place.

> 
> Thanks,
> 
> C.
> 
> Cédric Le Goater (3):
>   ppc/pnv: add a 'xscom_core_base' field to PnvChipClass
>   ppc/pnv: fix xscom address translation for POWER9
>   tests: add XSCOM tests for the PowerNV machine
> 
> David Gibson (1):
>   ppc/pnv: Fix fatal bug on 32-bit hosts
> 
>  hw/ppc/pnv.c   |  10 +++-
>  hw/ppc/pnv_xscom.c |   8 +--
>  include/hw/ppc/pnv.h   |   1 +
>  include/hw/ppc/pnv_xscom.h |   5 +-
>  tests/Makefile.include |   1 +
>  tests/pnv-xscom-test.c | 140 
> +
>  6 files changed, 156 insertions(+), 9 deletions(-)
>  create mode 100644 tests/pnv-xscom-test.c
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v12 10/22] vfio iommu type1: Add support for mediated devices

2016-11-14 Thread Alex Williamson
On Mon, 14 Nov 2016 21:12:24 +0530
Kirti Wankhede  wrote:

> VFIO IOMMU drivers are designed for the devices which are IOMMU capable.
> Mediated device only uses IOMMU APIs, the underlying hardware can be
> managed by an IOMMU domain.
> 
> Aim of this change is:
> - To use most of the code of TYPE1 IOMMU driver for mediated devices
> - To support direct assigned device and mediated device in single module
> 
> This change adds pin and unpin support for mediated device to TYPE1 IOMMU
> backend module. More details:
> - Domain for external user is tracked separately in vfio_iommu structure.
>   It is allocated when group for first mdev device is attached.
> - Pages pinned for external domain are tracked in each vfio_dma structure
>   for that iova range.
> - Page tracking rb-tree in vfio_dma keeps . Key of
>   rb-tree is iova, but it actually aims to track pfns.
> - On external pin request for an iova, page is pinned only once, if iova
>   is already pinned and tracked, ref_count is incremented.

This is referring only to the external (ie. pfn_list) tracking only,
correct?  In general, a page can be pinned up to twice per iova
referencing it, once for an iommu mapped domain and again in the
pfn_list, right?

> - External unin request unpins pages only when ref_count is 0.
  unpin

> - Pinned pages list is used to verify unpinning request and to unpin
>   remaining pages while detaching the group for that device.
> - Page accounting is updated to account in its address space where the
>   pages are pinned/unpinned, i.e dma->task
> -  Accouting for mdev device is only done if there is no iommu capable
>   domain in the container. When there is a direct device assigned to the
>   container and that domain is iommu capable, all pages are already pinned
>   during DMA_MAP.
> - Page accouting is updated on hot plug and unplug mdev device and pass
>   through device.
> 
> Tested by assigning below combinations of devices to a single VM:
> - GPU pass through only
> - vGPU device only
> - One GPU pass through and one vGPU device
> - Linux VM hot plug and unplug vGPU device while GPU pass through device
>   exist
> - Linux VM hot plug and unplug GPU pass through device while vGPU device
>   exist
> 
> Signed-off-by: Kirti Wankhede 
> Signed-off-by: Neo Jia 
> Change-Id: I295d6f0f2e0579b8d9882bfd8fd5a4194b97bd9a
> ---
>  drivers/vfio/vfio_iommu_type1.c | 587 
> +++-
>  1 file changed, 526 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index 50aca95cf61e..2697d874dd35 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -37,6 +37,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #define DRIVER_VERSION  "0.2"
>  #define DRIVER_AUTHOR   "Alex Williamson "
> @@ -56,6 +57,7 @@ MODULE_PARM_DESC(disable_hugepages,
>  
>  struct vfio_iommu {
>   struct list_headdomain_list;
> + struct vfio_domain  *external_domain; /* domain for external user */
>   struct mutexlock;
>   struct rb_root  dma_list;
>   boolv2;
> @@ -76,7 +78,9 @@ struct vfio_dma {
>   unsigned long   vaddr;  /* Process virtual addr */
>   size_t  size;   /* Map size (bytes) */
>   int prot;   /* IOMMU_READ/WRITE */
> + booliommu_mapped;
>   struct task_struct  *task;
> + struct rb_root  pfn_list;   /* Ex-user pinned pfn list */
>  };
>  
>  struct vfio_group {
> @@ -85,6 +89,21 @@ struct vfio_group {
>  };
>  
>  /*
> + * Guest RAM pinning working set or DMA target
> + */
> +struct vfio_pfn {
> + struct rb_node  node;
> + dma_addr_t  iova;   /* Device address */
> + unsigned long   pfn;/* Host pfn */
> + atomic_tref_count;
> +};
> +
> +#define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)  \
> + (!list_empty(>domain_list))
> +
> +static int put_pfn(unsigned long pfn, int prot);
> +
> +/*
>   * This code handles mapping and unmapping of user data buffers
>   * into DMA'ble space using the IOMMU
>   */
> @@ -132,6 +151,97 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, 
> struct vfio_dma *old)
>   rb_erase(>node, >dma_list);
>  }
>  
> +/*
> + * Helper Functions for host iova-pfn list
> + */
> +static struct vfio_pfn *vfio_find_vpfn(struct vfio_dma *dma, dma_addr_t iova)
> +{
> + struct vfio_pfn *vpfn;
> + struct rb_node *node = dma->pfn_list.rb_node;
> +
> + while (node) {
> + vpfn = rb_entry(node, struct vfio_pfn, node);
> +
> + if (iova < vpfn->iova)
> + node = node->rb_left;
> + else if 

Re: [Qemu-devel] [PATCH v3] pcie_aer: Convert pcie_aer_init to Error

2016-11-14 Thread Michael S. Tsirkin
On Thu, Nov 03, 2016 at 08:54:36PM +0800, Cao jin wrote:
> When user specify invalid property aer_log_max, device should fail to
> create, and report appropriate message.
> 
> Signed-off-by: Cao jin 
> Reviewed-by: Marcel Apfelbaum 

I'll review and merge after release. Pls ping me then.


> ---
> v3 changelog:
> 1. get rid of PCIE_AER_LOG_MAX_UNSET
> 
>  hw/net/e1000e.c|  2 +-
>  hw/pci-bridge/ioh3420.c|  3 ++-
>  hw/pci-bridge/xio3130_downstream.c |  3 ++-
>  hw/pci-bridge/xio3130_upstream.c   |  3 ++-
>  hw/pci/pcie_aer.c  | 17 +++--
>  include/hw/pci/pcie_aer.h  |  3 ++-
>  6 files changed, 16 insertions(+), 15 deletions(-)
> 
> diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
> index 4994e1c..89f96eb 100644
> --- a/hw/net/e1000e.c
> +++ b/hw/net/e1000e.c
> @@ -472,7 +472,7 @@ static void e1000e_pci_realize(PCIDevice *pci_dev, Error 
> **errp)
>  hw_error("Failed to initialize PM capability");
>  }
>  
> -if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF) < 0) {
> +if (pcie_aer_init(pci_dev, e1000e_aer_offset, PCI_ERR_SIZEOF, NULL) < 0) 
> {
>  hw_error("Failed to initialize AER capability");
>  }
>  
> diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
> index c8b5ac4..04180af 100644
> --- a/hw/pci-bridge/ioh3420.c
> +++ b/hw/pci-bridge/ioh3420.c
> @@ -135,8 +135,9 @@ static int ioh3420_initfn(PCIDevice *d)
>  goto err_pcie_cap;
>  }
>  
> -rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF);
> +rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF, );
>  if (rc < 0) {
> +error_report_err(err);
>  goto err;
>  }
>  pcie_aer_root_init(d);
> diff --git a/hw/pci-bridge/xio3130_downstream.c 
> b/hw/pci-bridge/xio3130_downstream.c
> index cef6e13..5713341 100644
> --- a/hw/pci-bridge/xio3130_downstream.c
> +++ b/hw/pci-bridge/xio3130_downstream.c
> @@ -97,8 +97,9 @@ static int xio3130_downstream_initfn(PCIDevice *d)
>  goto err_pcie_cap;
>  }
>  
> -rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
> +rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF, );
>  if (rc < 0) {
> +error_report_err(err);
>  goto err;
>  }
>  
> diff --git a/hw/pci-bridge/xio3130_upstream.c 
> b/hw/pci-bridge/xio3130_upstream.c
> index 4ad0440..94c1691 100644
> --- a/hw/pci-bridge/xio3130_upstream.c
> +++ b/hw/pci-bridge/xio3130_upstream.c
> @@ -85,8 +85,9 @@ static int xio3130_upstream_initfn(PCIDevice *d)
>  pcie_cap_flr_init(d);
>  pcie_cap_deverr_init(d);
>  
> -rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
> +rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF, );
>  if (rc < 0) {
> +error_report_err(err);
>  goto err;
>  }
>  
> diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
> index 048ce6a..2a4bd5a 100644
> --- a/hw/pci/pcie_aer.c
> +++ b/hw/pci/pcie_aer.c
> @@ -29,6 +29,7 @@
>  #include "hw/pci/msi.h"
>  #include "hw/pci/pci_bus.h"
>  #include "hw/pci/pcie_regs.h"
> +#include "qapi/error.h"
>  
>  //#define DEBUG_PCIE
>  #ifdef DEBUG_PCIE
> @@ -96,21 +97,17 @@ static void aer_log_clear_all_err(PCIEAERLog *aer_log)
>  aer_log->log_num = 0;
>  }
>  
> -int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size)
> +int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size,
> +  Error **errp)
>  {
> -PCIExpressDevice *exp;
> -
>  pcie_add_capability(dev, PCI_EXT_CAP_ID_ERR, PCI_ERR_VER,
>  offset, size);
> -exp = >exp;
> -exp->aer_cap = offset;
> +dev->exp.aer_cap = offset;
>  
> -/* log_max is property */
> -if (dev->exp.aer_log.log_max == PCIE_AER_LOG_MAX_UNSET) {
> -dev->exp.aer_log.log_max = PCIE_AER_LOG_MAX_DEFAULT;
> -}
> -/* clip down the value to avoid unreasobale memory usage */
> +/* clip down the value to avoid unreasonable memory usage */
>  if (dev->exp.aer_log.log_max > PCIE_AER_LOG_MAX_LIMIT) {
> +error_setg(errp, "Invalid aer_log_max %d. The max number of aer log "
> +"is %d", dev->exp.aer_log.log_max, PCIE_AER_LOG_MAX_LIMIT);
>  return -EINVAL;
>  }
>  dev->exp.aer_log.log = g_malloc0(sizeof dev->exp.aer_log.log[0] *
> diff --git a/include/hw/pci/pcie_aer.h b/include/hw/pci/pcie_aer.h
> index c2ee4e2..1cce61a 100644
> --- a/include/hw/pci/pcie_aer.h
> +++ b/include/hw/pci/pcie_aer.h
> @@ -87,7 +87,8 @@ struct PCIEAERErr {
>  
>  extern const VMStateDescription vmstate_pcie_aer_log;
>  
> -int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size);
> +int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size,
> +  Error **errp);
>  void pcie_aer_exit(PCIDevice *dev);
>  void pcie_aer_write_config(PCIDevice *dev,
> uint32_t addr, uint32_t val, int len);
> -- 
> 2.1.0
> 
> 

Re: [Qemu-devel] [PATCH v7 00/10] Convert msix_init() to error

2016-11-14 Thread Michael S. Tsirkin
On Mon, Nov 14, 2016 at 03:25:30PM +0800, Cao jin wrote:
> v7 changelog:
> 1. fix the segfaut bug in patch 2. So drop the all the R-b of it,
>please take a look, there is detailed description in the patch.
> 2. add the R-b from Hannes Reinecke

Pls remember to ping after release.

> Test:
> 1. make check: pass
> 2. After applied all the patch, command line test for all the
>affected devices, just make sure device realize process is ok,
>no crash, but no further use of device.
> CC: Jiri Pirko 
> CC: Gerd Hoffmann 
> CC: Dmitry Fleytman 
> CC: Jason Wang 
> CC: Michael S. Tsirkin 
> CC: Hannes Reinecke 
> CC: Paolo Bonzini 
> CC: Alex Williamson 
> CC: Markus Armbruster 
> CC: Marcel Apfelbaum 
> 
> Cao jin (10):
>   msix: Follow CODING_STYLE
>   hcd-xhci: check & correct param before using it
>   pci: Convert msix_init() to Error and fix callers to check it
>   megasas: change behaviour of msix switch
>   hcd-xhci: change behaviour of msix switch
>   megasas: remove unnecessary megasas_use_msix()
>   megasas: undo the overwrites of msi user configuration
>   vmxnet3: fix reference leak issue
>   vmxnet3: remove unnecessary internal msix flag
>   msi_init: convert assert to return -errno
> 
>  hw/block/nvme.c|  5 +++-
>  hw/misc/ivshmem.c  |  8 +++---
>  hw/net/e1000e.c|  6 -
>  hw/net/rocker/rocker.c |  7 -
>  hw/net/vmxnet3.c   | 46 +++--
>  hw/pci/msi.c   |  9 ---
>  hw/pci/msix.c  | 42 +-
>  hw/scsi/megasas.c  | 49 ---
>  hw/usb/hcd-xhci.c  | 69 
> ++
>  hw/vfio/pci.c  |  8 --
>  hw/virtio/virtio-pci.c | 11 
>  include/hw/pci/msix.h  |  5 ++--
>  12 files changed, 164 insertions(+), 101 deletions(-)
> 
> -- 
> 2.1.0
> 
> 



Re: [Qemu-devel] [PULL v2 00/34] virtio, vhost, pc, pci: tests, documentation, fixes and cleanups

2016-11-14 Thread Michael S. Tsirkin
On Mon, Nov 14, 2016 at 03:52:58PM +, Stefan Hajnoczi wrote:
> On Fri, Nov 11, 2016 at 08:09:58PM +0200, Michael S. Tsirkin wrote:
> > libvhost-user is the only thing that might be controvertial here, but it's 
> > only
> > affecting contrib/ and tests so I think it's still fair game, and several
> > people were asking for it.
> 
> I am being firm about the freeze policy.  Only fixes are allowed.
> Please send a v3 without libvhost-user.

What's a fix is at some level in the eye of the beholder.
Consider Igor's patch removing an unused fw cfg file, is this
a fix? In the past it was maintainer's decision.

This one cleans up test code.

> I understand that people want libvhost-user.  Please merge it in a -next
> branch and have them base their work on that.
> 
> Stefan


Well I feel bad about it.
It was ready in time, I deferred it because there was so much other
stuff that I did not want it to interfere with.

I was sure it's ok - it's just a test change, I don't really see why we
need to enforce policy for tests, they are not used in production.

Let's make an exception for once?

-- 
MST



[Qemu-devel] [kvm-unit-tests PATCH v6 07/11] arm/arm64: gicv2: add an IPI test

2016-11-14 Thread Andrew Jones
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
v6: move the spurious check to its own check_ function [drew]
v5: use modern registers [Andre]
v4: properly mask irqnr in ipi_handler
v2: add more details in the output if a test fails,
report spurious interrupts if we get them
---
 arm/Makefile.common  |   8 +--
 arm/gic.c| 199 +++
 arm/unittests.cfg|   8 +++
 lib/arm/asm/gic-v2.h |   2 +
 lib/arm/asm/gic.h|   4 ++
 5 files changed, 217 insertions(+), 4 deletions(-)
 create mode 100644 arm/gic.c

diff --git a/arm/Makefile.common b/arm/Makefile.common
index 6f56015c43c4..2fe7aeeca6d4 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -9,10 +9,10 @@ ifeq ($(LOADADDR),)
LOADADDR = 0x4000
 endif
 
-tests-common = \
-   $(TEST_DIR)/selftest.flat \
-   $(TEST_DIR)/spinlock-test.flat \
-   $(TEST_DIR)/pci-test.flat
+tests-common  = $(TEST_DIR)/selftest.flat
+tests-common += $(TEST_DIR)/spinlock-test.flat
+tests-common += $(TEST_DIR)/pci-test.flat
+tests-common += $(TEST_DIR)/gic.flat
 
 all: test_cases
 
diff --git a/arm/gic.c b/arm/gic.c
new file mode 100644
index ..b42c2b1ca1e1
--- /dev/null
+++ b/arm/gic.c
@@ -0,0 +1,199 @@
+/*
+ * GIC tests
+ *
+ * GICv2
+ *   + test sending/receiving IPIs
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int gic_version;
+static int acked[NR_CPUS], spurious[NR_CPUS];
+static cpumask_t ready;
+
+static void nr_cpu_check(int nr)
+{
+   if (nr_cpus < nr)
+   report_abort("At least %d cpus required", nr);
+}
+
+static void wait_on_ready(void)
+{
+   cpumask_set_cpu(smp_processor_id(), );
+   while (!cpumask_full())
+   cpu_relax();
+}
+
+static void check_acked(cpumask_t *mask)
+{
+   int missing = 0, extra = 0, unexpected = 0;
+   int nr_pass, cpu, i;
+
+   /* Wait up to 5s for all interrupts to be delivered */
+   for (i = 0; i < 50; ++i) {
+   mdelay(100);
+   nr_pass = 0;
+   for_each_present_cpu(cpu) {
+   smp_rmb();
+   nr_pass += cpumask_test_cpu(cpu, mask) ?
+   acked[cpu] == 1 : acked[cpu] == 0;
+   }
+   if (nr_pass == nr_cpus) {
+   report("Completed in %d ms", true, ++i * 100);
+   return;
+   }
+   }
+
+   for_each_present_cpu(cpu) {
+   if (cpumask_test_cpu(cpu, mask)) {
+   if (!acked[cpu])
+   ++missing;
+   else if (acked[cpu] > 1)
+   ++extra;
+   } else {
+   if (acked[cpu])
+   ++unexpected;
+   }
+   }
+
+   report("Timed-out (5s). ACKS: missing=%d extra=%d unexpected=%d",
+  false, missing, extra, unexpected);
+}
+
+static void check_spurious(void)
+{
+   int cpu;
+
+   smp_rmb();
+   for_each_present_cpu(cpu) {
+   if (spurious[cpu])
+   printf("ipi: WARN: cpu%d got %d spurious interrupts\n",
+   spurious[cpu], smp_processor_id());
+   }
+}
+
+static void ipi_handler(struct pt_regs *regs __unused)
+{
+   u32 irqstat = readl(gicv2_cpu_base() + GICC_IAR);
+   u32 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
+
+   if (irqnr != GICC_INT_SPURIOUS) {
+   writel(irqstat, gicv2_cpu_base() + GICC_EOIR);
+   smp_rmb(); /* pairs with wmb in ipi_test functions */
+   ++acked[smp_processor_id()];
+   smp_wmb(); /* pairs with rmb in check_acked */
+   } else {
+   ++spurious[smp_processor_id()];
+   smp_wmb();
+   }
+}
+
+static void ipi_test_self(void)
+{
+   cpumask_t mask;
+
+   report_prefix_push("self");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   cpumask_clear();
+   cpumask_set_cpu(0, );
+   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   check_acked();
+   report_prefix_pop();
+}
+
+static void ipi_test_smp(void)
+{
+   cpumask_t mask;
+   unsigned long tlist;
+
+   report_prefix_push("target-list");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   tlist = cpumask_bits(_present_mask)[0] & 0xaa;
+   cpumask_bits()[0] = tlist;
+   writel((u8)tlist << 16, gicv2_dist_base() + GICD_SGIR);
+   check_acked();
+   report_prefix_pop();
+
+   report_prefix_push("broadcast");
+   memset(acked, 0, sizeof(acked));
+   smp_wmb();
+   cpumask_copy(, _present_mask);
+   cpumask_clear_cpu(0, );
+   writel(1 << 

[Qemu-devel] [kvm-unit-tests PATCH v6 06/11] arm/arm64: add initial gicv2 support

2016-11-14 Thread Andrew Jones
Add some gicv2 support. This just adds init and enable
functions, allowing unit tests to start messing with it.

Reviewed-by: Andre Przywara 
Signed-off-by: Andrew Jones 

---
v6: added comments (register offset headers) [Alex]
v5: share/use only the modern register names [Andre]
v4:
 - only take defines from kernel we need now [Andre]
 - moved defines to asm/gic.h so they'll be shared with v3 [drew]
 - simplify enable by not caring if we reinit the distributor [drew]
 - init all GICD_INT_DEF_PRI_X4 registers [Eric]
---
 arm/Makefile.common|  1 +
 lib/arm/asm/gic-v2.h   | 34 ++
 lib/arm/asm/gic.h  | 39 ++
 lib/arm/gic.c  | 76 ++
 lib/arm64/asm/gic-v2.h |  1 +
 lib/arm64/asm/gic.h|  1 +
 6 files changed, 152 insertions(+)
 create mode 100644 lib/arm/asm/gic-v2.h
 create mode 100644 lib/arm/asm/gic.h
 create mode 100644 lib/arm/gic.c
 create mode 100644 lib/arm64/asm/gic-v2.h
 create mode 100644 lib/arm64/asm/gic.h

diff --git a/arm/Makefile.common b/arm/Makefile.common
index f37b5c2a3de4..6f56015c43c4 100644
--- a/arm/Makefile.common
+++ b/arm/Makefile.common
@@ -46,6 +46,7 @@ cflatobjs += lib/arm/mmu.o
 cflatobjs += lib/arm/bitops.o
 cflatobjs += lib/arm/psci.o
 cflatobjs += lib/arm/smp.o
+cflatobjs += lib/arm/gic.o
 
 libeabi = lib/arm/libeabi.a
 eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/gic-v2.h b/lib/arm/asm/gic-v2.h
new file mode 100644
index ..c2d5fecd4886
--- /dev/null
+++ b/lib/arm/asm/gic-v2.h
@@ -0,0 +1,34 @@
+/*
+ * All GIC* defines are lifted from include/linux/irqchip/arm-gic.h
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_GIC_V2_H_
+#define _ASMARM_GIC_V2_H_
+
+#ifndef _ASMARM_GIC_H_
+#error Do not directly include . Include 
+#endif
+
+#define GICD_ENABLE0x1
+#define GICC_ENABLE0x1
+
+#ifndef __ASSEMBLY__
+
+struct gicv2_data {
+   void *dist_base;
+   void *cpu_base;
+   unsigned int irq_nr;
+};
+extern struct gicv2_data gicv2_data;
+
+#define gicv2_dist_base()  (gicv2_data.dist_base)
+#define gicv2_cpu_base()   (gicv2_data.cpu_base)
+
+extern int gicv2_init(void);
+extern void gicv2_enable_defaults(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMARM_GIC_V2_H_ */
diff --git a/lib/arm/asm/gic.h b/lib/arm/asm/gic.h
new file mode 100644
index ..e3580bd1d42d
--- /dev/null
+++ b/lib/arm/asm/gic.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_GIC_H_
+#define _ASMARM_GIC_H_
+
+#include 
+
+/* Distributor registers */
+#define GICD_CTLR  0x
+#define GICD_TYPER 0x0004
+#define GICD_ISENABLER 0x0100
+#define GICD_IPRIORITYR0x0400
+
+#define GICD_TYPER_IRQS(typer) typer) & 0x1f) + 1) * 32)
+#define GICD_INT_EN_SET_SGI0x
+#define GICD_INT_DEF_PRI_X40xa0a0a0a0
+
+/* CPU interface registers */
+#define GICC_CTLR  0x
+#define GICC_PMR   0x0004
+
+#define GICC_INT_PRI_THRESHOLD 0xf0
+
+#ifndef __ASSEMBLY__
+
+/*
+ * gic_init will try to find all known gics, and then
+ * initialize the gic data for the one found.
+ * returns
+ *  0   : no gic was found
+ *  > 0 : the gic version of the gic found
+ */
+extern int gic_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMARM_GIC_H_ */
diff --git a/lib/arm/gic.c b/lib/arm/gic.c
new file mode 100644
index ..d655105e058b
--- /dev/null
+++ b/lib/arm/gic.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include 
+#include 
+#include 
+
+struct gicv2_data gicv2_data;
+
+/*
+ * Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
+ */
+static bool
+gic_get_dt_bases(const char *compatible, void **base1, void **base2)
+{
+   struct dt_pbus_reg reg;
+   struct dt_device gic;
+   struct dt_bus bus;
+   int node, ret;
+
+   dt_bus_init_defaults();
+   dt_device_init(, , NULL);
+
+   node = dt_device_find_compatible(, compatible);
+   assert(node >= 0 || node == -FDT_ERR_NOTFOUND);
+
+   if (node == -FDT_ERR_NOTFOUND)
+   return false;
+
+   dt_device_bind_node(, node);
+
+   ret = dt_pbus_translate(, 0, );
+   assert(ret == 0);
+   *base1 = ioremap(reg.addr, reg.size);
+
+   ret = dt_pbus_translate(, 1, );
+   assert(ret == 0);
+   *base2 = ioremap(reg.addr, reg.size);
+
+   return true;
+}
+
+int gicv2_init(void)
+{
+   return 

[Qemu-devel] [kvm-unit-tests PATCH v6 09/11] arm/arm64: add initial gicv3 support

2016-11-14 Thread Andrew Jones
Reviewed-by: Alex Bennée 
Signed-off-by: Andrew Jones 

---
v6:
 - added comments [Alex]
 - added stride parameter to gicv3_set_redist_base [Andre]
 - redist-wait s/rwp/uwp/ and comment [Andre]
 - removed unnecessary wait-for-rwps [Andre]
v5: use modern register names [Andre]
v4:
 - only take defines from kernel we need now [Andre]
 - simplify enable by not caring if we reinit the distributor [drew]
v2:
 - configure irqs as NS GRP1
---
 lib/arm/asm/arch_gicv3.h   |  47 
 lib/arm/asm/gic-v3.h   | 104 +
 lib/arm/asm/gic.h  |   5 ++-
 lib/arm/gic.c  |  64 
 lib/arm64/asm/arch_gicv3.h |  44 +++
 lib/arm64/asm/gic-v3.h |   1 +
 lib/arm64/asm/sysreg.h |  44 +++
 7 files changed, 308 insertions(+), 1 deletion(-)
 create mode 100644 lib/arm/asm/arch_gicv3.h
 create mode 100644 lib/arm/asm/gic-v3.h
 create mode 100644 lib/arm64/asm/arch_gicv3.h
 create mode 100644 lib/arm64/asm/gic-v3.h
 create mode 100644 lib/arm64/asm/sysreg.h

diff --git a/lib/arm/asm/arch_gicv3.h b/lib/arm/asm/arch_gicv3.h
new file mode 100644
index ..276577452a14
--- /dev/null
+++ b/lib/arm/asm/arch_gicv3.h
@@ -0,0 +1,47 @@
+/*
+ * All ripped off from arch/arm/include/asm/arch_gicv3.h
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_ARCH_GICV3_H_
+#define _ASMARM_ARCH_GICV3_H_
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+#include 
+
+#define __stringify xstr
+
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2)  p15, Op1, %0, CRn, CRm, Op2
+
+#define ICC_PMR__ACCESS_CP15(c4, 0, c6, 0)
+#define ICC_IGRPEN1__ACCESS_CP15(c12, 0, c12, 7)
+
+static inline void gicv3_write_pmr(u32 val)
+{
+   asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+}
+
+static inline void gicv3_write_grpen1(u32 val)
+{
+   asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+   isb();
+}
+
+/*
+ * We may access GICR_TYPER and GITS_TYPER by reading both the TYPER
+ * offset and the following offset (+ 4) and then combining them to
+ * form a 64-bit address.
+ */
+static inline u64 gicv3_read_typer(const volatile void __iomem *addr)
+{
+   u64 val = readl(addr);
+   val |= (u64)readl(addr + 4) << 32;
+   return val;
+}
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASMARM_ARCH_GICV3_H_ */
diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h
new file mode 100644
index ..73ade4681d21
--- /dev/null
+++ b/lib/arm/asm/gic-v3.h
@@ -0,0 +1,104 @@
+/*
+ * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h
+ *
+ * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#ifndef _ASMARM_GIC_V3_H_
+#define _ASMARM_GIC_V3_H_
+
+#ifndef _ASMARM_GIC_H_
+#error Do not directly include . Include 
+#endif
+
+/*
+ * Distributor registers
+ *
+ * We expect to be run in Non-secure mode, thus we define the
+ * group1 enable bits with respect to that view.
+ */
+#define GICD_CTLR_RWP  (1U << 31)
+#define GICD_CTLR_ARE_NS   (1U << 4)
+#define GICD_CTLR_ENABLE_G1A   (1U << 1)
+#define GICD_CTLR_ENABLE_G1(1U << 0)
+
+/* Re-Distributor registers, offsets from RD_base */
+#define GICR_TYPER 0x0008
+
+#define GICR_TYPER_LAST(1U << 4)
+
+/* Re-Distributor registers, offsets from SGI_base */
+#define GICR_IGROUPR0  GICD_IGROUPR
+#define GICR_ISENABLER0GICD_ISENABLER
+#define GICR_IPRIORITYR0   GICD_IPRIORITYR
+
+#include 
+
+#ifndef __ASSEMBLY__
+#include 
+#include 
+#include 
+#include 
+
+struct gicv3_data {
+   void *dist_base;
+   void *redist_base[NR_CPUS];
+   unsigned int irq_nr;
+};
+extern struct gicv3_data gicv3_data;
+
+#define gicv3_dist_base()  (gicv3_data.dist_base)
+#define gicv3_redist_base()
(gicv3_data.redist_base[smp_processor_id()])
+#define gicv3_sgi_base()   
(gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
+
+extern int gicv3_init(void);
+extern void gicv3_enable_defaults(void);
+extern void gicv3_set_redist_base(size_t stride);
+
+static inline void gicv3_do_wait_for_rwp(void *base)
+{
+   int count = 10; /* 1s */
+
+   while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) {
+   if (!--count) {
+   printf("GICv3: RWP timeout!\n");
+   abort();
+   }
+   cpu_relax();
+   udelay(10);
+   };
+}
+
+static inline void gicv3_dist_wait_for_rwp(void)
+{
+   gicv3_do_wait_for_rwp(gicv3_dist_base());
+}
+
+static inline void gicv3_redist_wait_for_uwp(void)
+{

[Qemu-devel] [kvm-unit-tests PATCH v6 04/11] arm/arm64: add some delay routines

2016-11-14 Thread Andrew Jones
Allow a thread to wait some specified amount of time. Can
specify in cycles, usecs, and msecs.

Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
 lib/arm/asm/processor.h   | 19 +++
 lib/arm/processor.c   | 15 +++
 lib/arm64/asm/processor.h | 19 +++
 lib/arm64/processor.c | 15 +++
 4 files changed, 68 insertions(+)

diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index ecf5bbe1824a..bc46d1f980ee 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -5,7 +5,9 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
+#include 
 #include 
+#include 
 
 enum vector {
EXCPTN_RST,
@@ -51,4 +53,21 @@ extern int mpidr_to_cpu(unsigned long mpidr);
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
 
+static inline u64 get_cntvct(void)
+{
+   u64 vct;
+   isb();
+   asm volatile("mrrc p15, 1, %Q0, %R0, c14" : "=r" (vct));
+   return vct;
+}
+
+extern void delay(u64 cycles);
+extern void udelay(unsigned long usecs);
+
+static inline void mdelay(unsigned long msecs)
+{
+   while (msecs--)
+   udelay(1000);
+}
+
 #endif /* _ASMARM_PROCESSOR_H_ */
diff --git a/lib/arm/processor.c b/lib/arm/processor.c
index 54fdb87ef019..c2ee360df688 100644
--- a/lib/arm/processor.c
+++ b/lib/arm/processor.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static const char *processor_modes[] = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" ,
@@ -141,3 +142,17 @@ bool is_user(void)
 {
return current_thread_info()->flags & TIF_USER_MODE;
 }
+
+void delay(u64 cycles)
+{
+   u64 start = get_cntvct();
+   while ((get_cntvct() - start) < cycles)
+   cpu_relax();
+}
+
+void udelay(unsigned long usec)
+{
+   unsigned int frq;
+   asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq));
+   delay((u64)usec * frq / 100);
+}
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 7e448dc81a6a..94f7ce35b65c 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -17,8 +17,10 @@
 #define SCTLR_EL1_M(1 << 0)
 
 #ifndef __ASSEMBLY__
+#include 
 #include 
 #include 
+#include 
 
 enum vector {
EL1T_SYNC,
@@ -89,5 +91,22 @@ extern int mpidr_to_cpu(unsigned long mpidr);
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
 
+static inline u64 get_cntvct(void)
+{
+   u64 vct;
+   isb();
+   asm volatile("mrs %0, cntvct_el0" : "=r" (vct));
+   return vct;
+}
+
+extern void delay(u64 cycles);
+extern void udelay(unsigned long usecs);
+
+static inline void mdelay(unsigned long msecs)
+{
+   while (msecs--)
+   udelay(1000);
+}
+
 #endif /* !__ASSEMBLY__ */
 #endif /* _ASMARM64_PROCESSOR_H_ */
diff --git a/lib/arm64/processor.c b/lib/arm64/processor.c
index deeab4ec9c8a..50fa835c6f1e 100644
--- a/lib/arm64/processor.c
+++ b/lib/arm64/processor.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static const char *vector_names[] = {
"el1t_sync",
@@ -253,3 +254,17 @@ bool is_user(void)
 {
return current_thread_info()->flags & TIF_USER_MODE;
 }
+
+void delay(u64 cycles)
+{
+   u64 start = get_cntvct();
+   while ((get_cntvct() - start) < cycles)
+   cpu_relax();
+}
+
+void udelay(unsigned long usec)
+{
+   unsigned int frq;
+   asm volatile("mrs %0, cntfrq_el0" : "=r" (frq));
+   delay((u64)usec * frq / 100);
+}
-- 
2.7.4




[Qemu-devel] [kvm-unit-tests PATCH v6 11/11] arm/arm64: gic: don't just use zero

2016-11-14 Thread Andrew Jones
Allow user to select who sends ipis and with which irq,
rather than just always sending irq=0 from cpu0.

Signed-off-by: Andrew Jones 

---
v6:
 - make sender/irq names more future-proof [drew]
 - sanity check inputs [drew]
 - introduce check_sender/irq and bad_sender/irq to more
   cleanly do checks [drew]
 - default sender and irq to 1, instead of still zero [drew]
v4: improve structure and make sure spurious checking is
done even when the sender isn't cpu0
v2: actually check that the irq received was the irq sent,
and (for gicv2) that the sender is the expected one.
---
 arm/gic.c | 124 +-
 1 file changed, 99 insertions(+), 25 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index d954a3775c26..638b8b140c96 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -11,6 +11,7 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -28,6 +29,8 @@ struct gic {
 
 static struct gic *gic;
 static int acked[NR_CPUS], spurious[NR_CPUS];
+static int bad_sender[NR_CPUS], bad_irq[NR_CPUS];
+static int cmdl_sender = 1, cmdl_irq = 1;
 static cpumask_t ready;
 
 static void nr_cpu_check(int nr)
@@ -43,10 +46,23 @@ static void wait_on_ready(void)
cpu_relax();
 }
 
+static void stats_reset(void)
+{
+   int i;
+
+   for (i = 0; i < nr_cpus; ++i) {
+   acked[i] = 0;
+   bad_sender[i] = -1;
+   bad_irq[i] = -1;
+   }
+   smp_wmb();
+}
+
 static void check_acked(cpumask_t *mask)
 {
int missing = 0, extra = 0, unexpected = 0;
int nr_pass, cpu, i;
+   bool bad = false;
 
/* Wait up to 5s for all interrupts to be delivered */
for (i = 0; i < 50; ++i) {
@@ -56,9 +72,21 @@ static void check_acked(cpumask_t *mask)
smp_rmb();
nr_pass += cpumask_test_cpu(cpu, mask) ?
acked[cpu] == 1 : acked[cpu] == 0;
+
+   if (bad_sender[cpu] != -1) {
+   printf("cpu%d received IPI from wrong sender 
%d\n",
+   cpu, bad_sender[cpu]);
+   bad = true;
+   }
+
+   if (bad_irq[cpu] != -1) {
+   printf("cpu%d received wrong irq %d\n",
+   cpu, bad_irq[cpu]);
+   bad = true;
+   }
}
if (nr_pass == nr_cpus) {
-   report("Completed in %d ms", true, ++i * 100);
+   report("Completed in %d ms", !bad, ++i * 100);
return;
}
}
@@ -91,6 +119,22 @@ static void check_spurious(void)
}
 }
 
+static void check_ipi_sender(u32 irqstat)
+{
+   if (gic_version() == 2) {
+   int src = (irqstat >> 10) & 7;
+
+   if (src != cmdl_sender)
+   bad_sender[smp_processor_id()] = src;
+   }
+}
+
+static void check_irqnr(u32 irqnr)
+{
+   if (irqnr != (u32)cmdl_irq)
+   bad_irq[smp_processor_id()] = irqnr;
+}
+
 static void ipi_handler(struct pt_regs *regs __unused)
 {
u32 irqstat = gic_read_iar();
@@ -98,8 +142,10 @@ static void ipi_handler(struct pt_regs *regs __unused)
 
if (irqnr != GICC_INT_SPURIOUS) {
gic_write_eoir(irqstat);
-   smp_rmb(); /* pairs with wmb in ipi_test functions */
+   smp_rmb(); /* pairs with wmb in stats_reset */
++acked[smp_processor_id()];
+   check_ipi_sender(irqstat);
+   check_irqnr(irqnr);
smp_wmb(); /* pairs with rmb in check_acked */
} else {
++spurious[smp_processor_id()];
@@ -109,19 +155,19 @@ static void ipi_handler(struct pt_regs *regs __unused)
 
 static void gicv2_ipi_send_self(void)
 {
-   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   writel(2 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
 }
 
-static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq __unused)
+static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq)
 {
u8 tlist = (u8)cpumask_bits(mask)[0];
 
-   writel(tlist << 16, gicv2_dist_base() + GICD_SGIR);
+   writel(tlist << 16 | irq, gicv2_dist_base() + GICD_SGIR);
 }
 
 static void gicv2_ipi_send_broadcast(void)
 {
-   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+   writel(1 << 24 | cmdl_irq, gicv2_dist_base() + GICD_SGIR);
 }
 
 static void gicv3_ipi_send_self(void)
@@ -130,12 +176,12 @@ static void gicv3_ipi_send_self(void)
 
cpumask_clear();
cpumask_set_cpu(smp_processor_id(), );
-   gicv3_ipi_send_tlist(, 0);
+   gicv3_ipi_send_tlist(, cmdl_irq);
 }
 
 static void gicv3_ipi_send_broadcast(void)
 {
-   gicv3_write_sgi1r(1ULL << 40);

[Qemu-devel] [kvm-unit-tests PATCH v6 10/11] arm/arm64: gicv3: add an IPI test

2016-11-14 Thread Andrew Jones
Signed-off-by: Andrew Jones 

---
v6: move most gicv2/gicv3 wrappers to common code [Alex]
v5:
 - fix copy+paste error in gicv3_write_eoir [drew]
 - use modern register names [Andre]
v4:
 - heavily comment gicv3_ipi_send_tlist() [Eric]
 - changes needed for gicv2 iar/irqstat fix to other patch
v2:
 - use IRM for gicv3 broadcast
---
 arm/gic.c  |  97 +-
 arm/unittests.cfg  |   6 ++
 lib/arm/asm/arch_gicv3.h   |  23 +++
 lib/arm/asm/gic-v3.h   |  10 +++-
 lib/arm/asm/gic.h  |  60 +++
 lib/arm/gic.c  | 145 ++---
 lib/arm64/asm/arch_gicv3.h |  22 +++
 7 files changed, 338 insertions(+), 25 deletions(-)

diff --git a/arm/gic.c b/arm/gic.c
index b42c2b1ca1e1..d954a3775c26 100644
--- a/arm/gic.c
+++ b/arm/gic.c
@@ -3,6 +3,8 @@
  *
  * GICv2
  *   + test sending/receiving IPIs
+ * GICv3
+ *   + test sending/receiving IPIs
  *
  * Copyright (C) 2016, Red Hat Inc, Andrew Jones 
  *
@@ -16,7 +18,15 @@
 #include 
 #include 
 
-static int gic_version;
+struct gic {
+   struct {
+   void (*send_self)(void);
+   void (*send_tlist)(cpumask_t *mask, int irq);
+   void (*send_broadcast)(void);
+   } ipi;
+};
+
+static struct gic *gic;
 static int acked[NR_CPUS], spurious[NR_CPUS];
 static cpumask_t ready;
 
@@ -83,11 +93,11 @@ static void check_spurious(void)
 
 static void ipi_handler(struct pt_regs *regs __unused)
 {
-   u32 irqstat = readl(gicv2_cpu_base() + GICC_IAR);
-   u32 irqnr = irqstat & GICC_IAR_INT_ID_MASK;
+   u32 irqstat = gic_read_iar();
+   u32 irqnr = gic_iar_irqnr(irqstat);
 
if (irqnr != GICC_INT_SPURIOUS) {
-   writel(irqstat, gicv2_cpu_base() + GICC_EOIR);
+   gic_write_eoir(irqstat);
smp_rmb(); /* pairs with wmb in ipi_test functions */
++acked[smp_processor_id()];
smp_wmb(); /* pairs with rmb in check_acked */
@@ -97,6 +107,38 @@ static void ipi_handler(struct pt_regs *regs __unused)
}
 }
 
+static void gicv2_ipi_send_self(void)
+{
+   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+}
+
+static void gicv2_ipi_send_tlist(cpumask_t *mask, int irq __unused)
+{
+   u8 tlist = (u8)cpumask_bits(mask)[0];
+
+   writel(tlist << 16, gicv2_dist_base() + GICD_SGIR);
+}
+
+static void gicv2_ipi_send_broadcast(void)
+{
+   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+}
+
+static void gicv3_ipi_send_self(void)
+{
+   cpumask_t mask;
+
+   cpumask_clear();
+   cpumask_set_cpu(smp_processor_id(), );
+   gicv3_ipi_send_tlist(, 0);
+}
+
+static void gicv3_ipi_send_broadcast(void)
+{
+   gicv3_write_sgi1r(1ULL << 40);
+   isb();
+}
+
 static void ipi_test_self(void)
 {
cpumask_t mask;
@@ -106,7 +148,7 @@ static void ipi_test_self(void)
smp_wmb();
cpumask_clear();
cpumask_set_cpu(0, );
-   writel(2 << 24, gicv2_dist_base() + GICD_SGIR);
+   gic->ipi.send_self();
check_acked();
report_prefix_pop();
 }
@@ -114,14 +156,15 @@ static void ipi_test_self(void)
 static void ipi_test_smp(void)
 {
cpumask_t mask;
-   unsigned long tlist;
+   int i;
 
report_prefix_push("target-list");
memset(acked, 0, sizeof(acked));
smp_wmb();
-   tlist = cpumask_bits(_present_mask)[0] & 0xaa;
-   cpumask_bits()[0] = tlist;
-   writel((u8)tlist << 16, gicv2_dist_base() + GICD_SGIR);
+   cpumask_copy(, _present_mask);
+   for (i = 0; i < nr_cpus; i += 2)
+   cpumask_clear_cpu(i, );
+   gic->ipi.send_tlist(, 0);
check_acked();
report_prefix_pop();
 
@@ -130,14 +173,14 @@ static void ipi_test_smp(void)
smp_wmb();
cpumask_copy(, _present_mask);
cpumask_clear_cpu(0, );
-   writel(1 << 24, gicv2_dist_base() + GICD_SGIR);
+   gic->ipi.send_broadcast();
check_acked();
report_prefix_pop();
 }
 
 static void ipi_enable(void)
 {
-   gicv2_enable_defaults();
+   gic_enable_defaults();
 #ifdef __arm__
install_exception_handler(EXCPTN_IRQ, ipi_handler);
 #else
@@ -154,18 +197,42 @@ static void ipi_recv(void)
wfi();
 }
 
+static struct gic gicv2 = {
+   .ipi = {
+   .send_self = gicv2_ipi_send_self,
+   .send_tlist = gicv2_ipi_send_tlist,
+   .send_broadcast = gicv2_ipi_send_broadcast,
+   },
+};
+
+static struct gic gicv3 = {
+   .ipi = {
+   .send_self = gicv3_ipi_send_self,
+   .send_tlist = gicv3_ipi_send_tlist,
+   .send_broadcast = gicv3_ipi_send_broadcast,
+   },
+};
+
 int main(int argc, char **argv)
 {
char pfx[8];
int cpu;
 
-   gic_version = gic_init();
-   if (!gic_version)
-   report_abort("No gic present!");
+   if (!gic_init())
+  

[Qemu-devel] [kvm-unit-tests PATCH v6 08/11] libcflat: add IS_ALIGNED() macro, and page sizes

2016-11-14 Thread Andrew Jones
From: Peter Xu 

These macros will be useful to do page alignment checks.

Reviewed-by: Andre Przywara 
Signed-off-by: Peter Xu 
[drew: also added SZ_64K and changed to shifts]
Signed-off-by: Andrew Jones 

---
v6: change to shifts [Alex]
---
 lib/libcflat.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 82005f5d014f..244e40a724be 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -33,6 +33,12 @@
 #define __ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
 #define __ALIGN(x, a)  __ALIGN_MASK(x, (typeof(x))(a) - 1)
 #define ALIGN(x, a)__ALIGN((x), (a))
+#define IS_ALIGNED(x, a)   (((x) & ((typeof(x))(a) - 1)) == 0)
+
+#define SZ_4K  (1 << 12)
+#define SZ_64K (1 << 16)
+#define SZ_2M  (1 << 21)
+#define SZ_1G  (1 << 30)
 
 typedef uint8_tu8;
 typedef int8_t s8;
-- 
2.7.4




[Qemu-devel] [kvm-unit-tests PATCH v6 05/11] arm/arm64: irq enable/disable

2016-11-14 Thread Andrew Jones
Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
 lib/arm/asm/processor.h   | 10 ++
 lib/arm64/asm/processor.h | 10 ++
 2 files changed, 20 insertions(+)

diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index bc46d1f980ee..959ecda5dced 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -35,6 +35,16 @@ static inline unsigned long current_cpsr(void)
 
 #define current_mode() (current_cpsr() & MODE_MASK)
 
+static inline void local_irq_enable(void)
+{
+   asm volatile("cpsie i" : : : "memory", "cc");
+}
+
+static inline void local_irq_disable(void)
+{
+   asm volatile("cpsid i" : : : "memory", "cc");
+}
+
 static inline unsigned long get_mpidr(void)
 {
unsigned long mpidr;
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 94f7ce35b65c..d54a4ed1c187 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -68,6 +68,16 @@ static inline unsigned long current_level(void)
return el & 0xc;
 }
 
+static inline void local_irq_enable(void)
+{
+   asm volatile("msr daifclr, #2" : : : "memory");
+}
+
+static inline void local_irq_disable(void)
+{
+   asm volatile("msr daifset, #2" : : : "memory");
+}
+
 #define DEFINE_GET_SYSREG(reg, type)   \
 static inline type get_##reg(void) \
 {  \
-- 
2.7.4




[Qemu-devel] [kvm-unit-tests PATCH v6 02/11] arm64: fix get_"sysreg32" and make MPIDR 64bit

2016-11-14 Thread Andrew Jones
mrs is always 64bit, so we should always use a 64bit register.
Sometimes we'll only want to return the lower 32, but not for
MPIDR, as that does define fields in the upper 32.

Reviewed-by: Alex Bennée 
Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 

---
v5: switch arm32's get_mpidr to 'unsigned long' too, to be
consistent with arm64 [Andre]
---
 lib/arm/asm/processor.h   |  4 ++--
 lib/arm64/asm/processor.h | 15 +--
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index f25e7eee3666..02f912f99974 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -33,9 +33,9 @@ static inline unsigned long current_cpsr(void)
 
 #define current_mode() (current_cpsr() & MODE_MASK)
 
-static inline unsigned int get_mpidr(void)
+static inline unsigned long get_mpidr(void)
 {
-   unsigned int mpidr;
+   unsigned long mpidr;
asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r" (mpidr));
return mpidr;
 }
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 84d5c7ce752b..9a208ff729b7 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -66,14 +66,17 @@ static inline unsigned long current_level(void)
return el & 0xc;
 }
 
-#define DEFINE_GET_SYSREG32(reg)   \
-static inline unsigned int get_##reg(void) \
+#define DEFINE_GET_SYSREG(reg, type)   \
+static inline type get_##reg(void) \
 {  \
-   unsigned int reg;   \
-   asm volatile("mrs %0, " #reg "_el1" : "=r" (reg));  \
-   return reg; \
+   unsigned long r;\
+   asm volatile("mrs %0, " #reg "_el1" : "=r" (r));\
+   return (type)r; \
 }
-DEFINE_GET_SYSREG32(mpidr)
+#define DEFINE_GET_SYSREG32(reg) DEFINE_GET_SYSREG(reg, unsigned int)
+#define DEFINE_GET_SYSREG64(reg) DEFINE_GET_SYSREG(reg, unsigned long)
+
+DEFINE_GET_SYSREG64(mpidr)
 
 /* Only support Aff0 for now, gicv2 only */
 #define mpidr_to_cpu(mpidr) ((int)((mpidr) & 0xff))
-- 
2.7.4




[Qemu-devel] [kvm-unit-tests PATCH v6 00/11] arm/arm64: add gic framework

2016-11-14 Thread Andrew Jones
v6:
 - rebased to latest master
 - several other changes thanks to Andre and Alex, changes in
   individual patch change logs
 - some code cleanups

v5:
 - fix arm32/gicv3 compile [drew]
 - use modern register names [Andre]
 - one Andre r-b

v4:
 - Eric's r-b's
 - Andre's suggestion to only take defines we need
 - several other changes listed in individual patches

v3:
 - Rebased on latest master
 - Added Alex's r-b's

v2:
 Rebased on latest master + my "populate argv[0]" series (will
 send a REPOST for that shortly. Additionally a few patches got
 fixes/features;
 07/10 got same fix as kernel 7c9b973061 "irqchip/gic-v3: Configure
   all interrupts as non-secure Group-1" in order to continue
   working over TCG, as the gicv3 code for TCG removed a hack
   it had there to make Linux happy.
 08/10 added more output for when things fail (if they fail)
 09/10 switched gicv3 broadcast implementation to using IRM. This
   found a bug in a recent (but not tip) kernel, which I was
   about to fix, but then I saw MarcZ beat me to it.
 10/10 actually check that the input irq is the received irq


Import defines, and steal enough helper functions, from Linux to
enable programming of the gic (v2 and v3). Then use the framework
to add an initial test (an ipi test; self, target-list, broadcast).

It's my hope that this framework will be a suitable base on which
more tests may be easily added, particularly because we have
vgic-new and tcg gicv3 emulation getting close to merge. (v3 UPDATE:
vgic-new and tcg gicv3 are merged now)

To run it, along with other tests, just do

 ./configure [ --arch=[arm|arm64] --cross-prefix=$PREFIX ]
 make
 export QEMU=$PATH_TO_QEMU
 ./run_tests.sh

To run it separately do, e.g.

$QEMU -machine virt,accel=tcg -cpu cortex-a57 \
 -device virtio-serial-device \
 -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
 -display none -serial stdio \
 -kernel arm/gic.flat \
 -smp 123 -machine gic-version=3 -append ipi
  ^^ note, we can go nuts with nr-cpus on TCG :-)

Or, a KVM example using a different "sender" cpu and irq (other than zero)

$QEMU -machine virt,accel=kvm -cpu host \
 -device virtio-serial-device \
 -device virtconsole,chardev=ctd -chardev testdev,id=ctd \
 -display none -serial stdio \
 -kernel arm/gic.flat \
 -smp 48 -machine gic-version=3 -append 'ipi sender=42 irq=1'


Patches:
01-05: fixes and functionality needed by the later gic patches
06-07: enable gicv2 and gicv2 IPI test
08-10: enable gicv3 and gicv3 IPI test
   11: extend the IPI tests to take variable sender and irq

Available here: https://github.com/rhdrjones/kvm-unit-tests/commits/arm/gic-v6


Andrew Jones (10):
  lib: xstr: allow multiple args
  arm64: fix get_"sysreg32" and make MPIDR 64bit
  arm/arm64: smp: support more than 8 cpus
  arm/arm64: add some delay routines
  arm/arm64: irq enable/disable
  arm/arm64: add initial gicv2 support
  arm/arm64: gicv2: add an IPI test
  arm/arm64: add initial gicv3 support
  arm/arm64: gicv3: add an IPI test
  arm/arm64: gic: don't just use zero

Peter Xu (1):
  libcflat: add IS_ALIGNED() macro, and page sizes

 arm/Makefile.common|   9 +-
 arm/gic.c  | 340 +
 arm/run|  19 ++-
 arm/selftest.c |   5 +-
 arm/unittests.cfg  |  14 ++
 lib/arm/asm/arch_gicv3.h   |  70 ++
 lib/arm/asm/gic-v2.h   |  36 +
 lib/arm/asm/gic-v3.h   | 112 +++
 lib/arm/asm/gic.h  | 106 ++
 lib/arm/asm/processor.h|  42 +-
 lib/arm/asm/setup.h|   4 +-
 lib/arm/gic.c  | 267 +++
 lib/arm/processor.c|  15 ++
 lib/arm/setup.c|  10 ++
 lib/arm64/asm/arch_gicv3.h |  66 +
 lib/arm64/asm/gic-v2.h |   1 +
 lib/arm64/asm/gic-v3.h |   1 +
 lib/arm64/asm/gic.h|   1 +
 lib/arm64/asm/processor.h  |  53 +--
 lib/arm64/asm/sysreg.h |  44 ++
 lib/arm64/processor.c  |  15 ++
 lib/libcflat.h |  10 +-
 22 files changed, 1212 insertions(+), 28 deletions(-)
 create mode 100644 arm/gic.c
 create mode 100644 lib/arm/asm/arch_gicv3.h
 create mode 100644 lib/arm/asm/gic-v2.h
 create mode 100644 lib/arm/asm/gic-v3.h
 create mode 100644 lib/arm/asm/gic.h
 create mode 100644 lib/arm/gic.c
 create mode 100644 lib/arm64/asm/arch_gicv3.h
 create mode 100644 lib/arm64/asm/gic-v2.h
 create mode 100644 lib/arm64/asm/gic-v3.h
 create mode 100644 lib/arm64/asm/gic.h
 create mode 100644 lib/arm64/asm/sysreg.h

-- 
2.7.4




[Qemu-devel] [kvm-unit-tests PATCH v6 03/11] arm/arm64: smp: support more than 8 cpus

2016-11-14 Thread Andrew Jones
By adding support for launching with gicv3 we can break the 8 vcpu
limit. This patch adds support to smp code and also selects the
vgic model corresponding to the host. The vgic model may also be
manually selected by adding e.g. -machine gic-version=3 to
extra_params.

Reviewed-by: Alex Bennée 
Reviewed-by: Andre Przywara 
Signed-off-by: Andrew Jones 

---
v5: left cpus a u32 for now. Changing to u64 requires a change to
devicetree. Will do it later. [Andre]
v4: improved commit message
---
 arm/run   | 19 ---
 arm/selftest.c|  5 -
 lib/arm/asm/processor.h   |  9 +++--
 lib/arm/asm/setup.h   |  4 ++--
 lib/arm/setup.c   | 10 ++
 lib/arm64/asm/processor.h |  9 +++--
 6 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/arm/run b/arm/run
index 1ee6231599d6..a35952b28b46 100755
--- a/arm/run
+++ b/arm/run
@@ -31,13 +31,6 @@ if [ -z "$ACCEL" ]; then
fi
 fi
 
-if [ "$HOST" = "aarch64" ] && [ "$ACCEL" = "kvm" ]; then
-   processor="host"
-   if [ "$ARCH" = "arm" ]; then
-   processor+=",aarch64=off"
-   fi
-fi
-
 qemu="${QEMU:-qemu-system-$ARCH_NAME}"
 qpath=$(which $qemu 2>/dev/null)
 
@@ -53,6 +46,18 @@ fi
 
 M='-machine virt'
 
+if [ "$ACCEL" = "kvm" ]; then
+   if $qemu $M,\? 2>&1 | grep gic-version > /dev/null; then
+   M+=',gic-version=host'
+   fi
+   if [ "$HOST" = "aarch64" ]; then
+   processor="host"
+   if [ "$ARCH" = "arm" ]; then
+   processor+=",aarch64=off"
+   fi
+   fi
+fi
+
 if ! $qemu $M -device '?' 2>&1 | grep virtconsole > /dev/null; then
echo "$qpath doesn't support virtio-console for chr-testdev. Exiting."
exit 2
diff --git a/arm/selftest.c b/arm/selftest.c
index 196164f5313d..2f117f795d2d 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -312,9 +312,10 @@ static bool psci_check(void)
 static cpumask_t smp_reported;
 static void cpu_report(void)
 {
+   unsigned long mpidr = get_mpidr();
int cpu = smp_processor_id();
 
-   report("CPU%d online", true, cpu);
+   report("CPU(%3d) mpidr=%lx", mpidr_to_cpu(mpidr) == cpu, cpu, mpidr);
cpumask_set_cpu(cpu, _reported);
halt();
 }
@@ -343,6 +344,7 @@ int main(int argc, char **argv)
 
} else if (strcmp(argv[1], "smp") == 0) {
 
+   unsigned long mpidr = get_mpidr();
int cpu;
 
report("PSCI version", psci_check());
@@ -353,6 +355,7 @@ int main(int argc, char **argv)
smp_boot_secondary(cpu, cpu_report);
}
 
+   report("CPU(%3d) mpidr=%lx", mpidr_to_cpu(mpidr) == 0, 0, 
mpidr);
cpumask_set_cpu(0, _reported);
while (!cpumask_full(_reported))
cpu_relax();
diff --git a/lib/arm/asm/processor.h b/lib/arm/asm/processor.h
index 02f912f99974..ecf5bbe1824a 100644
--- a/lib/arm/asm/processor.h
+++ b/lib/arm/asm/processor.h
@@ -40,8 +40,13 @@ static inline unsigned long get_mpidr(void)
return mpidr;
 }
 
-/* Only support Aff0 for now, up to 4 cpus */
-#define mpidr_to_cpu(mpidr) ((int)((mpidr) & 0xff))
+#define MPIDR_HWID_BITMASK 0xff
+extern int mpidr_to_cpu(unsigned long mpidr);
+
+#define MPIDR_LEVEL_SHIFT(level) \
+   (((1 << level) >> 1) << 3)
+#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
+   ((mpidr >> MPIDR_LEVEL_SHIFT(level)) & 0xff)
 
 extern void start_usr(void (*func)(void *arg), void *arg, unsigned long 
sp_usr);
 extern bool is_user(void);
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index cb8fdbd38dd5..1de99dd184d1 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -10,8 +10,8 @@
 #include 
 #include 
 
-#define NR_CPUS8
-extern u32 cpus[NR_CPUS];
+#define NR_CPUS255
+extern u32 cpus[NR_CPUS];  /* per-cpu IDs (MPIDRs) */
 extern int nr_cpus;
 
 #define NR_MEM_REGIONS 8
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 7e7b39f11dde..241bf9410447 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -30,6 +30,16 @@ int nr_cpus;
 struct mem_region mem_regions[NR_MEM_REGIONS];
 phys_addr_t __phys_offset, __phys_end;
 
+int mpidr_to_cpu(unsigned long mpidr)
+{
+   int i;
+
+   for (i = 0; i < nr_cpus; ++i)
+   if (cpus[i] == (mpidr & MPIDR_HWID_BITMASK))
+   return i;
+   return -1;
+}
+
 static void cpu_set(int fdtnode __unused, u32 regval, void *info __unused)
 {
int cpu = nr_cpus++;
diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
index 9a208ff729b7..7e448dc81a6a 100644
--- a/lib/arm64/asm/processor.h
+++ b/lib/arm64/asm/processor.h
@@ -78,8 +78,13 @@ static inline type get_##reg(void)   
\
 
 DEFINE_GET_SYSREG64(mpidr)
 
-/* Only support Aff0 for now, gicv2 only */
-#define 

[Qemu-devel] [kvm-unit-tests PATCH v6 01/11] lib: xstr: allow multiple args

2016-11-14 Thread Andrew Jones
Make implementation equivalent to Linux's include/linux/stringify.h

Reviewed-by: Eric Auger 
Signed-off-by: Andrew Jones 
---
 lib/libcflat.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 72b1bf9668ef..82005f5d014f 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -27,8 +27,8 @@
 
 #define __unused __attribute__((__unused__))
 
-#define xstr(s) xxstr(s)
-#define xxstr(s) #s
+#define xstr(s...) xxstr(s)
+#define xxstr(s...) #s
 
 #define __ALIGN_MASK(x, mask)  (((x) + (mask)) & ~(mask))
 #define __ALIGN(x, a)  __ALIGN_MASK(x, (typeof(x))(a) - 1)
-- 
2.7.4




[Qemu-devel] [PATCH 3/3] migration: Don't create decompression threads if not enabled

2016-11-14 Thread Juan Quintela
Signed-off-by: Juan Quintela 

--

I removed the [HACK] part because previous patch just check that
compression pages are not received.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/migration/ram.c b/migration/ram.c
index 4bb707c..24e2591 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2260,6 +2260,9 @@ void migrate_decompress_threads_create(void)
 {
 int i, thread_count;

+if (!migrate_use_compression()) {
+return;
+}
 thread_count = migrate_decompress_threads();
 decompress_threads = g_new0(QemuThread, thread_count);
 decomp_param = g_new0(DecompressParam, thread_count);
@@ -2281,6 +2284,9 @@ void migrate_decompress_threads_join(void)
 {
 int i, thread_count;

+if (!migrate_use_compression()) {
+return;
+}
 thread_count = migrate_decompress_threads();
 for (i = 0; i < thread_count; i++) {
 qemu_mutex_lock(_param[i].mutex);
-- 
2.7.4




[Qemu-devel] [PATCH 2/3] migration: Test for disabled features on reception

2016-11-14 Thread Juan Quintela
Right now, if we receive a compressed page or a xbzrle page while this
features are disabled, Bad Things (TM) can happen.  Just add a test for
them.

Signed-off-by: Juan Quintela 
---
 migration/ram.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/migration/ram.c b/migration/ram.c
index fb9252d..4bb707c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -2464,7 +2464,7 @@ static int ram_load_postcopy(QEMUFile *f)

 static int ram_load(QEMUFile *f, void *opaque, int version_id)
 {
-int flags = 0, ret = 0;
+int flags = 0, ret = 0, invalid_flags;
 static uint64_t seq_iter;
 int len = 0;
 /*
@@ -2479,6 +2479,15 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 ret = -EINVAL;
 }

+invalid_flags = 0;
+
+if (!migrate_use_xbzrle()) {
+invalid_flags |= RAM_SAVE_FLAG_XBZRLE;
+}
+
+if (!migrate_use_compression()) {
+invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;
+}
 /* This RCU critical section can be very long running.
  * When RCU reclaims in the code start to become numerous,
  * it will be necessary to reduce the granularity of this
@@ -2499,6 +2508,18 @@ static int ram_load(QEMUFile *f, void *opaque, int 
version_id)
 flags = addr & ~TARGET_PAGE_MASK;
 addr &= TARGET_PAGE_MASK;

+if (flags & invalid_flags) {
+if (flags & invalid_flags  & RAM_SAVE_FLAG_XBZRLE) {
+error_report("Received an unexpected XBRLE page");
+}
+if (flags & invalid_flags  & RAM_SAVE_FLAG_COMPRESS_PAGE) {
+error_report("Received an unexpected compressed page");
+}
+
+ret = -EINVAL;
+break;
+}
+
 if (flags & (RAM_SAVE_FLAG_COMPRESS | RAM_SAVE_FLAG_PAGE |
  RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {
 RAMBlock *block = ram_block_from_stream(f, flags);
-- 
2.7.4




[Qemu-devel] [PATCH 0/3] Migration fixes

2016-11-14 Thread Juan Quintela

Hi

This are the fixes that were of the multifd patches.

The most important one is the second patch, that one that checks for valid 
flags on reception.

Please, review.

Juan Quintela (3):
  migration: create Migration Incoming State at init time
  migration: Test for disabled features on reception
  migration: Don't create decompression threads if not enabled

 include/migration/migration.h |  1 -
 migration/migration.c | 38 +-
 migration/ram.c   | 29 -
 migration/savevm.c|  4 ++--
 4 files changed, 47 insertions(+), 25 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH 1/3] migration: create Migration Incoming State at init time

2016-11-14 Thread Juan Quintela
Signed-off-by: Juan Quintela 
---
 include/migration/migration.h |  1 -
 migration/migration.c | 38 +-
 migration/savevm.c|  4 ++--
 3 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/include/migration/migration.h b/include/migration/migration.h
index c309d23..a184509 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -119,7 +119,6 @@ struct MigrationIncomingState {
 };

 MigrationIncomingState *migration_incoming_get_current(void);
-MigrationIncomingState *migration_incoming_state_new(QEMUFile *f);
 void migration_incoming_state_destroy(void);

 /*
diff --git a/migration/migration.c b/migration/migration.c
index e331f28..51ca9b4 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -111,32 +111,28 @@ MigrationState *migrate_get_current(void)
 return _migration;
 }

-/* For incoming */
-static MigrationIncomingState *mis_current;
-
 MigrationIncomingState *migration_incoming_get_current(void)
 {
-return mis_current;
-}
+static bool once;
+static MigrationIncomingState mis_current;

-MigrationIncomingState *migration_incoming_state_new(QEMUFile* f)
-{
-mis_current = g_new0(MigrationIncomingState, 1);
-mis_current->from_src_file = f;
-mis_current->state = MIGRATION_STATUS_NONE;
-QLIST_INIT(_current->loadvm_handlers);
-qemu_mutex_init(_current->rp_mutex);
-qemu_event_init(_current->main_thread_load_event, false);
-
-return mis_current;
+if (!once) {
+mis_current.state = MIGRATION_STATUS_NONE;
+memset(_current, 0, sizeof(MigrationIncomingState));
+QLIST_INIT(_current.loadvm_handlers);
+qemu_mutex_init(_current.rp_mutex);
+qemu_event_init(_current.main_thread_load_event, false);
+once = true;
+}
+return _current;
 }

 void migration_incoming_state_destroy(void)
 {
-qemu_event_destroy(_current->main_thread_load_event);
-loadvm_free_handlers(mis_current);
-g_free(mis_current);
-mis_current = NULL;
+struct MigrationIncomingState *mis = migration_incoming_get_current();
+
+qemu_event_destroy(>main_thread_load_event);
+loadvm_free_handlers(mis);
 }


@@ -382,11 +378,11 @@ static void process_incoming_migration_bh(void *opaque)
 static void process_incoming_migration_co(void *opaque)
 {
 QEMUFile *f = opaque;
-MigrationIncomingState *mis;
+MigrationIncomingState *mis = migration_incoming_get_current();
 PostcopyState ps;
 int ret;

-mis = migration_incoming_state_new(f);
+mis->from_src_file = f;
 postcopy_state_set(POSTCOPY_INCOMING_NONE);
 migrate_set_state(>state, MIGRATION_STATUS_NONE,
   MIGRATION_STATUS_ACTIVE);
diff --git a/migration/savevm.c b/migration/savevm.c
index 0363372..d44a38c 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -2159,7 +2159,6 @@ void qmp_xen_load_devices_state(const char *filename, 
Error **errp)
 qio_channel_set_name(QIO_CHANNEL(ioc), "migration-xen-load-state");
 f = qemu_fopen_channel_input(QIO_CHANNEL(ioc));

-migration_incoming_state_new(f);
 ret = qemu_loadvm_state(f);
 qemu_fclose(f);
 if (ret < 0) {
@@ -2175,6 +2174,7 @@ int load_vmstate(const char *name)
 QEMUFile *f;
 int ret;
 AioContext *aio_context;
+MigrationIncomingState *mis = migration_incoming_get_current();

 if (!bdrv_all_can_snapshot()) {
 error_report("Device '%s' is writable but does not support snapshots.",
@@ -2225,7 +2225,7 @@ int load_vmstate(const char *name)
 }

 qemu_system_reset(VMRESET_SILENT);
-migration_incoming_state_new(f);
+mis->from_src_file = f;

 aio_context_acquire(aio_context);
 ret = qemu_loadvm_state(f);
-- 
2.7.4




[Qemu-devel] QEMU postcopy-test failing on ppc64

2016-11-14 Thread Stefan Hajnoczi
I hit a failure running "make check" on ppc64 for the first time.  Ideas?

Stefan

commit 682df581c65ed2c1b9e77093e332214ecaa1ee93

  GTESTER check-qtest-ppc64
Memory content inconsistency at 5af4000 first_byte = 1b last_byte = 1a
current = 7c hit_edge = 1
Memory content inconsistency at 5af5000 first_byte = 1b last_byte = 7c
current = 1b hit_edge = 1
Memory content inconsistency at 5e59000 first_byte = 1b last_byte = 1b
current = 1a hit_edge = 1
**
ERROR:tests/postcopy-test.c:345:check_guests_ram: 'bad' should be FALSE
GTester: last random seed: R02S9d79166a1ca7e21940a0f4b0b1255d5b



Re: [Qemu-devel] [RFC 0/3] aio: experimental virtio-blk polling mode

2016-11-14 Thread Paolo Bonzini


On 14/11/2016 21:12, Karl Rister wrote:
>  25646,929
>  51235,627
>1,02446,477
>2,00035,247
>2,04846,322
>4,00046,540
>4,09646,368
>8,00047,054
>8,19246,671
>   16,00046,466
>   16,38432,504
>   32,00020,620
>   32,76820,807

Huh, it breaks down exactly when it should start going faster
(10^9/46000 = ~21000).

Paolo



Re: [Qemu-devel] [PATCH 4/4] q35: introduce q35-lite

2016-11-14 Thread Michael S. Tsirkin
On Mon, Nov 14, 2016 at 04:06:02PM +0800, Chao Peng wrote:
> On Mon, 2016-11-07 at 18:09 +0100, Paolo Bonzini wrote:
> > 
> > On 06/11/2016 08:06, Michael S. Tsirkin wrote:
> > > 
> > > On Sat, Nov 05, 2016 at 03:19:51AM -0400, Chao Peng wrote:
> > > > 
> > > > > 
> > > > > This patch introduces a light weight machine type which shares
> > > > > the
> > > > > same codebase with existing q35 machine type but with some
> > > > > features
> > > > > disabled by default.
> > > > > 
> > > > > Signed-off-by: Chao Peng 
> > > I don't find this too useful, but if others do and send acks, I'll
> > > merge
> > > it, but only if it also has migration disabled.
> > > 
> > 
> > Agreed, it's enough to have patches 1-3.
> > 
> 
> I'm fine.

Pls post just the correct patches after the release.




Re: [Qemu-devel] [PATCH for-2.8 0/2] pc: remove redundant fw_cfg file "etc/boot-cpus"

2016-11-14 Thread Michael S. Tsirkin
On Fri, Nov 11, 2016 at 04:21:10PM +0100, Igor Mammedov wrote:
> 
> Commit 080ac219cc7d9c55adf925c3545b7450055ad625
>pc: Add 'etc/boot-cpus' fw_cfg file for machine with more than 255 CPUs
> 
> added "etc/boot-cpus" fw_cfg file durung 2.8 merge window, however
> QEMU alredy had similar legacy FW_CFG_NB_CPUS fw_cfg entry that
> should do practically the same. Considering FW_CFG_NB_CPUS's been
> around for a long time and is used by external projects (firmwares)
> we can't replace it with 'etc/boot-cpus' fw_cfg file.
> 
> Drop redundant 'etc/boot-cpus' fw_cfg file  and reuse FW_CFG_NB_CPUS
> instead.
> 
> So here goes QEMU part of fixup

I agree we shouldn't commit to a bad host/guest API
but I think we need to format it differently.
First revert the boot-cpus patch for 2.8.
On top of that, add a patch fixing FW_CFG_NB_CPUS.


> CC: Eduardo Habkost 
> CC: m...@redhat.com
> CC: Stefan Hajnoczi 
> CC: "Kevin O'Connor" 
> CC: Gerd Hoffmann 
> CC: Laszlo Ersek 
> 
> Igor Mammedov (2):
>   fw_cfg: move FW_CFG_NB_CPUS out of fw_cfg_init1()
>   pc: drop "etc/boot-cpus" fw_cfg file and use FW_CFG_NB_CPUS instead
> 
>  include/hw/i386/pc.h  |  4 ++--
>  hw/arm/virt.c |  4 +++-
>  hw/i386/pc.c  | 20 
>  hw/nvram/fw_cfg.c |  1 -
>  hw/ppc/mac_newworld.c |  1 +
>  hw/ppc/mac_oldworld.c |  1 +
>  hw/sparc/sun4m.c  |  1 +
>  hw/sparc64/sun4u.c|  1 +
>  8 files changed, 17 insertions(+), 16 deletions(-)
> 
> -- 
> 2.7.4



Re: [Qemu-devel] [PULL] slirp: Fix access to freed memory

2016-11-14 Thread no-reply
Hi,

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

Type: series
Subject: [Qemu-devel] [PULL] slirp: Fix access to freed memory
Message-id: 20161114202030.17685-2-samuel.thiba...@ens-lyon.org

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

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

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

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/20161114202030.17685-2-samuel.thiba...@ens-lyon.org -> 
patchew/20161114202030.17685-2-samuel.thiba...@ens-lyon.org
Switched to a new branch 'test'
438b2d1 slirp: Fix access to freed memory

=== OUTPUT BEGIN ===
Checking PATCH 1/1: slirp: Fix access to freed memory...
ERROR: suspect code indent for conditional statements (4, 6)
#30: FILE: slirp/socket.c:74:
+if (ifm->ifq_so == so) {
+  ifm->ifq_so = NULL;

ERROR: suspect code indent for conditional statements (4, 6)
#38: FILE: slirp/socket.c:82:
+if (ifm->ifq_so == so) {
+  ifm->ifq_so = NULL;

total: 2 errors, 0 warnings, 23 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...@freelists.org

  1   2   3   >