[Qemu-devel] [PATCH 1/2] virtio-balloon: export all balloon statistics

2016-02-19 Thread Denis V. Lunev
From: Igor Redko 

We are making experiments with different autoballooning strategies
based on the guest behavior. Thus we need to experiment with different
guest statistics. For now every counter change requires QEMU recompilation
and dances with Libvirt.

This patch introduces transport for unrecognized counters in virtio-balloon.
This transport can be used for measuring benefits from using new
balloon counters, before submitting any patches. Current alternative
is 'guest-exec' transport which isn't made for such delicate matters
and can influence test results.

Originally all counters with tag >= VIRTIO_BALLOON_S_NR were ignored.
Instead of this we keep first (VIRTIO_BALLOON_S_NR + 32) counters from the
queue and pass unrecognized ones with the following names: 'x-stat-',
where  is a tag number in hex. Defined counters are reported with their
regular names.

Signed-off-by: Igor Redko 
Signed-off-by: Denis V. Lunev 
CC: Michael S. Tsirkin 
---
 hw/virtio/virtio-balloon.c | 30 --
 include/hw/virtio/virtio-balloon.h |  3 ++-
 2 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index a382f43..cc551a3 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -66,8 +66,7 @@ static const char *balloon_stat_names[] = {
  */
 static inline void reset_stats(VirtIOBalloon *dev)
 {
-int i;
-for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
+dev->stats_cnt = 0;
 }
 
 static bool balloon_stats_supported(const VirtIOBalloon *s)
@@ -133,12 +132,20 @@ static void balloon_stats_get_all(Object *obj, Visitor 
*v, const char *name,
 if (err) {
 goto out_end;
 }
-for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
-visit_type_uint64(v, balloon_stat_names[i], &s->stats[i], &err);
+for (i = 0; !err && i < s->stats_cnt; i++) {
+if (s->stats[i].tag < VIRTIO_BALLOON_S_NR) {
+visit_type_uint64(v, balloon_stat_names[s->stats[i].tag],
+  &s->stats[i].val, &err);
+} else {
+gchar *str = g_strdup_printf("x-stat-%04x", s->stats[i].tag);
+visit_type_uint64(v, str, &s->stats[i].val, &err);
+g_free(str);
+}
 if (err) {
 break;
 }
 }
+
 error_propagate(errp, err);
 err = NULL;
 visit_end_struct(v, &err);
@@ -273,10 +280,21 @@ static void virtio_balloon_receive_stats(VirtIODevice 
*vdev, VirtQueue *vq)
== sizeof(stat)) {
 uint16_t tag = virtio_tswap16(vdev, stat.tag);
 uint64_t val = virtio_tswap64(vdev, stat.val);
+int i;
 
 offset += sizeof(stat);
-if (tag < VIRTIO_BALLOON_S_NR)
-s->stats[tag] = val;
+for (i = 0; i < s->stats_cnt; i++) {
+if (s->stats[i].tag == tag) {
+break;
+}
+}
+if (i < ARRAY_SIZE(s->stats)) {
+s->stats[i].tag = tag;
+s->stats[i].val = val;
+if (s->stats_cnt <= i) {
+s->stats_cnt = i + 1;
+}
+}
 }
 s->stats_vq_offset = offset;
 
diff --git a/include/hw/virtio/virtio-balloon.h 
b/include/hw/virtio/virtio-balloon.h
index 35f62ac..5c8730e 100644
--- a/include/hw/virtio/virtio-balloon.h
+++ b/include/hw/virtio/virtio-balloon.h
@@ -36,7 +36,8 @@ typedef struct VirtIOBalloon {
 VirtQueue *ivq, *dvq, *svq;
 uint32_t num_pages;
 uint32_t actual;
-uint64_t stats[VIRTIO_BALLOON_S_NR];
+VirtIOBalloonStatModern stats[VIRTIO_BALLOON_S_NR + 32];
+uint16_t stats_cnt;
 VirtQueueElement *stats_vq_elem;
 size_t stats_vq_offset;
 QEMUTimer *stats_timer;
-- 
2.1.4




[Qemu-devel] [PATCH 0/2] virtio-balloon: improve balloon statistics

2016-02-19 Thread Denis V. Lunev
New counter from the Linux kernel + generic framework to pass currently
unknown counters via QMP for debug purposes.

Signed-off-by: Denis V. Lunev 
CC: Igor Redko 
CC: Michael S. Tsirkin 




[Qemu-devel] [PATCH 2/2] virtio-balloon: add 'available' counter

2016-02-19 Thread Denis V. Lunev
The patch for the kernel part is in linux-next already:
commit ac88e7c908b920866e529862f2b2f0129b254ab2
Author: Igor Redko 
Date:   Thu Feb 18 09:23:01 2016 +1100

virtio_balloon: export 'available' memory to balloon statistics

Add a new field, VIRTIO_BALLOON_S_AVAIL, to virtio_balloon memory
statistics protocol, corresponding to 'Available' in /proc/meminfo.

Signed-off-by: Denis V. Lunev 
CC: Igor Redko 
CC: Michael S. Tsirkin 
---
 hw/virtio/virtio-balloon.c  | 1 +
 include/standard-headers/linux/virtio_balloon.h | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index cc551a3..b052dfb 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -53,6 +53,7 @@ static const char *balloon_stat_names[] = {
[VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
[VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
[VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
+   [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
[VIRTIO_BALLOON_S_NR] = NULL
 };
 
diff --git a/include/standard-headers/linux/virtio_balloon.h 
b/include/standard-headers/linux/virtio_balloon.h
index 2e2a6dc..0df7c2e 100644
--- a/include/standard-headers/linux/virtio_balloon.h
+++ b/include/standard-headers/linux/virtio_balloon.h
@@ -51,7 +51,8 @@ struct virtio_balloon_config {
 #define VIRTIO_BALLOON_S_MINFLT   3   /* Number of minor faults */
 #define VIRTIO_BALLOON_S_MEMFREE  4   /* Total amount of free memory */
 #define VIRTIO_BALLOON_S_MEMTOT   5   /* Total amount of memory */
-#define VIRTIO_BALLOON_S_NR   6
+#define VIRTIO_BALLOON_S_AVAIL6   /* Amount of available memory in guest */
+#define VIRTIO_BALLOON_S_NR   7
 
 /*
  * Memory statistics structure.
-- 
2.1.4




Re: [Qemu-devel] [PATCH 3/3] replay: introduce block devices record/replay

2016-02-19 Thread Pavel Dovgalyuk
> From: Pavel Dovgalyuk [mailto:dovga...@ispras.ru]
> > From: Kevin Wolf [mailto:kw...@redhat.com]
> > Am 16.02.2016 um 12:20 hat Pavel Dovgalyuk geschrieben:
> > > Coroutine Replay
> > > bool *done = req_replayed_list_get(reqid) // NULL
> > >   co =
> > req_completed_list_get(e.reqid); // NULL
> >
> > There was no yield, this context switch is impossible to happen. Same
> > for the switch back.
> >
> > > req_completed_list_insert(reqid, qemu_coroutine_self());
> > > qemu_coroutine_yield();
> >
> > This is the point at which a context switch happens. The only other
> > point in my code is the qemu_coroutine_enter() in the other function.
> 
> I've fixed aio_poll problem by disabling mutex lock for the 
> replay_run_block_event()
> execution. Now virtual machine deterministically runs 4e8 instructions of 
> Windows XP booting.
> 
> But then one non-deterministic event happens.
> Callback after finishing coroutine may be called from different contexts.
> apic_update_irq() function behaves differently being called from vcpu and io 
> threads.
> In one case it sets CPU_INTERRUPT_POLL and in other - nothing happens.

Kevin, do you have some ideas how to fix this issue?
This happens because of coroutines may be assigned to different threads.
Maybe there is some way of making this assignment more deterministic?

> Therefore execution becomes non-deterministic.
> In previous version of the patch I solved this problem by linking block 
> events to the
> execution checkpoints. IO thread have its own checkpoints and vcpu - its own.
> Therefore apic callbacks are always called from the same thread in replay as 
> in recording
> phase.

Pavel Dovgalyuk




[Qemu-devel] [PATCH 1/3] exec: store RAMBlock pointer into memory region

2016-02-19 Thread Gonglei
Each RAM memory region has a unique corresponding RAMBlock.
In the current realization, the memory region only stored
the ram_addr which means the offset of RAM address space,
We need to qurey the global ram.list to find the ram block
by ram_addr if we want to get the ram block, which is very
expensive.

Now, we store the RAMBlock pointer into memory region
structure. So, if we know the mr, we can easily get the
RAMBlock.

Signed-off-by: Gonglei 
---
 exec.c| 2 ++
 include/exec/memory.h | 1 +
 memory.c  | 1 +
 3 files changed, 4 insertions(+)

diff --git a/exec.c b/exec.c
index 1f24500..e29e369 100644
--- a/exec.c
+++ b/exec.c
@@ -1717,6 +1717,8 @@ ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, 
ram_addr_t max_size,
 error_propagate(errp, local_err);
 return -1;
 }
+/* store the ram block pointer into memroy region */
+mr->ram_block = new_block;
 return addr;
 }
 
diff --git a/include/exec/memory.h b/include/exec/memory.h
index c92734a..23e2e3e 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -172,6 +172,7 @@ struct MemoryRegion {
 bool global_locking;
 uint8_t dirty_log_mask;
 ram_addr_t ram_addr;
+void *ram_block;   /* RAMBlock pointer */
 Object *owner;
 const MemoryRegionIOMMUOps *iommu_ops;
 
diff --git a/memory.c b/memory.c
index 09041ed..b4451dd 100644
--- a/memory.c
+++ b/memory.c
@@ -912,6 +912,7 @@ void memory_region_init(MemoryRegion *mr,
 }
 mr->name = g_strdup(name);
 mr->owner = owner;
+mr->ram_block = NULL;
 
 if (name) {
 char *escaped_name = memory_region_escape_name(name);
-- 
1.8.5.2





[Qemu-devel] [PATCH 0/3] memory: an optimization

2016-02-19 Thread Gonglei
Perf top tells me qemu_get_ram_ptr consume too much cpu cycles.
> 22.56%  qemu-kvm [.] address_space_translate
>  13.29%  qemu-kvm [.] qemu_get_ram_ptr
>   4.71%  qemu-kvm [.] phys_page_find
>   4.43%  qemu-kvm [.] address_space_translate_internal
>   3.47%  libpthread-2.19.so   [.] __pthread_mutex_unlock_usercnt
>   3.08%  qemu-kvm [.] qemu_ram_addr_from_host
>   2.62%  qemu-kvm [.] address_space_map
>   2.61%  libc-2.19.so [.] _int_malloc
>   2.58%  libc-2.19.so [.] _int_free
>   2.38%  libc-2.19.so [.] malloc
>   2.06%  libpthread-2.19.so   [.] pthread_mutex_lock
>   1.68%  libc-2.19.so [.] malloc_consolidate
>   1.35%  libc-2.19.so [.] __memcpy_sse2_unaligned
>   1.23%  qemu-kvm [.] lduw_le_phys
>   1.18%  qemu-kvm [.] find_next_zero_bit
>   1.02%  qemu-kvm [.] object_unref

And Paolo suggested that we can get rid of qemu_get_ram_ptr
by storing the RAMBlock pointer into the memory region,
instead of the ram_addr_t value. And after appling this change,
I got much better performance indeed.

BTW, PATCH 3 is an occasional find.

Gonglei (3):
  exec: store RAMBlock pointer into memory region
  memory: optimize qemu_get_ram_ptr and qemu_ram_ptr_length
  memory: Remove the superfluous code

 exec.c| 48 ++--
 include/exec/memory.h |  7 +++
 memory.c  |  3 ++-
 3 files changed, 35 insertions(+), 23 deletions(-)

-- 
1.8.5.2





[Qemu-devel] [PATCH 2/3] memory: optimize qemu_get_ram_ptr and qemu_ram_ptr_length

2016-02-19 Thread Gonglei
these two functions consume too much cpu overhead to
find the RAMBlock by ram address.

After this patch, we can pass the RAMBlock pointer
to them so that they don't need to find the RAMBlock
anymore most of the time. We can get better performance
in address translation processing.

Signed-off-by: Gonglei 
---
 exec.c| 46 --
 include/exec/memory.h |  4 ++--
 memory.c  |  2 +-
 3 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/exec.c b/exec.c
index e29e369..f714238 100644
--- a/exec.c
+++ b/exec.c
@@ -1868,9 +1868,13 @@ void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
  *
  * Called within RCU critical section.
  */
-void *qemu_get_ram_ptr(ram_addr_t addr)
+void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
 {
-RAMBlock *block = qemu_get_ram_block(addr);
+RAMBlock *block = ram_block;
+
+if (block == NULL) {
+block = qemu_get_ram_block(addr);
+}
 
 if (xen_enabled() && block->host == NULL) {
 /* We need to check if the requested address is in the RAM
@@ -1891,15 +1895,18 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
  *
  * Called within RCU critical section.
  */
-static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
+static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
+ hwaddr *size)
 {
-RAMBlock *block;
+RAMBlock *block = ram_block;
 ram_addr_t offset_inside_block;
 if (*size == 0) {
 return NULL;
 }
 
-block = qemu_get_ram_block(addr);
+if (block == NULL) {
+block = qemu_get_ram_block(addr);
+}
 offset_inside_block = addr - block->offset;
 *size = MIN(*size, block->max_length - offset_inside_block);
 
@@ -2027,13 +2034,13 @@ static void notdirty_mem_write(void *opaque, hwaddr 
ram_addr,
 }
 switch (size) {
 case 1:
-stb_p(qemu_get_ram_ptr(ram_addr), val);
+stb_p(qemu_get_ram_ptr(NULL, ram_addr), val);
 break;
 case 2:
-stw_p(qemu_get_ram_ptr(ram_addr), val);
+stw_p(qemu_get_ram_ptr(NULL, ram_addr), val);
 break;
 case 4:
-stl_p(qemu_get_ram_ptr(ram_addr), val);
+stl_p(qemu_get_ram_ptr(NULL, ram_addr), val);
 break;
 default:
 abort();
@@ -2609,7 +2616,7 @@ static MemTxResult 
address_space_write_continue(AddressSpace *as, hwaddr addr,
 } else {
 addr1 += memory_region_get_ram_addr(mr);
 /* RAM case */
-ptr = qemu_get_ram_ptr(addr1);
+ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
 memcpy(ptr, buf, l);
 invalidate_and_set_dirty(mr, addr1, l);
 }
@@ -2700,7 +2707,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, 
hwaddr addr,
 }
 } else {
 /* RAM case */
-ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
+ptr = qemu_get_ram_ptr(mr->ram_block, mr->ram_addr + addr1);
 memcpy(buf, ptr, l);
 }
 
@@ -2785,7 +2792,7 @@ static inline void 
cpu_physical_memory_write_rom_internal(AddressSpace *as,
 } else {
 addr1 += memory_region_get_ram_addr(mr);
 /* ROM/RAM case */
-ptr = qemu_get_ram_ptr(addr1);
+ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
 switch (type) {
 case WRITE_DATA:
 memcpy(ptr, buf, l);
@@ -2997,7 +3004,7 @@ void *address_space_map(AddressSpace *as,
 
 memory_region_ref(mr);
 *plen = done;
-ptr = qemu_ram_ptr_length(raddr + base, plen);
+ptr = qemu_ram_ptr_length(mr->ram_block, raddr + base, plen);
 rcu_read_unlock();
 
 return ptr;
@@ -3081,7 +3088,8 @@ static inline uint32_t 
address_space_ldl_internal(AddressSpace *as, hwaddr addr,
 #endif
 } else {
 /* RAM case */
-ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ptr = qemu_get_ram_ptr(mr->ram_block,
+   (memory_region_get_ram_addr(mr)
 & TARGET_PAGE_MASK)
+ addr1);
 switch (endian) {
@@ -3176,7 +3184,8 @@ static inline uint64_t 
address_space_ldq_internal(AddressSpace *as, hwaddr addr,
 #endif
 } else {
 /* RAM case */
-ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ptr = qemu_get_ram_ptr(mr->ram_block,
+   (memory_region_get_ram_addr(mr)
 & TARGET_PAGE_MASK)
+ addr1);
 switch (endian) {
@@ -3291,7 +3300,8 @@ static inline uint32_t 
address_space_lduw_internal(AddressSpace *as,
 #endif
 } else {
 /* RAM case */
-ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ptr = qemu_get_ram_ptr(mr->ram_block,
+   (memory_region_get_ram_addr(mr)
 & TARGET_PAGE_MASK)

[Qemu-devel] [PATCH 3/3] memory: Remove the superfluous code

2016-02-19 Thread Gonglei
Signed-off-by: Gonglei 
---
 include/exec/memory.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 227fbf4..5f96e6b 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1399,8 +1399,6 @@ static inline bool memory_access_is_direct(MemoryRegion 
*mr, bool is_write)
 } else {
 return memory_region_is_ram(mr) || memory_region_is_romd(mr);
 }
-
-return false;
 }
 
 /**
-- 
1.8.5.2





Re: [Qemu-devel] [PATCH] migration: reorder code to make it symmetric

2016-02-19 Thread Wei Yang
Hi, Amit

Do you like this one?

On Thu, Feb 04, 2016 at 10:50:30PM +, Wei Yang wrote:
>In qemu_savevm_state_complete_precopy(), it iterates on each device to add
>a json object and transfer related status to destination, while the order
>of the last two steps could be refined.
>
>Current order:
>
>json_start_object()
>   save_section_header()
>   vmstate_save()
>json_end_object()
>   save_section_footer()
>
>After the change:
>
>json_start_object()
>   save_section_header()
>   vmstate_save()
>   save_section_footer()
>json_end_object()
>
>This patch reorder the code to to make it symmetric. No functional change.
>
>Signed-off-by: Wei Yang 
>---
> migration/savevm.c |5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
>diff --git a/migration/savevm.c b/migration/savevm.c
>index b9caf59..42bfab4 100644
>--- a/migration/savevm.c
>+++ b/migration/savevm.c
>@@ -1088,12 +1088,11 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, 
>bool iterable_only)
> json_prop_int(vmdesc, "instance_id", se->instance_id);
> 
> save_section_header(f, se, QEMU_VM_SECTION_FULL);
>-
> vmstate_save(f, se, vmdesc);
>-
>-json_end_object(vmdesc);
> trace_savevm_section_end(se->idstr, se->section_id, 0);
> save_section_footer(f, se);
>+
>+json_end_object(vmdesc);
> }
> 
> if (!in_postcopy) {
>-- 
>1.7.9.5

-- 
Wei Yang
Help you, Help me



[Qemu-devel] [PATCH 12/17] qapi: Don't special-case simple union wrappers

2016-02-19 Thread Eric Blake
Simple unions were carrying a special case that hid their 'data'
QMP member from the resulting C struct, via the hack method
QAPISchemaObjectTypeVariant.simple_union_type().  But using the
work we started by unboxing flat union and alternate branches, we
expose the simple union's implicit type in qapi-types.h as an
anonymous type, and drop our last use of the hack.

| struct ImageInfoSpecific {
| ImageInfoSpecificKind type;
| union { /* union tag is @type */
| void *data;
|-ImageInfoSpecificQCow2 *qcow2;
|-ImageInfoSpecificVmdk *vmdk;
|+struct {
|+ImageInfoSpecificQCow2 *data;
|+} qcow2;
|+struct {
|+ImageInfoSpecificVmdk *data;
|+} vmdk;
| } u;
| };

All clients of simple unions have to adjust from using su->u.member
to now using su->u.member.data; while this touches a number of
files in the tree, some earlier cleanup patches helped minimize
the change to the initialization of a temporary variable rather
than every single field access.  The generated qapi-visit.c code
is included in the files affected by the layout change, with a
diff that looks like:

|@@ -4510,10 +4567,16 @@ static void visit_type_ImageInfoSpecific
| }
| switch (obj->type) {
| case IMAGE_INFO_SPECIFIC_KIND_QCOW2:
|-visit_type_ImageInfoSpecificQCow2(v, "data", &obj->u.qcow2, &err);
|+visit_type_ImageInfoSpecificQCow2(v, "data", &obj->u.qcow2.data, 
&err);
|+if (err) {
|+goto out;
|+}
| break;
| case IMAGE_INFO_SPECIFIC_KIND_VMDK:
|-visit_type_ImageInfoSpecificVmdk(v, "data", &obj->u.vmdk, &err);
|+visit_type_ImageInfoSpecificVmdk(v, "data", &obj->u.vmdk.data, &err);
|+if (err) {
|+goto out;
|+}
| break;
| default:
| abort();
| }
|
| out:
| error_propagate(errp, err);

The added error checks there are a side effect of visiting all
fields of each implicit struct (there is only one such field for
simple unions); but do not change semantics, and will be important
when later patches allow for flat unions with anonymous branches
with more than one field.  That future work will look like:
{ 'union': 'Foo', 'base': 'Base', 'discriminator': 'type',
  'data': { 'branch1': { 'anonymous': 'str', 'number': 'int' },
'branch2': 'Named' } }

Signed-off-by: Eric Blake 
---
 scripts/qapi.py | 10 -
 scripts/qapi-types.py   | 22 ---
 scripts/qapi-visit.py   | 15 +++-
 backends/baum.c |  2 +-
 backends/msmouse.c  |  2 +-
 block/nbd.c |  6 +--
 block/qcow2.c   |  6 +--
 block/vmdk.c|  8 ++--
 blockdev.c  | 24 ++--
 hmp.c   |  8 ++--
 hw/char/escc.c  |  2 +-
 hw/input/hid.c  |  8 ++--
 hw/input/ps2.c  |  6 +--
 hw/input/virtio-input-hid.c |  8 ++--
 hw/mem/pc-dimm.c|  4 +-
 net/dump.c  |  2 +-
 net/hub.c   |  2 +-
 net/l2tpv3.c|  2 +-
 net/net.c   |  4 +-
 net/netmap.c|  2 +-
 net/slirp.c |  2 +-
 net/socket.c|  2 +-
 net/tap.c   |  4 +-
 net/vhost-user.c|  2 +-
 numa.c  |  4 +-
 qemu-char.c | 82 +
 qemu-nbd.c  |  6 +--
 replay/replay-input.c   | 44 +++---
 spice-qemu-char.c   | 14 ---
 tests/test-io-channel-socket.c  | 40 ++--
 tests/test-qmp-commands.c   |  2 +-
 tests/test-qmp-input-visitor.c  | 25 +++--
 tests/test-qmp-output-visitor.c | 24 ++--
 tpm.c   |  2 +-
 ui/console.c|  4 +-
 ui/input-keymap.c   | 10 ++---
 ui/input-legacy.c   |  8 ++--
 ui/input.c  | 34 -
 ui/vnc-auth-sasl.c  |  3 +-
 ui/vnc.c| 29 ---
 util/qemu-sockets.c | 35 +-
 41 files changed, 262 insertions(+), 257 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 8a4f952..1dc8801 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1115,16 +1115,6 @@ class 
QAPISchemaObjectTypeVariant(QAPISchemaObjectTypeMember):
 def __init__(self, name, typ):
 QAPISchemaObjectTypeMember.__init__(self, name, typ, False)

-# This function exists to support ugly simple union special cases
-# TODO get rid of them, and drop the function
-def simple_union_type(self):
-if (self.type.is_implicit() and
-isinstance(self.type, QAPISchemaObjectType)):
-assert len(self.type.members) == 1
-assert not self.type.variant

[Qemu-devel] [PATCH 14/17] qapi: Allow anonymous base for flat union

2016-02-19 Thread Eric Blake
Rather than requiring all flat unions to explicitly create
a separate base struct, we can allow the qapi schema to specify
the common fields via an inline dictionary. This is similar to
how commands can specify an inline anonymous type for its 'data',
and matches the fact that our code base already has several
flat unions that had to create a separate base type that is used
nowhere but in the union.

The patch also has to tweak things to avoid calling base.c_name()
on an implicit type (since implicit types do not have a name);
we already have qapi_FOO_base() which does the trick nicely.

Now that anonymous bases are legal, we need to rework the
flat-union-bad-base negative test (as previously written, it
forms what is now valid QAPI; tweak it to now provide coverage
of a new error message path), and add a positive test in
qapi-schema-test to use an anonymous base.

Note that this patch only allows anonymous bases for flat
unions; simple unions are enough syntactic sugar that we do
not want to burden them further.  Meanwhile, it would be easy
to modify qapi.py to also allow an anonymous base for structs;
however, there is less of a compelling technical reason to
do so, since you can always write the struct to directly
contain any members that the anonymous base would have
mentioned.

Signed-off-by: Eric Blake 

---
v1: rebase and rework to use gen_visit_fields_call(), test new error
Previously posted as part of qapi cleanup subset F:
v6: avoid redundant error check in gen_visit_union(), rebase to
earlier gen_err_check() improvements
---
 scripts/qapi.py| 11 +--
 scripts/qapi-types.py  | 12 +++-
 scripts/qapi-visit.py  |  6 +++---
 docs/qapi-code-gen.txt | 28 ++--
 tests/qapi-schema/flat-union-bad-base.err  |  2 +-
 tests/qapi-schema/flat-union-bad-base.json |  5 ++---
 tests/qapi-schema/qapi-schema-test.json|  6 +-
 tests/qapi-schema/qapi-schema-test.out |  9 -
 8 files changed, 41 insertions(+), 38 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 1dc8801..b8366e8 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -329,6 +329,8 @@ class QAPISchemaParser(object):


 def find_base_fields(base):
+if isinstance(base, dict):
+return base
 base_struct_define = find_struct(base)
 if not base_struct_define:
 return None
@@ -562,9 +564,9 @@ def check_union(expr, expr_info):

 # Else, it's a flat union.
 else:
-# The object must have a string member 'base'.
+# The object must have a string or dictionary 'base'.
 check_type(expr_info, "'base' for union '%s'" % name,
-   base, allow_metas=['struct'])
+   base, allow_dict=True, allow_metas=['struct'])
 if not base:
 raise QAPIExprError(expr_info,
 "Flat union '%s' must have a base"
@@ -1039,6 +1041,8 @@ class QAPISchemaMember(object):
 owner = owner[5:]
 if owner.endswith('-arg'):
 return '(parameter of %s)' % owner[:-4]
+elif owner.endswith('-base'):
+return '(base of %s)' % owner[:-5]
 else:
 assert owner.endswith('-wrapper')
 # Unreachable and not implemented
@@ -1323,6 +1327,9 @@ class QAPISchema(object):
 base = expr.get('base')
 tag_name = expr.get('discriminator')
 tag_member = None
+if isinstance(base, dict):
+base = (self._make_implicit_object_type(
+name, info, 'base', self._make_members(base, info)))
 if tag_name:
 variants = [self._make_variant(key, value)
 for (key, value) in data.iteritems()]
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 36ff770..5e07c22 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -72,13 +72,15 @@ struct %(c_name)s {
 ''',
  c_name=c_name(name))

-if base:
-ret += mcgen('''
+if base and not base.is_empty():
+if not base.is_implicit():
+ret += mcgen('''
 /* Members inherited from %(c_name)s: */
 ''',
- c_name=base.c_name())
+ c_name=base.c_name())
 ret += gen_struct_fields(base.members)
-ret += mcgen('''
+if not base.is_implicit():
+ret += mcgen('''
 /* Own members: */
 ''')
 ret += gen_struct_fields(members)
@@ -238,7 +240,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 def visit_object_type(self, name, info, base, members, variants):
 self._fwdecl += gen_fwd_object_or_array(name)
 self.decl += gen_object(name, base, members, variants)
-if base:
+if base and not base.is_implicit():
 self.decl += gen_upcast(name, base)
 self._gen_type_cleanup(name)

diff --git a/scripts/qa

[Qemu-devel] [PATCH 17/17] qapi: Make c_type() more OO-like

2016-02-19 Thread Eric Blake
QAPISchemaType.c_type() was a bit awkward.  Rather than having two
optional orthogonal boolean flags that should never both be true,
and where all callers pass a compile-time constant, provide three
different method names that can be overridden as needed, and where
the caller just uses the right variant.  It requires slightly more
Python, but is arguably easier to read.

Suggested-by: Markus Armbruster 
Signed-off-by: Eric Blake 
---
 scripts/qapi.py   | 38 +-
 scripts/qapi-types.py |  2 +-
 2 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index c5c4bcb..c15aa4a 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -826,8 +826,17 @@ class QAPISchemaVisitor(object):


 class QAPISchemaType(QAPISchemaEntity):
-def c_type(self, is_param=False, is_unboxed=False):
-return c_name(self.name) + pointer_suffix
+# Normal usage of the type, such as declaring a local variable
+def c_type(self):
+pass
+
+# Use of a type in a parameter list
+def c_param_type(self):
+return self.c_type()
+
+# Use of a type in a struct declaration
+def c_unboxed_type(self):
+return self.c_type()

 def c_null(self):
 return 'NULL'
@@ -859,8 +868,11 @@ class QAPISchemaBuiltinType(QAPISchemaType):
 def c_name(self):
 return self.name

-def c_type(self, is_param=False, is_unboxed=False):
-if is_param and self.name == 'str':
+def c_type(self):
+return self._c_type_name
+
+def c_param_type(self):
+if self.name == 'str':
 return 'const ' + self._c_type_name
 return self._c_type_name

@@ -893,7 +905,7 @@ class QAPISchemaEnumType(QAPISchemaType):
 # See QAPISchema._make_implicit_enum_type()
 return self.name.endswith('Kind')

-def c_type(self, is_param=False, is_unboxed=False):
+def c_type(self):
 return c_name(self.name)

 def member_names(self):
@@ -925,6 +937,9 @@ class QAPISchemaArrayType(QAPISchemaType):
 def is_implicit(self):
 return True

+def c_type(self):
+return c_name(self.name) + pointer_suffix
+
 def json_type(self):
 return 'array'

@@ -994,12 +1009,14 @@ class QAPISchemaObjectType(QAPISchemaType):
 assert not self.is_implicit()
 return QAPISchemaType.c_name(self)

-def c_type(self, is_param=False, is_unboxed=False):
+def c_type(self):
 assert not self.is_implicit()
-if is_unboxed:
-return c_name(self.name)
 return c_name(self.name) + pointer_suffix

+def c_unboxed_type(self):
+assert not self.is_implicit()
+return c_name(self.name)
+
 def json_type(self):
 return 'object'

@@ -1140,6 +1157,9 @@ class QAPISchemaAlternateType(QAPISchemaType):
 for v in self.variants.variants:
 v.check_clash(self.info, seen)

+def c_type(self):
+return c_name(self.name) + pointer_suffix
+
 def json_type(self):
 return 'value'

@@ -1634,7 +1654,7 @@ def gen_params(arg_type, extra):
 sep = ', '
 if memb.optional:
 ret += 'bool has_%s, ' % c_name(memb.name)
-ret += '%s %s' % (memb.type.c_type(is_param=True), c_name(memb.name))
+ret += '%s %s' % (memb.type.c_param_type(), c_name(memb.name))
 if extra:
 ret += sep + extra
 return ret
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5e07c22..7d4bfaf 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -140,7 +140,7 @@ def gen_variants(variants):
 ret += mcgen('''
 %(c_type)s %(c_name)s;
 ''',
- c_type=var.type.c_type(is_unboxed=True),
+ c_type=var.type.c_unboxed_type(),
  c_name=c_name(var.name))

 ret += mcgen('''
-- 
2.5.0




[Qemu-devel] [PATCH 13/17] qapi-visit: Move error check into gen_visit_fields_call()

2016-02-19 Thread Eric Blake
When first introduced, neither branch of gen_visit_fields_call()
would output a goto.  But now that the implicit struct visit
always ends with a goto, we should do the same for regular
struct visits, so that callers don't have to worry about whether
they are creating two identical goto's in a row.

Generated code gets slightly larger; if desired, we could patch
qapi.py:gen_visit_fields() to have a mode where it skips the
final goto and leave it up to the callers when to use that mode,
but that adds more maintenance burden when the compiler should
be smart enough to not bloat the .o file just because the .c
file got larger.

Signed-off-by: Eric Blake 
---
 scripts/qapi-visit.py | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 3aca6a7..5d861ba 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -55,6 +55,7 @@ def gen_visit_fields_call(typ, direct_name, 
implicit_name=None):
 visit_type_%(c_type)s_fields(v, %(c_name)s, &err);
 ''',
  c_type=typ.c_name(), c_name=direct_name)
+ret += gen_err_check()
 return ret


@@ -79,7 +80,6 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s *obj, Error **er

 if base:
 ret += gen_visit_fields_call(base, '(%s *)obj' % base.c_name())
-ret += gen_err_check()

 ret += gen_visit_fields(members, prefix='obj->')

@@ -111,9 +111,9 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s *obj, Error **er
 }
 ''')

-# 'goto out' produced for base, by gen_visit_fields() for each member,
-# and if variants were present
-if base or members or variants:
+# 'goto out' produced for non-empty base, by gen_visit_fields() for
+# each member, and if variants were present
+if (base and not base.is_empty()) or members or variants:
 ret += mcgen('''

 out:
-- 
2.5.0




[Qemu-devel] [PATCH 04/17] ui: Shorten references into InputEvent

2016-02-19 Thread Eric Blake
An upcoming patch will alter how simple unions, like InputEvent,
are laid out, which will impact all lines of the form 'evt->u.XXX'.
To minimize the impact of that patch, use a temporary variable to
reduce the number of lines needing modification when an internal
reference within InputEvent changes layout.

There was one instance in hid.c:hid_pointer_event() where the code
was referring to evt->u.rel inside the case label where evt->u.abs
is the correct name; thankfully, both members of the union have the
same type, so it happened to work, but it is now cleaner.

Signed-off-by: Eric Blake 
---
 hw/char/escc.c  | 12 +-
 hw/input/hid.c  | 36 +-
 hw/input/ps2.c  | 27 ++-
 hw/input/virtio-input-hid.c | 33 ---
 replay/replay-input.c   | 31 --
 ui/input-legacy.c   | 26 +-
 ui/input.c  | 54 ++---
 7 files changed, 130 insertions(+), 89 deletions(-)

diff --git a/hw/char/escc.c b/hw/char/escc.c
index 98a1c21..c7a24ac 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -842,14 +842,16 @@ static void sunkbd_handle_event(DeviceState *dev, 
QemuConsole *src,
 {
 ChannelState *s = (ChannelState *)dev;
 int qcode, keycode;
+InputKeyEvent *key;

 assert(evt->type == INPUT_EVENT_KIND_KEY);
-qcode = qemu_input_key_value_to_qcode(evt->u.key->key);
+key = evt->u.key;
+qcode = qemu_input_key_value_to_qcode(key->key);
 trace_escc_sunkbd_event_in(qcode, QKeyCode_lookup[qcode],
-   evt->u.key->down);
+   key->down);

 if (qcode == Q_KEY_CODE_CAPS_LOCK) {
-if (evt->u.key->down) {
+if (key->down) {
 s->caps_lock_mode ^= 1;
 if (s->caps_lock_mode == 2) {
 return; /* Drop second press */
@@ -863,7 +865,7 @@ static void sunkbd_handle_event(DeviceState *dev, 
QemuConsole *src,
 }

 if (qcode == Q_KEY_CODE_NUM_LOCK) {
-if (evt->u.key->down) {
+if (key->down) {
 s->num_lock_mode ^= 1;
 if (s->num_lock_mode == 2) {
 return; /* Drop second press */
@@ -877,7 +879,7 @@ static void sunkbd_handle_event(DeviceState *dev, 
QemuConsole *src,
 }

 keycode = qcode_to_keycode[qcode];
-if (!evt->u.key->down) {
+if (!key->down) {
 keycode |= 0x80;
 }
 trace_escc_sunkbd_event_out(keycode);
diff --git a/hw/input/hid.c b/hw/input/hid.c
index b41efbb..5db4d68 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -116,37 +116,42 @@ static void hid_pointer_event(DeviceState *dev, 
QemuConsole *src,
 };
 HIDState *hs = (HIDState *)dev;
 HIDPointerEvent *e;
+InputMoveEvent *move;
+InputBtnEvent *btn;

 assert(hs->n < QUEUE_LENGTH);
 e = &hs->ptr.queue[(hs->head + hs->n) & QUEUE_MASK];

 switch (evt->type) {
 case INPUT_EVENT_KIND_REL:
-if (evt->u.rel->axis == INPUT_AXIS_X) {
-e->xdx += evt->u.rel->value;
-} else if (evt->u.rel->axis == INPUT_AXIS_Y) {
-e->ydy += evt->u.rel->value;
+move = evt->u.rel;
+if (move->axis == INPUT_AXIS_X) {
+e->xdx += move->value;
+} else if (move->axis == INPUT_AXIS_Y) {
+e->ydy += move->value;
 }
 break;

 case INPUT_EVENT_KIND_ABS:
-if (evt->u.rel->axis == INPUT_AXIS_X) {
-e->xdx = evt->u.rel->value;
-} else if (evt->u.rel->axis == INPUT_AXIS_Y) {
-e->ydy = evt->u.rel->value;
+move = evt->u.abs;
+if (move->axis == INPUT_AXIS_X) {
+e->xdx = move->value;
+} else if (move->axis == INPUT_AXIS_Y) {
+e->ydy = move->value;
 }
 break;

 case INPUT_EVENT_KIND_BTN:
-if (evt->u.btn->down) {
-e->buttons_state |= bmap[evt->u.btn->button];
-if (evt->u.btn->button == INPUT_BUTTON_WHEELUP) {
+btn = evt->u.btn;
+if (btn->down) {
+e->buttons_state |= bmap[btn->button];
+if (btn->button == INPUT_BUTTON_WHEELUP) {
 e->dz--;
-} else if (evt->u.btn->button == INPUT_BUTTON_WHEELDOWN) {
+} else if (btn->button == INPUT_BUTTON_WHEELDOWN) {
 e->dz++;
 }
 } else {
-e->buttons_state &= ~bmap[evt->u.btn->button];
+e->buttons_state &= ~bmap[btn->button];
 }
 break;

@@ -223,9 +228,10 @@ static void hid_keyboard_event(DeviceState *dev, 
QemuConsole *src,
 HIDState *hs = (HIDState *)dev;
 int scancodes[3], i, count;
 int slot;
+InputKeyEvent *key = evt->u.key;

-count = qemu_input_key_value_to_scancode(evt->u.key->key,
- evt->u.key->down,
+count = qemu_input_key_value_to_scancode(key->key,
+

[Qemu-devel] [PATCH 05/17] qapi: Avoid use of 'data' member of qapi unions

2016-02-19 Thread Eric Blake
qapi code generators currently create a 'void *data' member as
part of the anonymous union embedded in the C struct corresponding
to a qapi union.  However, directly assigning to this member of
the union feels a bit fishy, when we can directly use the rest
of the struct instead.

Signed-off-by: Eric Blake 

---
v1: no change
Previously posted as part of qapi cleanup series F:
v6: rebase to latest
---
 blockdev.c | 31 +--
 ui/input.c |  2 +-
 2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 1f73478..09b9586 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1204,15 +1204,11 @@ void hmp_commit(Monitor *mon, const QDict *qdict)
 }
 }

-static void blockdev_do_action(TransactionActionKind type, void *data,
-   Error **errp)
+static void blockdev_do_action(TransactionAction *action, Error **errp)
 {
-TransactionAction action;
 TransactionActionList list;

-action.type = type;
-action.u.data = data;
-list.value = &action;
+list.value = action;
 list.next = NULL;
 qmp_transaction(&list, false, NULL, errp);
 }
@@ -1238,8 +1234,11 @@ void qmp_blockdev_snapshot_sync(bool has_device, const 
char *device,
 .has_mode = has_mode,
 .mode = mode,
 };
-blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
-   &snapshot, errp);
+TransactionAction action = {
+.type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC,
+.u.blockdev_snapshot_sync = &snapshot,
+};
+blockdev_do_action(&action, errp);
 }

 void qmp_blockdev_snapshot(const char *node, const char *overlay,
@@ -1249,9 +1248,11 @@ void qmp_blockdev_snapshot(const char *node, const char 
*overlay,
 .node = (char *) node,
 .overlay = (char *) overlay
 };
-
-blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT,
-   &snapshot_data, errp);
+TransactionAction action = {
+.type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT,
+.u.blockdev_snapshot = &snapshot_data,
+};
+blockdev_do_action(&action, errp);
 }

 void qmp_blockdev_snapshot_internal_sync(const char *device,
@@ -1262,9 +1263,11 @@ void qmp_blockdev_snapshot_internal_sync(const char 
*device,
 .device = (char *) device,
 .name = (char *) name
 };
-
-blockdev_do_action(TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,
-   &snapshot, errp);
+TransactionAction action = {
+.type = TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_INTERNAL_SYNC,
+.u.blockdev_snapshot_internal_sync = &snapshot,
+};
+blockdev_do_action(&action, errp);
 }

 SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
diff --git a/ui/input.c b/ui/input.c
index e15c618..1e81c25 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -472,7 +472,7 @@ InputEvent *qemu_input_event_new_move(InputEventKind kind,
 InputMoveEvent *move = g_new0(InputMoveEvent, 1);

 evt->type = kind;
-evt->u.data = move;
+evt->u.rel = move; /* also would work as evt->u.abs */
 move->axis = axis;
 move->value = value;
 return evt;
-- 
2.5.0




[Qemu-devel] [PATCH 15/17] qapi: Use anonymous base in SchemaInfo

2016-02-19 Thread Eric Blake
Now that the generator supports it, we might as well use an
anonymous base rather than breaking out a single-use
SchemaInfoBase structure.

Oddly enough, this change does not affect the resulting
introspection output (because we already inline the members of
a base type into an object, and had no independent use of the
base type reachable from a command).

Signed-off-by: Eric Blake 

---
v1: no change
Previously posted as part of qapi cleanup subset F:
v6: new patch
---
 qapi/introspect.json | 12 +---
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/qapi/introspect.json b/qapi/introspect.json
index 9e9369e..3fd81fb 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -75,16 +75,6 @@
 'command', 'event' ] }

 ##
-# @SchemaInfoBase
-#
-# Members common to any @SchemaInfo.
-#
-# Since: 2.5
-##
-{ 'struct': 'SchemaInfoBase',
-  'data': { 'name': 'str', 'meta-type': 'SchemaMetaType' } }
-
-##
 # @SchemaInfo
 #
 # @name: the entity's name, inherited from @base.
@@ -103,7 +93,7 @@
 # Since: 2.5
 ##
 { 'union': 'SchemaInfo',
-  'base': 'SchemaInfoBase',
+  'base': { 'name': 'str', 'meta-type': 'SchemaMetaType' },
   'discriminator': 'meta-type',
   'data': {
   'builtin': 'SchemaInfoBuiltin',
-- 
2.5.0




[Qemu-devel] [PATCH 16/17] qapi: Use anonymous base in CpuInfo

2016-02-19 Thread Eric Blake
Now that the generator supports it, we might as well use an
anonymous base rather than breaking out a single-use CpuInfoBase
structure.

Signed-off-by: Eric Blake 

---
v1: no change
Previously posted as part of qapi cleanup subset F:
v6: new patch
---
 scripts/qapi.py  |  2 +-
 qapi-schema.json | 20 ++--
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index b8366e8..c5c4bcb 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -62,8 +62,8 @@ returns_whitelist = [
 # Whitelist of entities allowed to violate case conventions
 case_whitelist = [
 # From QMP:
+':obj-CpuInfo-base',# CPU, visible through query-cpu
 'ACPISlotType', # DIMM, visible through query-acpi-ospm-status
-'CpuInfoBase',  # CPU, visible through query-cpu
 'CpuInfoMIPS',  # PC, visible through query-cpu
 'CpuInfoTricore',   # PC, visible through query-cpu
 'InputAxis',# TODO: drop when x-input-send-event is fixed
diff --git a/qapi-schema.json b/qapi-schema.json
index f64d4ab..f02e6a1 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -753,9 +753,9 @@
   'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 'other' ] }

 ##
-# @CpuInfoBase:
+# @CpuInfo:
 #
-# Common information about a virtual CPU
+# Information about a virtual CPU
 #
 # @CPU: the index of the virtual CPU
 #
@@ -776,18 +776,10 @@
 # Notes: @halted is a transient state that changes frequently.  By the time the
 #data is sent to the client, the guest may no longer be halted.
 ##
-{ 'struct': 'CpuInfoBase',
-  'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
-   'qom_path': 'str', 'thread_id': 'int', 'arch': 'CpuInfoArch' } }
-
-##
-# @CpuInfo:
-#
-# Information about a virtual CPU
-#
-# Since: 0.14.0
-##
-{ 'union': 'CpuInfo', 'base': 'CpuInfoBase', 'discriminator': 'arch',
+{ 'union': 'CpuInfo',
+  'base': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
+   'qom_path': 'str', 'thread_id': 'int', 'arch': 'CpuInfoArch' },
+  'discriminator': 'arch',
   'data': { 'x86': 'CpuInfoX86',
 'sparc': 'CpuInfoSPARC',
 'ppc': 'CpuInfoPPC',
-- 
2.5.0




[Qemu-devel] [PATCH 11/17] qapi-visit: Simplify visit of empty branch in union

2016-02-19 Thread Eric Blake
Now that we have is_empty() and gen_visit_fields_call(), it's
fairly easy to skip the visit of a variant type that has no
members.  Only one such instance exists at the moment
(CpuInfoOther), but the idea of a union where some branches
add no fields beyond the base type is common enough that we
may add syntax for other cases, as in
  { 'union':'U', 'base':'B', 'discriminator':'D',
'data': { 'default': {}, 'extra':'Type' } }

Note that the Abort type is another example of an empty type,
but it is only used by a simple union rather than a flat
union; and with simple unions, the wrapper type providing
the 'data' QMP key is not empty.

Signed-off-by: Eric Blake 
---
 scripts/qapi-visit.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index ab773f6..127c84e0 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -44,7 +44,9 @@ static void visit_type_%(c_type)s_fields(Visitor *v, 
%(c_type)s *obj, Error **er
 def gen_visit_fields_call(typ, c_name):
 ret = ''
 assert isinstance(typ, QAPISchemaObjectType)
-if typ.is_implicit():
+if typ.is_empty():
+pass
+elif typ.is_implicit():
 # TODO ugly special case for simple union
 assert len(typ.members) == 1
 assert not typ.variants
-- 
2.5.0




[Qemu-devel] [PATCH 08/17] qapi-visit: Factor out gen_visit_fields_call()

2016-02-19 Thread Eric Blake
Upcoming patches will be adding several contexts where we want
to handle the visit of an implicit type (an anonymous base type,
or an anonymous branch of a flat union) by directly inlining
the visit of each of the implicit type's member fields. The work
is made easier by factoring out a new helper method,
gen_visit_fields_call(), so that the caller doesn't need to
care whether the type it is visiting is implicit or normal.

For now, the only implicit type we encounter are the branches
of a simple union; the initial implementation of the helper
method is hard-coded to that usage, but it gets us one step
closer to completely dropping the hack of simple_union_type().

Generated output is unchanged.

Signed-off-by: Eric Blake 
---
 scripts/qapi-visit.py | 48 ++--
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2308268..ab773f6 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -31,7 +31,7 @@ void visit_type_%(c_name)s(Visitor *v, const char *name, 
%(c_type)sobj, Error **


 def gen_visit_fields_decl(typ):
-if typ.name in struct_fields_seen:
+if typ.is_implicit() or typ.name in struct_fields_seen:
 return ''
 struct_fields_seen.add(typ.name)
 return mcgen('''
@@ -41,6 +41,25 @@ static void visit_type_%(c_type)s_fields(Visitor *v, 
%(c_type)s *obj, Error **er
  c_type=typ.c_name())


+def gen_visit_fields_call(typ, c_name):
+ret = ''
+assert isinstance(typ, QAPISchemaObjectType)
+if typ.is_implicit():
+# TODO ugly special case for simple union
+assert len(typ.members) == 1
+assert not typ.variants
+ret += mcgen('''
+visit_type_%(c_type)s(v, "data", %(c_name)s, &err);
+''',
+ c_type=typ.members[0].type.c_name(), c_name=c_name)
+else:
+ret += mcgen('''
+visit_type_%(c_type)s_fields(v, %(c_name)s, &err);
+''',
+ c_type=typ.c_name(), c_name=c_name)
+return ret
+
+
 def gen_visit_struct_fields(name, base, members, variants):
 ret = ''

@@ -48,9 +67,7 @@ def gen_visit_struct_fields(name, base, members, variants):
 ret += gen_visit_fields_decl(base)
 if variants:
 for var in variants.variants:
-# Ugly special case for simple union TODO get rid of it
-if not var.simple_union_type():
-ret += gen_visit_fields_decl(var.type)
+ret += gen_visit_fields_decl(var.type)

 struct_fields_seen.add(name)
 ret += mcgen('''
@@ -63,10 +80,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s *obj, Error **er
  c_name=c_name(name))

 if base:
-ret += mcgen('''
-visit_type_%(c_type)s_fields(v, (%(c_type)s *)obj, &err);
-''',
- c_type=base.c_name())
+ret += gen_visit_fields_call(base, '(%s *)obj' % base.c_name())
 ret += gen_err_check()

 ret += gen_visit_fields(members, prefix='obj->')
@@ -78,26 +92,16 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s *obj, Error **er
  c_name=c_name(variants.tag_member.name))

 for var in variants.variants:
-# TODO ugly special case for simple union
-simple_union_type = var.simple_union_type()
 ret += mcgen('''
 case %(case)s:
 ''',
  case=c_enum_const(variants.tag_member.type.name,
var.name,
variants.tag_member.type.prefix))
-if simple_union_type:
-ret += mcgen('''
-visit_type_%(c_type)s(v, "data", &obj->u.%(c_name)s, &err);
-''',
- c_type=simple_union_type.c_name(),
- c_name=c_name(var.name))
-else:
-ret += mcgen('''
-visit_type_%(c_type)s_fields(v, &obj->u.%(c_name)s, &err);
-''',
- c_type=var.type.c_name(),
- c_name=c_name(var.name))
+push_indent()
+ret += gen_visit_fields_call(var.type,
+ '&obj->u.' + c_name(var.name))
+pop_indent()
 ret += mcgen('''
 break;
 ''')
-- 
2.5.0




[Qemu-devel] [PATCH 10/17] qapi: Fix command with named empty argument type

2016-02-19 Thread Eric Blake
The generator special-cased

 { 'command':'foo', 'data': {} }

to avoid emitting a visitor variable, but failed to see that

 { 'struct':'NamedEmptyType, 'data': {} }
 { 'command':'foo', 'data':'NamedEmptyType' }

needs the same treatment.  There, the generator happily generates a
visitor to get no arguments, and a visitor to destroy no arguments;
and the compiler isn't happy with that, as demonstrated by the updated
qapi-schema-test.json:

  tests/test-qmp-marshal.c: In function ‘qmp_marshal_user_def_cmd0’:
  tests/test-qmp-marshal.c:264:14: error: variable ‘v’ set but not used 
[-Werror=unused-but-set-variable]
   Visitor *v;
^

No change to generated code except for the testsuite addition.

Signed-off-by: Eric Blake 
Reviewed-by: Marc-André Lureau 

---
v1: enhance commit message
Previously posted as part of qapi cleanup subset E:
v9: no change
v8: no change
v7: no change
v6: new patch
---
 scripts/qapi-commands.py| 6 +++---
 tests/test-qmp-commands.c   | 5 +
 tests/qapi-schema/qapi-schema-test.json | 2 ++
 tests/qapi-schema/qapi-schema-test.out  | 2 ++
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index f831621..854b389 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -65,7 +65,7 @@ def gen_marshal_vars(arg_type, ret_type):
 ''',
  c_type=ret_type.c_type())

-if arg_type:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
 QapiDeallocVisitor *qdv;
@@ -97,7 +97,7 @@ def gen_marshal_vars(arg_type, ret_type):
 def gen_marshal_input_visit(arg_type, dealloc=False):
 ret = ''

-if not arg_type:
+if not arg_type or arg_type.is_empty():
 return ret

 if dealloc:
@@ -177,7 +177,7 @@ def gen_marshal(name, arg_type, ret_type):

 # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields()
 # for each arg_type member, and by gen_call() for ret_type
-if (arg_type and arg_type.members) or ret_type:
+if (arg_type and not arg_type.is_empty()) or ret_type:
 ret += mcgen('''

 out:
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index d6171f2..650ba46 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -13,6 +13,11 @@ void qmp_user_def_cmd(Error **errp)
 {
 }

+Empty2 *qmp_user_def_cmd0(Error **errp)
+{
+return g_new0(Empty2, 1);
+}
+
 void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
 {
 }
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index b5d0c53..33e8517 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -18,6 +18,8 @@
 { 'struct': 'Empty1', 'data': { } }
 { 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }

+{ 'command': 'user_def_cmd0', 'data': 'Empty2', 'returns': 'Empty2' }
+
 # for testing override of default naming heuristic
 { 'enum': 'QEnumTwo',
   'prefix': 'QENUM_TWO',
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 225e2db..6b97fa5 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -203,6 +203,8 @@ command guest-sync :obj-guest-sync-arg -> any
gen=True success_response=True
 command user_def_cmd None -> None
gen=True success_response=True
+command user_def_cmd0 Empty2 -> Empty2
+   gen=True success_response=True
 command user_def_cmd1 :obj-user_def_cmd1-arg -> None
gen=True success_response=True
 command user_def_cmd2 :obj-user_def_cmd2-arg -> UserDefTwo
-- 
2.5.0




[Qemu-devel] [PATCH 02/17] chardev: Shorten references into ChardevBackend

2016-02-19 Thread Eric Blake
An upcoming patch will alter how simple unions, like ChardevBackend,
are laid out, which will impact all lines of the form 'backend->u.XXX'.
To minimize the impact of that patch, use a temporary variable to
reduce the number of lines needing modification when an internal
reference within ChardevBackend changes layout.

Signed-off-by: Eric Blake 
---
 qemu-char.c | 122 
 1 file changed, 66 insertions(+), 56 deletions(-)

diff --git a/qemu-char.c b/qemu-char.c
index fc8ffda..5ea1d34 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -724,7 +724,7 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
 ChardevMux *mux = backend->u.mux;
 CharDriverState *chr, *drv;
 MuxDriver *d;
-ChardevCommon *common = qapi_ChardevMux_base(backend->u.mux);
+ChardevCommon *common = qapi_ChardevMux_base(mux);

 drv = qemu_chr_find(mux->chardev);
 if (drv == NULL) {
@@ -1043,7 +1043,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
 char *filename_in;
 char *filename_out;
 const char *filename = opts->device;
-ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.pipe);
+ChardevCommon *common = qapi_ChardevHostdev_base(opts);


 filename_in = g_strdup_printf("%s.in", filename);
@@ -1123,7 +1123,7 @@ static CharDriverState *qemu_chr_open_stdio(const char 
*id,
 ChardevStdio *opts = backend->u.stdio;
 CharDriverState *chr;
 struct sigaction act;
-ChardevCommon *common = qapi_ChardevStdio_base(backend->u.stdio);
+ChardevCommon *common = qapi_ChardevStdio_base(opts);

 if (is_daemonized()) {
 error_setg(errp, "cannot use stdio with -daemonize");
@@ -2141,7 +2141,7 @@ static CharDriverState *qemu_chr_open_pipe(const char *id,
 const char *filename = opts->device;
 CharDriverState *chr;
 WinCharState *s;
-ChardevCommon *common = qapi_ChardevHostdev_base(backend->u.pipe);
+ChardevCommon *common = qapi_ChardevHostdev_base(opts);

 chr = qemu_chr_alloc(common, errp);
 if (!chr) {
@@ -3216,7 +3216,7 @@ static CharDriverState *qemu_chr_open_ringbuf(const char 
*id,
   Error **errp)
 {
 ChardevRingbuf *opts = backend->u.ringbuf;
-ChardevCommon *common = qapi_ChardevRingbuf_base(backend->u.ringbuf);
+ChardevCommon *common = qapi_ChardevRingbuf_base(opts);
 CharDriverState *chr;
 RingBufCharDriver *d;

@@ -3506,26 +3506,29 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, 
ChardevBackend *backend,
 Error **errp)
 {
 const char *path = qemu_opt_get(opts, "path");
+ChardevFile *file;

 if (path == NULL) {
 error_setg(errp, "chardev: file: no filename given");
 return;
 }
-backend->u.file = g_new0(ChardevFile, 1);
-qemu_chr_parse_common(opts, qapi_ChardevFile_base(backend->u.file));
-backend->u.file->out = g_strdup(path);
+file = backend->u.file = g_new0(ChardevFile, 1);
+qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));
+file->out = g_strdup(path);

-backend->u.file->has_append = true;
-backend->u.file->append = qemu_opt_get_bool(opts, "append", false);
+file->has_append = true;
+file->append = qemu_opt_get_bool(opts, "append", false);
 }

 static void qemu_chr_parse_stdio(QemuOpts *opts, ChardevBackend *backend,
  Error **errp)
 {
-backend->u.stdio = g_new0(ChardevStdio, 1);
-qemu_chr_parse_common(opts, qapi_ChardevStdio_base(backend->u.stdio));
-backend->u.stdio->has_signal = true;
-backend->u.stdio->signal = qemu_opt_get_bool(opts, "signal", true);
+ChardevStdio *stdio;
+
+stdio = backend->u.stdio = g_new0(ChardevStdio, 1);
+qemu_chr_parse_common(opts, qapi_ChardevStdio_base(stdio));
+stdio->has_signal = true;
+stdio->signal = qemu_opt_get_bool(opts, "signal", true);
 }

 #ifdef HAVE_CHARDEV_SERIAL
@@ -3533,14 +3536,15 @@ static void qemu_chr_parse_serial(QemuOpts *opts, 
ChardevBackend *backend,
   Error **errp)
 {
 const char *device = qemu_opt_get(opts, "path");
+ChardevHostdev *serial;

 if (device == NULL) {
 error_setg(errp, "chardev: serial/tty: no device path given");
 return;
 }
-backend->u.serial = g_new0(ChardevHostdev, 1);
-qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(backend->u.serial));
-backend->u.serial->device = g_strdup(device);
+serial = backend->u.serial = g_new0(ChardevHostdev, 1);
+qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(serial));
+serial->device = g_strdup(device);
 }
 #endif

@@ -3549,14 +3553,15 @@ static void qemu_chr_parse_parallel(QemuOpts *opts, 
ChardevBackend *backend,
 Error **errp)
 {
 const char *device = qemu_opt_get(opts, "path");
+ChardevHostdev *parallel;

 if (device == NULL) {
 error_setg(errp, "charde

[Qemu-devel] [PATCH 03/17] util: Shorten references into SocketAddress

2016-02-19 Thread Eric Blake
An upcoming patch will alter how simple unions, like SocketAddress,
are laid out, which will impact all lines of the form 'addr->u.XXX'.
To minimize the impact of that patch, use C99 initialization or a
temporary variable to reduce the number of lines needing modification
when an internal reference within SocketAddress changes layout.

Signed-off-by: Eric Blake 
---
 block/nbd.c| 14 --
 qemu-char.c| 43 --
 qemu-nbd.c |  9 +
 tests/test-io-channel-socket.c | 26 -
 ui/vnc.c   | 39 +++---
 util/qemu-sockets.c| 11 ++-
 6 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/block/nbd.c b/block/nbd.c
index db57b49..9f333c9 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -204,18 +204,20 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QDict 
*options, char **export,
 saddr = g_new0(SocketAddress, 1);

 if (qdict_haskey(options, "path")) {
+UnixSocketAddress *q_unix;
 saddr->type = SOCKET_ADDRESS_KIND_UNIX;
-saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
-saddr->u.q_unix->path = g_strdup(qdict_get_str(options, "path"));
+q_unix = saddr->u.q_unix = g_new0(UnixSocketAddress, 1);
+q_unix->path = g_strdup(qdict_get_str(options, "path"));
 qdict_del(options, "path");
 } else {
+InetSocketAddress *inet;
 saddr->type = SOCKET_ADDRESS_KIND_INET;
-saddr->u.inet = g_new0(InetSocketAddress, 1);
-saddr->u.inet->host = g_strdup(qdict_get_str(options, "host"));
+inet = saddr->u.inet = g_new0(InetSocketAddress, 1);
+inet->host = g_strdup(qdict_get_str(options, "host"));
 if (!qdict_get_try_str(options, "port")) {
-saddr->u.inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
+inet->port = g_strdup_printf("%d", NBD_DEFAULT_PORT);
 } else {
-saddr->u.inet->port = g_strdup(qdict_get_str(options, "port"));
+inet->port = g_strdup(qdict_get_str(options, "port"));
 }
 qdict_del(options, "host");
 qdict_del(options, "port");
diff --git a/qemu-char.c b/qemu-char.c
index 5ea1d34..cfc82bc 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3659,20 +3659,23 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,

 addr = g_new0(SocketAddress, 1);
 if (path) {
+UnixSocketAddress *q_unix;
 addr->type = SOCKET_ADDRESS_KIND_UNIX;
-addr->u.q_unix = g_new0(UnixSocketAddress, 1);
-addr->u.q_unix->path = g_strdup(path);
+q_unix = addr->u.q_unix = g_new0(UnixSocketAddress, 1);
+q_unix->path = g_strdup(path);
 } else {
 addr->type = SOCKET_ADDRESS_KIND_INET;
 addr->u.inet = g_new0(InetSocketAddress, 1);
-addr->u.inet->host = g_strdup(host);
-addr->u.inet->port = g_strdup(port);
-addr->u.inet->has_to = qemu_opt_get(opts, "to");
-addr->u.inet->to = qemu_opt_get_number(opts, "to", 0);
-addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
-addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
-addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
-addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+*addr->u.inet = (InetSocketAddress) {
+.host = g_strdup(host),
+.port = g_strdup(port),
+.has_to = qemu_opt_get(opts, "to"),
+.to = qemu_opt_get_number(opts, "to", 0),
+.has_ipv4 = qemu_opt_get(opts, "ipv4"),
+.ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
+.has_ipv6 = qemu_opt_get(opts, "ipv6"),
+.ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
+};
 }
 sock->addr = addr;
 }
@@ -3712,12 +3715,14 @@ static void qemu_chr_parse_udp(QemuOpts *opts, 
ChardevBackend *backend,
 addr = g_new0(SocketAddress, 1);
 addr->type = SOCKET_ADDRESS_KIND_INET;
 addr->u.inet = g_new0(InetSocketAddress, 1);
-addr->u.inet->host = g_strdup(host);
-addr->u.inet->port = g_strdup(port);
-addr->u.inet->has_ipv4 = qemu_opt_get(opts, "ipv4");
-addr->u.inet->ipv4 = qemu_opt_get_bool(opts, "ipv4", 0);
-addr->u.inet->has_ipv6 = qemu_opt_get(opts, "ipv6");
-addr->u.inet->ipv6 = qemu_opt_get_bool(opts, "ipv6", 0);
+*addr->u.inet = (InetSocketAddress) {
+.host = g_strdup(host),
+.port = g_strdup(port),
+.has_ipv4 = qemu_opt_get(opts, "ipv4"),
+.ipv4 = qemu_opt_get_bool(opts, "ipv4", 0),
+.has_ipv6 = qemu_opt_get(opts, "ipv6"),
+.ipv6 = qemu_opt_get_bool(opts, "ipv6", 0),
+};
 udp->remote = addr;

 if (has_local) {
@@ -3725,8 +3730,10 @@ static void qemu_chr_parse_udp(QemuOpts *opts, 
ChardevBackend *backend,
 addr = g_new0(SocketAddress, 1);
 addr->type = SOCKET_ADDRESS_KIND_INET;

[Qemu-devel] [PATCH 00/17] qapi implicit types (continuing the qapi cleanup theme)

2016-02-19 Thread Eric Blake
I don't know what letter and or number to assign this batch, so I'll
just call it v1 of 'qapi-implicit' :)  It does, however, incorporate
reviews on several patches that were in subset E v9 [1], and some
that were posted (but not yet reviewed) in subset F v6 [2]; the
remaining patches are new but provide the promised work at cleaning
up the generated code for simple unions, so that their implicit
wrapper type is now unboxed without any special-case handling.

1-7: general cleanups, including a bug fix in patch 1
8: add the framework for doing inline visits of implicit types
9-11: add is_empty() helper, including a bug fix in patch 10
12-13: use the framework for simple unions
14: use the framework for anonymous bases of flat unions
15-17: tail-end cleanups

[1] https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg03504.html
[2] https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg04389.html

Based on current qemu.git master.

Also available as a tag at this location:
git fetch git://repo.or.cz/qemu/ericb.git qapi-implicitv1

and will soon be part of my branch at:
http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi

Backport diff based on patches that were previously posted:

001/17:[down] 'chardev: Properly initialize ChardevCommon components'
002/17:[down] 'chardev: Shorten references into ChardevBackend'
003/17:[down] 'util: Shorten references into SocketAddress'
004/17:[down] 'ui: Shorten references into InputEvent'
005/17:[] [--] 'qapi: Avoid use of 'data' member of qapi unions'
006/17:[down] 'chardev: Drop useless ChardevDummy type'
007/17:[0002] [FC] 'qapi: Drop useless 'data' member of unions'
008/17:[down] 'qapi-visit: Factor out gen_visit_fields_call()'
009/17:[0003] [FC] 'qapi: Add type.is_empty() helper'
010/17:[] [--] 'qapi: Fix command with named empty argument type'
011/17:[down] 'qapi-visit: Simplify visit of empty branch in union'
012/17:[down] 'qapi: Don't special-case simple union wrappers'
013/17:[down] 'qapi-visit: Move error check into gen_visit_fields_call()'
014/17:[0052] [FC] 'qapi: Allow anonymous base for flat union'
015/17:[] [--] 'qapi: Use anonymous base in SchemaInfo'
016/17:[] [--] 'qapi: Use anonymous base in CpuInfo'
017/17:[down] 'qapi: Make c_type() more OO-like'

Remaining qapi cleanups that are still on my queue, and have had
patches posted to list:
- visitor cleanup: add documentation, optimize list visits, add
visit_type_null(), prevent leaked memory after visit_type_FOO
(reviewed as tail of subset E v9) [3]
- add a JSON output visitor (unreviewed at v2) [4]
- support boxed parameters for events and commands, use it to
introspect netdev_add (unreviewed subset F, at v6) [5]

[3] https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg03504.html
[4] https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg03929.html
[5] https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg04389.html

We'll see how much of that actually makes it in by 2.6 soft freeze.

Eric Blake (17):
  chardev: Properly initialize ChardevCommon components
  chardev: Shorten references into ChardevBackend
  util: Shorten references into SocketAddress
  ui: Shorten references into InputEvent
  qapi: Avoid use of 'data' member of qapi unions
  chardev: Drop useless ChardevDummy type
  qapi: Drop useless 'data' member of unions
  qapi-visit: Factor out gen_visit_fields_call()
  qapi: Add type.is_empty() helper
  qapi: Fix command with named empty argument type
  qapi-visit: Simplify visit of empty branch in union
  qapi: Don't special-case simple union wrappers
  qapi-visit: Move error check into gen_visit_fields_call()
  qapi: Allow anonymous base for flat union
  qapi: Use anonymous base in SchemaInfo
  qapi: Use anonymous base in CpuInfo
  qapi: Make c_type() more OO-like

 scripts/qapi.py|  66 ++---
 scripts/qapi-commands.py   |   6 +-
 scripts/qapi-event.py  |   7 +-
 scripts/qapi-types.py  |  45 +++---
 scripts/qapi-visit.py  |  55 +++
 include/sysemu/char.h  |  10 ++
 backends/baum.c|   2 +-
 backends/msmouse.c |   2 +-
 block/nbd.c|  16 ++-
 block/qcow2.c  |   6 +-
 block/vmdk.c   |   8 +-
 blockdev.c |  49 ---
 hmp.c  |   8 +-
 hw/char/escc.c |  12 +-
 hw/input/hid.c |  36 +++--
 hw/input/ps2.c |  27 ++--
 hw/input/virtio-input-hid.c|  33 +++--
 hw/mem/pc-dimm.c   |   4 +-
 net/dump.c |   2 +-
 net/hub.c  |   2 +-
 net/l2tpv3.c   |   2 +-
 net/net.c  |   4 +-
 net/netmap.c  

[Qemu-devel] [PATCH 07/17] qapi: Drop useless 'data' member of unions

2016-02-19 Thread Eric Blake
Now that we no longer have any clients of the 'void *data'
member injected into unions, we can drop it.  Update the
testsuite to drop the negative test union-clash-data, and
replace it with a positive test in qapi-schema-test that
proves that we no longer have a name collision.

Signed-off-by: Eric Blake 

---
v1: drop patch that forced :empty as base to all structs
Previously posted as part of qapi cleanup subset F:
v6: rebase to earlier changes
---
 scripts/qapi-types.py   | 9 -
 tests/Makefile  | 1 -
 tests/qapi-schema/qapi-schema-test.json | 2 +-
 tests/qapi-schema/qapi-schema-test.out  | 4 ++--
 tests/qapi-schema/union-clash-data.err  | 0
 tests/qapi-schema/union-clash-data.exit | 1 -
 tests/qapi-schema/union-clash-data.json | 7 ---
 tests/qapi-schema/union-clash-data.out  | 9 -
 8 files changed, 3 insertions(+), 30 deletions(-)
 delete mode 100644 tests/qapi-schema/union-clash-data.err
 delete mode 100644 tests/qapi-schema/union-clash-data.exit
 delete mode 100644 tests/qapi-schema/union-clash-data.json
 delete mode 100644 tests/qapi-schema/union-clash-data.out

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index eac90d2..b68e85a 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -116,17 +116,8 @@ static inline %(base)s *qapi_%(c_name)s_base(const 
%(c_name)s *obj)


 def gen_variants(variants):
-# FIXME: What purpose does data serve, besides preventing a union that
-# has a branch named 'data'? We use it in qapi-visit.py to decide
-# whether to bypass the switch statement if visiting the discriminator
-# failed; but since we 0-initialize structs, and cannot tell what
-# branch of the union is in use if the discriminator is invalid, there
-# should not be any data leaks even without a data pointer.  Or, if
-# 'data' is merely added to guarantee we don't have an empty union,
-# shouldn't we enforce that at .json parse time?
 ret = mcgen('''
 union { /* union tag is @%(c_name)s */
-void *data;
 ''',
 c_name=c_name(variants.tag_member.name))

diff --git a/tests/Makefile b/tests/Makefile
index 04e34b5..cd4bbd4 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -358,7 +358,6 @@ qapi-schema += unicode-str.json
 qapi-schema += union-base-no-discriminator.json
 qapi-schema += union-branch-case.json
 qapi-schema += union-clash-branches.json
-qapi-schema += union-clash-data.json
 qapi-schema += union-empty.json
 qapi-schema += union-invalid-base.json
 qapi-schema += union-optional-branch.json
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 632964a..b5d0c53 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -115,7 +115,7 @@
 'number': ['number'],
 'boolean': ['bool'],
 'string': ['str'],
-'sizes': ['size'],
+'data': ['size'],
 'any': ['any'] } }

 # testing commands
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index f5e2a73..225e2db 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -139,9 +139,9 @@ object UserDefNativeListUnion
 case number: :obj-numberList-wrapper
 case boolean: :obj-boolList-wrapper
 case string: :obj-strList-wrapper
-case sizes: :obj-sizeList-wrapper
+case data: :obj-sizeList-wrapper
 case any: :obj-anyList-wrapper
-enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 
'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'sizes', 'any']
+enum UserDefNativeListUnionKind ['integer', 's8', 's16', 's32', 's64', 'u8', 
'u16', 'u32', 'u64', 'number', 'boolean', 'string', 'data', 'any']
 object UserDefOne
 base UserDefZero
 member string: str optional=False
diff --git a/tests/qapi-schema/union-clash-data.err 
b/tests/qapi-schema/union-clash-data.err
deleted file mode 100644
index e69de29..000
diff --git a/tests/qapi-schema/union-clash-data.exit 
b/tests/qapi-schema/union-clash-data.exit
deleted file mode 100644
index 573541a..000
--- a/tests/qapi-schema/union-clash-data.exit
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/tests/qapi-schema/union-clash-data.json 
b/tests/qapi-schema/union-clash-data.json
deleted file mode 100644
index 7308e69..000
--- a/tests/qapi-schema/union-clash-data.json
+++ /dev/null
@@ -1,7 +0,0 @@
-# Union branch 'data'
-# FIXME: this parses, but then fails to compile due to a duplicate 'data'
-# (one from the branch name, another as a filler to avoid an empty union).
-# we should either detect the collision at parse time, or change the
-# generated struct to allow this to compile.
-{ 'union': 'TestUnion',
-  'data': { 'data': 'int' } }
diff --git a/tests/qapi-schema/union-clash-data.out 
b/tests/qapi-schema/union-clash-data.out
deleted file mode 100644
index f5752f4..000
--- a/tests/qapi

[Qemu-devel] [PATCH 01/17] chardev: Properly initialize ChardevCommon components

2016-02-19 Thread Eric Blake
Commit d0d7708b forgot to parse logging for spice chardevs and
virtual consoles. This requires making qemu_chr_parse_common()
non-static. While at it, use a temporary variable to make the
code shorter, as well as reduce the churn when a later patch
alters the layout of simple unions.

Signed-off-by: Eric Blake 
CC: Daniel P. Berrange 
---
 include/sysemu/char.h | 10 ++
 qemu-char.c   |  2 +-
 spice-qemu-char.c | 12 
 ui/console.c  | 20 +++-
 4 files changed, 30 insertions(+), 14 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index e035d1c..e46884f 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -115,6 +115,16 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 Error **errp);

 /**
+ * @qemu_chr_parse_common:
+ *
+ * Parse the common options available to all character backends.
+ *
+ * @opts the options that still need parsing
+ * @backend a new backend
+ */
+void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend);
+
+/**
  * @qemu_chr_new:
  *
  * Create a new character backend from a URI.
diff --git a/qemu-char.c b/qemu-char.c
index ad11b75..fc8ffda 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3490,7 +3490,7 @@ fail:
 return NULL;
 }

-static void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
+void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)
 {
 const char *logfile = qemu_opt_get(opts, "logfile");

diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 7c1f438..21885c5 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -366,26 +366,30 @@ static void qemu_chr_parse_spice_vmc(QemuOpts *opts, 
ChardevBackend *backend,
  Error **errp)
 {
 const char *name = qemu_opt_get(opts, "name");
+ChardevSpiceChannel *spicevmc;

 if (name == NULL) {
 error_setg(errp, "chardev: spice channel: no name given");
 return;
 }
-backend->u.spicevmc = g_new0(ChardevSpiceChannel, 1);
-backend->u.spicevmc->type = g_strdup(name);
+spicevmc = backend->u.spicevmc = g_new0(ChardevSpiceChannel, 1);
+qemu_chr_parse_common(opts, qapi_ChardevSpiceChannel_base(spicevmc));
+spicevmc->type = g_strdup(name);
 }

 static void qemu_chr_parse_spice_port(QemuOpts *opts, ChardevBackend *backend,
   Error **errp)
 {
 const char *name = qemu_opt_get(opts, "name");
+ChardevSpicePort *spiceport;

 if (name == NULL) {
 error_setg(errp, "chardev: spice port: no name given");
 return;
 }
-backend->u.spiceport = g_new0(ChardevSpicePort, 1);
-backend->u.spiceport->fqdn = g_strdup(name);
+spiceport = backend->u.spiceport = g_new0(ChardevSpicePort, 1);
+qemu_chr_parse_common(opts, qapi_ChardevSpicePort_base(spiceport));
+spiceport->fqdn = g_strdup(name);
 }

 static void register_types(void)
diff --git a/ui/console.c b/ui/console.c
index b739ae9..7db0fd2 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -2060,31 +2060,33 @@ static void qemu_chr_parse_vc(QemuOpts *opts, 
ChardevBackend *backend,
   Error **errp)
 {
 int val;
+ChardevVC *vc;

-backend->u.vc = g_new0(ChardevVC, 1);
+vc = backend->u.vc = g_new0(ChardevVC, 1);
+qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc));

 val = qemu_opt_get_number(opts, "width", 0);
 if (val != 0) {
-backend->u.vc->has_width = true;
-backend->u.vc->width = val;
+vc->has_width = true;
+vc->width = val;
 }

 val = qemu_opt_get_number(opts, "height", 0);
 if (val != 0) {
-backend->u.vc->has_height = true;
-backend->u.vc->height = val;
+vc->has_height = true;
+vc->height = val;
 }

 val = qemu_opt_get_number(opts, "cols", 0);
 if (val != 0) {
-backend->u.vc->has_cols = true;
-backend->u.vc->cols = val;
+vc->has_cols = true;
+vc->cols = val;
 }

 val = qemu_opt_get_number(opts, "rows", 0);
 if (val != 0) {
-backend->u.vc->has_rows = true;
-backend->u.vc->rows = val;
+vc->has_rows = true;
+vc->rows = val;
 }
 }

-- 
2.5.0




[Qemu-devel] [PATCH 06/17] chardev: Drop useless ChardevDummy type

2016-02-19 Thread Eric Blake
Commit d0d7708b made ChardevDummy be an empty wrapper type around
ChardevCommon.  But there is no technical reason for this indirection,
so simplify the code by directly using the base type.

Also change the fallback assignment to assign u.null rather than
u.data, since a future patch will remove the data member of the C
struct generated for QAPI unions.

Signed-off-by: Eric Blake 
---
 backends/baum.c|  2 +-
 backends/msmouse.c |  2 +-
 qemu-char.c|  6 +++---
 qapi-schema.json   | 15 ++-
 4 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/backends/baum.c b/backends/baum.c
index 374562a..c11320e 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -567,7 +567,7 @@ static CharDriverState *chr_baum_init(const char *id,
   ChardevReturn *ret,
   Error **errp)
 {
-ChardevCommon *common = qapi_ChardevDummy_base(backend->u.braille);
+ChardevCommon *common = backend->u.braille;
 BaumDriverState *baum;
 CharDriverState *chr;
 brlapi_handle_t *handle;
diff --git a/backends/msmouse.c b/backends/msmouse.c
index 9a82efd..5e1833c 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -68,7 +68,7 @@ static CharDriverState *qemu_chr_open_msmouse(const char *id,
   ChardevReturn *ret,
   Error **errp)
 {
-ChardevCommon *common = qapi_ChardevDummy_base(backend->u.msmouse);
+ChardevCommon *common = backend->u.msmouse;
 CharDriverState *chr;

 chr = qemu_chr_alloc(common, errp);
diff --git a/qemu-char.c b/qemu-char.c
index cfc82bc..6a0fc74 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -420,7 +420,7 @@ static CharDriverState *qemu_chr_open_null(const char *id,
Error **errp)
 {
 CharDriverState *chr;
-ChardevCommon *common = qapi_ChardevDummy_base(backend->u.null);
+ChardevCommon *common = backend->u.null;

 chr = qemu_chr_alloc(common, errp);
 if (!chr) {
@@ -1366,7 +1366,7 @@ static CharDriverState *qemu_chr_open_pty(const char *id,
 PtyCharDriver *s;
 int master_fd, slave_fd;
 char pty_name[PATH_MAX];
-ChardevCommon *common = qapi_ChardevDummy_base(backend->u.pty);
+ChardevCommon *common = backend->u.pty;

 master_fd = qemu_openpty_raw(&slave_fd, pty_name);
 if (master_fd < 0) {
@@ -3817,7 +3817,7 @@ CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
 } else {
 ChardevCommon *cc = g_new0(ChardevCommon, 1);
 qemu_chr_parse_common(opts, cc);
-backend->u.data = cc;
+backend->u.null = cc; /* Any ChardevCommon member would work */
 }

 ret = qmp_chardev_add(bid ? bid : id, backend, errp);
diff --git a/qapi-schema.json b/qapi-schema.json
index 8d04897..f64d4ab 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3271,23 +3271,20 @@
 #
 # Since: 1.4 (testdev since 2.2)
 ##
-{ 'struct': 'ChardevDummy', 'data': { },
-  'base': 'ChardevCommon' }
-
 { 'union': 'ChardevBackend', 'data': { 'file'   : 'ChardevFile',
'serial' : 'ChardevHostdev',
'parallel': 'ChardevHostdev',
'pipe'   : 'ChardevHostdev',
'socket' : 'ChardevSocket',
'udp': 'ChardevUdp',
-   'pty': 'ChardevDummy',
-   'null'   : 'ChardevDummy',
+   'pty': 'ChardevCommon',
+   'null'   : 'ChardevCommon',
'mux': 'ChardevMux',
-   'msmouse': 'ChardevDummy',
-   'braille': 'ChardevDummy',
-   'testdev': 'ChardevDummy',
+   'msmouse': 'ChardevCommon',
+   'braille': 'ChardevCommon',
+   'testdev': 'ChardevCommon',
'stdio'  : 'ChardevStdio',
-   'console': 'ChardevDummy',
+   'console': 'ChardevCommon',
'spicevmc' : 'ChardevSpiceChannel',
'spiceport' : 'ChardevSpicePort',
'vc' : 'ChardevVC',
-- 
2.5.0




[Qemu-devel] [PATCH 09/17] qapi: Add type.is_empty() helper

2016-02-19 Thread Eric Blake
And use it in qapi-types and qapi-event.  Down the road, we may
want to lift our artificial restriction of no variants at the
top level of an event, at which point, inlining our check for
whether members is empty will no longer be sufficient, but
adding a check for variants adds verbosity; in the meantime,
add some asserts in places where we don't handle variants.

More immediately, the new .is_empty() helper will help fix a bug
in qapi-visit in the next patch, where the generator did not
handle an explicit empty type in the same was as a missing type.

No change to generated code.

Signed-off-by: Eric Blake 

---
v1: add some asserts
Previously posted as part of qapi cleanup subset E:
v9: improve commit message
v8: no change
v7: rebase to context change
v6: new patch
---
 scripts/qapi.py   | 5 +
 scripts/qapi-event.py | 7 ---
 scripts/qapi-types.py | 2 +-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 849..8a4f952 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -962,6 +962,7 @@ class QAPISchemaObjectType(QAPISchemaType):
 assert isinstance(self.base, QAPISchemaObjectType)
 self.base.check(schema)
 self.base.check_clash(schema, self.info, seen)
+assert not self.base.variants
 for m in self.local_members:
 m.check(schema)
 m.check_clash(self.info, seen)
@@ -983,6 +984,10 @@ class QAPISchemaObjectType(QAPISchemaType):
 # See QAPISchema._make_implicit_object_type()
 return self.name[0] == ':'

+def is_empty(self):
+assert self.members is not None
+return not self.members and not self.variants
+
 def c_name(self):
 assert not self.is_implicit()
 return QAPISchemaType.c_name(self)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 544ae12..8be3b44 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -39,7 +39,7 @@ def gen_event_send(name, arg_type):
 ''',
 proto=gen_event_send_proto(name, arg_type))

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 QmpOutputVisitor *qov;
 Visitor *v;
@@ -58,7 +58,8 @@ def gen_event_send(name, arg_type):
 ''',
  name=name)

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
+assert not arg_type.variants
 ret += mcgen('''
 qov = qmp_output_visitor_new();
 v = qmp_output_get_visitor(qov);
@@ -88,7 +89,7 @@ out_obj:
 ''',
  c_enum=c_enum_const(event_enum_name, name))

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 out:
 qmp_output_visitor_cleanup(qov);
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index b68e85a..1eb5622 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -90,7 +90,7 @@ struct %(c_name)s {
 # potential issues with attempting to malloc space for zero-length
 # structs in C, and also incompatibility with C++ (where an empty
 # struct is size 1).
-if not (base and base.members) and not members and not variants:
+if (not base or base.is_empty()) and not members and not variants:
 ret += mcgen('''
 char qapi_dummy_field_for_empty_struct;
 ''')
-- 
2.5.0




Re: [Qemu-devel] [PATCH v1 1/1] etraxfs_dma: Dont forward zero-length payload to clients

2016-02-19 Thread Edgar E. Iglesias
On Tue, Feb 16, 2016 at 12:53:32PM +0100, Edgar E. Iglesias wrote:
> From: "Edgar E. Iglesias" 

Applied


> 
> Signed-off-by: Edgar E. Iglesias 
> ---
>  hw/dma/etraxfs_dma.c | 13 -
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/dma/etraxfs_dma.c b/hw/dma/etraxfs_dma.c
> index 9cbb165..d5650eb 100644
> --- a/hw/dma/etraxfs_dma.c
> +++ b/hw/dma/etraxfs_dma.c
> @@ -440,13 +440,16 @@ static int channel_out_run(struct fs_dma_ctrl *ctrl, 
> int c)
>   D(printf("channel %d pushes %x %u bytes eop=%u\n", c,
>saved_data_buf, len, out_eop));
>  
> - if (ctrl->channels[c].client->client.push)
> - ctrl->channels[c].client->client.push(
> - ctrl->channels[c].client->client.opaque,
> - buf, len, out_eop);
> - else
> + if (ctrl->channels[c].client->client.push) {
> +if (len > 0) {
> + ctrl->channels[c].client->client.push(
> + ctrl->channels[c].client->client.opaque,
> + buf, len, out_eop);
> + }
> + } else {
>   printf("WARNING: DMA ch%d dataloss,"
>  " no attached client.\n", c);
> + }
>  
>   saved_data_buf += len;
>  
> -- 
> 1.9.1
> 



Re: [Qemu-devel] [PATCH 1/2] vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries

2016-02-19 Thread Wei Yang
On Fri, Feb 19, 2016 at 09:45:32AM -0700, Alex Williamson wrote:
>On Fri, 19 Feb 2016 15:18:10 +
>Wei Yang  wrote:
>
>> Even PCI_CAP_FLAGS has the same value as PCI_MSIX_FLAGS, the later one is
>> the more proper on retrieving MSIX entries.
>> 
>> This patch uses PCI_MSIX_FLAGS to retrieve the MSIX entries.
>> 
>> Signed-off-by: Wei Yang 
>> ---
>>  hw/vfio/pci.c |2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>> 
>> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
>> index e66c47f..321423b 100644
>> --- a/hw/vfio/pci.c
>> +++ b/hw/vfio/pci.c
>> @@ -1210,7 +1210,7 @@ static int vfio_msix_early_setup(VFIOPCIDevice *vdev)
>>  }
>>  
>>  if (pread(fd, &ctrl, sizeof(ctrl),
>> -  vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
>> +  vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
>>  return -errno;
>>  }
>>  
>
>This is certainly trivial, I'll grab it for the respin of yesterday's
>pull request.  Thanks,

Thanks Alex, have a nice weekend :-)

>
>Alex

-- 
Wei Yang
Help you, Help me



[Qemu-devel] [Bug 1546680] Re: Incorrect display colors when running big endian guest on POWER8 little endian host

2016-02-19 Thread Timothy Pearson
** Tags added: power8

** Tags removed: power8
** Tags added: ppc qemu vga

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1546680

Title:
  Incorrect display colors when running big endian guest on POWER8
  little endian host

Status in QEMU:
  New

Bug description:
  When running a big endian CentOS guest on a little endian host system
  the display shows severe color issues, probably due to endianness not
  being properly detected / switched in the emulated display hardware.
  Little endian guests show no display issues on the same host hardware
  and software.

  See attachment for an example of the problem.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1546680/+subscriptions



Re: [Qemu-devel] [PATCH] hw/arm/virt: Assume EL3 boot rom will handle PSCI if one is provided

2016-02-19 Thread Laszlo Ersek
On 02/19/16 22:41, Ard Biesheuvel wrote:
> On 19 February 2016 at 22:03, Laszlo Ersek  wrote:
>> Ard, any opinion on this?
>>
> 
> I agree with Peter. Note that this is strictly about emulation, under
> KVM we always run at EL1 or below and PSCI calls are handled by the
> host kernel, not QEMU

Great, that's all I wanted to hear -- out of scope for me. :)

Actually, I have now read the patch even, and I have the following comments:

- As long as "using_psci" is true, the behavior doesn't change. Great.

- The only place where using_psci *changes* to false is reachable only
with (vms->secure && firmware_loaded). That's what wasn't immediately
obvious from the patch -- when vms->secure is true (-machine secure=on),
it's out of scope for me. :)

- However, I think I might have noticed a bug -- or rather missed
something trivial --, namely, where is "using_psci" *initially* set to
true? The "machines" static array is not touched.

Thanks!
Laszlo

> 
> 
>> On 02/19/16 17:21, Peter Maydell wrote:
>>> If the user passes us an EL3 boot rom, then it is going to want to
>>> implement the PSCI interface itself. In this case, disable QEMU's
>>> internal PSCI implementation so it does not get in the way, and
>>> instead start all CPUs in an SMP configuration at once (the boot
>>> rom will catch them all and pen up the secondaries until needed).
>>> The boot rom code is also responsible for editing the device tree
>>> to include any necessary information about its own PSCI implementation
>>> before eventually passing it to a NonSecure guest.
>>>
>>> (This "start all CPUs at once" approach is what both ARM Trusted
>>> Firmware and UEFI expect, since it is what the ARM Foundation Model
>>> does; the other approach would be to provide some emulated hardware
>>> for "start the secondaries" but this is simplest.)
>>>
>>> This is a compatibility break, but I don't believe that anybody
>>> was using a secure boot ROM with an SMP configuration. Such a setup
>>> would be somewhat broken since there was nothing preventing nonsecure
>>> guest code from calling the QEMU PSCI function to start up a secondary
>>> core in a way that completely bypassed the secure world.
>>>
>>> Signed-off-by: Peter Maydell 
>>> ---
>>> This is slightly RFC-ish because I don't actually have any secure boot
>>> rom code that will cope with SMP right now. But I think that since this
>>> is a compat break we're better off putting it into 2.6 than not.
>>>
>>>  hw/arm/virt.c | 33 ++---
>>>  1 file changed, 26 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>>> index 4499e2c..0f01902 100644
>>> --- a/hw/arm/virt.c
>>> +++ b/hw/arm/virt.c
>>> @@ -73,6 +73,7 @@ typedef struct VirtBoardInfo {
>>>  uint32_t clock_phandle;
>>>  uint32_t gic_phandle;
>>>  uint32_t v2m_phandle;
>>> +bool using_psci;
>>>  } VirtBoardInfo;
>>>
>>>  typedef struct {
>>> @@ -231,6 +232,10 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi)
>>>  void *fdt = vbi->fdt;
>>>  ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
>>>
>>> +if (!vbi->using_psci) {
>>> +return;
>>> +}
>>> +
>>>  qemu_fdt_add_subnode(fdt, "/psci");
>>>  if (armcpu->psci_version == 2) {
>>>  const char comp[] = "arm,psci-0.2\0arm,psci";
>>> @@ -342,7 +347,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
>>>  qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
>>>  armcpu->dtb_compatible);
>>>
>>> -if (vbi->smp_cpus > 1) {
>>> +if (vbi->using_psci && vbi->smp_cpus > 1) {
>>>  qemu_fdt_setprop_string(vbi->fdt, nodename,
>>>  "enable-method", "psci");
>>>  }
>>> @@ -1081,6 +1086,7 @@ static void machvirt_init(MachineState *machine)
>>>  VirtGuestInfoState *guest_info_state = g_malloc0(sizeof 
>>> *guest_info_state);
>>>  VirtGuestInfo *guest_info = &guest_info_state->info;
>>>  char **cpustr;
>>> +bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
>>>
>>>  if (!cpu_model) {
>>>  cpu_model = "cortex-a15";
>>> @@ -1146,6 +1152,16 @@ static void machvirt_init(MachineState *machine)
>>>  memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
>>> UINT64_MAX);
>>>  memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
>>> +
>>> +if (firmware_loaded) {
>>> +/* If we have an EL3 boot ROM then the assumption is that it 
>>> will
>>> + * implement PSCI itself, so disable QEMU's internal 
>>> implementation
>>> + * so it doesn't get in the way. Instead of starting secondary
>>> + * CPUs in PSCI powerdown state we will start them all running 
>>> and
>>> + * let the boot ROM sort them out.
>>> + */
>>> +vbi->using_psci = false;
>>> +}
>>>  }
>>>
>>>  create_fdt(vbi)

Re: [Qemu-devel] [PATCH] hw/arm/virt: Assume EL3 boot rom will handle PSCI if one is provided

2016-02-19 Thread Ard Biesheuvel
On 19 February 2016 at 22:03, Laszlo Ersek  wrote:
> Ard, any opinion on this?
>

I agree with Peter. Note that this is strictly about emulation, under
KVM we always run at EL1 or below and PSCI calls are handled by the
host kernel, not QEMU



> On 02/19/16 17:21, Peter Maydell wrote:
>> If the user passes us an EL3 boot rom, then it is going to want to
>> implement the PSCI interface itself. In this case, disable QEMU's
>> internal PSCI implementation so it does not get in the way, and
>> instead start all CPUs in an SMP configuration at once (the boot
>> rom will catch them all and pen up the secondaries until needed).
>> The boot rom code is also responsible for editing the device tree
>> to include any necessary information about its own PSCI implementation
>> before eventually passing it to a NonSecure guest.
>>
>> (This "start all CPUs at once" approach is what both ARM Trusted
>> Firmware and UEFI expect, since it is what the ARM Foundation Model
>> does; the other approach would be to provide some emulated hardware
>> for "start the secondaries" but this is simplest.)
>>
>> This is a compatibility break, but I don't believe that anybody
>> was using a secure boot ROM with an SMP configuration. Such a setup
>> would be somewhat broken since there was nothing preventing nonsecure
>> guest code from calling the QEMU PSCI function to start up a secondary
>> core in a way that completely bypassed the secure world.
>>
>> Signed-off-by: Peter Maydell 
>> ---
>> This is slightly RFC-ish because I don't actually have any secure boot
>> rom code that will cope with SMP right now. But I think that since this
>> is a compat break we're better off putting it into 2.6 than not.
>>
>>  hw/arm/virt.c | 33 ++---
>>  1 file changed, 26 insertions(+), 7 deletions(-)
>>
>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>> index 4499e2c..0f01902 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -73,6 +73,7 @@ typedef struct VirtBoardInfo {
>>  uint32_t clock_phandle;
>>  uint32_t gic_phandle;
>>  uint32_t v2m_phandle;
>> +bool using_psci;
>>  } VirtBoardInfo;
>>
>>  typedef struct {
>> @@ -231,6 +232,10 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi)
>>  void *fdt = vbi->fdt;
>>  ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
>>
>> +if (!vbi->using_psci) {
>> +return;
>> +}
>> +
>>  qemu_fdt_add_subnode(fdt, "/psci");
>>  if (armcpu->psci_version == 2) {
>>  const char comp[] = "arm,psci-0.2\0arm,psci";
>> @@ -342,7 +347,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
>>  qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
>>  armcpu->dtb_compatible);
>>
>> -if (vbi->smp_cpus > 1) {
>> +if (vbi->using_psci && vbi->smp_cpus > 1) {
>>  qemu_fdt_setprop_string(vbi->fdt, nodename,
>>  "enable-method", "psci");
>>  }
>> @@ -1081,6 +1086,7 @@ static void machvirt_init(MachineState *machine)
>>  VirtGuestInfoState *guest_info_state = g_malloc0(sizeof 
>> *guest_info_state);
>>  VirtGuestInfo *guest_info = &guest_info_state->info;
>>  char **cpustr;
>> +bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
>>
>>  if (!cpu_model) {
>>  cpu_model = "cortex-a15";
>> @@ -1146,6 +1152,16 @@ static void machvirt_init(MachineState *machine)
>>  memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
>> UINT64_MAX);
>>  memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
>> +
>> +if (firmware_loaded) {
>> +/* If we have an EL3 boot ROM then the assumption is that it 
>> will
>> + * implement PSCI itself, so disable QEMU's internal 
>> implementation
>> + * so it doesn't get in the way. Instead of starting secondary
>> + * CPUs in PSCI powerdown state we will start them all running 
>> and
>> + * let the boot ROM sort them out.
>> + */
>> +vbi->using_psci = false;
>> +}
>>  }
>>
>>  create_fdt(vbi);
>> @@ -1175,12 +1191,15 @@ static void machvirt_init(MachineState *machine)
>>  object_property_set_bool(cpuobj, false, "has_el3", NULL);
>>  }
>>
>> -object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC, 
>> "psci-conduit",
>> -NULL);
>> +if (vbi->using_psci) {
>> +object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC,
>> +"psci-conduit", NULL);
>>
>> -/* Secondary CPUs start in PSCI powered-down state */
>> -if (n > 0) {
>> -object_property_set_bool(cpuobj, true, "start-powered-off", 
>> NULL);
>> +/* Secondary CPUs start in PSCI powered-down state */
>> +if (n > 0) {
>> +object_property_set_bool(cpuobj, true,
>>

Re: [Qemu-devel] [PATCH 1/1] virtio-rng: fix condition checking on period_ms

2016-02-19 Thread Wei Huang


On 02/19/2016 02:59 PM, Laszlo Ersek wrote:
> On 02/19/16 21:57, Laszlo Ersek wrote:
>> On 02/19/16 19:13, Wei Huang wrote:
>>> The condition checking on vrng->conf.period_ms appears to be wrong,
>>> conflicting with the error comment following it.
>>>
>>> Signed-off-by: Wei Huang 
>>> ---
>>>  hw/virtio/virtio-rng.c | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
>>> index 473c044..a06427c 100644
>>> --- a/hw/virtio/virtio-rng.c
>>> +++ b/hw/virtio/virtio-rng.c
>>> @@ -149,7 +149,7 @@ static void virtio_rng_device_realize(DeviceState *dev, 
>>> Error **errp)
>>>  VirtIORNG *vrng = VIRTIO_RNG(dev);
>>>  Error *local_err = NULL;
>>>  
>>> -if (!vrng->conf.period_ms > 0) {
>>> +if (!(vrng->conf.period_ms > 0)) {
>>>  error_setg(errp, "'period' parameter expects a positive integer");
>>>  return;
>>>  }
>>>
>>
>> The current condition is absolutely weird, but I think it happens to
>> work correctly:
>>
>> Period_ms has type uint32_t. If it is positive, then !period_ms is zero.
>> 0>0 is false, hence the error message is not printed.
>>
>> If period_ms is zero, then !period_ms is 1. 1>0 is true, hence the error
>> message is printed.
>>
>> I would rewrite the check as
>>
>> if (vrng->conf.period_ms == 0) {
>> error_setg(...)
> 
> ... actually, what the heck are you looking at? :) This has been fixed
> up in:
> 

Oops. It looks like I was looking at an older HEAD. :-( Please ignore
it. Sorry for the noise and thanks for pointing it out.

-Wei

> commit a3a292c420d2fec3c07a7ca56fbb064cd57a298a
> Author: Amit Shah 
> Date:   Thu Dec 11 13:17:42 2014 +0530
> 
> virtio-rng: fix check for period_ms validity
> 
> Thanks
> Laszlo
> 



Re: [Qemu-devel] [PATCH v2 7/9] i.MX: Add i.MX6 SOC implementation.

2016-02-19 Thread Jean-Christophe DUBOIS

Le 19/02/2016 10:32, Peter Maydell a écrit :

On 19 February 2016 at 06:32, Jean-Christophe DUBOIS
 wrote:

Le 18/02/2016 22:46, Peter Maydell a écrit :

Does SMP work with EL3 not enabled, or is this a different bug?


If I set has_el3 to false, I can boot the 4 cores without problem. With
has_el3 set to true (default value) I am getting the above behavior (boot OK
in uniprocessor mode, and misbehaving if -smp >= 2).

Odd. If you can point me to a test image I can use to investigate
(preferably with System.map and commit hash of kernel used to build it)
I'll see if I can find time to have a look at what's going on there.


I put my test image at the following address:

http://dl.free.fr/rADch1Xnx

You will get a tgz file with the following files in it:

 * imx6q-sabrelite.dtb
 * README
 * rootfs.cpio.gz
 * System.map
 * zImage

Instruction to run the image are in the README file.

The kernel is compiled using the imx_v6_v7_defconfig file (without 
modification) in the linux source tree


Thanks

JC



-- PMM





Re: [Qemu-devel] [PATCH] hw/arm/virt: Assume EL3 boot rom will handle PSCI if one is provided

2016-02-19 Thread Laszlo Ersek
Ard, any opinion on this?

Thanks
Laszlo

On 02/19/16 17:21, Peter Maydell wrote:
> If the user passes us an EL3 boot rom, then it is going to want to
> implement the PSCI interface itself. In this case, disable QEMU's
> internal PSCI implementation so it does not get in the way, and
> instead start all CPUs in an SMP configuration at once (the boot
> rom will catch them all and pen up the secondaries until needed).
> The boot rom code is also responsible for editing the device tree
> to include any necessary information about its own PSCI implementation
> before eventually passing it to a NonSecure guest.
> 
> (This "start all CPUs at once" approach is what both ARM Trusted
> Firmware and UEFI expect, since it is what the ARM Foundation Model
> does; the other approach would be to provide some emulated hardware
> for "start the secondaries" but this is simplest.)
> 
> This is a compatibility break, but I don't believe that anybody
> was using a secure boot ROM with an SMP configuration. Such a setup
> would be somewhat broken since there was nothing preventing nonsecure
> guest code from calling the QEMU PSCI function to start up a secondary
> core in a way that completely bypassed the secure world.
> 
> Signed-off-by: Peter Maydell 
> ---
> This is slightly RFC-ish because I don't actually have any secure boot
> rom code that will cope with SMP right now. But I think that since this
> is a compat break we're better off putting it into 2.6 than not.
> 
>  hw/arm/virt.c | 33 ++---
>  1 file changed, 26 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 4499e2c..0f01902 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -73,6 +73,7 @@ typedef struct VirtBoardInfo {
>  uint32_t clock_phandle;
>  uint32_t gic_phandle;
>  uint32_t v2m_phandle;
> +bool using_psci;
>  } VirtBoardInfo;
>  
>  typedef struct {
> @@ -231,6 +232,10 @@ static void fdt_add_psci_node(const VirtBoardInfo *vbi)
>  void *fdt = vbi->fdt;
>  ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(0));
>  
> +if (!vbi->using_psci) {
> +return;
> +}
> +
>  qemu_fdt_add_subnode(fdt, "/psci");
>  if (armcpu->psci_version == 2) {
>  const char comp[] = "arm,psci-0.2\0arm,psci";
> @@ -342,7 +347,7 @@ static void fdt_add_cpu_nodes(const VirtBoardInfo *vbi)
>  qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible",
>  armcpu->dtb_compatible);
>  
> -if (vbi->smp_cpus > 1) {
> +if (vbi->using_psci && vbi->smp_cpus > 1) {
>  qemu_fdt_setprop_string(vbi->fdt, nodename,
>  "enable-method", "psci");
>  }
> @@ -1081,6 +1086,7 @@ static void machvirt_init(MachineState *machine)
>  VirtGuestInfoState *guest_info_state = g_malloc0(sizeof 
> *guest_info_state);
>  VirtGuestInfo *guest_info = &guest_info_state->info;
>  char **cpustr;
> +bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
>  
>  if (!cpu_model) {
>  cpu_model = "cortex-a15";
> @@ -1146,6 +1152,16 @@ static void machvirt_init(MachineState *machine)
>  memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory",
> UINT64_MAX);
>  memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1);
> +
> +if (firmware_loaded) {
> +/* If we have an EL3 boot ROM then the assumption is that it will
> + * implement PSCI itself, so disable QEMU's internal 
> implementation
> + * so it doesn't get in the way. Instead of starting secondary
> + * CPUs in PSCI powerdown state we will start them all running 
> and
> + * let the boot ROM sort them out.
> + */
> +vbi->using_psci = false;
> +}
>  }
>  
>  create_fdt(vbi);
> @@ -1175,12 +1191,15 @@ static void machvirt_init(MachineState *machine)
>  object_property_set_bool(cpuobj, false, "has_el3", NULL);
>  }
>  
> -object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC, 
> "psci-conduit",
> -NULL);
> +if (vbi->using_psci) {
> +object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_HVC,
> +"psci-conduit", NULL);
>  
> -/* Secondary CPUs start in PSCI powered-down state */
> -if (n > 0) {
> -object_property_set_bool(cpuobj, true, "start-powered-off", 
> NULL);
> +/* Secondary CPUs start in PSCI powered-down state */
> +if (n > 0) {
> +object_property_set_bool(cpuobj, true,
> + "start-powered-off", NULL);
> +}
>  }
>  
>  if (object_property_find(cpuobj, "reset-cbar", NULL)) {
> @@ -1249,7 +1268,7 @@ static void machvirt_init(MachineState *machine)
>  vbi->bootinfo.board_id = -1;
>  vbi->booti

Re: [Qemu-devel] [PATCH 1/1] virtio-rng: fix condition checking on period_ms

2016-02-19 Thread Laszlo Ersek
On 02/19/16 21:57, Laszlo Ersek wrote:
> On 02/19/16 19:13, Wei Huang wrote:
>> The condition checking on vrng->conf.period_ms appears to be wrong,
>> conflicting with the error comment following it.
>>
>> Signed-off-by: Wei Huang 
>> ---
>>  hw/virtio/virtio-rng.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
>> index 473c044..a06427c 100644
>> --- a/hw/virtio/virtio-rng.c
>> +++ b/hw/virtio/virtio-rng.c
>> @@ -149,7 +149,7 @@ static void virtio_rng_device_realize(DeviceState *dev, 
>> Error **errp)
>>  VirtIORNG *vrng = VIRTIO_RNG(dev);
>>  Error *local_err = NULL;
>>  
>> -if (!vrng->conf.period_ms > 0) {
>> +if (!(vrng->conf.period_ms > 0)) {
>>  error_setg(errp, "'period' parameter expects a positive integer");
>>  return;
>>  }
>>
> 
> The current condition is absolutely weird, but I think it happens to
> work correctly:
> 
> Period_ms has type uint32_t. If it is positive, then !period_ms is zero.
> 0>0 is false, hence the error message is not printed.
> 
> If period_ms is zero, then !period_ms is 1. 1>0 is true, hence the error
> message is printed.
> 
> I would rewrite the check as
> 
> if (vrng->conf.period_ms == 0) {
> error_setg(...)

... actually, what the heck are you looking at? :) This has been fixed
up in:

commit a3a292c420d2fec3c07a7ca56fbb064cd57a298a
Author: Amit Shah 
Date:   Thu Dec 11 13:17:42 2014 +0530

virtio-rng: fix check for period_ms validity

Thanks
Laszlo




Re: [Qemu-devel] [PATCH 1/1] virtio-rng: fix condition checking on period_ms

2016-02-19 Thread Laszlo Ersek
On 02/19/16 19:13, Wei Huang wrote:
> The condition checking on vrng->conf.period_ms appears to be wrong,
> conflicting with the error comment following it.
> 
> Signed-off-by: Wei Huang 
> ---
>  hw/virtio/virtio-rng.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
> index 473c044..a06427c 100644
> --- a/hw/virtio/virtio-rng.c
> +++ b/hw/virtio/virtio-rng.c
> @@ -149,7 +149,7 @@ static void virtio_rng_device_realize(DeviceState *dev, 
> Error **errp)
>  VirtIORNG *vrng = VIRTIO_RNG(dev);
>  Error *local_err = NULL;
>  
> -if (!vrng->conf.period_ms > 0) {
> +if (!(vrng->conf.period_ms > 0)) {
>  error_setg(errp, "'period' parameter expects a positive integer");
>  return;
>  }
> 

The current condition is absolutely weird, but I think it happens to
work correctly:

Period_ms has type uint32_t. If it is positive, then !period_ms is zero.
0>0 is false, hence the error message is not printed.

If period_ms is zero, then !period_ms is 1. 1>0 is true, hence the error
message is printed.

I would rewrite the check as

if (vrng->conf.period_ms == 0) {
error_setg(...)

Thanks
Laszlo



[Qemu-devel] [PATCH v3 1/2] generic-loader: Add a generic loader

2016-02-19 Thread Alistair Francis
Add a generic loader to QEMU which can be used to load images or set
memory values.

This only supports ARM architectures at the moment.

Signed-off-by: Alistair Francis 
---
V3:
 - Pass the ram_size to load_image_targphys()
V2:
 - Add maintainers entry
 - Perform bounds checking
 - Register and unregister the reset in the realise/unrealise
Changes since RFC:
 - Add BE support

 MAINTAINERS  |   6 ++
 default-configs/arm-softmmu.mak  |   1 +
 hw/misc/Makefile.objs|   2 +
 hw/misc/generic-loader.c | 143 +++
 include/hw/misc/generic-loader.h |  50 ++
 5 files changed, 202 insertions(+)
 create mode 100644 hw/misc/generic-loader.c
 create mode 100644 include/hw/misc/generic-loader.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9adeda3..7dae3dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -963,6 +963,12 @@ F: hw/acpi/nvdimm.c
 F: hw/mem/nvdimm.c
 F: include/hw/mem/nvdimm.h
 
+Generic Loader
+M: Alistair Francis 
+S: Maintained
+F: hw/misc/generic-loader.c
+F: include/hw/misc/generic-loader.h
+
 Subsystems
 --
 Audio
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index a9f82a1..b246b75 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -110,3 +110,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_LOADER=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ea6cd3c..9f05dcf 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -46,3 +46,5 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 obj-$(CONFIG_PVPANIC) += pvpanic.o
 obj-$(CONFIG_EDU) += edu.o
 obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
+
+obj-$(CONFIG_LOADER) += generic-loader.o
diff --git a/hw/misc/generic-loader.c b/hw/misc/generic-loader.c
new file mode 100644
index 000..20f07a8
--- /dev/null
+++ b/hw/misc/generic-loader.c
@@ -0,0 +1,143 @@
+/*
+ * Generic Loader
+ *
+ * Copyright (C) 2014 Li Guang
+ * Copyright (C) 2016 Xilinx Inc.
+ * Written by Li Guang 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "sysemu/dma.h"
+#include "hw/loader.h"
+#include "hw/misc/generic-loader.h"
+
+#define CPU_NONE 0xFF
+
+static void generic_loader_reset(void *opaque)
+{
+GenericLoaderState *s = GENERIC_LOADER(opaque);
+
+if (s->cpu) {
+CPUClass *cc = CPU_GET_CLASS(s->cpu);
+cpu_reset(s->cpu);
+cc->set_pc(s->cpu, s->addr);
+}
+
+if (s->data_len) {
+assert(s->data_len < sizeof(s->data));
+dma_memory_write((s->cpu ? s->cpu : first_cpu)->as, s->addr, &s->data,
+ s->data_len);
+}
+}
+
+static void generic_loader_realize(DeviceState *dev, Error **errp)
+{
+GenericLoaderState *s = GENERIC_LOADER(dev);
+hwaddr entry;
+int big_endian;
+int size = 0;
+
+qemu_register_reset(generic_loader_reset, dev);
+
+if (s->cpu_nr != CPU_NONE) {
+CPUState *cs = first_cpu;
+int cpu_num = 0;
+
+CPU_FOREACH(cs) {
+if (cpu_num == s->cpu_nr) {
+s->cpu = cs;
+break;
+} else if (!CPU_NEXT(cs)) {
+error_setg(errp, "Specified boot CPU#%d is nonexistent",
+   s->cpu_nr);
+return;
+} else {
+cpu_num++;
+}
+}
+}
+
+#ifdef TARGET_WORDS_BIGENDIAN
+big_endian = 1;
+#else
+big_endian = 0;
+#endif
+
+if (s->file) {
+if (!s->force_raw) {
+size = load_elf(s->file, NULL, NULL, &entry, NULL, NULL,
+big_endian, ELF_ARCH, 0);
+
+if (size < 0) {
+size = load_uimage(s->file, &entry, NULL, NULL, NULL, NULL);
+}
+}
+
+if (size < 0) {
+/* Default to the maximum size being the machines ram size */
+size = load_image_targphys(s->file, s->addr, ram_size);
+} else {
+s->addr = entry;
+}
+
+if (size < 0) {
+error_setg(errp, "Cannot load specified image %s", s->file);
+return;
+}
+}
+
+if (s->data_len && (s->data_len > sizeof(s->data))) {
+error_setg(errp, "data-len cannot be more then the data size");
+return;
+}
+}
+
+static void generic_loader_unrealize(DeviceState *dev, Error **errp)
+{
+qemu_unregister_reset(generic_loader_reset, dev);
+}

[Qemu-devel] [PATCH v3 0/2] Add a generic loader

2016-02-19 Thread Alistair Francis
This work is based on the original work by Li Guang with extra
features added by Peter C and myself.

The idea of this loader is to allow the user to load multiple images
or values into QEMU at startup.

Memory values can be loaded like this: -device 
loader,addr=0xfd1a0104,data=0x800e,data-len=4

Images can be loaded like this: -device loader,file=./images/u-boot.elf,cpu=0

This can be useful and we use it a lot in Xilinx to load multiple images
into a machine at creation (ATF, Kernel and DTB for example).

It can also be used to set registers.

The limiation for arch is based off settting the ELF_ARCH macro.

The reset patch is required otherwise the reset will never be registered
and the loader can't change the PC in the case of images.

V2:
 - Add an entry to the maintainers file
 - Add some documentation
 - Perform bounds checking on the data_len
 - Register and unregister the reset in the realise/unrealise
Changes since RFC:
 - Add support for BE


Alistair Francis (2):
  generic-loader: Add a generic loader
  docs: Add a generic loader explanation document

 MAINTAINERS  |   6 ++
 default-configs/arm-softmmu.mak  |   1 +
 docs/generic-loader.txt  |  21 ++
 hw/misc/Makefile.objs|   2 +
 hw/misc/generic-loader.c | 143 +++
 include/hw/misc/generic-loader.h |  50 ++
 6 files changed, 223 insertions(+)
 create mode 100644 docs/generic-loader.txt
 create mode 100644 hw/misc/generic-loader.c
 create mode 100644 include/hw/misc/generic-loader.h

-- 
2.5.0




[Qemu-devel] [PATCH v3 2/2] docs: Add a generic loader explanation document

2016-02-19 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---

 docs/generic-loader.txt | 21 +
 1 file changed, 21 insertions(+)
 create mode 100644 docs/generic-loader.txt

diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt
new file mode 100644
index 000..69e262d
--- /dev/null
+++ b/docs/generic-loader.txt
@@ -0,0 +1,21 @@
+Copyright (c) 2016 Xilinx Inc.
+
+This work is licensed under the terms of the GNU GPL, version 2 or later.  See
+the COPYING file in the top-level directory.
+
+
+This loader allows the user to load multiple images or values into QEMU at 
startup.
+
+Loading Memory Values
+---
+Memory values can be loaded like this:
+-device loader,addr=0xfd1a0104,data=0x800e,data-len=4
+
+Loading Images
+---
+Images can be loaded like this:
+-device loader,file=./images/boot.elf,cpu=0
+
+The limiation for arch is based off settting the ELF_ARCH macro.
+
+At the moment only the ARM arhitectures are supported
-- 
2.5.0




[Qemu-devel] [PATCH v2 0/8] arm: Steps towards EL2 support round 6

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Hi,

Another round of patches towards EL2 support. This one adds partial
Instruction Syndrome generation for Data Aborts while running in AArch64.

I don't feel very confident with the way I collect the regsize info used
to fill out the SF field. Feedback on that would be great.

Once we sort out the details on how this should be implemented we can
fill out the parts needed for AArch32. Possibly in a future version of
this same series.

Comments welcome!

Best regards,
Edgar

ChangeLog:

v1 -> v2:
* Reworked the syndrome generation code to reuse syn_data_abort for
  the encoding.
* Reworded a bunch of comments.
* Fixed thumb vs 16bit IL field issue.

Edgar E. Iglesias (8):
  tcg: Add tcg_set_insn_param
  gen-icount: Use tcg_set_insn_param
  target-arm: Add the IL flag to syn_data_abort
  target-arm: Add more fields to the data abort syndrome generator
  target-arm/translate-a64.c: Use extract32 in disas_ldst_reg_imm9
  target-arm/translate-a64.c: Unify some of the ldst_reg decoding
  target-arm: A64: Create Instruction Syndromes for Data Aborts
  target-arm: Use isyn.swstep.ex to hold the is_ldex state

 include/exec/gen-icount.h  |  16 +++---
 target-arm/cpu.h   |   2 +-
 target-arm/internals.h |  24 +++--
 target-arm/op_helper.c |  41 +--
 target-arm/translate-a64.c | 123 -
 target-arm/translate.c |  11 ++--
 target-arm/translate.h |  27 --
 tcg/tcg.h  |   6 +++
 8 files changed, 201 insertions(+), 49 deletions(-)

-- 
1.9.1




Re: [Qemu-devel] [RFC PATCH v2 09/10] net/colo-proxy: Compare pri pkt to sec pkt

2016-02-19 Thread Dr. David Alan Gilbert
* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:
> From: zhangchen 
> 
> We will compare packet sent by primary guest
> to secondary guest,if same,send primary packet.
> else we will notify colo to do checkpoint to
> make secondary guset running same as primary
> 
> Signed-off-by: zhangchen 
> Signed-off-by: zhanghailiang 
> ---
>  net/colo-proxy.c | 64 
> 
>  1 file changed, 64 insertions(+)
> 
> diff --git a/net/colo-proxy.c b/net/colo-proxy.c
> index 06bab80..abb289f 100644
> --- a/net/colo-proxy.c
> +++ b/net/colo-proxy.c
> @@ -602,6 +602,70 @@ static void colo_proxy_notify_checkpoint(void)
>  colo_do_checkpoint = true;
>  }
>  
> +/*
> + * The IP packets sent by primary and secondary
> + * will be comparison in here
> + * TODO: support ip fragment
> + * return:0  means packet same
> + *> 0 || < 0 means packet different
> + */
> +static int colo_packet_compare(Packet *ppkt, Packet *spkt)
> +{
> +trace_colo_proxy("colo_packet_compare data   ppkt");
> +trace_colo_proxy_packet_size(ppkt->size);
> +trace_colo_proxy_packet_src(inet_ntoa(ppkt->ip->ip_src));
> +trace_colo_proxy_packet_dst(inet_ntoa(ppkt->ip->ip_dst));
> +colo_proxy_dump_packet(ppkt);
> +trace_colo_proxy("colo_packet_compare data   spkt");
> +trace_colo_proxy_packet_size(spkt->size);
> +trace_colo_proxy_packet_src(inet_ntoa(spkt->ip->ip_src));
> +trace_colo_proxy_packet_dst(inet_ntoa(spkt->ip->ip_dst));
> +colo_proxy_dump_packet(spkt);
> +
> +if (ppkt->size == spkt->size) {
> +return memcmp(ppkt->data, spkt->data, spkt->size);
> +} else {
> +trace_colo_proxy("colo_packet_compare size not same");
> +return -1;
> +}
> +}
> +
> +static void colo_compare_connection(void *opaque, void *user_data)
> +{
> +Connection *conn = opaque;
> +Packet *pkt = NULL;
> +GList *result = NULL;
> +
> +while (!g_queue_is_empty(&conn->primary_list) &&
> +!g_queue_is_empty(&conn->secondary_list)) {
> +pkt = g_queue_pop_head(&conn->primary_list);
> +result = g_queue_find_custom(&conn->secondary_list,
> +pkt, (GCompareFunc)colo_packet_compare);

Are you sure the 'ppkt' and 'spkt' are the right way around in 
colo_packet_compare?
(Not that in this simple version it makes much difference).
My reading of g_queue_find_custom's man page is that the first parameter
of the compare function comes from the list, which is the secondary.

> +if (result) {
> +colo_send_primary_packet(pkt, NULL);
> +trace_colo_proxy("packet same and release packet");
> +} else {
> +g_queue_push_tail(&conn->primary_list, pkt);

You pop the packets off the head of the primary list above,
but push it back to the tail here; why do you reorder?

Dave

> +trace_colo_proxy("packet different");
> +colo_proxy_notify_checkpoint();
> +break;
> +}
> +}
> +}
> +
> +static void *colo_proxy_compare_thread(void *opaque)
> +{
> +COLOProxyState *s = opaque;
> +
> +while (s->status == COLO_PROXY_RUNNING) {
> +qemu_event_wait(&s->need_compare_ev);
> +qemu_event_reset(&s->need_compare_ev);
> +g_queue_foreach(&s->conn_list, colo_compare_connection, NULL);
> +}
> +
> +return NULL;
> +}
> +
>  static void colo_proxy_start_one(NetFilterState *nf,
>void *opaque, Error **errp)
>  {
> -- 
> 1.9.1
> 
> 
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-devel] [PATCH v2 4/8] target-arm: Add more fields to the data abort syndrome generator

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add the following flags to the data abort syndrome generator:
* isv - Instruction syndrome valid
* sas - Syndrome access size
* sse - Syndrome sign extend
* srt - Syndrome register transfer
* sf  - Sixty-Four bit register width
* ar  - Acquire/Release

These flags are not yet used, so this patch has no functional change.

Signed-off-by: Edgar E. Iglesias 
---
 target-arm/internals.h | 20 ++--
 target-arm/op_helper.c |  8 ++--
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/target-arm/internals.h b/target-arm/internals.h
index 34e2688..4e9d9f5 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -383,13 +383,29 @@ static inline uint32_t syn_insn_abort(int same_el, int 
ea, int s1ptw, int fsc)
 | (ea << 9) | (s1ptw << 7) | fsc;
 }
 
-static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw,
+static inline uint32_t syn_data_abort(int same_el, int isv,
+  int sas, int sse, int srt,
+  int sf, int ar,
+  int ea, int cm, int s1ptw,
   int wnr, int fsc,
   bool is_16bit)
 {
-return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
+uint32_t v;
+v = (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
 | (is_16bit ? 0 : ARM_EL_IL)
 | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
+
+/* Insn Syndrome fields are RES0 if ISV is unset.  */
+if (isv) {
+v |= (isv << 24) | (sas << 22) | (sse << 21) | (srt << 16)
+ | (sf << 15) | (ar << 14);
+} else {
+/* If ISV is zero, the IL field should be set to one.
+ * See ARM ARMv8 D7.2.27 for more details.
+ */
+v |= ARM_EL_IL;
+}
+return v;
 }
 
 static inline uint32_t syn_swstep(int same_el, int isv, int ex)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 7e845d5..2522d3c 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -115,7 +115,9 @@ void tlb_fill(CPUState *cs, target_ulong addr, int 
is_write, int mmu_idx,
 syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
 exc = EXCP_PREFETCH_ABORT;
 } else {
-syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn,
+syn = syn_data_abort(same_el,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, fi.s1ptw, is_write == 1, syn,
  1);
 if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
 fsr |= (1 << 11);
@@ -162,7 +164,9 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 
int is_write,
 }
 
 raise_exception(env, EXCP_DATA_ABORT,
-syn_data_abort(same_el, 0, 0, 0, is_write == 1, 0x21,
+syn_data_abort(same_el,
+   0, 0, 0, 0, 0, 0,
+   0, 0, 0, is_write == 1, 0x21,
1),
 target_el);
 }
-- 
1.9.1




[Qemu-devel] [PATCH v2 8/8] target-arm: Use isyn.swstep.ex to hold the is_ldex state

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Switch to using isyn.swstep.ex to hold the is_ldex state for
SWStep syndrome generation.

No functional change.

Signed-off-by: Edgar E. Iglesias 
---
 target-arm/translate-a64.c |  6 +++---
 target-arm/translate.c |  6 +++---
 target-arm/translate.h | 13 -
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 5250c08..ab249d1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -260,7 +260,7 @@ static void gen_step_complete_exception(DisasContext *s)
  * of the exception, and our syndrome information is always correct.
  */
 gen_ss_advance(s);
-gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
+gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->isyn.swstep.ex),
   default_exception_el(s));
 s->is_jmp = DISAS_EXC;
 }
@@ -1865,7 +1865,7 @@ static void disas_ldst_excl(DisasContext *s, uint32_t 
insn)
 
 if (is_excl) {
 if (!is_store) {
-s->is_ldex = true;
+s->isyn.swstep.ex = true;
 gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
 } else {
 gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
@@ -11136,7 +11136,7 @@ void gen_intermediate_code_a64(ARMCPU *cpu, 
TranslationBlock *tb)
  */
 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
-dc->is_ldex = false;
+dc->isyn.swstep.ex = false;
 dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
 init_tmp_a64_array(dc);
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 7d83c94..5aee066 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -250,7 +250,7 @@ static void gen_step_complete_exception(DisasContext *s)
  * of the exception, and our syndrome information is always correct.
  */
 gen_ss_advance(s);
-gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
+gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->isyn.swstep.ex),
   default_exception_el(s));
 s->is_jmp = DISAS_EXC;
 }
@@ -7431,7 +7431,7 @@ static void gen_load_exclusive(DisasContext *s, int rt, 
int rt2,
 {
 TCGv_i32 tmp = tcg_temp_new_i32();
 
-s->is_ldex = true;
+s->isyn.swstep.ex = true;
 
 switch (size) {
 case 0:
@@ -11341,7 +11341,7 @@ void gen_intermediate_code(CPUARMState *env, 
TranslationBlock *tb)
  */
 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
-dc->is_ldex = false;
+dc->isyn.swstep.ex = false;
 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
 
 cpu_F0s = tcg_temp_new_i32();
diff --git a/target-arm/translate.h b/target-arm/translate.h
index e002c90..1c4c087 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -49,11 +49,6 @@ typedef struct DisasContext {
  */
 bool ss_active;
 bool pstate_ss;
-/* True if the insn just emitted was a load-exclusive instruction
- * (necessary for syndrome information for single step exceptions),
- * ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
- */
-bool is_ldex;
 /* True if a single-step exception will be taken to the current EL */
 bool ss_same_el;
 /* Bottom two bits of XScale c15_cpar coprocessor access control reg */
@@ -69,6 +64,14 @@ typedef struct DisasContext {
 bool sf;
 bool ar;
 } dabt;
+/* SWStep section.  */
+struct {
+/* True if the insn just emitted was a load-exclusive instruction
+ * (necessary for syndrome information for single step exceptions),
+ * ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
+ */
+bool ex;
+} swstep;
 } isyn;
 /* TCG op index of the current insn_start.  */
 int insn_start_idx;
-- 
1.9.1




[Qemu-devel] [PATCH v2 3/8] target-arm: Add the IL flag to syn_data_abort

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add the IL flag to syn_data_abort(). Since we at the moment
never set ISV, the IL flag is always set to one.

Signed-off-by: Edgar E. Iglesias 
---
 target-arm/internals.h | 4 +++-
 target-arm/op_helper.c | 6 --
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/target-arm/internals.h b/target-arm/internals.h
index 2e70272..34e2688 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -384,9 +384,11 @@ static inline uint32_t syn_insn_abort(int same_el, int ea, 
int s1ptw, int fsc)
 }
 
 static inline uint32_t syn_data_abort(int same_el, int ea, int cm, int s1ptw,
-  int wnr, int fsc)
+  int wnr, int fsc,
+  bool is_16bit)
 {
 return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
+| (is_16bit ? 0 : ARM_EL_IL)
 | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
 }
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 538887c..7e845d5 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -115,7 +115,8 @@ void tlb_fill(CPUState *cs, target_ulong addr, int 
is_write, int mmu_idx,
 syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
 exc = EXCP_PREFETCH_ABORT;
 } else {
-syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn);
+syn = syn_data_abort(same_el, 0, 0, fi.s1ptw, is_write == 1, syn,
+ 1);
 if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
 fsr |= (1 << 11);
 }
@@ -161,7 +162,8 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 
int is_write,
 }
 
 raise_exception(env, EXCP_DATA_ABORT,
-syn_data_abort(same_el, 0, 0, 0, is_write == 1, 0x21),
+syn_data_abort(same_el, 0, 0, 0, is_write == 1, 0x21,
+   1),
 target_el);
 }
 
-- 
1.9.1




[Qemu-devel] [PATCH v2 6/8] target-arm/translate-a64.c: Unify some of the ldst_reg decoding

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

The various load/store variants under disas_ldst_reg can all reuse the
same decoding for opc, size, rt and is_vector.

This patch unifies the decoding in preparation for generating
instruction syndromes for data aborts.
This will allow us to reduce the number of places to hook in updates
to the load/store state needed to generate the insn syndromes.

No functional change.

Reviewed-by: Sergey Fedorov 
Signed-off-by: Edgar E. Iglesias 
---
 target-arm/translate-a64.c | 41 +++--
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index bf31f8a..9e26d5e 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2075,19 +2075,19 @@ static void disas_ldst_pair(DisasContext *s, uint32_t 
insn)
  * size: 00 -> 8 bit, 01 -> 16 bit, 10 -> 32 bit, 11 -> 64bit
  * opc: 00 -> store, 01 -> loadu, 10 -> loads 64, 11 -> loads 32
  */
-static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn)
+static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
+int opc,
+int size,
+int rt,
+bool is_vector)
 {
-int rt = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 int imm9 = sextract32(insn, 12, 9);
-int opc = extract32(insn, 22, 2);
-int size = extract32(insn, 30, 2);
 int idx = extract32(insn, 10, 2);
 bool is_signed = false;
 bool is_store = false;
 bool is_extended = false;
 bool is_unpriv = (idx == 2);
-bool is_vector = extract32(insn, 26, 1);
 bool post_index;
 bool writeback;
 
@@ -2194,19 +2194,19 @@ static void disas_ldst_reg_imm9(DisasContext *s, 
uint32_t insn)
  * Rn: address register or SP for base
  * Rm: offset register or ZR for offset
  */
-static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn)
+static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
+   int opc,
+   int size,
+   int rt,
+   bool is_vector)
 {
-int rt = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 int shift = extract32(insn, 12, 1);
 int rm = extract32(insn, 16, 5);
-int opc = extract32(insn, 22, 2);
 int opt = extract32(insn, 13, 3);
-int size = extract32(insn, 30, 2);
 bool is_signed = false;
 bool is_store = false;
 bool is_extended = false;
-bool is_vector = extract32(insn, 26, 1);
 
 TCGv_i64 tcg_rm;
 TCGv_i64 tcg_addr;
@@ -2283,14 +2283,14 @@ static void disas_ldst_reg_roffset(DisasContext *s, 
uint32_t insn)
  * Rn: base address register (inc SP)
  * Rt: target register
  */
-static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn)
+static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
+int opc,
+int size,
+int rt,
+bool is_vector)
 {
-int rt = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 unsigned int imm12 = extract32(insn, 10, 12);
-bool is_vector = extract32(insn, 26, 1);
-int size = extract32(insn, 30, 2);
-int opc = extract32(insn, 22, 2);
 unsigned int offset;
 
 TCGv_i64 tcg_addr;
@@ -2349,20 +2349,25 @@ static void disas_ldst_reg_unsigned_imm(DisasContext 
*s, uint32_t insn)
 /* Load/store register (all forms) */
 static void disas_ldst_reg(DisasContext *s, uint32_t insn)
 {
+int rt = extract32(insn, 0, 5);
+int opc = extract32(insn, 22, 2);
+bool is_vector = extract32(insn, 26, 1);
+int size = extract32(insn, 30, 2);
+
 switch (extract32(insn, 24, 2)) {
 case 0:
 if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
-disas_ldst_reg_roffset(s, insn);
+disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
 } else {
 /* Load/store register (unscaled immediate)
  * Load/store immediate pre/post-indexed
  * Load/store register unprivileged
  */
-disas_ldst_reg_imm9(s, insn);
+disas_ldst_reg_imm9(s, insn, opc, size, rt, is_vector);
 }
 break;
 case 1:
-disas_ldst_reg_unsigned_imm(s, insn);
+disas_ldst_reg_unsigned_imm(s, insn, opc, size, rt, is_vector);
 break;
 default:
 unallocated_encoding(s);
-- 
1.9.1




[Qemu-devel] [PATCH v2 5/8] target-arm/translate-a64.c: Use extract32 in disas_ldst_reg_imm9

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use extract32 instead of open coding the bit masking when decoding
is_signed and is_extended. This streamlines the decoding with some
of the other ldst variants.

No functional change.

Reviewed-by: Sergey Fedorov 
Signed-off-by: Edgar E. Iglesias 
---
 target-arm/translate-a64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 7f65aea..bf31f8a 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2117,8 +2117,8 @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t 
insn)
 return;
 }
 is_store = (opc == 0);
-is_signed = opc & (1<<1);
-is_extended = (size < 3) && (opc & 1);
+is_signed = extract32(opc, 1, 1);
+is_extended = (size < 3) && extract32(opc, 0, 1);
 }
 
 switch (idx) {
-- 
1.9.1




[Qemu-devel] [PATCH v2 7/8] target-arm: A64: Create Instruction Syndromes for Data Aborts

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add support for generating the instruction syndrome for Data Aborts.
These syndromes are used by hypervisors for example to trap and emulate
memory accesses.

We save the decoded data out-of-band with the TBs at translation time.
When exceptions hit, the extra data attached to the TB is used to
recreate the state needed to encode instruction syndromes.
This avoids the need to emit moves with every load/store.

Based on a suggestion from Peter Maydell.

Suggested-by: Peter Maydell 
Signed-off-by: Edgar E. Iglesias 
---
 target-arm/cpu.h   |  2 +-
 target-arm/op_helper.c | 47 +++---
 target-arm/translate-a64.c | 72 +-
 target-arm/translate.c |  5 +++-
 target-arm/translate.h | 14 +
 5 files changed, 127 insertions(+), 13 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 1623821..c3ade8d 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -95,7 +95,7 @@
 struct arm_boot_info;
 
 #define NB_MMU_MODES 7
-#define TARGET_INSN_START_EXTRA_WORDS 1
+#define TARGET_INSN_START_EXTRA_WORDS 2
 
 /* We currently assume float and double are IEEE single and double
precision respectively.
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 2522d3c..6070588 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -75,6 +75,37 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, 
uint32_t def,
 
 #if !defined(CONFIG_USER_ONLY)
 
+static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
+unsigned int target_el,
+bool same_el,
+bool s1ptw, int is_write,
+int fsc)
+{
+uint32_t syn;
+
+if (target_el != 2 || s1ptw) {
+/* ISV is only set for data aborts routed to EL2 and
+ * never for stage-1 page table walks faulting on stage 2.
+ *
+ * See ARMv8 specs, D7-1974:
+ * ISS encoding for an exception from a Data Abort, the
+ * ISV field.
+ */
+template_syn = 0;
+}
+/* Fields: IL, ISV, SAS, SSE, SRT, SF and AR come from the template
+ * syndrome created at translation time.
+ * Now we create the runtime syndrome with the remaining fields.
+ */
+syn = syn_data_abort(same_el,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, s1ptw, is_write == 1, fsc,
+ 0);
+/* Merge runtime syndrome with the template syndrome.  */
+syn |= template_syn;
+return syn;
+}
+
 /* try to fill the TLB and return an exception if error. If retaddr is
  * NULL, it means that the function was called in C code (i.e. not
  * from generated code or from helper.c)
@@ -115,10 +146,8 @@ void tlb_fill(CPUState *cs, target_ulong addr, int 
is_write, int mmu_idx,
 syn = syn_insn_abort(same_el, 0, fi.s1ptw, syn);
 exc = EXCP_PREFETCH_ABORT;
 } else {
-syn = syn_data_abort(same_el,
- 0, 0, 0, 0, 0, 0,
- 0, 0, fi.s1ptw, is_write == 1, syn,
- 1);
+syn = merge_syn_data_abort(env->exception.syndrome, target_el,
+   same_el, fi.s1ptw, is_write, syn);
 if (is_write == 1 && arm_feature(env, ARM_FEATURE_V6)) {
 fsr |= (1 << 11);
 }
@@ -139,6 +168,7 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, 
int is_write,
 CPUARMState *env = &cpu->env;
 int target_el;
 bool same_el;
+uint32_t syn;
 
 if (retaddr) {
 /* now we have a real cpu fault */
@@ -163,12 +193,9 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr 
vaddr, int is_write,
 env->exception.fsr |= (1 << 11);
 }
 
-raise_exception(env, EXCP_DATA_ABORT,
-syn_data_abort(same_el,
-   0, 0, 0, 0, 0, 0,
-   0, 0, 0, is_write == 1, 0x21,
-   1),
-target_el);
+syn = merge_syn_data_abort(env->exception.syndrome, target_el,
+   same_el, 0, is_write, 0x21);
+raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
 }
 
 #endif /* !defined(CONFIG_USER_ONLY) */
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 9e26d5e..5250c08 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1803,6 +1803,24 @@ static void gen_store_exclusive(DisasContext *s, int rd, 
int rt, int rt2,
 }
 #endif
 
+static void disas_ldr_update_isyn_sse_sf(DisasContext *s, int size,
+bool is_signed, int opc)
+{
+int opc0 = extract32(opc, 0, 1);
+int regsize;
+
+s->isyn.dabt.sse = is_signed;
+/* Updat

[Qemu-devel] [PATCH v2 2/8] gen-icount: Use tcg_set_insn_param

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Use tcg_set_insn_param() instead of directly accessing internal
tcg data structures to update an insn param.

Reviewed-by: Richard Henderson 
Signed-off-by: Edgar E. Iglesias 
---
 include/exec/gen-icount.h | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 05d89d3..a011324 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -5,14 +5,13 @@
 
 /* Helpers for instruction counting code generation.  */
 
-static TCGArg *icount_arg;
+static int icount_start_insn_idx;
 static TCGLabel *icount_label;
 static TCGLabel *exitreq_label;
 
 static inline void gen_tb_start(TranslationBlock *tb)
 {
 TCGv_i32 count, flag, imm;
-int i;
 
 exitreq_label = gen_new_label();
 flag = tcg_temp_new_i32();
@@ -31,13 +30,12 @@ static inline void gen_tb_start(TranslationBlock *tb)
-ENV_OFFSET + offsetof(CPUState, icount_decr.u32));
 
 imm = tcg_temp_new_i32();
+/* We emit a movi with a dummy immediate argument. Keep the insn index
+ * of the movi so that we later (when we know the actual insn count)
+ * can update the immediate argument with the actual insn count.  */
+icount_start_insn_idx = tcg_op_buf_count();
 tcg_gen_movi_i32(imm, 0xdeadbeef);
 
-/* This is a horrid hack to allow fixing up the value later.  */
-i = tcg_ctx.gen_last_op_idx;
-i = tcg_ctx.gen_op_buf[i].args;
-icount_arg = &tcg_ctx.gen_opparam_buf[i + 1];
-
 tcg_gen_sub_i32(count, count, imm);
 tcg_temp_free_i32(imm);
 
@@ -53,7 +51,9 @@ static void gen_tb_end(TranslationBlock *tb, int num_insns)
 tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED);
 
 if (tb->cflags & CF_USE_ICOUNT) {
-*icount_arg = num_insns;
+/* Update the num_insn immediate parameter now that we know
+ * the actual insn count.  */
+tcg_set_insn_param(icount_start_insn_idx, 1, num_insns);
 gen_set_label(icount_label);
 tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
 }
-- 
1.9.1




[Qemu-devel] [PATCH v2 1/8] tcg: Add tcg_set_insn_param

2016-02-19 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Add tcg_set_insn_param as a mechanism to modify an insn
parameter after emiting the insn. This is useful for icount
and also for embedding fault information for a specific insn.

Reviewed-by: Richard Henderson 
Signed-off-by: Edgar E. Iglesias 
---
 tcg/tcg.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 83da5fb..00dd124 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -585,6 +585,12 @@ struct TCGContext {
 
 extern TCGContext tcg_ctx;
 
+static inline void tcg_set_insn_param(int op_idx, int arg, TCGArg v)
+{
+int op_argi = tcg_ctx.gen_op_buf[op_idx].args;
+tcg_ctx.gen_opparam_buf[op_argi + arg] = v;
+}
+
 /* The number of opcodes emitted so far.  */
 static inline int tcg_op_buf_count(void)
 {
-- 
1.9.1




Re: [Qemu-devel] [RFC PATCH v2 08/10] net/colo-proxy: Handle packet and connection

2016-02-19 Thread Dr. David Alan Gilbert
* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:
> From: zhangchen 
> 
> In here we will handle ip packet and connection
> 
> Signed-off-by: zhangchen 
> Signed-off-by: zhanghailiang 
> ---
>  net/colo-proxy.c | 130 
> +++
>  1 file changed, 130 insertions(+)
> 
> diff --git a/net/colo-proxy.c b/net/colo-proxy.c
> index 5e5c72e..06bab80 100644
> --- a/net/colo-proxy.c
> +++ b/net/colo-proxy.c
> @@ -167,11 +167,141 @@ static int connection_key_equal(const void *opaque1, 
> const void *opaque2)
>  return memcmp(opaque1, opaque2, sizeof(ConnectionKey)) == 0;
>  }
>  
> +static void connection_destroy(void *opaque)
> +{
> +Connection *conn = opaque;
> +
> +g_queue_foreach(&conn->primary_list, packet_destroy, NULL);
> +g_queue_free(&conn->primary_list);
> +g_queue_foreach(&conn->secondary_list, packet_destroy, NULL);

Be careful about these lists and which threads access them;
I found I could occasionally trigger a seg fault as two
threads tried to manipulate them at once; I just put a 'list_lock'
in the connection, which seems to fix it, but I might have to be
more careful with deadlocks.

> +g_queue_free(&conn->secondary_list);
> +g_slice_free(Connection, conn);
> +}
> +
> +static Connection *connection_new(ConnectionKey *key)
> +{
> +Connection *conn = g_slice_new(Connection);
> +
> +conn->ip_proto = key->ip_proto;
> +conn->processing = false;
> +g_queue_init(&conn->primary_list);
> +g_queue_init(&conn->secondary_list);
> +
> +return conn;
> +}
> +
> +/*
> + * Clear hashtable, stop this hash growing really huge
> + */
> +static void clear_connection_hashtable(COLOProxyState *s)
> +{
> +s->hashtable_size = 0;
> +g_hash_table_remove_all(colo_conn_hash);
> +trace_colo_proxy("clear_connection_hashtable");
> +}
> +
>  bool colo_proxy_query_checkpoint(void)
>  {
>  return colo_do_checkpoint;
>  }
>  
> +/* Return 0 on success, or return -1 if the pkt is corrupted */
> +static int parse_packet_early(Packet *pkt, ConnectionKey *key)
> +{
> +int network_length;
> +uint8_t *data = pkt->data;
> +uint16_t l3_proto;
> +uint32_t tmp_ports;
> +ssize_t l2hdr_len = eth_get_l2_hdr_length(data);
> +
> +pkt->network_layer = data + ETH_HLEN;
> +l3_proto = eth_get_l3_proto(data, l2hdr_len);
> +if (l3_proto != ETH_P_IP) {
> +if (l3_proto == ETH_P_ARP) {
> +return -1;
> +}
> +return 0;
> +}
> +
> +network_length = pkt->ip->ip_hl * 4;
> +pkt->transport_layer = pkt->network_layer + network_length;
> +key->ip_proto = pkt->ip->ip_p;
> +key->src = pkt->ip->ip_src;
> +key->dst = pkt->ip->ip_dst;
> +
> +switch (key->ip_proto) {
> +case IPPROTO_TCP:
> +case IPPROTO_UDP:
> +case IPPROTO_DCCP:
> +case IPPROTO_ESP:
> +case IPPROTO_SCTP:
> +case IPPROTO_UDPLITE:
> +tmp_ports = *(uint32_t *)(pkt->transport_layer);
> +key->src_port = tmp_ports & 0x;
> +key->dst_port = tmp_ports >> 16;

These fields are not byteswapped; it makes it very confusing
when printing them for debug;  I added htons around every
reading of the ports from the packets.

Dave

> +break;
> +case IPPROTO_AH:
> +tmp_ports = *(uint32_t *)(pkt->transport_layer + 4);
> +key->src_port = tmp_ports & 0x;
> +key->dst_port = tmp_ports >> 16;
> +break;
> +default:
> +break;
> +}
> +
> +return 0;
> +}
> +
> +static Packet *packet_new(COLOProxyState *s, void *data,
> +  int size, ConnectionKey *key, NetClientState 
> *sender)
> +{
> +Packet *pkt = g_slice_new(Packet);
> +
> +pkt->data = data;
> +pkt->size = size;
> +pkt->s = s;
> +pkt->sender = sender;
> +
> +if (parse_packet_early(pkt, key)) {
> +packet_destroy(pkt, NULL);
> +pkt = NULL;
> +}
> +
> +return pkt;
> +}
> +
> +static void packet_destroy(void *opaque, void *user_data)
> +{
> +Packet *pkt = opaque;
> +g_free(pkt->data);
> +g_slice_free(Packet, pkt);
> +}
> +
> +/* if not found, creata a new connection and add to hash table */
> +static Connection *colo_proxy_get_conn(COLOProxyState *s,
> +ConnectionKey *key)
> +{
> +/* FIXME: protect colo_conn_hash */
> +Connection *conn = g_hash_table_lookup(colo_conn_hash, key);
> +
> +if (conn == NULL) {
> +ConnectionKey *new_key = g_malloc(sizeof(*key));
> +
> +conn = connection_new(key);
> +memcpy(new_key, key, sizeof(*key));
> +
> +s->hashtable_size++;
> +if (s->hashtable_size > hashtable_max_size) {
> +trace_colo_proxy("colo proxy connection hashtable full, clear 
> it");
> +clear_connection_hashtable(s);
> +} else {
> +g_hash_table_insert(colo_conn_hash, new_key, conn);
> +}
> +}
> +
> + return conn;
> +}
> +
>  static ssize_t colo_proxy_enqueue_pri

Re: [Qemu-devel] [RFC PATCH v2 06/10] net/colo-proxy: add socket used by forward func

2016-02-19 Thread Dr. David Alan Gilbert
* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:
> From: zhangchen 
> 
> Colo need to forward packets
> we start socket server in secondary and primary
> connect to secondary in startup
> the packet recv by primary forward to secondary
> the packet send by secondary forward to primary
> 
> Signed-off-by: zhangchen 
> Signed-off-by: zhanghailiang 

I found one problem with the socket setup is that the
packets from the primary and secondary aren't tied to the
checkpoint they are part of; so for example a packet from the secondary
may reach the primary at the start of the next checkpoint, causing a
miscomparison.
I added a counter to discard old packets.

Dave

> ---
>  net/colo-proxy.c | 114 
> +++
>  1 file changed, 114 insertions(+)
> 
> diff --git a/net/colo-proxy.c b/net/colo-proxy.c
> index ba2bbe7..2347bbf 100644
> --- a/net/colo-proxy.c
> +++ b/net/colo-proxy.c
> @@ -172,6 +172,69 @@ bool colo_proxy_query_checkpoint(void)
>  return colo_do_checkpoint;
>  }
>  
> +/*
> + * send a packet to peer
> + * >=0: success
> + * <0: fail
> + */
> +static ssize_t colo_proxy_sock_send(NetFilterState *nf,
> + const struct iovec *iov,
> + int iovcnt)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(nf);
> +ssize_t ret = 0;
> +ssize_t size = 0;
> +struct iovec sizeiov = {
> +.iov_base = &size,
> +.iov_len = sizeof(size)
> +};
> +size = iov_size(iov, iovcnt);
> +if (!size) {
> +return 0;
> +}
> +
> +ret = iov_send(s->sockfd, &sizeiov, 1, 0, sizeof(size));
> +if (ret < 0) {
> +return ret;
> +}
> +ret = iov_send(s->sockfd, iov, iovcnt, 0, size);
> +return ret;
> +}
> +
> +/*
> + * receive a packet from peer
> + * in primary: enqueue packet to secondary_list
> + * in secondary: pass packet to next
> + */
> +static void colo_proxy_sock_receive(void *opaque)
> +{
> +NetFilterState *nf = opaque;
> +COLOProxyState *s = FILTER_COLO_PROXY(nf);
> +ssize_t len = 0;
> +struct iovec sizeiov = {
> +.iov_base = &len,
> +.iov_len = sizeof(len)
> +};
> +
> +iov_recv(s->sockfd, &sizeiov, 1, 0, sizeof(len));
> +if (len > 0 && len < NET_BUFSIZE) {
> +char *buf = g_malloc0(len);
> +struct iovec iov = {
> +.iov_base = buf,
> +.iov_len = len
> +};
> +
> +iov_recv(s->sockfd, &iov, 1, 0, len);
> +if (s->colo_mode == COLO_MODE_PRIMARY) {
> +colo_proxy_enqueue_secondary_packet(nf, buf, len);
> +/* buf will be release when pakcet destroy */
> +} else {
> +qemu_net_queue_send(s->incoming_queue, nf->netdev,
> +0, (const uint8_t *)buf, len, NULL);
> +}
> +}
> +}
> +
>  static ssize_t colo_proxy_receive_iov(NetFilterState *nf,
>   NetClientState *sender,
>   unsigned flags,
> @@ -208,6 +271,57 @@ static void colo_proxy_cleanup(NetFilterState *nf)
>  qemu_event_destroy(&s->need_compare_ev);
>  }
>  
> +/* wait for peer connecting
> + * NOTE: this function will block the caller
> + * 0 on success, otherwise returns -1
> + */
> +static int colo_wait_incoming(COLOProxyState *s)
> +{
> +struct sockaddr_in addr;
> +socklen_t addrlen = sizeof(addr);
> +int accept_sock, err;
> +int fd = inet_listen(s->addr, NULL, 256, SOCK_STREAM, 0, NULL);
> +
> +if (fd < 0) {
> +error_report("colo proxy listen failed");
> +return -1;
> +}
> +
> +do {
> +accept_sock = qemu_accept(fd, (struct sockaddr *)&addr, &addrlen);
> +err = socket_error();
> +} while (accept_sock < 0 && err == EINTR);
> +closesocket(fd);
> +
> +if (accept_sock < 0) {
> +error_report("colo proxy accept failed(%s)", strerror(err));
> +return -1;
> +}
> +s->sockfd = accept_sock;
> +
> +qemu_set_fd_handler(s->sockfd, colo_proxy_sock_receive, NULL, (void *)s);
> +
> +return 0;
> +}
> +
> +/* try to connect listening server
> + * 0 on success, otherwise something wrong
> + */
> +static ssize_t colo_proxy_connect(COLOProxyState *s)
> +{
> +int sock;
> +sock = inet_connect(s->addr, NULL);
> +
> +if (sock < 0) {
> +error_report("colo proxy inet_connect failed");
> +return -1;
> +}
> +s->sockfd = sock;
> +qemu_set_fd_handler(s->sockfd, colo_proxy_sock_receive, NULL, (void *)s);
> +
> +return 0;
> +}
> +
>  static void colo_proxy_notify_checkpoint(void)
>  {
>  trace_colo_proxy("colo_proxy_notify_checkpoint");
> -- 
> 1.9.1
> 
> 
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH v2 1/2] generic-loader: Add a generic loader

2016-02-19 Thread Alistair Francis
On Thu, Feb 18, 2016 at 5:16 PM, Alistair Francis
 wrote:
> Add a generic loader to QEMU which can be used to load images or set
> memory values.
>
> This only supports ARM architectures at the moment.
>
> Signed-off-by: Alistair Francis 

I don't seem to be able to see this on the list. Maybe this is that
email sending problem again?

> ---
> V2:
>  - Add maintainers entry
>  - Perform bounds checking
>  - Register and unregister the reset in the realise/unrealise
> Changes since RFC:
>  - Add BE support
>
>  MAINTAINERS  |   6 ++
>  default-configs/arm-softmmu.mak  |   1 +
>  hw/misc/Makefile.objs|   2 +
>  hw/misc/generic-loader.c | 142 
> +++
>  include/hw/misc/generic-loader.h |  50 ++
>  5 files changed, 201 insertions(+)
>  create mode 100644 hw/misc/generic-loader.c
>  create mode 100644 include/hw/misc/generic-loader.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 02710f8..1bc92c3 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -956,6 +956,12 @@ F: hw/acpi/nvdimm.c
>  F: hw/mem/nvdimm.c
>  F: include/hw/mem/nvdimm.h
>
> +Generic Loader
> +M: Alistair Francis 
> +S: Maintained
> +F: hw/misc/generic-loader.c
> +F: include/hw/misc/generic-loader.h
> +
>  Subsystems
>  --
>  Audio
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index a9f82a1..b246b75 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -110,3 +110,4 @@ CONFIG_IOH3420=y
>  CONFIG_I82801B11=y
>  CONFIG_ACPI=y
>  CONFIG_SMBIOS=y
> +CONFIG_LOADER=y
> diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
> index ea6cd3c..9f05dcf 100644
> --- a/hw/misc/Makefile.objs
> +++ b/hw/misc/Makefile.objs
> @@ -46,3 +46,5 @@ obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
>  obj-$(CONFIG_PVPANIC) += pvpanic.o
>  obj-$(CONFIG_EDU) += edu.o
>  obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
> +
> +obj-$(CONFIG_LOADER) += generic-loader.o
> diff --git a/hw/misc/generic-loader.c b/hw/misc/generic-loader.c
> new file mode 100644
> index 000..e551a38
> --- /dev/null
> +++ b/hw/misc/generic-loader.c
> @@ -0,0 +1,142 @@
> +/*
> + * Generic Loader
> + *
> + * Copyright (C) 2014 Li Guang
> + * Copyright (C) 2016 Xilinx Inc.
> + * Written by Li Guang 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * for more details.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/sysbus.h"
> +#include "sysemu/dma.h"
> +#include "hw/loader.h"
> +#include "hw/misc/generic-loader.h"
> +
> +#define CPU_NONE 0xFF
> +
> +static void generic_loader_reset(void *opaque)
> +{
> +GenericLoaderState *s = GENERIC_LOADER(opaque);
> +
> +if (s->cpu) {
> +CPUClass *cc = CPU_GET_CLASS(s->cpu);
> +cpu_reset(s->cpu);
> +cc->set_pc(s->cpu, s->addr);
> +}
> +
> +if (s->data_len) {
> +assert(s->data_len < sizeof(s->data));
> +dma_memory_write((s->cpu ? s->cpu : first_cpu)->as, s->addr, 
> &s->data,
> + s->data_len);
> +}
> +}
> +
> +static void generic_loader_realize(DeviceState *dev, Error **errp)
> +{
> +GenericLoaderState *s = GENERIC_LOADER(dev);
> +hwaddr entry;
> +int big_endian;
> +int size = 0;
> +
> +qemu_register_reset(generic_loader_reset, dev);
> +
> +if (s->cpu_nr != CPU_NONE) {
> +CPUState *cs = first_cpu;
> +int cpu_num = 0;
> +
> +CPU_FOREACH(cs) {
> +if (cpu_num == s->cpu_nr) {
> +s->cpu = cs;
> +break;
> +} else if (!CPU_NEXT(cs)) {
> +error_setg(errp, "Specified boot CPU#%d is nonexistent",
> +   s->cpu_nr);
> +return;
> +} else {
> +cpu_num++;
> +}
> +}
> +}
> +
> +#ifdef TARGET_WORDS_BIGENDIAN
> +big_endian = 1;
> +#else
> +big_endian = 0;
> +#endif
> +
> +if (s->file) {
> +if (!s->force_raw) {
> +size = load_elf(s->file, NULL, NULL, &entry, NULL, NULL,
> +big_endian, ELF_ARCH, 0);
> +
> +if (size < 0) {
> +size = load_uimage(s->file, &entry, NULL, NULL, NULL, NULL);
> +}
> +}
> +
> +if (size < 0) {
> +size = load_image_targphys(s->file, s->addr, 0);

This is wrong, nothing will ever get loaded.

Fixing and sending a V3.

Thanks,

Alistair

> +} else {
> +s->addr = entry;
> +}
>

Re: [Qemu-devel] [RFC PATCH v2 05/10] net/colo-proxy: Add colo interface to use proxy

2016-02-19 Thread Dr. David Alan Gilbert
* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:
> From: zhangchen 
> 
> Add interface used by migration/colo.c
> so colo framework can work with proxy
> 
> Signed-off-by: zhangchen 
> Signed-off-by: zhanghailiang 
> ---
>  net/colo-proxy.c | 93 
> 
>  1 file changed, 93 insertions(+)
> 
> diff --git a/net/colo-proxy.c b/net/colo-proxy.c
> index f448ee1..ba2bbe7 100644
> --- a/net/colo-proxy.c
> +++ b/net/colo-proxy.c
> @@ -167,6 +167,11 @@ static int connection_key_equal(const void *opaque1, 
> const void *opaque2)
>  return memcmp(opaque1, opaque2, sizeof(ConnectionKey)) == 0;
>  }
>  
> +bool colo_proxy_query_checkpoint(void)
> +{
> +return colo_do_checkpoint;
> +}
> +
>  static ssize_t colo_proxy_receive_iov(NetFilterState *nf,
>   NetClientState *sender,
>   unsigned flags,
> @@ -203,6 +208,94 @@ static void colo_proxy_cleanup(NetFilterState *nf)
>  qemu_event_destroy(&s->need_compare_ev);
>  }
>  
> +static void colo_proxy_notify_checkpoint(void)
> +{
> +trace_colo_proxy("colo_proxy_notify_checkpoint");
> +colo_do_checkpoint = true;
> +}
> +
> +static void colo_proxy_start_one(NetFilterState *nf,
> +  void *opaque, Error **errp)
> +{
> +COLOProxyState *s;
> +int mode, ret;
> +
> +if (strcmp(object_get_typename(OBJECT(nf)), TYPE_FILTER_COLO_PROXY)) {
> +return;
> +}
> +
> +mode = *(int *)opaque;
> +s = FILTER_COLO_PROXY(nf);
> +assert(s->colo_mode == mode);
> +
> +if (s->colo_mode == COLO_MODE_PRIMARY) {
> +char thread_name[1024];
> +
> +ret = colo_proxy_connect(s);
> +if (ret) {
> +error_setg(errp, "colo proxy connect failed");
> +return ;
> +}
> +
> +s->status = COLO_PROXY_RUNNING;
> +sprintf(thread_name, "proxy compare %s", nf->netdev_id);
> +qemu_thread_create(&s->thread, thread_name,
> +colo_proxy_compare_thread, s,
> +QEMU_THREAD_JOINABLE);

Note most OSs have a ~14 character limit on the size of the thread
name, otherwise they ignore the request to set the name (and the
thread shows up as 'migration'), so I suggest keep it as "proxy:%s".

Dave

> +} else {
> +ret = colo_wait_incoming(s);
> +if (ret) {
> +error_setg(errp, "colo proxy wait incoming failed");
> +return ;
> +}
> +s->status = COLO_PROXY_RUNNING;
> +}
> +}
> +
> +int colo_proxy_start(int mode)
> +{
> +Error *err = NULL;
> +qemu_foreach_netfilter(colo_proxy_start_one, &mode, &err);
> +if (err) {
> +return -1;
> +}
> +return 0;
> +}
> +
> +static void colo_proxy_stop_one(NetFilterState *nf,
> +  void *opaque, Error **errp)
> +{
> +COLOProxyState *s;
> +int mode;
> +
> +if (strcmp(object_get_typename(OBJECT(nf)), TYPE_FILTER_COLO_PROXY)) {
> +return;
> +}
> +
> +s = FILTER_COLO_PROXY(nf);
> +mode = *(int *)opaque;
> +assert(s->colo_mode == mode);
> +
> +s->status = COLO_PROXY_DONE;
> +if (s->sockfd >= 0) {
> +qemu_set_fd_handler(s->sockfd, NULL, NULL, NULL);
> +closesocket(s->sockfd);
> +}
> +if (s->colo_mode == COLO_MODE_PRIMARY) {
> +colo_proxy_primary_checkpoint(s);
> +qemu_event_set(&s->need_compare_ev);
> +qemu_thread_join(&s->thread);
> +} else {
> +colo_proxy_secondary_checkpoint(s);
> +}
> +}
> +
> +void colo_proxy_stop(int mode)
> +{
> +Error *err = NULL;
> +qemu_foreach_netfilter(colo_proxy_stop_one, &mode, &err);
> +}
> +
>  static void colo_proxy_setup(NetFilterState *nf, Error **errp)
>  {
>  COLOProxyState *s = FILTER_COLO_PROXY(nf);
> -- 
> 1.9.1
> 
> 
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [RFC PATCH v2 03/10] Colo-proxy: add colo-proxy framework

2016-02-19 Thread Dr. David Alan Gilbert
* Zhang Chen (zhangchen.f...@cn.fujitsu.com) wrote:
> From: zhangchen 
> 

> +static void colo_proxy_setup(NetFilterState *nf, Error **errp)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(nf);
> +
> +if (!s->addr) {
> +error_setg(errp, "filter colo_proxy needs 'addr' property set!");
> +return;
> +}
> +
> +if (nf->direction != NET_FILTER_DIRECTION_ALL) {
> +error_setg(errp, "colo need queue all packet,"
> +"please startup colo-proxy with queue=all\n");
> +return;
> +}
> +
> +s->sockfd = -1;
> +s->hashtable_size = 0;
> +colo_do_checkpoint = false;
> +qemu_event_init(&s->need_compare_ev, false);
> +
> +s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);

I found that I had to be careful that this queue got flushed.  If the packet
can't be sent immediately, then the packet only gets sent if another
packet is added to the queue later.  I added a state change notifier to
flush it when the VM started running (this is more of a problem in my hybrid
mode case).

Note also that the queue is not protected by locks; so take care since packets
are sent from both the comparison thread and the colo thread (when it flushes)
and I think it's read by the main thread as well potentially as packets are 
sent.

Dave


> +colo_conn_hash = g_hash_table_new_full(connection_key_hash,
> +   connection_key_equal,
> +   g_free,
> +   connection_destroy);
> +g_queue_init(&s->conn_list);
> +}
> +
> +static void colo_proxy_class_init(ObjectClass *oc, void *data)
> +{
> +NetFilterClass *nfc = NETFILTER_CLASS(oc);
> +
> +nfc->setup = colo_proxy_setup;
> +nfc->cleanup = colo_proxy_cleanup;
> +nfc->receive_iov = colo_proxy_receive_iov;
> +}
> +
> +static int colo_proxy_get_mode(Object *obj, Error **errp)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(obj);
> +
> +return s->colo_mode;
> +}
> +
> +static void
> +colo_proxy_set_mode(Object *obj, int mode, Error **errp)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(obj);
> +
> +s->colo_mode = mode;
> +}
> +
> +static char *colo_proxy_get_addr(Object *obj, Error **errp)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(obj);
> +
> +return g_strdup(s->addr);
> +}
> +
> +static void
> +colo_proxy_set_addr(Object *obj, const char *value, Error **errp)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(obj);
> +g_free(s->addr);
> +s->addr = g_strdup(value);
> +if (!s->addr) {
> +error_setg(errp, "colo_proxy needs 'addr'"
> + "property set!");
> +return;
> +}
> +}
> +
> +static void colo_proxy_init(Object *obj)
> +{
> +object_property_add_enum(obj, "mode", "COLOMode", COLOMode_lookup,
> + colo_proxy_get_mode, colo_proxy_set_mode, NULL);
> +object_property_add_str(obj, "addr", colo_proxy_get_addr,
> +colo_proxy_set_addr, NULL);
> +}
> +
> +static void colo_proxy_fini(Object *obj)
> +{
> +COLOProxyState *s = FILTER_COLO_PROXY(obj);
> +g_free(s->addr);
> +}
> +
> +static const TypeInfo colo_proxy_info = {
> +.name = TYPE_FILTER_COLO_PROXY,
> +.parent = TYPE_NETFILTER,
> +.class_init = colo_proxy_class_init,
> +.instance_init = colo_proxy_init,
> +.instance_finalize = colo_proxy_fini,
> +.instance_size = sizeof(COLOProxyState),
> +};
> +
> +static void register_types(void)
> +{
> +type_register_static(&colo_proxy_info);
> +}
> +
> +type_init(register_types);
> diff --git a/net/colo-proxy.h b/net/colo-proxy.h
> new file mode 100644
> index 000..affc117
> --- /dev/null
> +++ b/net/colo-proxy.h
> @@ -0,0 +1,24 @@
> +/*
> + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
> + * (a.k.a. Fault Tolerance or Continuous Replication)
> + *
> + * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO., LTD.
> + * Copyright (c) 2015 FUJITSU LIMITED
> + * Copyright (c) 2015 Intel Corporation
> + *
> + * Author: Zhang Chen 
> + *
> + * 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 QEMU_COLO_PROXY_H
> +#define QEMU_COLO_PROXY_H
> +
> +int colo_proxy_start(int mode);
> +void colo_proxy_stop(int mode);
> +int colo_proxy_do_checkpoint(int mode);
> +bool colo_proxy_query_checkpoint(void);
> +
> +#endif /* QEMU_COLO_PROXY_H */
> -- 
> 1.9.1
> 
> 
> 
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH v2 2/2] target-arm: Implement MDCR_EL3.TPM and MDCR_EL2.TPM traps

2016-02-19 Thread Alistair Francis
On Fri, Feb 19, 2016 at 6:39 AM, Peter Maydell  wrote:
> Implement the performance monitor register traps controlled
> by MDCR_EL3.TPM and MDCR_EL2.TPM. Most of the performance
> registers already have an access function to deal with the
> user-enable bit, and the TPM checks can be added there. We
> also need a new access function which only implements the
> TPM checks for use by the few not-EL0-accessible registers
> and by PMUSERENR_EL0 (which is always EL0-readable).
>
> Signed-off-by: Peter Maydell 
> ---
>  target-arm/helper.c | 43 ---
>  1 file changed, 36 insertions(+), 7 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index e9b89e6..ef3f1ce 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -439,6 +439,24 @@ static CPAccessResult access_tda(CPUARMState *env, const 
> ARMCPRegInfo *ri,
>  return CP_ACCESS_OK;
>  }
>
> +/* Check for traps to performance monitor registers, which are controlled
> + * by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3.
> + */
> +static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
> + bool isread)
> +{
> +int el = arm_current_el(env);
> +
> +if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
> +&& !arm_is_secure_below_el3(env)) {
> +return CP_ACCESS_TRAP_EL2;
> +}
> +if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
> +return CP_ACCESS_TRAP_EL3;
> +}

Hey Peter,

Why not use else if?

Also, I'll hopefully be able to have another look at the PMU patches
next week. I'll make sure to rebase them on top of this.

> +return CP_ACCESS_OK;
> +}
> +
>  static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t 
> value)
>  {
>  ARMCPU *cpu = arm_env_get_cpu(env);
> @@ -774,11 +792,22 @@ static CPAccessResult pmreg_access(CPUARMState *env, 
> const ARMCPRegInfo *ri,
> bool isread)
>  {
>  /* Performance monitor registers user accessibility is controlled
> - * by PMUSERENR.
> + * by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
> + * trapping to EL2 or EL3 for other accesses.
>   */
> -if (arm_current_el(env) == 0 && !env->cp15.c9_pmuserenr) {
> +int el = arm_current_el(env);
> +
> +if (el == 0 && !env->cp15.c9_pmuserenr) {
>  return CP_ACCESS_TRAP;
>  }
> +if (el < 2 && (env->cp15.mdcr_el2 & MDCR_TPM)
> +&& !arm_is_secure_below_el3(env)) {
> +return CP_ACCESS_TRAP_EL2;
> +}
> +if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
> +return CP_ACCESS_TRAP_EL3;
> +}

Same here

Thanks,

Alistair

> +
>  return CP_ACCESS_OK;
>  }
>
> @@ -1101,28 +1130,28 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
>.access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
>.accessfn = pmreg_access },
>  { .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 
> 0,
> -  .access = PL0_R | PL1_RW,
> +  .access = PL0_R | PL1_RW, .accessfn = access_tpm,
>.fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
>.resetvalue = 0,
>.writefn = pmuserenr_write, .raw_writefn = raw_write },
>  { .name = "PMUSERENR_EL0", .state = ARM_CP_STATE_AA64,
>.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 0,
> -  .access = PL0_R | PL1_RW, .type = ARM_CP_ALIAS,
> +  .access = PL0_R | PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
>.fieldoffset = offsetof(CPUARMState, cp15.c9_pmuserenr),
>.resetvalue = 0,
>.writefn = pmuserenr_write, .raw_writefn = raw_write },
>  { .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 
> = 1,
> -  .access = PL1_RW,
> +  .access = PL1_RW, .accessfn = access_tpm,
>.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
>.resetvalue = 0,
>.writefn = pmintenset_write, .raw_writefn = raw_write },
>  { .name = "PMINTENCLR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 
> = 2,
> -  .access = PL1_RW, .type = ARM_CP_ALIAS,
> +  .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
>.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
>.writefn = pmintenclr_write, },
>  { .name = "PMINTENCLR_EL1", .state = ARM_CP_STATE_AA64,
>.opc0 = 3, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 2,
> -  .access = PL1_RW, .type = ARM_CP_ALIAS,
> +  .access = PL1_RW, .accessfn = access_tpm, .type = ARM_CP_ALIAS,
>.fieldoffset = offsetof(CPUARMState, cp15.c9_pminten),
>.writefn = pmintenclr_write },
>  { .name = "VBAR", .state = ARM_CP_STATE_BOTH,
> --
> 1.9.1
>
>



Re: [Qemu-devel] [PATCH v1 1/2] qdev-monitor.c: Register reset function if the device has one

2016-02-19 Thread Alistair Francis
On Fri, Feb 19, 2016 at 9:15 AM, Andreas Färber  wrote:
> Am 18.02.2016 um 10:56 schrieb Markus Armbruster:
>> Alistair Francis  writes:
>>
>>> If the device being added when running qdev_device_add() has
>>> a reset function, register it so that it can be called.
>>>
>>> Signed-off-by: Alistair Francis 
>>> ---
>>>
>>>  qdev-monitor.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>> diff --git a/qdev-monitor.c b/qdev-monitor.c
>>> index 81e3ff3..0a99d01 100644
>>> --- a/qdev-monitor.c
>>> +++ b/qdev-monitor.c
>>> @@ -561,6 +561,8 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error 
>>> **errp)
>>>
>>>  if (bus) {
>>>  qdev_set_parent_bus(dev, bus);
>>> +} else if (dc->reset) {
>>> +qemu_register_reset((void (*)(void *))dc->reset, dev);
>>>  }
>>>
>>>  id = qemu_opts_id(opts);
>>
>> This looks wrong to me.
>>
>> You stuff all the device reset methods into the global reset_handlers
>> list, where they get called in some semi-random order.  This breaks when
>> there are reset order dependencies between devices, e.g. between a
>> device and the bus it plugs into.
>>
>> Propagating the reset signal to all the devices is a qdev problem.
>> Copying Andreas for further insight.
>
> We had a similar discussion for s390x, and I had started a big reset
> refactoring, but we agreed to go for a stop-gap solution for 2.5. The
> recently posted hw/core/bus.c refactoring originated from that branch.
>
> The overall idea was that for buses reset propagates along buses (so
> yes, NACK to this patch), but where no bus exists it shall propagate to
> QOM children, too.
>
> So Alistair, if you have a device that needs a reset while not sitting
> on a bus, please register the register hook in your device's realize
> hook for now.

Ok, that is fair. I have moved the reset register/unregister to the
realise/unrealise functions in V2.

Thanks,

Alistair

>
> Regards,
> Andreas
>
> --
> SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Felix Imendörffer, Jane Smithard, Graham Norton; HRB 21284 (AG Nürnberg)
>



Re: [Qemu-devel] [PULL 00/14] VFIO updates 2016-02-19

2016-02-19 Thread Peter Maydell
On 19 February 2016 at 17:39, Alex Williamson
 wrote:
> The following changes since commit 1b3337bb1d1c3125a2140c47629f36540ac57605:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2016-02-19' 
> into staging (2016-02-19 15:19:13 +)
>
> are available in the git repository at:
>
>
>   git://github.com/awilliam/qemu-vfio.git tags/vfio-update-20160219.1
>
> for you to fetch changes up to b58b17f744b5465d0fc76eba1be549a9f5704bab:
>
>   vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries (2016-02-19 
> 09:42:32 -0700)
>
> 
> VFIO updates 2016-02-19
>
>  - AER pre-enable and misc fixes (Cao jin and Chen Fan)
>  - PCI_CAP_LIST_NEXT & PCI_MSIX_FLAGS cleanup (Wei Yang)
>  - AMD XGBE KVM platform passthrough (Eric Auger)
>

Applied, thanks.

-- PMM



Re: [Qemu-devel] [PATCH 15/37] tcg: Clean up includes

2016-02-19 Thread Peter Maydell
On 6 February 2016 at 13:43, Peter Maydell  wrote:
> On 6 February 2016 at 00:51, Richard Henderson  wrote:
>> On 01/27/2016 05:17 AM, Peter Maydell wrote:
>>> diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
>>> index 9187d34..d90636c 100644
>>> --- a/tcg/i386/tcg-target.c
>>> +++ b/tcg/i386/tcg-target.c
>>> @@ -22,6 +22,7 @@
>>>* THE SOFTWARE.
>>>*/
>>>
>>> +#include "qemu/osdep.h"
>>>   #include "tcg-be-ldst.h"
>>>
>>>   #ifndef NDEBUG
>>
>>
>> Nack to these, and the others like them.
>> These files are not standalone, they are
>> included into tcg.c, so we ought not be
>> re-including qemu/osdep.h here.
>
> Mmm, but I preferred to retain the invariant that "all .c
> files include osdep.h first" rather than special casing
> these; the re-include is harmless.
>
> Alternatively we could rename these tcg-target.c
> files to some other extension that makes it clearer that
> they're not standalone source files.

How do you feel about renaming the tcg-target.c files to
tcg-target.inc.c ? Then I can make clean-includes know that
*.inc.c are not to have the cleaning rules applied to them.

thanks
-- PMM



[Qemu-devel] [PATCH v9 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-19 Thread Gabriel L. Somlo
Generate an ACPI DSDT node for fw_cfg on pc and arm guests.

New since v8:

- patch 3/5: on pc/x86, place FWCF node in scope \_SB.PCI0
  (instead of directly under \_SB), to prevent any possible
  resource conflict as might be observed by Windows
  (thanks again to Igor Mammedov for the suggestion!)

Thanks,
  --Gabriel

>New since v7:
>
>   - edited commit blurb on 3/5 to match updated content, i.e. that
> the ACPI node is now inserted into the DSDT (no longer the SSDT).
> (Thanks to Igor Mammedov for catching that!)
>
>>New since v6:
>>  - rebased to fit on top of fb306ff and f264d36, which moved things
>>around in pc's acpi-build.c (only patch 3/5 affected);
>>  - kernel-side fw_cfg sysfs driver accepted into upstream linux
>>
>>>New since v5:
>>>
>>> - rebased on top of latest QEMU git master
>>>
New since v4:

- rebased on top of Marc's DMA series
- drop machine compat dependency for insertion into x86/ssdt
  (patch 3/5), following agreement between Igor and Eduardo
- [mm]io register range now covers DMA register as well, if
  available.
- s/bios/firmware in doc file updates

>New since v3:
>
>   - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
> inserting fw_cfg acpi node only for machines >= 2.5.
>
>   - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
> off to avoid Windows complaining -- thanks Igor for catching that!)
>
>If there's any other feedback besides questions regarding the
>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>
>>New since v2:
>>
>>  - pc/i386 node in ssdt only on machine types *newer* than 2.4
>>(as suggested by Eduardo)
>>
>>I appreciate any further comments and reviews. Hopefully we can make
>>this palatable for upstream, modulo the lingering concerns about whether
>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>sorted out with the kernel crew...
>>
>>>New since v1:
>>>
>>> - expose control register size (suggested by Marc Marí)
>>>
>>> - leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>
>>> - using "QEMU0002" as the value of _HID (thanks Michael)
>>>
>>> - added documentation blurb to docs/specs/fw_cfg.txt
>>>   (mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>
 This series adds a fw_cfg device node to the SSDT (on pc), or to the
 DSDT (on arm).

- Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
  define from pc.c to pc.h, so that it could be used from
  acpi-build.c in patch 2/3.
 
- Patch 2/3 adds a fw_cfg node to the pc SSDT.
 
- Patch 3/3 adds a fw_cfg node to the arm DSDT.

 I made up some names - "FWCF" for the node name, and "FWCF0001"
 for _HID; no idea whether that's appropriate, or how else I should
 figure out what to use instead...

 Also, using scope "\\_SB", based on where fw_cfg shows up in the
 output of "info qtree". Again, if that's wrong, please point me in
 the right direction.

 Re. 3/3 (also mentioned after the commit blurb in the patch itself),
 I noticed none of the other DSDT entries contain a _STA field, 
 wondering
 why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to dsdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v9 3/5] acpi: pc: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. While the guest-side
firmware can't utilize this information (since it has to access
the hard-coded fw_cfg device to extract ACPI tables to begin with),
having fw_cfg listed in ACPI will help the guest kernel keep a more
accurate inventory of in-use IO port regions.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4554eb8..915fddd 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
 aml_append(scope, aml_name_decl("_S5", pkg));
 aml_append(dsdt, scope);
 
+/* create fw_cfg node, unconditionally */
+{
+/* when using port i/o, the 8-bit data register *always* overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
+ * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
+uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
+   "dma_enabled", NULL) ?
+  ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :
+  FW_CFG_CTL_SIZE;
+
+scope = aml_scope("\\_SB.PCI0");
+dev = aml_device("FWCF");
+
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+crs = aml_resource_template();
+aml_append(crs,
+aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)
+);
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+aml_append(scope, dev);
+aml_append(dsdt, scope);
+}
+
 if (misc->applesmc_io_base) {
 scope = aml_scope("\\_SB.PCI0.ISA");
 dev = aml_device("SMC");
-- 
2.4.3




[Qemu-devel] [PATCH v9 2/5] pc: fw_cfg: move ioport base constant to pc.h

2016-02-19 Thread Gabriel L. Somlo
Move BIOS_CFG_IOPORT define from pc.c to pc.h, and rename
it to FW_CFG_IO_BASE.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/pc.c | 5 ++---
 include/hw/i386/pc.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0aeefd2..56ec6cd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -78,7 +78,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
@@ -756,7 +755,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
 int i, j;
 unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
 
-fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1258,7 +1257,7 @@ void xen_load_linux(PCMachineState *pcms)
 
 assert(MACHINE(pcms)->kernel_filename != NULL);
 
-fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
 rom_set_fw(fw_cfg);
 
 load_linux(pcms, fw_cfg);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8b3546e..79ffe5b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -266,6 +266,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name);
 
 ISADevice *pc_find_fdc0(void);
 
+#define FW_CFG_IO_BASE 0x510
+
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-- 
2.4.3




[Qemu-devel] [PATCH v9 1/5] fw_cfg: expose control register size in fw_cfg.h

2016-02-19 Thread Gabriel L. Somlo
Expose the size of the control register (FW_CFG_CTL_SIZE) in fw_cfg.h.
Add comment to fw_cfg_io_realize() pointing out that since the
8-bit data register is always subsumed by the 16-bit control
register in the port I/O case, we use the control register width
as the *total* width of the (classic, non-DMA) port I/O region reserved
for the device.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/nvram/fw_cfg.c | 4 +++-
 include/hw/nvram/fw_cfg.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 79c5742..ef2a219 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -32,7 +32,6 @@
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-#define FW_CFG_CTL_SIZE 2
 #define FW_CFG_NAME "fw_cfg"
 #define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
@@ -882,6 +881,9 @@ static void fw_cfg_io_realize(DeviceState *dev, Error 
**errp)
 FWCfgIoState *s = FW_CFG_IO(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
+/* when using port i/o, the 8-bit data register ALWAYS overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE */
 memory_region_init_io(&s->comb_iomem, OBJECT(s), &fw_cfg_comb_mem_ops,
   FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
 sysbus_add_io(sbd, s->iobase, &s->comb_iomem);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 664eaf6..2667ca9 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,6 +46,9 @@
 
 #define FW_CFG_INVALID  0x
 
+/* width in bytes of fw_cfg control register */
+#define FW_CFG_CTL_SIZE 0x02
+
 #define FW_CFG_MAX_FILE_PATH56
 
 #ifndef NO_QEMU_PROTOS
-- 
2.4.3




[Qemu-devel] [PATCH v9 5/5] fw_cfg: document ACPI device node information

2016-02-19 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 docs/specs/fw_cfg.txt | 9 +
 1 file changed, 9 insertions(+)

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 2099ad9..5414140 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -84,6 +84,15 @@ Selector Register address: Base + 8 (2 bytes)
 Data Register address: Base + 0 (8 bytes)
 DMA Address address:   Base + 16 (8 bytes)
 
+== ACPI Interface ==
+
+The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
+ACPI tables to be passed into the guest through the fw_cfg device itself,
+the guest-side firmware can not use ACPI to find fw_cfg. However, once the
+firmware is finished setting up ACPI tables and hands control over to the
+guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
+inventory of in-use IOport or MMIO regions.
+
 == Firmware Configuration Items ==
 
 === Signature (Key 0x, FW_CFG_SIGNATURE) ===
-- 
2.4.3




[Qemu-devel] [PATCH v9 4/5] acpi: arm: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. This is mostly
informational, as the authoritative fw_cfg MMIO region(s)
are listed in the Device Tree. However, since we are building
ACPI tables, we might as well be thorough while at it...

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8cf9a21..7d7998b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -81,6 +81,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -548,6 +562,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
+acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
-- 
2.4.3




[Qemu-devel] [PULL 11/14] hw/arm/sysbus-fdt: helpers for clock node generation

2016-02-19 Thread Alex Williamson
From: Eric Auger 

Some passthrough'ed devices depend on clock nodes. Those need to be
generated in the guest device tree. This patch introduces some helpers
to build a clock node from information retrieved in the host device tree.

- copy_properties_from_host copies properties from a host device tree
  node to a guest device tree node
- fdt_build_clock_node builds a guest clock node and checks the host
  fellow clock is a fixed one.

fdt_build_clock_node will become static as soon as it gets used. A
dummy pre-declaration is needed for compilation of this patch.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Signed-off-by: Alex Williamson 
---
 hw/arm/sysbus-fdt.c |  120 +++
 1 file changed, 120 insertions(+)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 68a3de5..8575cfe 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -22,6 +22,7 @@
  */
 
 #include "qemu/osdep.h"
+#include 
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
@@ -57,6 +58,125 @@ typedef struct NodeCreationPair {
 int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque);
 } NodeCreationPair;
 
+/* helpers */
+
+typedef struct HostProperty {
+const char *name;
+bool optional;
+} HostProperty;
+
+/**
+ * copy_properties_from_host
+ *
+ * copies properties listed in an array from host device tree to
+ * guest device tree. If a non optional property is not found, the
+ * function asserts. An optional property is ignored if not found
+ * in the host device tree.
+ * @props: array of HostProperty to copy
+ * @nb_props: number of properties in the array
+ * @host_dt: host device tree blob
+ * @guest_dt: guest device tree blob
+ * @node_path: host dt node path where the property is supposed to be
+  found
+ * @nodename: guest node name the properties should be added to
+ */
+static void copy_properties_from_host(HostProperty *props, int nb_props,
+  void *host_fdt, void *guest_fdt,
+  char *node_path, char *nodename)
+{
+int i, prop_len;
+const void *r;
+Error *err = NULL;
+
+for (i = 0; i < nb_props; i++) {
+r = qemu_fdt_getprop(host_fdt, node_path,
+ props[i].name,
+ &prop_len,
+ props[i].optional ? &err : &error_fatal);
+if (r) {
+qemu_fdt_setprop(guest_fdt, nodename,
+ props[i].name, r, prop_len);
+} else {
+if (prop_len != -FDT_ERR_NOTFOUND) {
+/* optional property not returned although property exists */
+error_report_err(err);
+} else {
+error_free(err);
+}
+}
+}
+}
+
+/* clock properties whose values are copied/pasted from host */
+static HostProperty clock_copied_properties[] = {
+{"compatible", false},
+{"#clock-cells", false},
+{"clock-frequency", true},
+{"clock-output-names", true},
+};
+
+/**
+ * fdt_build_clock_node
+ *
+ * Build a guest clock node, used as a dependency from a passthrough'ed
+ * device. Most information are retrieved from the host clock node.
+ * Also check the host clock is a fixed one.
+ *
+ * @host_fdt: host device tree blob from which info are retrieved
+ * @guest_fdt: guest device tree blob where the clock node is added
+ * @host_phandle: phandle of the clock in host device tree
+ * @guest_phandle: phandle to assign to the guest node
+ */
+void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
+ uint32_t host_phandle,
+ uint32_t guest_phandle);
+void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
+ uint32_t host_phandle,
+ uint32_t guest_phandle)
+{
+char *node_path = NULL;
+char *nodename;
+const void *r;
+int ret, node_offset, prop_len, path_len = 16;
+
+node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
+if (node_offset <= 0) {
+error_setg(&error_fatal,
+   "not able to locate clock handle %d in host device tree",
+   host_phandle);
+}
+node_path = g_malloc(path_len);
+while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
+== -FDT_ERR_NOSPACE) {
+path_len += 16;
+node_path = g_realloc(node_path, path_len);
+}
+if (ret < 0) {
+error_setg(&error_fatal,
+   "not able to retrieve node path for clock handle %d",
+   host_phandle);
+}
+
+r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
+ &error_fatal);
+if (strcmp(r, "fixed-clock")) {
+error_setg(&error_fatal,
+   "clock handle %d is not a fixed clock", host_phandle);
+}
+
+nodename = strrchr(node_p

[Qemu-devel] [PULL 12/14] hw/arm/sysbus-fdt: enable amd-xgbe dynamic instantiation

2016-02-19 Thread Alex Williamson
From: Eric Auger 

This patch allows the instantiation of the vfio-amd-xgbe device
from the QEMU command line (-device vfio-amd-xgbe,host="").

The guest is exposed with a device tree node that combines the description
of both XGBE and PHY (representation supported from 4.2 onwards kernel):
Documentation/devicetree/bindings/net/amd-xgbe.txt.

There are 5 register regions, 6 interrupts including 4 optional
edge-sensitive per-channel interrupts.

Some property values are inherited from host device tree. Host device tree
must feature a combined XGBE/PHY representation (>= 4.2 host kernel).

2 clock nodes (dma and ptp) also are created. It is checked those clocks
are fixed on host side.

AMD XGBE node creation function has a dependency on vfio Linux header and
more generally node creation function for VFIO platform devices only make
sense with CONFIG_LINUX so let's protect this code with #ifdef CONFIG_LINUX.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Signed-off-by: Alex Williamson 
---
 hw/arm/sysbus-fdt.c |  194 +--
 1 file changed, 188 insertions(+), 6 deletions(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 8575cfe..9920388 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -23,6 +23,10 @@
 
 #include "qemu/osdep.h"
 #include 
+#include "qemu-common.h"
+#ifdef CONFIG_LINUX
+#include 
+#endif
 #include "hw/arm/sysbus-fdt.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
@@ -30,6 +34,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/vfio/vfio-platform.h"
 #include "hw/vfio/vfio-calxeda-xgmac.h"
+#include "hw/vfio/vfio-amd-xgbe.h"
 #include "hw/arm/fdt.h"
 
 /*
@@ -65,6 +70,8 @@ typedef struct HostProperty {
 bool optional;
 } HostProperty;
 
+#ifdef CONFIG_LINUX
+
 /**
  * copy_properties_from_host
  *
@@ -127,12 +134,9 @@ static HostProperty clock_copied_properties[] = {
  * @host_phandle: phandle of the clock in host device tree
  * @guest_phandle: phandle to assign to the guest node
  */
-void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
- uint32_t host_phandle,
- uint32_t guest_phandle);
-void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
- uint32_t host_phandle,
- uint32_t guest_phandle)
+static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
+uint32_t host_phandle,
+uint32_t guest_phandle)
 {
 char *node_path = NULL;
 char *nodename;
@@ -177,6 +181,28 @@ void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
 g_free(node_path);
 }
 
+/**
+ * sysfs_to_dt_name: convert the name found in sysfs into the node name
+ * for instance e090.xgmac is converted into xgmac@e090
+ * @sysfs_name: directory name in sysfs
+ *
+ * returns the device tree name upon success or NULL in case the sysfs name
+ * does not match the expected format
+ */
+static char *sysfs_to_dt_name(const char *sysfs_name)
+{
+gchar **substrings =  g_strsplit(sysfs_name, ".", 2);
+char *dt_name = NULL;
+
+if (!substrings || !substrings[0] || !substrings[1]) {
+goto out;
+}
+dt_name = g_strdup_printf("%s@%s", substrings[1], substrings[0]);
+out:
+g_strfreev(substrings);
+return dt_name;
+}
+
 /* Device Specific Code */
 
 /**
@@ -244,9 +270,165 @@ fail_reg:
 return ret;
 }
 
+/* AMD xgbe properties whose values are copied/pasted from host */
+static HostProperty amd_xgbe_copied_properties[] = {
+{"compatible", false},
+{"dma-coherent", true},
+{"amd,per-channel-interrupt", true},
+{"phy-mode", false},
+{"mac-address", true},
+{"amd,speed-set", false},
+{"amd,serdes-blwc", true},
+{"amd,serdes-cdr-rate", true},
+{"amd,serdes-pq-skew", true},
+{"amd,serdes-tx-amp", true},
+{"amd,serdes-dfe-tap-config", true},
+{"amd,serdes-dfe-tap-enable", true},
+{"clock-names", false},
+};
+
+/**
+ * add_amd_xgbe_fdt_node
+ *
+ * Generates the combined xgbe/phy node following kernel >=4.2
+ * binding documentation:
+ * Documentation/devicetree/bindings/net/amd-xgbe.txt:
+ * Also 2 clock nodes are created (dma and ptp)
+ *
+ * Asserts in case of error
+ */
+static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+PlatformBusFDTData *data = opaque;
+PlatformBusDevice *pbus = data->pbus;
+VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
+VFIODevice *vbasedev = &vdev->vbasedev;
+VFIOINTp *intp;
+const char *parent_node = data->pbus_node_name;
+char **node_path, *nodename, *dt_name;
+void *guest_fdt = data->fdt, *host_fdt;
+const void *r;
+int i, prop_len;
+uint32_t *irq_attr, *reg_attr, *host_clock_phandles;
+uint64_t mmio_base, irq_number;
+uint32_t guest_clock_phandles[2];
+
+host_fdt = load_device_tree_from_sysfs();
+
+dt_name = sysfs_to_dt_name(vbasedev->name);
+if (!dt_na

[Qemu-devel] [PATCH 1/1] virtio-rng: fix condition checking on period_ms

2016-02-19 Thread Wei Huang
The condition checking on vrng->conf.period_ms appears to be wrong,
conflicting with the error comment following it.

Signed-off-by: Wei Huang 
---
 hw/virtio/virtio-rng.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index 473c044..a06427c 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -149,7 +149,7 @@ static void virtio_rng_device_realize(DeviceState *dev, 
Error **errp)
 VirtIORNG *vrng = VIRTIO_RNG(dev);
 Error *local_err = NULL;
 
-if (!vrng->conf.period_ms > 0) {
+if (!(vrng->conf.period_ms > 0)) {
 error_setg(errp, "'period' parameter expects a positive integer");
 return;
 }
-- 
2.4.3




Re: [Qemu-devel] [PATCH 4/8] scripts/clean-includes: Enhance to handle header files

2016-02-19 Thread Peter Maydell
On 18 February 2016 at 19:04, Eric Blake  wrote:
> On 02/18/2016 11:05 AM, Peter Maydell wrote:
>> Enhance clean-includes to handle header files as well as .c source
>> files. For headers we merely remove all the redundant #include
>> lines, including any includes of qemu/osdep.h itself.
>>
>> There is a simple mollyguard on the include file processing to
>> skip a few key headers like osdep.h itself, to avoid producing
>> bad patches if the script is run on every file in include/.
>>
>> Signed-off-by: Peter Maydell 
>> Reviewed-by: Eric Blake 
>> ---
>>  scripts/clean-includes | 50 
>> ++
>>  1 file changed, 42 insertions(+), 8 deletions(-)
>
> I already saw your followup explaining about the spurious R-b, so let's
> make it real this time :)
>
>>
>> diff --git a/scripts/clean-includes b/scripts/clean-includes
>> index 1af1f82..737a5ce 100755
>> --- a/scripts/clean-includes
>> +++ b/scripts/clean-includes
>> @@ -1,7 +1,8 @@
>>  #!/bin/sh -e
>>  #
>>  # Clean up QEMU #include lines by ensuring that qemu/osdep.h
>> -# is the first include listed.
>> +# is the first include listed, and no headers provided by
>> +# osdep.h itself are redundantly included.
>
> Do you want to mention 'is the first include listed in .c files', now
> that this cleanup also scrubs .h files?  Or, since you go into details
> below and this is just the summary, maybe 'is the first include
> encountered'?
>
>>  #
>>  # Copyright (c) 2015 Linaro Limited
>
> Want to add 2016?
>
>>  #
>> @@ -22,6 +23,11 @@
>>
>>  # This script requires Coccinelle to be installed.
>>
>> +# .c files will have the osdep.h included added, and redundant
>> +# includes removed.
>> +# .h files will have redundant includes (including includes of osdep.h)
>> +# removed.
>
> Maybe a note here that "this is because any other .h file will not be
> included by a .c file until after osdep.h" ?  Or is that too verbose?
>
>> +  case "$f" in
>> +*.c)
>> +  MODE=c
>> +  ;;
>> +
>> *include/qemu/osdep.h|include/qemu/compiler.h|include/config.h|include/standard-headers/)
>
> Spaces around | may make this more legible, and doesn't affect correctness.

Your comment here reveals a bug, incidentally -- I meant (with the '*' at the
front) to make this work whether $f was "include/foo.h" or "./include/foo.h"
or "/path/to/qemu/include/foo.h". I guess I want

*include/qemu/osdep.h | \
*include/qemu/compiler.h | \
*include/config.h | \
*include/standard-headers/ )

(including some line breaks to help readability a little).

thanks
-- PMM



Re: [Qemu-devel] [PULL 00/14] VFIO updates 2016-02-19

2016-02-19 Thread Alex Williamson
On Fri, 19 Feb 2016 10:39:31 -0700
Alex Williamson  wrote:

> The following changes since commit 1b3337bb1d1c3125a2140c47629f36540ac57605:
> 
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2016-02-19' 
> into staging (2016-02-19 15:19:13 +)
> 
> are available in the git repository at:
> 
> 
>   git://github.com/awilliam/qemu-vfio.git tags/vfio-update-20160219.1
> 
> for you to fetch changes up to b58b17f744b5465d0fc76eba1be549a9f5704bab:
> 
>   vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries (2016-02-19 
> 09:42:32 -0700)
> 
> 
> VFIO updates 2016-02-19
> 
>  - AER pre-enable and misc fixes (Cao jin and Chen Fan)
>  - PCI_CAP_LIST_NEXT & PCI_MSIX_FLAGS cleanup (Wei Yang)
>  - AMD XGBE KVM platform passthrough (Eric Auger)
> 
> 
> Chen Fan (4):
>   pcie: modify the capability size assert
>   vfio: make the 4 bytes aligned for capability size
>   aer: impove pcie_aer_init to support vfio device
>   pcie_aer: expose pcie_aer_msg() interface
> 
> Eric Auger (8):
>   hw/vfio/platform: amd-xgbe device
>   device_tree: introduce load_device_tree_from_sysfs
>   device_tree: introduce qemu_fdt_node_path
>   device_tree: qemu_fdt_getprop converted to use the error API
>   device_tree: qemu_fdt_getprop_cell converted to use the error API
>   hw/arm/sysbus-fdt: helpers for clock node generation
>   hw/arm/sysbus-fdt: enable amd-xgbe dynamic instantiation
>   hw/arm/sysbus-fdt: remove qemu_fdt_setprop returned value check
> 
> Wei Yang (2):
>   vfio/pci: replace 1 with PCI_CAP_LIST_NEXT to make code self-explain
>   vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries
> 
>  device_tree.c  | 182 +++--
>  hw/arm/boot.c  |   6 +-
>  hw/arm/sysbus-fdt.c| 319 
> +++--
>  hw/arm/vexpress.c  |   6 +-
>  hw/pci-bridge/ioh3420.c|   2 +-
>  hw/pci-bridge/xio3130_downstream.c |   2 +-
>  hw/pci-bridge/xio3130_upstream.c   |   2 +-
>  hw/pci/pcie.c  |   2 +-
>  hw/pci/pcie_aer.c  |   6 +-
>  hw/vfio/Makefile.objs  |   1 +
>  hw/vfio/amd-xgbe.c |  55 +++
>  hw/vfio/pci.c  |  13 +-
>  include/hw/pci/pcie_aer.h  |   3 +-
>  include/hw/vfio/vfio-amd-xgbe.h|  51 ++
>  include/sysemu/device_tree.h   |  53 +-
>  15 files changed, 660 insertions(+), 43 deletions(-)
>  create mode 100644 hw/vfio/amd-xgbe.c
>  create mode 100644 include/hw/vfio/vfio-amd-xgbe.h

To be clear, this is a respin of the 2/18 pull with Eric's v8 making
the following change:

+g_slist_free_full(path_list, g_free);

becomes:

+for (iter = path_list; iter; iter = iter->next) {
+g_free(iter->data);
+}
+g_slist_free(path_list);

Also pulled in a trivial patch from Wei Yang.  Thanks,

Alex



[Qemu-devel] [PULL 13/14] hw/arm/sysbus-fdt: remove qemu_fdt_setprop returned value check

2016-02-19 Thread Alex Williamson
From: Eric Auger 

qemu_fdt_setprop asserts in case of error hence no need to check
the returned value.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Signed-off-by: Alex Williamson 
---
 hw/arm/sysbus-fdt.c |   19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 9920388..04afeae 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -217,7 +217,7 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice 
*sbdev, void *opaque)
 PlatformBusDevice *pbus = data->pbus;
 void *fdt = data->fdt;
 const char *parent_node = data->pbus_node_name;
-int compat_str_len, i, ret = -1;
+int compat_str_len, i;
 char *nodename;
 uint32_t *irq_attr, *reg_attr;
 uint64_t mmio_base, irq_number;
@@ -242,12 +242,8 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice 
*sbdev, void *opaque)
 reg_attr[2 * i + 1] = cpu_to_be32(
 memory_region_size(&vdev->regions[i]->mem));
 }
-ret = qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
-   vbasedev->num_regions * 2 * sizeof(uint32_t));
-if (ret) {
-error_report("could not set reg property of node %s", nodename);
-goto fail_reg;
-}
+qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
+ vbasedev->num_regions * 2 * sizeof(uint32_t));
 
 irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
 for (i = 0; i < vbasedev->num_irqs; i++) {
@@ -257,17 +253,12 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice 
*sbdev, void *opaque)
 irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
 irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
 }
-ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
+qemu_fdt_setprop(fdt, nodename, "interrupts",
  irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
-if (ret) {
-error_report("could not set interrupts property of node %s",
- nodename);
-}
 g_free(irq_attr);
-fail_reg:
 g_free(reg_attr);
 g_free(nodename);
-return ret;
+return 0;
 }
 
 /* AMD xgbe properties whose values are copied/pasted from host */




[Qemu-devel] [PULL 09/14] device_tree: qemu_fdt_getprop converted to use the error API

2016-02-19 Thread Alex Williamson
From: Eric Auger 

Current qemu_fdt_getprop exits if the property is not found. It is
sometimes needed to read an optional property, in which case we do
not wish to exit but simply returns a null value.

This patch converts qemu_fdt_getprop to accept an Error **, and existing
users are converted to pass &error_fatal. This preserves the existing
behaviour. Then to use the API with your optional semantic a null
parameter can be conveyed.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Crosthwaite 
Signed-off-by: Alex Williamson 
---
 device_tree.c|   11 ++-
 include/sysemu/device_tree.h |   13 -
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/device_tree.c b/device_tree.c
index b29a433..3d41c44 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -333,18 +333,18 @@ int qemu_fdt_setprop_string(void *fdt, const char 
*node_path,
 }
 
 const void *qemu_fdt_getprop(void *fdt, const char *node_path,
- const char *property, int *lenp)
+ const char *property, int *lenp, Error **errp)
 {
 int len;
 const void *r;
+
 if (!lenp) {
 lenp = &len;
 }
 r = fdt_getprop(fdt, findnode_nofail(fdt, node_path), property, lenp);
 if (!r) {
-error_report("%s: Couldn't get %s/%s: %s", __func__,
- node_path, property, fdt_strerror(*lenp));
-exit(1);
+error_setg(errp, "%s: Couldn't get %s/%s: %s", __func__,
+  node_path, property, fdt_strerror(*lenp));
 }
 return r;
 }
@@ -353,7 +353,8 @@ uint32_t qemu_fdt_getprop_cell(void *fdt, const char 
*node_path,
const char *property)
 {
 int len;
-const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len);
+const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len,
+ &error_fatal);
 if (len != 4) {
 error_report("%s: %s/%s not 4 bytes long (not a cell?)",
  __func__, node_path, property);
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index 552df21..48bf3b5 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -54,8 +54,19 @@ int qemu_fdt_setprop_string(void *fdt, const char *node_path,
 int qemu_fdt_setprop_phandle(void *fdt, const char *node_path,
  const char *property,
  const char *target_node_path);
+/**
+ * qemu_fdt_getprop: retrieve the value of a given property
+ * @fdt: pointer to the device tree blob
+ * @node_path: node path
+ * @property: name of the property to find
+ * @lenp: fdt error if any or length of the property on success
+ * @errp: handle to an error object
+ *
+ * returns a pointer to the property on success and NULL on failure
+ */
 const void *qemu_fdt_getprop(void *fdt, const char *node_path,
- const char *property, int *lenp);
+ const char *property, int *lenp,
+ Error **errp);
 uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
const char *property);
 uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);




Re: [Qemu-devel] [PULL 0/6] softfloat queue

2016-02-19 Thread Peter Maydell
On 19 February 2016 at 16:36, Peter Maydell  wrote:
> This is just the MAINTAINERS change plus dropping the fast types.
> I've included the minor MIPS change (by agreement with Leon) and the
> osdep.h change that drops the solaris compat baggage.
>
> thanks
> -- PMM
>
>
>
> The following changes since commit 1b3337bb1d1c3125a2140c47629f36540ac57605:
>
>   Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2016-02-19' 
> into staging (2016-02-19 15:19:13 +)
>
> are available in the git repository at:
>
>
>   git://git.linaro.org/people/pmaydell/qemu-arm.git 
> tags/pull-softfloat-20160219
>
> for you to fetch changes up to 1badb5869831de916792628b5e159176f7e342b8:
>
>   MAINTAINERS: Add section for FPU emulation (2016-02-19 16:27:22 +)
>
> 
> softfloat queue:
>  * update MAINTAINERS with a section for softfloat
>  * drop all the uses of int_fast*_t types

Applied, thanks.

-- PMM



[Qemu-devel] [PULL 06/14] hw/vfio/platform: amd-xgbe device

2016-02-19 Thread Alex Williamson
From: Eric Auger 

This patch introduces the amd-xgbe VFIO platform device. It
allows the guest to do passthrough on a device exposing an
"amd,xgbe-seattle-v1a" compat string.

Signed-off-by: Eric Auger 
Reviewed-by: Alex Bennée 
Signed-off-by: Alex Williamson 
---
 hw/vfio/Makefile.objs   |1 +
 hw/vfio/amd-xgbe.c  |   55 +++
 include/hw/vfio/vfio-amd-xgbe.h |   51 
 3 files changed, 107 insertions(+)
 create mode 100644 hw/vfio/amd-xgbe.c
 create mode 100644 include/hw/vfio/vfio-amd-xgbe.h

diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index d324863..ceddbb8 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -3,4 +3,5 @@ obj-$(CONFIG_SOFTMMU) += common.o
 obj-$(CONFIG_PCI) += pci.o pci-quirks.o
 obj-$(CONFIG_SOFTMMU) += platform.o
 obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o
+obj-$(CONFIG_SOFTMMU) += amd-xgbe.o
 endif
diff --git a/hw/vfio/amd-xgbe.c b/hw/vfio/amd-xgbe.c
new file mode 100644
index 000..53451eb
--- /dev/null
+++ b/hw/vfio/amd-xgbe.c
@@ -0,0 +1,55 @@
+/*
+ * AMD XGBE VFIO device
+ *
+ * Copyright Linaro Limited, 2015
+ *
+ * Authors:
+ *  Eric Auger 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "hw/vfio/vfio-amd-xgbe.h"
+
+static void amd_xgbe_realize(DeviceState *dev, Error **errp)
+{
+VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev);
+VFIOAmdXgbeDeviceClass *k = VFIO_AMD_XGBE_DEVICE_GET_CLASS(dev);
+
+vdev->compat = g_strdup("amd,xgbe-seattle-v1a");
+
+k->parent_realize(dev, errp);
+}
+
+static const VMStateDescription vfio_platform_amd_xgbe_vmstate = {
+.name = TYPE_VFIO_AMD_XGBE,
+.unmigratable = 1,
+};
+
+static void vfio_amd_xgbe_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VFIOAmdXgbeDeviceClass *vcxc =
+VFIO_AMD_XGBE_DEVICE_CLASS(klass);
+vcxc->parent_realize = dc->realize;
+dc->realize = amd_xgbe_realize;
+dc->desc = "VFIO AMD XGBE";
+dc->vmsd = &vfio_platform_amd_xgbe_vmstate;
+}
+
+static const TypeInfo vfio_amd_xgbe_dev_info = {
+.name = TYPE_VFIO_AMD_XGBE,
+.parent = TYPE_VFIO_PLATFORM,
+.instance_size = sizeof(VFIOAmdXgbeDevice),
+.class_init = vfio_amd_xgbe_class_init,
+.class_size = sizeof(VFIOAmdXgbeDeviceClass),
+};
+
+static void register_amd_xgbe_dev_type(void)
+{
+type_register_static(&vfio_amd_xgbe_dev_info);
+}
+
+type_init(register_amd_xgbe_dev_type)
diff --git a/include/hw/vfio/vfio-amd-xgbe.h b/include/hw/vfio/vfio-amd-xgbe.h
new file mode 100644
index 000..9fff65e
--- /dev/null
+++ b/include/hw/vfio/vfio-amd-xgbe.h
@@ -0,0 +1,51 @@
+/*
+ * VFIO AMD XGBE device
+ *
+ * Copyright Linaro Limited, 2015
+ *
+ * Authors:
+ *  Eric Auger 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef HW_VFIO_VFIO_AMD_XGBE_H
+#define HW_VFIO_VFIO_AMD_XGBE_H
+
+#include "hw/vfio/vfio-platform.h"
+
+#define TYPE_VFIO_AMD_XGBE "vfio-amd-xgbe"
+
+/**
+ * This device exposes:
+ * - 5 MMIO regions: MAC, PCS, SerDes Rx/Tx regs,
+ SerDes Integration Registers 1/2 & 2/2
+ * - 2 level sensitive IRQs and optional DMA channel IRQs
+ */
+struct VFIOAmdXgbeDevice {
+VFIOPlatformDevice vdev;
+};
+
+typedef struct VFIOAmdXgbeDevice VFIOAmdXgbeDevice;
+
+struct VFIOAmdXgbeDeviceClass {
+/*< private >*/
+VFIOPlatformDeviceClass parent_class;
+/*< public >*/
+DeviceRealize parent_realize;
+};
+
+typedef struct VFIOAmdXgbeDeviceClass VFIOAmdXgbeDeviceClass;
+
+#define VFIO_AMD_XGBE_DEVICE(obj) \
+ OBJECT_CHECK(VFIOAmdXgbeDevice, (obj), TYPE_VFIO_AMD_XGBE)
+#define VFIO_AMD_XGBE_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VFIOAmdXgbeDeviceClass, (klass), \
+TYPE_VFIO_AMD_XGBE)
+#define VFIO_AMD_XGBE_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VFIOAmdXgbeDeviceClass, (obj), \
+  TYPE_VFIO_AMD_XGBE)
+
+#endif




[Qemu-devel] [PULL 14/14] vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries

2016-02-19 Thread Alex Williamson
From: Wei Yang 

Even PCI_CAP_FLAGS has the same value as PCI_MSIX_FLAGS, the later one is
the more proper on retrieving MSIX entries.

This patch uses PCI_MSIX_FLAGS to retrieve the MSIX entries.

Signed-off-by: Wei Yang 
Signed-off-by: Alex Williamson 
---
 hw/vfio/pci.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index dc5fa9f..20b505f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1207,7 +1207,7 @@ static int vfio_msix_early_setup(VFIOPCIDevice *vdev)
 }
 
 if (pread(fd, &ctrl, sizeof(ctrl),
-  vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
+  vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
 return -errno;
 }
 




[Qemu-devel] [PULL 08/14] device_tree: introduce qemu_fdt_node_path

2016-02-19 Thread Alex Williamson
From: Eric Auger 

This new helper routine returns a NULL terminated array of
node paths matching a node name and a compat string.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Signed-off-by: Alex Williamson 
---
 device_tree.c|   54 ++
 include/sysemu/device_tree.h |   18 ++
 2 files changed, 72 insertions(+)

diff --git a/device_tree.c b/device_tree.c
index 9e77c69..b29a433 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -226,6 +226,60 @@ static int findnode_nofail(void *fdt, const char 
*node_path)
 return offset;
 }
 
+char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
+  Error **errp)
+{
+int offset, len, ret;
+const char *iter_name;
+unsigned int path_len = 16, n = 0;
+GSList *path_list = NULL, *iter;
+char **path_array;
+
+offset = fdt_node_offset_by_compatible(fdt, -1, compat);
+
+while (offset >= 0) {
+iter_name = fdt_get_name(fdt, offset, &len);
+if (!iter_name) {
+offset = len;
+break;
+}
+if (!strcmp(iter_name, name)) {
+char *path;
+
+path = g_malloc(path_len);
+while ((ret = fdt_get_path(fdt, offset, path, path_len))
+  == -FDT_ERR_NOSPACE) {
+path_len += 16;
+path = g_realloc(path, path_len);
+}
+path_list = g_slist_prepend(path_list, path);
+n++;
+}
+offset = fdt_node_offset_by_compatible(fdt, offset, compat);
+}
+
+if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
+error_setg(errp, "%s: abort parsing dt for %s/%s: %s",
+   __func__, name, compat, fdt_strerror(offset));
+for (iter = path_list; iter; iter = iter->next) {
+g_free(iter->data);
+}
+g_slist_free(path_list);
+return NULL;
+}
+
+path_array = g_new(char *, n + 1);
+path_array[n--] = NULL;
+
+for (iter = path_list; iter; iter = iter->next) {
+path_array[n--] = iter->data;
+}
+
+g_slist_free(path_list);
+
+return path_array;
+}
+
 int qemu_fdt_setprop(void *fdt, const char *node_path,
  const char *property, const void *val, int size)
 {
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index 62093ba..552df21 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -25,6 +25,24 @@ void *load_device_tree(const char *filename_path, int 
*sizep);
 void *load_device_tree_from_sysfs(void);
 #endif
 
+/**
+ * qemu_fdt_node_path: return the paths of nodes matching a given
+ * name and compat string
+ * @fdt: pointer to the dt blob
+ * @name: node name
+ * @compat: compatibility string
+ * @errp: handle to an error object
+ *
+ * returns a newly allocated NULL-terminated array of node paths.
+ * Use g_strfreev() to free it. If one or more nodes were found, the
+ * array contains the path of each node and the last element equals to
+ * NULL. If there is no error but no matching node was found, the
+ * returned array contains a single element equal to NULL. If an error
+ * was encountered when parsing the blob, the function returns NULL
+ */
+char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
+  Error **errp);
+
 int qemu_fdt_setprop(void *fdt, const char *node_path,
  const char *property, const void *val, int size);
 int qemu_fdt_setprop_cell(void *fdt, const char *node_path,




[Qemu-devel] [PULL 10/14] device_tree: qemu_fdt_getprop_cell converted to use the error API

2016-02-19 Thread Alex Williamson
From: Eric Auger 

This patch aligns the prototype with qemu_fdt_getprop. The caller
can choose whether the function self-asserts on error (passing
&error_fatal as Error ** argument, corresponding to the legacy behavior),
or behaves differently such as simply output a message.

In this later case the caller can use the new lenp parameter to interpret
the error if any.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Crosthwaite 
Signed-off-by: Alex Williamson 
---
 device_tree.c|   21 ++---
 hw/arm/boot.c|6 --
 hw/arm/vexpress.c|6 --
 include/sysemu/device_tree.h |   14 +-
 4 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/device_tree.c b/device_tree.c
index 3d41c44..6204af8 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -350,15 +350,22 @@ const void *qemu_fdt_getprop(void *fdt, const char 
*node_path,
 }
 
 uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
-   const char *property)
+   const char *property, int *lenp, Error **errp)
 {
 int len;
-const uint32_t *p = qemu_fdt_getprop(fdt, node_path, property, &len,
- &error_fatal);
-if (len != 4) {
-error_report("%s: %s/%s not 4 bytes long (not a cell?)",
- __func__, node_path, property);
-exit(1);
+const uint32_t *p;
+
+if (!lenp) {
+lenp = &len;
+}
+p = qemu_fdt_getprop(fdt, node_path, property, lenp, errp);
+if (!p) {
+return 0;
+} else if (*lenp != 4) {
+error_setg(errp, "%s: %s/%s not 4 bytes long (not a cell?)",
+   __func__, node_path, property);
+*lenp = -EINVAL;
+return 0;
 }
 return be32_to_cpu(*p);
 }
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index cce8c7c..0a56d34c 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -437,8 +437,10 @@ static int load_dtb(hwaddr addr, const struct 
arm_boot_info *binfo,
 return 0;
 }
 
-acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
-scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
+acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
+   NULL, &error_fatal);
+scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
+   NULL, &error_fatal);
 if (acells == 0 || scells == 0) {
 fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 
0)\n");
 goto fail;
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 3154aea..726c4e0 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -478,8 +478,10 @@ static void vexpress_modify_dtb(const struct arm_boot_info 
*info, void *fdt)
 uint32_t acells, scells, intc;
 const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info;
 
-acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells");
-scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells");
+acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells",
+   NULL, &error_fatal);
+scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells",
+   NULL, &error_fatal);
 intc = find_int_controller(fdt);
 if (!intc) {
 /* Not fatal, we just won't provide virtio. This will
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index 48bf3b5..705650a 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -67,8 +67,20 @@ int qemu_fdt_setprop_phandle(void *fdt, const char 
*node_path,
 const void *qemu_fdt_getprop(void *fdt, const char *node_path,
  const char *property, int *lenp,
  Error **errp);
+/**
+ * qemu_fdt_getprop_cell: retrieve the value of a given 4 byte property
+ * @fdt: pointer to the device tree blob
+ * @node_path: node path
+ * @property: name of the property to find
+ * @lenp: fdt error if any or -EINVAL if the property size is different from
+ *4 bytes, or 4 (expected length of the property) upon success.
+ * @errp: handle to an error object
+ *
+ * returns the property value on success
+ */
 uint32_t qemu_fdt_getprop_cell(void *fdt, const char *node_path,
-   const char *property);
+   const char *property, int *lenp,
+   Error **errp);
 uint32_t qemu_fdt_get_phandle(void *fdt, const char *path);
 uint32_t qemu_fdt_alloc_phandle(void *fdt);
 int qemu_fdt_nop_node(void *fdt, const char *node_path);




[Qemu-devel] [PULL 05/14] vfio/pci: replace 1 with PCI_CAP_LIST_NEXT to make code self-explain

2016-02-19 Thread Alex Williamson
From: Wei Yang 

Use the macro PCI_CAP_LIST_NEXT instead of 1, so that the code would be
more self-explain.

This patch makes this change and also fixs one typo in comment.

Signed-off-by: Wei Yang 
Signed-off-by: Alex Williamson 
---
 hw/vfio/pci.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index e671506..dc5fa9f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1509,7 +1509,7 @@ static uint8_t vfio_std_cap_max_size(PCIDevice *pdev, 
uint8_t pos)
 uint16_t next = PCI_CONFIG_SPACE_SIZE;
 
 for (tmp = pdev->config[PCI_CAPABILITY_LIST]; tmp;
- tmp = pdev->config[tmp + 1]) {
+ tmp = pdev->config[tmp + PCI_CAP_LIST_NEXT]) {
 if (tmp > pos && tmp < next) {
 next = tmp;
 }
@@ -1698,7 +1698,7 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t 
pos)
 int ret;
 
 cap_id = pdev->config[pos];
-next = pdev->config[pos + 1];
+next = pdev->config[pos + PCI_CAP_LIST_NEXT];
 
 /*
  * If it becomes important to configure capabilities to their actual
@@ -1712,7 +1712,7 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t 
pos)
  * pci_add_capability always inserts the new capability at the head
  * of the chain.  Therefore to end up with a chain that matches the
  * physical device, we insert from the end by making this recursive.
- * This is also why we pre-caclulate size above as cached config space
+ * This is also why we pre-calculate size above as cached config space
  * will be changed as we unwind the stack.
  */
 if (next) {
@@ -1728,7 +1728,7 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t 
pos)
 }
 
 /* Use emulated next pointer to allow dropping caps */
-pci_set_byte(vdev->emulated_config_bits + pos + 1, 0xff);
+pci_set_byte(vdev->emulated_config_bits + pos + PCI_CAP_LIST_NEXT, 0xff);
 
 switch (cap_id) {
 case PCI_CAP_ID_MSI:




[Qemu-devel] [PULL 03/14] aer: impove pcie_aer_init to support vfio device

2016-02-19 Thread Alex Williamson
From: Chen Fan 

pcie_aer_init was used to emulate an aer capability for pcie device,
but for vfio device, the aer config space size is mutable and is not
always equal to PCI_ERR_SIZEOF(0x48). it depends on where the TLP Prefix
register required, so here we add a size argument.

Signed-off-by: Chen Fan 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Alex Williamson 
---
 hw/pci-bridge/ioh3420.c|2 +-
 hw/pci-bridge/xio3130_downstream.c |2 +-
 hw/pci-bridge/xio3130_upstream.c   |2 +-
 hw/pci/pcie_aer.c  |4 ++--
 include/hw/pci/pcie_aer.h  |2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index 9e048eb..0937fa3 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -126,7 +126,7 @@ static int ioh3420_initfn(PCIDevice *d)
 goto err_pcie_cap;
 }
 pcie_cap_root_init(d);
-rc = pcie_aer_init(d, IOH_EP_AER_OFFSET);
+rc = pcie_aer_init(d, IOH_EP_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci-bridge/xio3130_downstream.c 
b/hw/pci-bridge/xio3130_downstream.c
index c32f271..cf1ee63 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -89,7 +89,7 @@ static int xio3130_downstream_initfn(PCIDevice *d)
 goto err_pcie_cap;
 }
 pcie_cap_arifwd_init(d);
-rc = pcie_aer_init(d, XIO3130_AER_OFFSET);
+rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 19798c0..164ef58 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -78,7 +78,7 @@ 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);
+rc = pcie_aer_init(d, XIO3130_AER_OFFSET, PCI_ERR_SIZEOF);
 if (rc < 0) {
 goto err;
 }
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index a9d9d06..8043020 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -95,12 +95,12 @@ static void aer_log_clear_all_err(PCIEAERLog *aer_log)
 aer_log->log_num = 0;
 }
 
-int pcie_aer_init(PCIDevice *dev, uint16_t offset)
+int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size)
 {
 PCIExpressDevice *exp;
 
 pcie_add_capability(dev, PCI_EXT_CAP_ID_ERR, PCI_ERR_VER,
-offset, PCI_ERR_SIZEOF);
+offset, size);
 exp = &dev->exp;
 exp->aer_cap = offset;
 
diff --git a/include/hw/pci/pcie_aer.h b/include/hw/pci/pcie_aer.h
index 2fb8388..156acb0 100644
--- a/include/hw/pci/pcie_aer.h
+++ b/include/hw/pci/pcie_aer.h
@@ -87,7 +87,7 @@ struct PCIEAERErr {
 
 extern const VMStateDescription vmstate_pcie_aer_log;
 
-int pcie_aer_init(PCIDevice *dev, uint16_t offset);
+int pcie_aer_init(PCIDevice *dev, uint16_t offset, uint16_t size);
 void pcie_aer_exit(PCIDevice *dev);
 void pcie_aer_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);




[Qemu-devel] [PULL 07/14] device_tree: introduce load_device_tree_from_sysfs

2016-02-19 Thread Alex Williamson
From: Eric Auger 

This function returns the host device tree blob from sysfs
(/proc/device-tree). It uses a recursive function inspired
from dtc read_fstree.

Signed-off-by: Eric Auger 
Reviewed-by: Peter Maydell 
Signed-off-by: Alex Williamson 
---
 device_tree.c|  100 ++
 include/sysemu/device_tree.h |8 +++
 2 files changed, 108 insertions(+)

diff --git a/device_tree.c b/device_tree.c
index b1ad836..9e77c69 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -13,6 +13,10 @@
 
 #include "qemu/osdep.h"
 
+#ifdef CONFIG_LINUX
+#include 
+#endif
+
 #include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "sysemu/device_tree.h"
@@ -112,6 +116,102 @@ fail:
 return NULL;
 }
 
+#ifdef CONFIG_LINUX
+
+#define SYSFS_DT_BASEDIR "/proc/device-tree"
+
+/**
+ * read_fstree: this function is inspired from dtc read_fstree
+ * @fdt: preallocated fdt blob buffer, to be populated
+ * @dirname: directory to scan under SYSFS_DT_BASEDIR
+ * the search is recursive and the tree is searched down to the
+ * leaves (property files).
+ *
+ * the function asserts in case of error
+ */
+static void read_fstree(void *fdt, const char *dirname)
+{
+DIR *d;
+struct dirent *de;
+struct stat st;
+const char *root_dir = SYSFS_DT_BASEDIR;
+const char *parent_node;
+
+if (strstr(dirname, root_dir) != dirname) {
+error_setg(&error_fatal, "%s: %s must be searched within %s",
+   __func__, dirname, root_dir);
+}
+parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];
+
+d = opendir(dirname);
+if (!d) {
+error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
+}
+
+while ((de = readdir(d)) != NULL) {
+char *tmpnam;
+
+if (!g_strcmp0(de->d_name, ".")
+|| !g_strcmp0(de->d_name, "..")) {
+continue;
+}
+
+tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);
+
+if (lstat(tmpnam, &st) < 0) {
+error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
+}
+
+if (S_ISREG(st.st_mode)) {
+gchar *val;
+gsize len;
+
+if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
+error_setg(&error_fatal, "%s not able to extract info from %s",
+   __func__, tmpnam);
+}
+
+if (strlen(parent_node) > 0) {
+qemu_fdt_setprop(fdt, parent_node,
+ de->d_name, val, len);
+} else {
+qemu_fdt_setprop(fdt, "/", de->d_name, val, len);
+}
+g_free(val);
+} else if (S_ISDIR(st.st_mode)) {
+char *node_name;
+
+node_name = g_strdup_printf("%s/%s",
+parent_node, de->d_name);
+qemu_fdt_add_subnode(fdt, node_name);
+g_free(node_name);
+read_fstree(fdt, tmpnam);
+}
+
+g_free(tmpnam);
+}
+
+closedir(d);
+}
+
+/* load_device_tree_from_sysfs: extract the dt blob from host sysfs */
+void *load_device_tree_from_sysfs(void)
+{
+void *host_fdt;
+int host_fdt_size;
+
+host_fdt = create_device_tree(&host_fdt_size);
+read_fstree(host_fdt, SYSFS_DT_BASEDIR);
+if (fdt_check_header(host_fdt)) {
+error_setg(&error_fatal,
+   "%s host device tree extracted into memory is invalid",
+   __func__);
+}
+return host_fdt;
+}
+
+#endif /* CONFIG_LINUX */
+
 static int findnode_nofail(void *fdt, const char *node_path)
 {
 int offset;
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index 359e143..62093ba 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -16,6 +16,14 @@
 
 void *create_device_tree(int *sizep);
 void *load_device_tree(const char *filename_path, int *sizep);
+#ifdef CONFIG_LINUX
+/**
+ * load_device_tree_from_sysfs: reads the device tree information in the
+ * /proc/device-tree directory and return the corresponding binary blob
+ * buffer pointer. Asserts in case of error.
+ */
+void *load_device_tree_from_sysfs(void);
+#endif
 
 int qemu_fdt_setprop(void *fdt, const char *node_path,
  const char *property, const void *val, int size);




[Qemu-devel] [PULL 01/14] pcie: modify the capability size assert

2016-02-19 Thread Alex Williamson
From: Chen Fan 

Device's Offset and size can reach PCIE_CONFIG_SPACE_SIZE,
fix the corresponding assert.

Signed-off-by: Chen Fan 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Alex Williamson 
---
 hw/pci/pcie.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 435a6cf..4aca0c5 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -608,7 +608,7 @@ void pcie_add_capability(PCIDevice *dev,
 
 assert(offset >= PCI_CONFIG_SPACE_SIZE);
 assert(offset < offset + size);
-assert(offset + size < PCIE_CONFIG_SPACE_SIZE);
+assert(offset + size <= PCIE_CONFIG_SPACE_SIZE);
 assert(size >= 8);
 assert(pci_is_express(dev));
 




[Qemu-devel] [PULL 02/14] vfio: make the 4 bytes aligned for capability size

2016-02-19 Thread Alex Williamson
From: Chen Fan 

this function search the capability from the end, the last
size should 0x100 - pos, not 0xff - pos.

Signed-off-by: Chen Fan 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Alex Williamson 
---
 hw/vfio/pci.c |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 49f3d2d..e671506 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -1505,7 +1505,8 @@ static void vfio_unmap_bars(VFIOPCIDevice *vdev)
  */
 static uint8_t vfio_std_cap_max_size(PCIDevice *pdev, uint8_t pos)
 {
-uint8_t tmp, next = 0xff;
+uint8_t tmp;
+uint16_t next = PCI_CONFIG_SPACE_SIZE;
 
 for (tmp = pdev->config[PCI_CAPABILITY_LIST]; tmp;
  tmp = pdev->config[tmp + 1]) {




[Qemu-devel] [PULL 04/14] pcie_aer: expose pcie_aer_msg() interface

2016-02-19 Thread Alex Williamson
From: Chen Fan 

For vfio device, we need to propagate the aer error to
Guest OS. we use the pcie_aer_msg() to send aer error
to guest.

Signed-off-by: Chen Fan 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Alex Williamson 
---
 hw/pci/pcie_aer.c |2 +-
 include/hw/pci/pcie_aer.h |1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 8043020..e2d4e68 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -371,7 +371,7 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const 
PCIEAERMsg *msg)
  *
  * Walk up the bus tree from the device, propagate the error message.
  */
-static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
+void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg)
 {
 uint8_t type;
 
diff --git a/include/hw/pci/pcie_aer.h b/include/hw/pci/pcie_aer.h
index 156acb0..c2ee4e2 100644
--- a/include/hw/pci/pcie_aer.h
+++ b/include/hw/pci/pcie_aer.h
@@ -102,5 +102,6 @@ void pcie_aer_root_write_config(PCIDevice *dev,
 
 /* error injection */
 int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err);
+void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg);
 
 #endif /* QEMU_PCIE_AER_H */




[Qemu-devel] [PULL 00/14] VFIO updates 2016-02-19

2016-02-19 Thread Alex Williamson
The following changes since commit 1b3337bb1d1c3125a2140c47629f36540ac57605:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2016-02-19' into 
staging (2016-02-19 15:19:13 +)

are available in the git repository at:


  git://github.com/awilliam/qemu-vfio.git tags/vfio-update-20160219.1

for you to fetch changes up to b58b17f744b5465d0fc76eba1be549a9f5704bab:

  vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries (2016-02-19 
09:42:32 -0700)


VFIO updates 2016-02-19

 - AER pre-enable and misc fixes (Cao jin and Chen Fan)
 - PCI_CAP_LIST_NEXT & PCI_MSIX_FLAGS cleanup (Wei Yang)
 - AMD XGBE KVM platform passthrough (Eric Auger)


Chen Fan (4):
  pcie: modify the capability size assert
  vfio: make the 4 bytes aligned for capability size
  aer: impove pcie_aer_init to support vfio device
  pcie_aer: expose pcie_aer_msg() interface

Eric Auger (8):
  hw/vfio/platform: amd-xgbe device
  device_tree: introduce load_device_tree_from_sysfs
  device_tree: introduce qemu_fdt_node_path
  device_tree: qemu_fdt_getprop converted to use the error API
  device_tree: qemu_fdt_getprop_cell converted to use the error API
  hw/arm/sysbus-fdt: helpers for clock node generation
  hw/arm/sysbus-fdt: enable amd-xgbe dynamic instantiation
  hw/arm/sysbus-fdt: remove qemu_fdt_setprop returned value check

Wei Yang (2):
  vfio/pci: replace 1 with PCI_CAP_LIST_NEXT to make code self-explain
  vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries

 device_tree.c  | 182 +++--
 hw/arm/boot.c  |   6 +-
 hw/arm/sysbus-fdt.c| 319 +++--
 hw/arm/vexpress.c  |   6 +-
 hw/pci-bridge/ioh3420.c|   2 +-
 hw/pci-bridge/xio3130_downstream.c |   2 +-
 hw/pci-bridge/xio3130_upstream.c   |   2 +-
 hw/pci/pcie.c  |   2 +-
 hw/pci/pcie_aer.c  |   6 +-
 hw/vfio/Makefile.objs  |   1 +
 hw/vfio/amd-xgbe.c |  55 +++
 hw/vfio/pci.c  |  13 +-
 include/hw/pci/pcie_aer.h  |   3 +-
 include/hw/vfio/vfio-amd-xgbe.h|  51 ++
 include/sysemu/device_tree.h   |  53 +-
 15 files changed, 660 insertions(+), 43 deletions(-)
 create mode 100644 hw/vfio/amd-xgbe.c
 create mode 100644 include/hw/vfio/vfio-amd-xgbe.h



Re: [Qemu-devel] [PATCH] log: Redirect stderr to logfile if deamonized

2016-02-19 Thread Paolo Bonzini


On 18/02/2016 18:12, Dimitris Aragiorgis wrote:
> * Paolo Bonzini  [2016-02-18 16:22:13 +0100]:
> 
>>
>>
>> On 18/02/2016 12:38, Dimitris Aragiorgis wrote:
>>> In case of daemonize, use the logfile passed with the -D option in
>>> order to redirect stderr to it instead of /dev/null.
>>>
>>> Also remove some unused code in log.h.
>>>
>>> Signed-off-by: Dimitris Aragiorgis 
>>> ---
>>>  include/qemu/log.h |6 --
>>>  os-posix.c |6 +-
>>>  util/log.c |   11 +--
>>>  3 files changed, 14 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/include/qemu/log.h b/include/qemu/log.h
>>> index 30817f7..dda65fd 100644
>>> --- a/include/qemu/log.h
>>> +++ b/include/qemu/log.h
>>> @@ -94,12 +94,6 @@ static inline void qemu_log_close(void)
>>>  }
>>>  }
>>>  
>>> -/* Set up a new log file */
>>> -static inline void qemu_log_set_file(FILE *f)
>>> -{
>>> -qemu_logfile = f;
>>> -}
>>> -
>>>  /* define log items */
>>>  typedef struct QEMULogItem {
>>>  int mask;
>>> diff --git a/os-posix.c b/os-posix.c
>>> index cce62ed..92fa3ba 100644
>>> --- a/os-posix.c
>>> +++ b/os-posix.c
>>> @@ -37,6 +37,7 @@
>>>  #include "qemu-options.h"
>>>  #include "qemu/rcu.h"
>>>  #include "qemu/error-report.h"
>>> +#include "qemu/log.h"
>>>  
>>>  #ifdef CONFIG_LINUX
>>>  #include 
>>> @@ -275,7 +276,10 @@ void os_setup_post(void)
>>>  
>>>  dup2(fd, 0);
>>>  dup2(fd, 1);
>>> -dup2(fd, 2);
>>> +/* In case -D is given do not redirect stderr to /dev/null */
>>> +if (!qemu_logfile) {
>>> +dup2(fd, 2);
>>> +}
>>>  
>>>  close(fd);
>>>  
>>> diff --git a/util/log.c b/util/log.c
>>> index 2709e98..a7ddc7e 100644
>>> --- a/util/log.c
>>> +++ b/util/log.c
>>> @@ -56,13 +56,20 @@ void do_qemu_set_log(int log_flags, bool 
>>> use_own_buffers)
>>>  #ifdef CONFIG_TRACE_LOG
>>>  qemu_loglevel |= LOG_TRACE;
>>>  #endif
>>> -if (qemu_loglevel && !qemu_logfile) {
>>> +if ((qemu_loglevel || is_daemonized()) && !qemu_logfile) {
>>>  if (logfilename) {
>>>  qemu_logfile = fopen(logfilename, log_append ? "a" : "w");
>>>  if (!qemu_logfile) {
>>>  perror(logfilename);
>>>  _exit(1);
>>>  }
>>> +/* In case we are a daemon redirect stderr to logfile */
>>> +if (is_daemonized()) {
>>> +dup2(fileno(qemu_logfile), STDERR_FILENO);
>>> +fclose(qemu_logfile);
>>> +/* This will skip closing logfile in qemu_log_close() */
>>> +qemu_logfile = stderr;
>>> +}
>>>  } else {
>>>  /* Default to stderr if no log file specified */
>>>  qemu_logfile = stderr;
>>> @@ -82,7 +89,7 @@ void do_qemu_set_log(int log_flags, bool use_own_buffers)
>>>  log_append = 1;
>>>  }
>>>  }
>>> -if (!qemu_loglevel && qemu_logfile) {
>>> +if (!qemu_loglevel && !is_daemonized() && qemu_logfile) {
>>>  qemu_log_close();
>>>  }
>>
>> Why is this necessary?  Perhaps qemu_log_close should dup(1,2) if QEMU
>> is daemonized.  The rest looks great.
>>
> 
> Without !is_daemonized(), if we use -daemon with -D without -d,
> qemu_log_close() will eventually set qemu_logfile to NULL. This
> will make os_setup_post() redirect stderr to /dev/null, which
> is unwanted.

Sorry, I missed the context of this hunk.  The patch is okay, thanks for
putting up with me!

Paolo



Re: [Qemu-devel] [RFC 0/1] riscv: Add full-system emulation support for the RISC-V Instruction Set Architecture (RV64G)

2016-02-19 Thread Stefan Hajnoczi
On Thu, Feb 18, 2016 at 05:02:04PM -0800, Sagar Karandikar wrote:
> With this RFC, I mainly wanted to get input on the overall design of the 
> target
> implementation, as well as see if any regular contributors would be 
> interested 
> in co-mentoring RISC-V related projects for QEMU's Google Summer of Code with 
> me.

RISC-V GSoC is a great idea!  It's an exciting new architecture and I'm
sure students would like to participate.

Getting some of your own patches merged will help.  That way the student
can also upstream their code.

I'm not familiar enough with TCG to act as co-mentor on this project but
I hope another regular QEMU contributor is interested.

Stefan


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v1 1/2] qdev-monitor.c: Register reset function if the device has one

2016-02-19 Thread Paolo Bonzini


On 19/02/2016 11:55, Peter Maydell wrote:
>> Any abstraction we have in QEMU should have at least a parallel (though
>> > it need not be the same) in real hardware.  Reset signals _do_ propagate
>> > along buses, or at least along some buses, so "debusifying" reset seems
>> > like a counterproductive goal to me.
> Reset for some buses propagates along buses, but not in all
> cases.

Agreed.  But still this doesn't change the fact that "debusifying" reset
is a non-goal.

> In any case our current "reset" semantics are "power on
> reset", not any kind of driven-by-hardware-reset-lines reset.

It depends.  There are several cases (PCI, SCSI) where qdev_reset_all is
used from within the code in order to provide hardware reset semantics.

Paolo



Re: [Qemu-devel] [PATCH v1 1/2] qdev-monitor.c: Register reset function if the device has one

2016-02-19 Thread Andreas Färber
Am 18.02.2016 um 10:56 schrieb Markus Armbruster:
> Alistair Francis  writes:
> 
>> If the device being added when running qdev_device_add() has
>> a reset function, register it so that it can be called.
>>
>> Signed-off-by: Alistair Francis 
>> ---
>>
>>  qdev-monitor.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/qdev-monitor.c b/qdev-monitor.c
>> index 81e3ff3..0a99d01 100644
>> --- a/qdev-monitor.c
>> +++ b/qdev-monitor.c
>> @@ -561,6 +561,8 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error 
>> **errp)
>>  
>>  if (bus) {
>>  qdev_set_parent_bus(dev, bus);
>> +} else if (dc->reset) {
>> +qemu_register_reset((void (*)(void *))dc->reset, dev);
>>  }
>>  
>>  id = qemu_opts_id(opts);
> 
> This looks wrong to me.
> 
> You stuff all the device reset methods into the global reset_handlers
> list, where they get called in some semi-random order.  This breaks when
> there are reset order dependencies between devices, e.g. between a
> device and the bus it plugs into.
> 
> Propagating the reset signal to all the devices is a qdev problem.
> Copying Andreas for further insight.

We had a similar discussion for s390x, and I had started a big reset
refactoring, but we agreed to go for a stop-gap solution for 2.5. The
recently posted hw/core/bus.c refactoring originated from that branch.

The overall idea was that for buses reset propagates along buses (so
yes, NACK to this patch), but where no bus exists it shall propagate to
QOM children, too.

So Alistair, if you have a device that needs a reset while not sitting
on a bus, please register the register hook in your device's realize
hook for now.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton; HRB 21284 (AG Nürnberg)



Re: [Qemu-devel] [PATCH v1 01/10] qdict: implement a qdict_crumple method for un-flattening a dict

2016-02-19 Thread Daniel P. Berrange
On Fri, Feb 19, 2016 at 10:01:07AM -0700, Eric Blake wrote:
> On 02/19/2016 09:47 AM, Daniel P. Berrange wrote:
> > The qdict_flatten() method will take a dict whose elements are
> > further nested dicts/lists and flatten them by concatenating
> > keys.
> > 
> > The qdict_crumple() method aims todo the reverse, taking a flat
> 
> s/todo/to do/
> 
> > qdict, and turning it into a set of nested dicts/lists. It will
> > apply nesting based on the key name, with a '.' indicating a
> > new level in the hierarchy. If the keys in the nested structure
> > are all numeric, it will create a list, otherwise it will create
> > a dict.
> > 
> 
> Interesting idea. I haven't closely reviewed the patch yet, but do have
> a comment on the commit message:
> 
> > 
> > If the key is intended to contain a literal '.', then it must
> > be escaped as '..'. ie a flat dict
> 
> Hmm. We forbid the use of '.' inside QAPI key names in most places, but
> have an exception that downstream extensions use '.'.  So, I guess the
> only place you'd really use this is trying to target a
> downstream-extension key name:

I originally put code into object_property_add() to forbid use of
a '.' in a property name, but quickly found we have alot of such
usage already :-(  On a x86_64 default machine I get:

Property sse4.1 on class qemu64-x86_64-cpu
Property sse4.2 on class qemu64-x86_64-cpu
Property pc.ram[*] on class container
Property pc.ram[0] on class container
Property pc.bios[*] on class container
Property pc.bios[0] on class container
Property pc.rom[*] on class container
Property pc.rom[0] on class container
Property fwcfg.dma[*] on class fw_cfg_io
Property fwcfg.dma[0] on class fw_cfg_io
Property pci.0 on class i440FX-pcihost
Property isa.0 on class PIIX3
Property vga.vram[*] on class VGA
Property vga.vram[0] on class VGA
Property vga.mmio[*] on class container
Property vga.mmio[0] on class container
Property vga.rom[*] on class VGA
Property vga.rom[0] on class VGA
Property e1000.rom[*] on class e1000
Property e1000.rom[0] on class e1000
Property ide.0 on class piix3-ide
Property ide.1 on class piix3-ide

Now none of those are implementing the UserCreatable interface
right now, so wouldn't be a problem for -object usage, but I
felt if we allow '.' in property names for devices, we ought
to make sure the code deals with it everything.

So it seems forbiding '.' in property names won't fly :-(

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH v1 01/10] qdict: implement a qdict_crumple method for un-flattening a dict

2016-02-19 Thread Eric Blake
On 02/19/2016 09:47 AM, Daniel P. Berrange wrote:
> The qdict_flatten() method will take a dict whose elements are
> further nested dicts/lists and flatten them by concatenating
> keys.
> 
> The qdict_crumple() method aims todo the reverse, taking a flat

s/todo/to do/

> qdict, and turning it into a set of nested dicts/lists. It will
> apply nesting based on the key name, with a '.' indicating a
> new level in the hierarchy. If the keys in the nested structure
> are all numeric, it will create a list, otherwise it will create
> a dict.
> 

Interesting idea. I haven't closely reviewed the patch yet, but do have
a comment on the commit message:

> 
> If the key is intended to contain a literal '.', then it must
> be escaped as '..'. ie a flat dict

Hmm. We forbid the use of '.' inside QAPI key names in most places, but
have an exception that downstream extensions use '.'.  So, I guess the
only place you'd really use this is trying to target a
downstream-extension key name:

> 
>   {
>  'foo..bar': 'wizz',
>  'bar.foo..bar': 'eek',

as in '__com..example_bar': 'eek' to set the downstream key-name of
'__com.example_bar'.  I'm not sure the special casing of '.' is worth
it, particularly since qdict_flatten() doesn't have it in the reverse
direction.

> The intent of this function is that it allows a set of QemuOpts
> to be turned into a nested data structure that mirrors the nested
> used when the same object is defined over QMP.
> 
> Signed-off-by: Daniel P. Berrange 
> ---

I hope to offer a more detailed review next week (I'm trying to get some
of my own patches polished today).

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v8 3/5] acpi: pc: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
On Fri, Feb 19, 2016 at 02:49:53PM +0100, Igor Mammedov wrote:
> On Thu, 11 Feb 2016 17:06:03 -0500
> "Gabriel L. Somlo"  wrote:
> 
> > Add a fw_cfg device node to the ACPI DSDT. While the guest-side
> > firmware can't utilize this information (since it has to access
> > the hard-coded fw_cfg device to extract ACPI tables to begin with),
> > having fw_cfg listed in ACPI will help the guest kernel keep a more
> > accurate inventory of in-use IO port regions.
> > 
> > Signed-off-by: Gabriel Somlo 
> > Reviewed-by: Laszlo Ersek 
> > Reviewed-by: Marc Marí 
> > ---
> >  hw/i386/acpi-build.c | 29 +
> >  1 file changed, 29 insertions(+)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4554eb8..4762fd2 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
> >  aml_append(scope, aml_name_decl("_S5", pkg));
> >  aml_append(dsdt, scope);
> >  
> > +/* create fw_cfg node, unconditionally */
> > +{
> > +/* when using port i/o, the 8-bit data register *always* overlaps
> > + * with half of the 16-bit control register. Hence, the total size
> > + * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
> > + * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
> > +uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
> > +   "dma_enabled", NULL) ?
> > +  ROUND_UP(FW_CFG_CTL_SIZE, 4) + 
> > sizeof(dma_addr_t) :
> > +  FW_CFG_CTL_SIZE;
> > +
> > +scope = aml_scope("\\_SB");
> > +dev = aml_device("FWCF");
> > +
> > +aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
> From my tests with different Windows versions, it doesn't prevent
> WS2003 and WS2008 from showing a prompt for unknown device that asks for a 
> driver.

I installed windows 2008 server r2 64bit, on both pc and q35 machines,
and still only saw the "unknown device" in the Device Manager after
forcing _STA to 0xF (instead of 0xB).

> One however could shut it up by allowing OS look for a driver
> which is not found and then tell  not to ask for it anymore.

It's entirely possible that "after a while" something would pop up and
ask for a driver anyway. I did try to "humor it" by allowing it to
search for a driver, and it failed, and the device was still showing
up as unknown (remember, this is with _STA set to 0xF, which I did
only to force it to show up :)

I never waited around long enough for it to prompt me, so that may be
the difference between our tests...

> 
> So existing users will have to perform this action once
> they have migrated to newer QEMU regardless of machine version.
> 
> > +
> > +/* device present, functioning, decoding, not shown in UI */
> > +aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> > +
> > +crs = aml_resource_template();
> > +aml_append(crs,
> > +aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, 
> > io_size)
> > +);
> that creates \_SB.FWCF._CRS 
> +Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource 
> Settings
> +{
> +IO (Decode16,
> +0x0510, // Range Minimum
> +0x0510, // Range Maximum
> +0x01,   // Alignment
> +0x0C,   // Length
> +)
> +})
> 
> which collides with \_SB.PCI0._CRS
> WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, 
> EntireRange,
> 0x, // Granularity
> 0x, // Range Minimum
> 0x0CF7, // Range Maximum
> 0x, // Translation Offset
> 0x0CF8,
> 
> that shouldn't happen, and solution for this is to put
> FWCF device descriptor in \_SB.PCI0 scope so FWCF would consume
> from PCI0 IO range.
> 
> That won't help Windows to notice a conflict, if there is any,
> as there aren't any drivers for QEMU0002 device but at least
> when Windows gets a driver it won't crash due above conflict.

OK, so the difference between "\_SB" and "\_SB.PCI0" is that, with
_STA forced to 0xF, the "resources" tab of the "unknown device" no
longer shows conflicts on the IO range of 510-518.

With that being said, I still hope most people won't ever make it this
far (with _STA set to 0xB). But in case they ever do, yes, placing
FWCF in \_SB.PCI0 should take care of it -- thanks for showing me that!

V9 (coming up soon) should reflect that change.

Thanks much,
--Gabriel

> 
> > +aml_append(dev, aml_name_decl("_CRS", crs));
> > +
> > +aml_append(scope, dev);
> > +aml_append(dsdt, scope);
> > +}
> > +
> >  if (misc->applesmc_io_base)

[Qemu-devel] [PATCH v1 09/10] chardev: add support for ACLs for TLS clients

2016-02-19 Thread Daniel P. Berrange
Currently any client which can complete the TLS handshake
is able to use a chardev server. The server admin can turn
on the 'verify-peer' option for the x509 creds to require
the client to provide a x509 certificate. This means the
client will have to acquire a certificate from the CA before
they are permitted to use the chardev server. This is still
a fairly weak bar.

This adds a 'tls-acl=ACL-ID' option to the socket chardev
backend which takes the ID of a previously added 'QAuthZ'
object instance. This ACL will be used to validate the client's
x509 distinguished name. Clients failing the ACL will not be
permitted to use the chardev server.

For example to setup an ACL that only allows connection from
a client whose x509 certificate distinguished name contains
'CN=fred', you would use:

  $QEMU -object tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\
endpoint=server,verify-peer=yes \
-object authz-simple,id=acl0,policy=deny,\
rules.0.match=*CN=fred,rules.0.policy=allow \
-chardev socket,host=127.0.0.1,port=9000,server,\
 tls-creds=tls0,tls-acl=acl0 \
...other qemud args...

Signed-off-by: Daniel P. Berrange 
---
 qapi-schema.json |  2 ++
 qemu-char.c  | 16 +++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 2f33d62..afa2bf4 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3150,6 +3150,7 @@
 # @addr: socket address to listen on (server=true)
 #or connect to (server=false)
 # @tls-creds: #optional the ID of the TLS credentials object (since 2.6)
+# @tls-acl: #optional the ID of the QAuthZ authorization object (since 2.6)
 # @server: #optional create server socket (default: true)
 # @wait: #optional wait for incoming connection on server
 #sockets (default: false).
@@ -3165,6 +3166,7 @@
 ##
 { 'struct': 'ChardevSocket', 'data': { 'addr'   : 'SocketAddress',
  '*tls-creds'  : 'str',
+ '*tls-acl': 'str',
  '*server': 'bool',
  '*wait'  : 'bool',
  '*nodelay'   : 'bool',
diff --git a/qemu-char.c b/qemu-char.c
index ad11b75..0610f31 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2533,6 +2533,7 @@ typedef struct {
 QIOChannelSocket *listen_ioc;
 guint listen_tag;
 QCryptoTLSCreds *tls_creds;
+char *tls_acl;
 int connected;
 int max_size;
 int do_telnetopt;
@@ -2963,7 +2964,7 @@ static void tcp_chr_tls_init(CharDriverState *chr)
 if (s->is_listen) {
 tioc = qio_channel_tls_new_server(
 s->ioc, s->tls_creds,
-NULL, /* XXX Use an ACL */
+s->tls_acl,
 &err);
 } else {
 tioc = qio_channel_tls_new_client(
@@ -3084,6 +3085,7 @@ static void tcp_chr_close(CharDriverState *chr)
 if (s->tls_creds) {
 object_unref(OBJECT(s->tls_creds));
 }
+g_free(s->tls_acl);
 if (s->write_msgfds_num) {
 g_free(s->write_msgfds);
 }
@@ -3615,6 +3617,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 const char *host = qemu_opt_get(opts, "host");
 const char *port = qemu_opt_get(opts, "port");
 const char *tls_creds = qemu_opt_get(opts, "tls-creds");
+const char *tls_acl = qemu_opt_get(opts, "tls-acl");
 SocketAddress *addr;
 
 if (!path) {
@@ -3633,6 +3636,11 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 }
 }
 
+if (tls_acl && !tls_creds) {
+error_setg(errp, "ACL should not be provided when TLS is disabled");
+return;
+}
+
 backend->u.socket = g_new0(ChardevSocket, 1);
 qemu_chr_parse_common(opts, qapi_ChardevSocket_base(backend->u.socket));
 
@@ -3647,6 +3655,7 @@ static void qemu_chr_parse_socket(QemuOpts *opts, 
ChardevBackend *backend,
 backend->u.socket->has_reconnect = true;
 backend->u.socket->reconnect = reconnect;
 backend->u.socket->tls_creds = g_strdup(tls_creds);
+backend->u.socket->tls_acl = g_strdup(tls_acl);
 
 addr = g_new0(SocketAddress, 1);
 if (path) {
@@ -4077,6 +4086,9 @@ QemuOptsList qemu_chardev_opts = {
 .name = "tls-creds",
 .type = QEMU_OPT_STRING,
 },{
+.name = "tls-acl",
+.type = QEMU_OPT_STRING,
+},{
 .name = "width",
 .type = QEMU_OPT_NUMBER,
 },{
@@ -4324,6 +4336,7 @@ static CharDriverState *qmp_chardev_open_socket(const 
char *id,
 }
 }
 }
+s->tls_acl = g_strdup(sock->tls_acl);
 
 qapi_copy_SocketAddress(&s->addr, sock->addr);
 
@@ -4369,6 +4382,7 @@ static CharDriverState *qmp_chardev_open_socket(const 
char *id,
 if (s->tls_creds) {
 object_unref(OBJECT(s->tls_creds));
 }
+g_free(s->tls_acl);
 g_free(s);
   

[Qemu-devel] [PATCH v1 05/10] util: add QAuthZSimple object type for a simple access control list

2016-02-19 Thread Daniel P. Berrange
Add a QAuthZSimple object type that implements the QAuthZ
interface. This simple built-in implementation maintains
a trivial access control list with a sequence of match
rules and a final default policy. This replicates the
functionality currently provided by the qemu_acl module.

To create an instance of this object via the QMP monitor,
the syntax used would be

  {
"execute": "object-add",
"arguments": {
  "qom-type": "authz-simple",
  "id": "auth0",
  "parameters": {
"rules": [
   { "match": "fred", "policy": "allow" },
   { "match": "bob", "policy": "allow" },
   { "match": "danb", "policy": "deny" },
   { "match": "dan*", "policy": "allow" }
],
"policy": "deny"
  }
}
  }

Or via the -object command line

  $QEMU \
 -object authz-simple,id=acl0,policy=deny,\
 match.0.name=fred,match.0.policy=allow, \
 match.1.name=bob,match.1.policy=allow, \
 match.2.name=danb,match.2.policy=deny, \
 match.3.name=dan*,match.3.policy=allow

This sets up an authorization rule that allows 'fred',
'bob' and anyone whose name starts with 'dan', except
for 'danb'. Everyone unmatched is denied.

Signed-off-by: Daniel P. Berrange 
---
 Makefile|   2 +-
 include/qemu/authz-simple.h | 107 +++
 qapi-schema.json|   6 +-
 qapi/util.json  |  31 ++
 tests/.gitignore|   1 +
 tests/Makefile  |   3 +
 tests/test-authz-simple.c   | 156 +++
 util/Makefile.objs  |   1 +
 util/authz-simple.c | 255 
 9 files changed, 560 insertions(+), 2 deletions(-)
 create mode 100644 include/qemu/authz-simple.h
 create mode 100644 qapi/util.json
 create mode 100644 tests/test-authz-simple.c
 create mode 100644 util/authz-simple.c

diff --git a/Makefile b/Makefile
index 3a1f52f..d8ff7fa 100644
--- a/Makefile
+++ b/Makefile
@@ -274,7 +274,7 @@ qapi-modules = $(SRC_PATH)/qapi-schema.json 
$(SRC_PATH)/qapi/common.json \
$(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.json \
$(SRC_PATH)/qapi/event.json $(SRC_PATH)/qapi/introspect.json \
$(SRC_PATH)/qapi/crypto.json $(SRC_PATH)/qapi/rocker.json \
-   $(SRC_PATH)/qapi/trace.json
+   $(SRC_PATH)/qapi/trace.json $(SRC_PATH)/qapi/util.json
 
 qapi-types.c qapi-types.h :\
 $(qapi-modules) $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
diff --git a/include/qemu/authz-simple.h b/include/qemu/authz-simple.h
new file mode 100644
index 000..74c09e3
--- /dev/null
+++ b/include/qemu/authz-simple.h
@@ -0,0 +1,107 @@
+/*
+ * QEMU simple authorization driver
+ *
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ *
+ */
+
+#ifndef QAUTHZ_SIMPLE_H__
+#define QAUTHZ_SIMPLE_H__
+
+#include "qemu/authz.h"
+
+
+#define TYPE_QAUTHZ_SIMPLE "authz-simple"
+
+#define QAUTHZ_SIMPLE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(QAuthZSimpleClass, (klass), \
+TYPE_QAUTHZ_SIMPLE)
+#define QAUTHZ_SIMPLE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(QAuthZSimpleClass, (obj), \
+  TYPE_QAUTHZ_SIMPLE)
+#define QAUTHZ_SIMPLE(obj) \
+ INTERFACE_CHECK(QAuthZSimple, (obj), \
+ TYPE_QAUTHZ_SIMPLE)
+
+typedef struct QAuthZSimple QAuthZSimple;
+typedef struct QAuthZSimpleClass QAuthZSimpleClass;
+
+
+/**
+ * QAuthZSimple:
+ *
+ * This authorization driver provides a simple mechanism
+ * for granting access by matching user names against a
+ * list of globs. Each match rule has an associated policy
+ * and a catch all policy applies if no rule matches
+ *
+ * To create an instace of this class via QMP:
+ *
+ *  {
+ *"execute": "object-add",
+ *"arguments": {
+ *  "qom-type": "authz-simple",
+ *  "id": "auth0",
+ *  "parameters": {
+ *"rules": [
+ *   { "match": "fred", "policy": "allow" },
+ *   { "match": "bob", "policy": "allow" },
+ *   { "match": "danb", "policy": "deny" },
+ *   { "match": "dan*", "policy": "allow" }
+ *],
+ *"policy": "deny"
+ *  }
+ *}
+ *  }
+ *
+ * Or via the CLI:
+ *
+ *   $QEMU  \
+ *-object auth

[Qemu-devel] [PATCH v1 04/10] util: add QAuthZ object as an authorization base class

2016-02-19 Thread Daniel P. Berrange
The current qemu_acl module provides a simple access control
list facility inside QEMU, which is used via a set of monitor
commands acl_show, acl_policy, acl_add, acl_remove & acl_reset.

Note there is no ability to create ACLs - the network services
(eg VNC server) were expected to create ACLs that they want to
check.

There is also no way to define ACLs on the command line, nor
potentially integrate with external authorization systems like
polkit, pam, ldap lookup, etc.

The QAuthZ object defines a minimal abstract QOM class that can
be subclassed for creating different authorization providers.

Signed-off-by: Daniel P. Berrange 
---
 MAINTAINERS  |  7 +
 Makefile |  1 +
 Makefile.objs|  2 ++
 Makefile.target  |  2 ++
 include/qemu/authz.h | 81 
 util/Makefile.objs   |  2 ++
 util/authz.c | 45 +
 7 files changed, 140 insertions(+)
 create mode 100644 include/qemu/authz.h
 create mode 100644 util/authz.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 02710f8..1bd469a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1276,6 +1276,13 @@ S: Maintained
 F: include/qemu/sockets.h
 F: util/qemu-sockets.c
 
+Authorization
+M: Daniel P. Berrange 
+S: Maintained
+F: util/authz*
+F: include/qemu/authz*
+F: tests/test-authz-*
+
 Usermode Emulation
 --
 Overall
diff --git a/Makefile b/Makefile
index 16db398..3a1f52f 100644
--- a/Makefile
+++ b/Makefile
@@ -150,6 +150,7 @@ endif
 dummy := $(call unnest-vars,, \
 stub-obj-y \
 util-obj-y \
+util-qom-obj-y \
 qga-obj-y \
 ivshmem-client-obj-y \
 ivshmem-server-obj-y \
diff --git a/Makefile.objs b/Makefile.objs
index fbcaa74..8bc9a77 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -4,6 +4,8 @@ stub-obj-y = stubs/
 util-obj-y = util/ qobject/ qapi/
 util-obj-y += qmp-introspect.o qapi-types.o qapi-visit.o qapi-event.o
 
+util-qom-obj-y += util/
+
 ###
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
diff --git a/Makefile.target b/Makefile.target
index 34ddb7e..9728f86 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -171,6 +171,7 @@ include $(SRC_PATH)/Makefile.objs
 dummy := $(call unnest-vars,,target-obj-y)
 target-obj-y-save := $(target-obj-y)
 dummy := $(call unnest-vars,.., \
+   util-qom-obj-y \
block-obj-y \
block-obj-m \
crypto-obj-y \
@@ -183,6 +184,7 @@ target-obj-y := $(target-obj-y-save)
 all-obj-y += $(common-obj-y)
 all-obj-y += $(target-obj-y)
 all-obj-y += $(qom-obj-y)
+all-obj-y += $(util-qom-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
 all-obj-$(CONFIG_USER_ONLY) += $(crypto-aes-obj-y)
 all-obj-$(CONFIG_SOFTMMU) += $(crypto-obj-y)
diff --git a/include/qemu/authz.h b/include/qemu/authz.h
new file mode 100644
index 000..89fa6da
--- /dev/null
+++ b/include/qemu/authz.h
@@ -0,0 +1,81 @@
+/*
+ * QEMU authorization framework
+ *
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ *
+ */
+
+#ifndef QAUTHZ_H__
+#define QAUTHZ_H__
+
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qom/object.h"
+
+
+#define TYPE_QAUTHZ "authz"
+
+#define QAUTHZ_CLASS(klass) \
+ OBJECT_CLASS_CHECK(QAuthZClass, (klass), \
+TYPE_QAUTHZ)
+#define QAUTHZ_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(QAuthZClass, (obj), \
+  TYPE_QAUTHZ)
+#define QAUTHZ(obj) \
+ INTERFACE_CHECK(QAuthZ, (obj), \
+ TYPE_QAUTHZ)
+
+typedef struct QAuthZ QAuthZ;
+typedef struct QAuthZClass QAuthZClass;
+
+/**
+ * QAuthZ:
+ *
+ * The QAuthZ class defines an API contract to be used
+ * for providing an authorization driver for network
+ * services.
+ */
+
+struct QAuthZ {
+Object parent_obj;
+};
+
+
+struct QAuthZClass {
+ObjectClass parent_class;
+
+bool (*is_allowed)(QAuthZ *authz,
+   const char *identity,
+   Error **errp);
+};
+
+
+/**
+ * qauthz_is_allowed:
+ * @authz: the authorization object
+ * @identity: the user identity to authorize
+ * @errp: pointer to a NULL initialized error object
+ *
+ * Check if a user @identi

[Qemu-devel] [PATCH v1 10/10] vnc: allow specifying a custom ACL object name

2016-02-19 Thread Daniel P. Berrange
The VNC server has historically had support for ACLs to check
both the SASL username and the TLS x509 distinguished name.
The VNC server was responsible for creating the initial ACL,
and the client app was then responsible for populating it with
rules using the HMP 'acl_add' command.

This is not satisfactory for a variety of reasons. There is
no way to populate the ACLs from the command line, users are
forced to use the HMP. With multiple network services all
supporting TLS and ACLs now, it is desirable to be able to
define a single ACL that is referenced by all services.

To address these limitations, two new options are added to the
VNC server CLI. The 'tls-acl' option takes the ID of a QAuthZ
object to use for checking TLS x509 distinguished names, and
the 'sasl-acl' option takes the ID of another object to use for
checking SASL usernames.

In this example, we setup two ACLs. The first allows any client
with a certificate issued by the 'RedHat' organization in the
'London' locality. The second ACL allows clients with either
the 'j...@redhat.com' or  'f...@redhat.com' kerberos usernames.
Both ACLs must pass for the user to be allowed.

$QEMU -object tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\
  endpoint=server,verify-peer=yes \
  -object authz-simple,id=acl0,policy=deny,\
  rules.0.match=O=RedHat,,L=London,rules.0.policy=allow \
  -object authz-simple,id=acl0,policy=deny,\
  rules.0.match=f...@redhat.com,rules.0.policy=allow \
  rules.0.match=j...@redhat.com,rules.0.policy=allow \
  -vnc 0.0.0.0:1,tls-creds=tls0,tls-acl=tlsacl0,
   sasl,sasl-acl=saslacl0 \
  ...other QEMU args...

Signed-off-by: Daniel P. Berrange 
---
 ui/vnc.c | 73 
 1 file changed, 60 insertions(+), 13 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 9971dfc..1a922cf 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3258,6 +3258,12 @@ static QemuOptsList qemu_vnc_opts = {
 .name = "acl",
 .type = QEMU_OPT_BOOL,
 },{
+.name = "tls-acl",
+.type = QEMU_OPT_STRING,
+},{
+.name = "sasl-acl",
+.type = QEMU_OPT_STRING,
+},{
 .name = "lossy",
 .type = QEMU_OPT_BOOL,
 },{
@@ -3480,6 +3486,10 @@ void vnc_display_open(const char *id, Error **errp)
 int saslErr;
 #endif
 int acl = 0;
+const char *tlsacl;
+#ifdef CONFIG_VNC_SASL
+const char *saslacl;
+#endif
 int lock_key_sync = 1;
 
 if (!vs) {
@@ -3666,6 +3676,21 @@ void vnc_display_open(const char *id, Error **errp)
 }
 }
 acl = qemu_opt_get_bool(opts, "acl", false);
+tlsacl = qemu_opt_get(opts, "tls-acl");
+if (acl && tlsacl) {
+error_setg(errp, "'acl' option is mutually exclusive with the "
+   "'tls-acl' options");
+goto fail;
+}
+
+#ifdef CONFIG_VNC_SASL
+saslacl = qemu_opt_get(opts, "sasl-acl");
+if (acl && saslacl) {
+error_setg(errp, "'acl' option is mutually exclusive with the "
+   "'sasl-acl' options");
+goto fail;
+}
+#endif
 
 share = qemu_opt_get(opts, "share");
 if (share) {
@@ -3695,7 +3720,9 @@ void vnc_display_open(const char *id, Error **errp)
 vs->non_adaptive = true;
 }
 
-if (acl) {
+if (tlsacl) {
+vs->tlsaclname = g_strdup(tlsacl);
+} else if (acl) {
 if (strcmp(vs->id, "default") == 0) {
 vs->tlsaclname = g_strdup("vnc.x509dname");
 } else {
@@ -3706,19 +3733,39 @@ void vnc_display_open(const char *id, Error **errp)
   &error_abort);
 }
 #ifdef CONFIG_VNC_SASL
-if (acl && sasl) {
-char *aclname;
+if (sasl) {
+if (saslacl) {
+Object *container, *acl;
+container = object_get_objects_root();
+acl = object_resolve_path_component(container, saslacl);
+if (!acl) {
+error_setg(errp, "Cannot find ACL %s", saslacl);
+goto fail;
+}
 
-if (strcmp(vs->id, "default") == 0) {
-aclname = g_strdup("vnc.username");
-} else {
-aclname = g_strdup_printf("vnc.%s.username", vs->id);
-}
-vs->sasl.acl =
-QAUTHZ(qauthz_simple_new(aclname,
- QAUTHZ_SIMPLE_POLICY_DENY,
- &error_abort));
-g_free(aclname);
+if (!object_dynamic_cast(acl, TYPE_QAUTHZ)) {
+error_setg(errp, "Object '%s' is not a QAuthZ subclass",
+   saslacl);
+goto fail;
+}
+vs->sasl.acl = QAUTHZ(acl);
+} else if (acl) {
+char *aclname;
+
+if (strcmp(vs->id, "default") == 0) {
+aclname = g_strdup("vnc.username");
+   

[Qemu-devel] [PATCH v1 06/10] acl: delete existing ACL implementation

2016-02-19 Thread Daniel P. Berrange
The 'qemu_acl' type was a previous non-QOM based attempt to
provide an authorization facility in QEMU. Because it is
non-QOM based it cannot be created via the command line and
requires special monitor commands to manipulate it.

The new QAuthZ and QAuthZSimple QOM classes provide a superset
of the functionality in qemu_acl, so the latter can now be
deleted. The HMP 'acl_*' monitor commands are converted to
use the new QAuthZSimple data type instead in order to provide
backwards compatibility, but their use is discouraged.

Signed-off-by: Daniel P. Berrange 
---
 Makefile   |   6 +-
 crypto/tlssession.c|  28 --
 include/qemu/acl.h |  74 
 monitor.c  | 161 ++-
 tests/Makefile |   2 +-
 tests/test-crypto-tlssession.c |  13 +--
 tests/test-io-channel-tls.c|  14 +--
 ui/vnc-auth-sasl.c |   2 +-
 ui/vnc-auth-sasl.h |   4 +-
 ui/vnc.c   |  11 ++-
 util/Makefile.objs |   1 -
 util/acl.c | 188 -
 12 files changed, 156 insertions(+), 348 deletions(-)
 delete mode 100644 include/qemu/acl.h
 delete mode 100644 util/acl.c

diff --git a/Makefile b/Makefile
index d8ff7fa..10381c5 100644
--- a/Makefile
+++ b/Makefile
@@ -235,9 +235,9 @@ util/module.o-cflags = 
-D'CONFIG_BLOCK_MODULES=$(block-modules)'
 
 qemu-img.o: qemu-img-cmds.h
 
-qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) libqemuutil.a libqemustub.a
-qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) libqemuutil.a libqemustub.a
+qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) $(util-qom-obj-y) libqemuutil.a libqemustub.a
+qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) $(util-qom-obj-y) libqemuutil.a libqemustub.a
+qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) 
$(qom-obj-y) $(util-qom-obj-y) libqemuutil.a libqemustub.a
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index e0d9658..26e8097 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -22,7 +22,7 @@
 #include "crypto/tlssession.h"
 #include "crypto/tlscredsanon.h"
 #include "crypto/tlscredsx509.h"
-#include "qemu/acl.h"
+#include "qemu/authz.h"
 #include "trace.h"
 
 #ifdef CONFIG_GNUTLS
@@ -207,6 +207,7 @@ qcrypto_tls_session_check_certificate(QCryptoTLSSession 
*session,
 unsigned int nCerts, i;
 time_t now;
 gnutls_x509_crt_t cert = NULL;
+Error *err = NULL;
 
 now = time(NULL);
 if (now == ((time_t)-1)) {
@@ -295,16 +296,33 @@ qcrypto_tls_session_check_certificate(QCryptoTLSSession 
*session,
 goto error;
 }
 if (session->aclname) {
-qemu_acl *acl = qemu_acl_find(session->aclname);
-int allow;
-if (!acl) {
+QAuthZ *acl;
+Object *obj;
+Object *container;
+bool allow;
+
+container = object_get_objects_root();
+obj = object_resolve_path_component(container,
+session->aclname);
+if (!obj) {
 error_setg(errp, "Cannot find ACL %s",
session->aclname);
 goto error;
 }
 
-allow = qemu_acl_party_is_allowed(acl, session->peername);
+if (!object_dynamic_cast(obj, TYPE_QAUTHZ)) {
+error_setg(errp, "Object '%s' is not a QAuthZ subclass",
+   session->aclname);
+goto error;
+}
 
+acl = QAUTHZ(obj);
+
+allow = qauthz_is_allowed(acl, session->peername, &err);
+if (err) {
+error_propagate(errp, err);
+goto error;
+}
 if (!allow) {
 error_setg(errp, "TLS x509 ACL check for %s is denied",
session->peername);
diff --git a/include/qemu/acl.h b/include/qemu/acl.h
deleted file mode 100644
index 116487e..000
--- a/include/qemu/acl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * QEMU access control list management
- *
- * Copyright (C) 2009 Red Hat, Inc
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of

[Qemu-devel] [PATCH v1 07/10] qemu-nbd: add support for ACLs for TLS clients

2016-02-19 Thread Daniel P. Berrange
Currently any client which can complete the TLS handshake
is able to use the NBD server. The server admin can turn
on the 'verify-peer' option for the x509 creds to require
the client to provide a x509 certificate. This means the
client will have to acquire a certificate from the CA before
they are permitted to use the NBD server. This is still a
fairly weak bar.

This adds a '--tls-acl ACL-ID' option to the qemu-nbd command
which takes the ID of a previously added 'QAuthZ' object
instance. This ACL will be used to validate the client's
x509 distinguished name. Clients failing the ACL will not be
permitted to use the NBD server.

For example to setup an ACL that only allows connection from
a client whose x509 certificate distinguished name contains
'CN=fred', you would use:

  qemu-nbd -object tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\
   endpoint=server,verify-peer=yes \
   -object authz-simple,id=acl0,policy=deny,\
   rules.0.match=*CN=fred,rules.0.policy=allow \
   -tls-creds tls0 \
   -tls-acl acl0
   other qemu-nbd args...

Signed-off-by: Daniel P. Berrange 
---
 qemu-nbd.c| 13 -
 qemu-nbd.texi |  4 
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 933ca4a..4f202f3 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -43,6 +43,7 @@
 #define QEMU_NBD_OPT_DETECT_ZEROES 4
 #define QEMU_NBD_OPT_OBJECT5
 #define QEMU_NBD_OPT_TLSCREDS  6
+#define QEMU_NBD_OPT_TLSACL7
 
 static NBDExport *exp;
 static bool newproto;
@@ -56,6 +57,7 @@ static int nb_fds;
 static QIOChannelSocket *server_ioc;
 static int server_watch = -1;
 static QCryptoTLSCreds *tlscreds;
+static const char *tlsacl;
 
 static void usage(const char *name)
 {
@@ -344,7 +346,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition 
cond, gpointer opaque)
 nb_fds++;
 nbd_update_server_watch();
 nbd_client_new(newproto ? NULL : exp, cioc,
-   tlscreds, NULL, nbd_client_closed);
+   tlscreds, tlsacl, nbd_client_closed);
 object_unref(OBJECT(cioc));
 
 return TRUE;
@@ -475,6 +477,7 @@ int main(int argc, char **argv)
 { "object", 1, NULL, QEMU_NBD_OPT_OBJECT },
 { "export-name", 1, NULL, 'x' },
 { "tls-creds", 1, NULL, QEMU_NBD_OPT_TLSCREDS },
+{ "tls-acl", 1, NULL, QEMU_NBD_OPT_TLSACL },
 { NULL, 0, NULL, 0 }
 };
 int ch;
@@ -672,6 +675,9 @@ int main(int argc, char **argv)
 case QEMU_NBD_OPT_TLSCREDS:
 tlscredsid = optarg;
 break;
+case QEMU_NBD_OPT_TLSACL:
+tlsacl = optarg;
+break;
 }
 }
 
@@ -708,6 +714,11 @@ int main(int argc, char **argv)
  error_get_pretty(local_err));
 exit(EXIT_FAILURE);
 }
+} else {
+if (tlsacl) {
+error_report("--tls-acl is not permitted without --tls-creds");
+exit(EXIT_FAILURE);
+}
 }
 
 if (disconnect) {
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 227a73c..935d0d3 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -81,6 +81,10 @@ the new style NBD protocol negotiation
 Enable mandatory TLS encryption for the server by setting the ID
 of the TLS credentials object previously created with the --object
 option.
+@item --tls-acl=ID
+Specify the ID of a qauthz object previously created with the
+--object option. This will be used to authorize users who
+connect against their x509 distinguish name.
 @item -v, --verbose
 Display extra debugging information
 @item -h, --help
-- 
2.5.0




[Qemu-devel] [PATCH v1 03/10] qom: support arbitrary non-scalar properties with -object

2016-02-19 Thread Daniel P. Berrange
The current -object command line syntax only allows for
creation of objects with scalar properties, or a list
with a fixed scalar element type. Objects which have
properties that are represented as structs in the QAPI
schema cannot be created using -object.

This is a design limitation of the way the OptsVisitor
is written. It simply iterates over the QemuOpts values
as a flat list. The support for lists is enabled by
allowing the same key to be repeated in the opts string.

It is not practical to extend the OptsVisitor to support
more complex data structures while also maintaining
the existing list handling behaviour that is relied upon
by other areas of QEMU.

Fortunately there is no existing object that implements
the UserCreatable interface that relies on the list
handling behaviour, so it is possible to swap out the
OptsVisitor for a different visitor implementation, so
-object supports non-scalar properties, thus leaving
other users of OptsVisitor unaffected.

The previously added qdict_crumple() method is able to
take a qdict containing a flat set of properties and
turn that into a arbitrarily nested set of dicts and
lists. By combining qemu_opts_to_qdict and qdict_crumple()
together, we can turn the opt string into a data structure
that is practically identical to that passed over QMP
when defining an object. The only difference is that all
the scalar values are represented as strings, rather than
strings, ints and bools. This is sufficient to let us
replace the OptsVisitor with the QMPInputVisitor for
use with -object.

Thus -object can now support non-scalar properties,
for example the QMP object

  {
"execute": "object-add",
"arguments": {
  "qom-type": "demo",
  "id": "demo0",
  "parameters": {
"foo": [
  { "bar": "one", "wizz": "1" },
  { "bar": "two", "wizz": "2" }
]
  }
}
  }

Would be creatable via the CLI now using

$QEMU \
  -object demo,id=demo0,\
  foo.0.bar=one,foo.0.wizz=1,\
  foo.1.bar=two,foo.1.wizz=2

This is also wired up to work for the 'object_add' command
in the HMP monitor with the same syntax.

  (hmp) object_add demo,id=demo0,\
   foo.0.bar=one,foo.0.wizz=1,\
   foo.1.bar=two,foo.1.wizz=2

Signed-off-by: Daniel P. Berrange 
---
 hmp.c  |  18 +--
 qom/object_interfaces.c|  20 ++-
 tests/check-qom-proplist.c | 316 -
 3 files changed, 334 insertions(+), 20 deletions(-)

diff --git a/hmp.c b/hmp.c
index bfbd667..614bbf8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -25,7 +25,7 @@
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
 #include "monitor/qdev.h"
-#include "qapi/opts-visitor.h"
+#include "qapi/qmp-input-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/string-output-visitor.h"
 #include "qapi/util.h"
@@ -1656,20 +1656,12 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
 void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
 Error *err = NULL;
-QemuOpts *opts;
-OptsVisitor *ov;
+QmpInputVisitor *qiv;
 Object *obj = NULL;
 
-opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
-if (err) {
-hmp_handle_error(mon, &err);
-return;
-}
-
-ov = opts_visitor_new(opts);
-obj = user_creatable_add(qdict, opts_get_visitor(ov), &err);
-opts_visitor_cleanup(ov);
-qemu_opts_del(opts);
+qiv = qmp_input_visitor_new_full((QObject *)qdict, true, true);
+obj = user_creatable_add(qdict, qmp_input_get_visitor(qiv), &err);
+qmp_input_visitor_cleanup(qiv);
 
 if (err) {
 hmp_handle_error(mon, &err);
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index c2f6e29..3d6d56f 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -1,9 +1,9 @@
 #include "qemu/osdep.h"
 #include "qom/object_interfaces.h"
 #include "qemu/module.h"
+#include "qemu/option.h"
 #include "qapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
-#include "qapi/opts-visitor.h"
+#include "qapi/qmp-input-visitor.h"
 
 void user_creatable_complete(Object *obj, Error **errp)
 {
@@ -120,6 +120,7 @@ Object *user_creatable_add_type(const char *type, const 
char *id,
 obj = object_new(type);
 if (qdict) {
 for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
+
 object_property_set(obj, v, e->key, &local_err);
 if (local_err) {
 goto out;
@@ -151,15 +152,22 @@ out:
 
 Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
 {
-OptsVisitor *ov;
+QmpInputVisitor *qiv;
 QDict *pdict;
+QObject *pobj;
 Object *obj = NULL;
 
-ov = opts_visitor_new(opts);
 pdict = qemu_opts_to_qdict(opts, NULL);
+pobj = qdict_crumple(pdict, errp);
+if (!pobj) {
+goto cleanup;
+}
+qiv = qmp_input_visitor_new_full(pobj, true, true);
 
-obj = user_creatable_add(pdict, opts_get_visitor(ov), errp);
-opts_visitor

Re: [Qemu-devel] [PATCH 1/2] vfio/pci: use PCI_MSIX_FLAGS on retrieving the MSIX entries

2016-02-19 Thread Alex Williamson
On Fri, 19 Feb 2016 15:18:10 +
Wei Yang  wrote:

> Even PCI_CAP_FLAGS has the same value as PCI_MSIX_FLAGS, the later one is
> the more proper on retrieving MSIX entries.
> 
> This patch uses PCI_MSIX_FLAGS to retrieve the MSIX entries.
> 
> Signed-off-by: Wei Yang 
> ---
>  hw/vfio/pci.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index e66c47f..321423b 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -1210,7 +1210,7 @@ static int vfio_msix_early_setup(VFIOPCIDevice *vdev)
>  }
>  
>  if (pread(fd, &ctrl, sizeof(ctrl),
> -  vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
> +  vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) {
>  return -errno;
>  }
>  

This is certainly trivial, I'll grab it for the respin of yesterday's
pull request.  Thanks,

Alex



[Qemu-devel] [PATCH v1 02/10] qapi: allow QmpInputVisitor to auto-cast types

2016-02-19 Thread Daniel P. Berrange
Currently the QmpInputVisitor assumes that all scalar
values are directly represented as their final types.
ie it assumes an 'int' is using QInt, and a 'bool' is
using QBool.

This extends it so that QString is optionally permitted
for any of the non-string scalar types. This behaviour
is turned on by requesting the 'autocast' flag in the
constructor.

This makes it possible to use QmpInputVisitor with a
QDict produced from QemuOpts, where everything is in
string format.

Signed-off-by: Daniel P. Berrange 
---
 include/qapi/qmp-input-visitor.h |   3 +
 qapi/qmp-input-visitor.c |  96 +++-
 tests/test-qmp-input-visitor.c   | 115 ++-
 3 files changed, 196 insertions(+), 18 deletions(-)

diff --git a/include/qapi/qmp-input-visitor.h b/include/qapi/qmp-input-visitor.h
index 3ed499c..c25cb7c 100644
--- a/include/qapi/qmp-input-visitor.h
+++ b/include/qapi/qmp-input-visitor.h
@@ -21,6 +21,9 @@ typedef struct QmpInputVisitor QmpInputVisitor;
 
 QmpInputVisitor *qmp_input_visitor_new(QObject *obj);
 QmpInputVisitor *qmp_input_visitor_new_strict(QObject *obj);
+QmpInputVisitor *qmp_input_visitor_new_full(QObject *obj,
+bool strict,
+bool autocast);
 
 void qmp_input_visitor_cleanup(QmpInputVisitor *v);
 
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index e659832..59d2165 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -35,6 +35,7 @@ struct QmpInputVisitor
 StackObject stack[QIV_STACK_SIZE];
 int nb_stack;
 bool strict;
+bool autocast;
 };
 
 static QmpInputVisitor *to_qiv(Visitor *v)
@@ -217,15 +218,26 @@ static void qmp_input_type_int64(Visitor *v, const char 
*name, int64_t *obj,
  Error **errp)
 {
 QmpInputVisitor *qiv = to_qiv(v);
-QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
+QObject *qobj = qmp_input_get_object(qiv, name, true);
+QInt *qint;
+QString *qstr;
 
-if (!qint) {
-error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
-   "integer");
+qint = qobject_to_qint(qobj);
+if (qint) {
+*obj = qint_get_int(qint);
 return;
 }
 
-*obj = qint_get_int(qint);
+qstr = qobject_to_qstring(qobj);
+if (qstr && qstr->string && qiv->autocast) {
+errno = 0;
+if (qemu_strtoll(qstr->string, NULL, 10, obj) == 0) {
+return;
+}
+}
+
+error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+   "integer");
 }
 
 static void qmp_input_type_uint64(Visitor *v, const char *name, uint64_t *obj,
@@ -233,30 +245,61 @@ static void qmp_input_type_uint64(Visitor *v, const char 
*name, uint64_t *obj,
 {
 /* FIXME: qobject_to_qint mishandles values over INT64_MAX */
 QmpInputVisitor *qiv = to_qiv(v);
-QInt *qint = qobject_to_qint(qmp_input_get_object(qiv, name, true));
+QObject *qobj = qmp_input_get_object(qiv, name, true);
+QInt *qint;
+QString *qstr;
 
-if (!qint) {
-error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
-   "integer");
+qint = qobject_to_qint(qobj);
+if (qint) {
+*obj = qint_get_int(qint);
 return;
 }
 
-*obj = qint_get_int(qint);
+qstr = qobject_to_qstring(qobj);
+if (qstr && qstr->string && qiv->autocast) {
+errno = 0;
+if (qemu_strtoull(qstr->string, NULL, 10, obj) == 0) {
+return;
+}
+}
+
+error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+   "integer");
 }
 
 static void qmp_input_type_bool(Visitor *v, const char *name, bool *obj,
 Error **errp)
 {
 QmpInputVisitor *qiv = to_qiv(v);
-QBool *qbool = qobject_to_qbool(qmp_input_get_object(qiv, name, true));
+QObject *qobj = qmp_input_get_object(qiv, name, true);
+QBool *qbool;
+QString *qstr;
 
-if (!qbool) {
-error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
-   "boolean");
+qbool = qobject_to_qbool(qobj);
+if (qbool) {
+*obj = qbool_get_bool(qbool);
 return;
 }
 
-*obj = qbool_get_bool(qbool);
+
+qstr = qobject_to_qstring(qobj);
+if (qstr && qstr->string && qiv->autocast) {
+if (!strcasecmp(qstr->string, "on") ||
+!strcasecmp(qstr->string, "yes") ||
+!strcasecmp(qstr->string, "true")) {
+*obj = true;
+return;
+}
+if (!strcasecmp(qstr->string, "off") ||
+!strcasecmp(qstr->string, "no") ||
+!strcasecmp(qstr->string, "false")) {
+*obj = false;
+return;
+}
+}
+
+error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
+   "boolean");
 }
 
 static void qmp_input_type_s

  1   2   3   4   >