Re: [Qemu-devel] [PATCH] multiboot: validate multiboot header address values

2017-09-06 Thread P J P
+-- On Tue, 5 Sep 2017, Thomas Garnier wrote --+
| Btw, can you open a CVE for that? (and reference it in the commit).

  Done; Sent revised patch v1.

Thank you.
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F



[Qemu-devel] [PATCH v1] multiboot: validate multiboot header address values

2017-09-06 Thread P J P
From: Prasad J Pandit 

While loading kernel via multiboot-v1 image, (flags & 0x0001)
indicates that multiboot header contains valid addresses to load
the kernel image. These addresses are used to compute kernel
size and kernel text offset in the OS image. Validate these
address values to avoid an OOB access issue.

This is CVE-2017-14167.

Reported-by: Thomas Garnier 
Signed-off-by: Prasad J Pandit 
---
 hw/i386/multiboot.c | 19 +++
 1 file changed, 19 insertions(+)

Update: add CVE-ID to the commit message.

diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
index 6001f4caa2..c7b70c91d5 100644
--- a/hw/i386/multiboot.c
+++ b/hw/i386/multiboot.c
@@ -221,15 +221,34 @@ int load_multiboot(FWCfgState *fw_cfg,
 uint32_t mh_header_addr = ldl_p(header+i+12);
 uint32_t mh_load_end_addr = ldl_p(header+i+20);
 uint32_t mh_bss_end_addr = ldl_p(header+i+24);
+
 mh_load_addr = ldl_p(header+i+16);
+if (mh_header_addr < mh_load_addr) {
+fprintf(stderr, "invalid mh_load_addr address\n");
+exit(1);
+}
+
 uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
 uint32_t mb_load_size = 0;
 mh_entry_addr = ldl_p(header+i+28);
 
 if (mh_load_end_addr) {
+if (mh_bss_end_addr < mh_load_addr) {
+fprintf(stderr, "invalid mh_bss_end_addr address\n");
+exit(1);
+}
 mb_kernel_size = mh_bss_end_addr - mh_load_addr;
+
+if (mh_load_end_addr < mh_load_addr) {
+fprintf(stderr, "invalid mh_load_end_addr address\n");
+exit(1);
+}
 mb_load_size = mh_load_end_addr - mh_load_addr;
 } else {
+if (kernel_file_size < mb_kernel_text_offset) {
+fprintf(stderr, "invalid kernel_file_size\n");
+exit(1);
+}
 mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
 mb_load_size = mb_kernel_size;
 }
-- 
2.13.5




Re: [Qemu-devel] [PATCH v2 07/19] s390x: move two function declarations to s390-virtio-ccw.h

2017-09-06 Thread Thomas Huth
On 04.09.2017 17:43, David Hildenbrand wrote:
> We can also drop the extern. Fix up includes.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  include/hw/s390x/s390-virtio-ccw.h | 3 +++
>  target/s390x/cpu.h | 2 --
>  target/s390x/diag.c| 1 +
>  target/s390x/interrupt.c   | 3 +++
>  4 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/include/hw/s390x/s390-virtio-ccw.h 
> b/include/hw/s390x/s390-virtio-ccw.h
> index 41a9d2862b..42f2ccdb43 100644
> --- a/include/hw/s390x/s390-virtio-ccw.h
> +++ b/include/hw/s390x/s390-virtio-ccw.h
> @@ -56,4 +56,7 @@ bool gs_allowed(void);
>   */
>  bool css_migration_enabled(void);
>  
> +S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
> +void subsystem_reset(void);
> +
>  #endif
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index 2343f2f1f7..6c0abb9894 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -720,8 +720,6 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, 
> uint8_t ar, void *hostbuf,
>  
>  
>  /* outside of target/s390x/ */
> -S390CPU *s390_cpu_addr2state(uint16_t cpu_addr);
> -extern void subsystem_reset(void);
>  int sclp_service_call(CPUS390XState *env, uint64_t sccb, uint32_t code);
>  
>  #endif
> diff --git a/target/s390x/diag.c b/target/s390x/diag.c
> index e6b5e6de37..82a623948d 100644
> --- a/target/s390x/diag.c
> +++ b/target/s390x/diag.c
> @@ -20,6 +20,7 @@
>  #include "hw/watchdog/wdt_diag288.h"
>  #include "sysemu/cpus.h"
>  #include "hw/s390x/ipl.h"
> +#include "hw/s390x/s390-virtio-ccw.h"
>  
>  static int modified_clear_reset(S390CPU *cpu)
>  {
> diff --git a/target/s390x/interrupt.c b/target/s390x/interrupt.c
> index 058e219fe5..9aa6b89301 100644
> --- a/target/s390x/interrupt.c
> +++ b/target/s390x/interrupt.c
> @@ -15,6 +15,9 @@
>  #include "exec/exec-all.h"
>  #include "sysemu/kvm.h"
>  #include "hw/s390x/ioinst.h"
> +#if !defined(CONFIG_USER_ONLY)
> +#include "hw/s390x/s390-virtio-ccw.h"
> +#endif
>  
>  /* Ensure to exit the TB after this call! */
>  void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilen)
> 

If I listen to my gut feeling, I still think we should rather move
s390_cpu_addr2state() to cpu.c instead. It does not sound as it's really
specific to the virtio-ccw machine... Just my 0.02 €

 Thomas



Re: [Qemu-devel] [PATCH v2 09/19] target/s390x: use trigger_pgm_exception() in s390_cpu_handle_mmu_fault()

2017-09-06 Thread Thomas Huth
On 04.09.2017 17:43, David Hildenbrand wrote:
> This looks cleaner. linux-user will not use the ilen field, so setting
> it doesn't do any harm.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/excp_helper.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
> index 361f970db3..14d3160e92 100644
> --- a/target/s390x/excp_helper.c
> +++ b/target/s390x/excp_helper.c
> @@ -59,8 +59,7 @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
>  {
>  S390CPU *cpu = S390_CPU(cs);
>  
> -cs->exception_index = EXCP_PGM;
> -cpu->env.int_pgm_code = PGM_ADDRESSING;
> +trigger_pgm_exception(&cpu->env, PGM_ADDRESSING, ILEN_AUTO);
>  /* On real machines this value is dropped into LowMem.  Since this
> is userland, simply put this someplace that cpu_loop can find it.  */
>  cpu->env.__excp_addr = address;
> 

Reviewed-by: Thomas Huth 



Re: [Qemu-devel] [PATCH v2 06/19] s390x: move s390_virtio_hypercall() to s390-virtio-hcall.h

2017-09-06 Thread Thomas Huth
On 04.09.2017 17:43, David Hildenbrand wrote:
> Implemented in hw/s390x/s390-virtio-hcall.c, so let's move it to the
> right header file.

That's fair.

Reviewed-by: Thomas Huth 



Re: [Qemu-devel] [PATCH v2 05/19] target/s390x: move typedef of S390CPU to its definition

2017-09-06 Thread Thomas Huth
On 04.09.2017 17:43, David Hildenbrand wrote:
> Let's move it to the palce where struct S390CPU is defined.

s/palce/place/

> Suggested-by: Thomas Huth 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/cpu-qom.h | 2 --
>  target/s390x/cpu.h | 4 ++--
>  2 files changed, 2 insertions(+), 4 deletions(-)

Seems to compile fine for me with this patch applied, so:

Tested-by: Thomas Huth 



Re: [Qemu-devel] [PATCH v2 01/19] exec, dump, i386, ppc, s390x: don't include exec/cpu-all.h explicitly

2017-09-06 Thread Thomas Huth
On 04.09.2017 17:42, David Hildenbrand wrote:
> All but a handfull of filles include exec/cpu-all.h via cpu.h only.
> As these files already include cpu.h, let's just drop the additional
> include.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  dump.c| 1 -
>  exec.c| 2 --
>  target/i386/arch_dump.c   | 1 -
>  target/i386/arch_memory_mapping.c | 1 -
>  target/i386/svm_helper.c  | 1 -
>  target/ppc/arch_dump.c| 1 -
>  target/s390x/arch_dump.c  | 1 -
>  7 files changed, 8 deletions(-)
> 
> diff --git a/dump.c b/dump.c
> index a79773d0f7..2ef6a678e8 100644
> --- a/dump.c
> +++ b/dump.c
> @@ -15,7 +15,6 @@
>  #include "qemu/cutils.h"
>  #include "elf.h"
>  #include "cpu.h"
> -#include "exec/cpu-all.h"
>  #include "exec/hwaddr.h"
>  #include "monitor/monitor.h"
>  #include "sysemu/kvm.h"
> diff --git a/exec.c b/exec.c
> index d20c34ca83..d109de2014 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -23,7 +23,6 @@
>  
>  #include "qemu/cutils.h"
>  #include "cpu.h"
> -#include "exec/exec-all.h"

You should maybe mention exec-all.h in the patch description, too.
(I think it can be dropped here because it is included by
translate-all.h already).

If you tweak the patch description:
Reviewed-by: Thomas Huth 



Re: [Qemu-devel] [PATCH v6 12/29] libqos: Track QTestState with QPCIBus

2017-09-06 Thread Thomas Huth
On 06.09.2017 23:00, Eric Blake wrote:
> On 09/05/2017 04:36 AM, Thomas Huth wrote:
>> On 01.09.2017 20:03, Eric Blake wrote:
>>> When initializing a QPCIBus, track which QTestState the bus is
>>> associated with (so that a later patch can then explicitly use
>>> that test state for all communication on the bus, rather than
>>> blindly relying on global_qtest).  Update the initialization
>>> functions to take another parameter, and update all callers to
>>> pass in state (for now, most callers get away with passing the
>>> current global_qtest as the current state, although this required
>>> fixing the order of initialization to ensure qtest_start() is
>>> called before qpci_init*() in rtl8139-test, and provided an
>>> opportunity to pass in the allocator in e1000e-test).
>>>
>>> Signed-off-by: Eric Blake 
>>> ---
>> [...]
>>> diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
>>> index 6226546c28..c95428e1cb 100644
>>> --- a/tests/libqos/libqos.c
>>> +++ b/tests/libqos/libqos.c
>>> @@ -26,8 +26,8 @@ QOSState *qtest_vboot(QOSOps *ops, const char 
>>> *cmdline_fmt, va_list ap)
>>>  if (ops->init_allocator) {
>>>  qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
>>>  }
>>> -if (ops->qpci_init && qs->alloc) {
>>> -qs->pcibus = ops->qpci_init(qs->alloc);
>>> +if (ops->qpci_init) {
>>
>> Why did you remove the check for qs->alloc?
>>
>>> +qs->pcibus = ops->qpci_init(qs->qts, qs->alloc);
> 
> Because we want to ensure qpci_init() is called to set qs->qts
> (presumably, whether or not qs->alloc is set).  Furthermore, only two
> files declare a 'static QOSOps' structure in the first place
> (libqos-pc.c and libqos-spapr.c); where both files set both the
> .init_allocator and .qpci_init callbacks; a little bit of auditing shows
> that the .init_allocator() never returns NULL (although that requires
> browsing yet more files for malloc-{pc,spapr}.c).

OK, thanks for the explanation! ... but maybe we should
g_assert(gs->alloc) somewhere instead? ... just an idea, I'm also fine
if you leave it away.

 Thomas



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH 3/3] Backup Tool: Test for Incremental Backup

2017-09-06 Thread Ishani
Hello,
I apologize for late reply. I was occupied by exams.
I will send a revision asap. 
Thanks.

- On Sep 2, 2017, at 4:23 AM, jsnow js...@redhat.com wrote:

> On 08/30/2017 10:02 PM, Fam Zheng wrote:
>> On Thu, 08/31 00:45, Ishani Chugh wrote:
>>> This patch is the test for incremental backup implementation in Backup tool.
>>> The test employs two basic subtests:
>>> 1) Backing up an empty guest and comparing it with base image.
>>> 2) Writing a pattern to the guest, creating backup, writing
>>>a pattern again, creating backup and comparing with base image.
>>>
>>> Signed-off-by: Ishani Chugh 
>>> ---
>>>  tests/qemu-iotests/193 | 86 
>>> ++
>>>  tests/qemu-iotests/193.out | 34 ++
>>>  tests/qemu-iotests/group   |  1 +
>>>  3 files changed, 121 insertions(+)
>>>  create mode 100755 tests/qemu-iotests/193
>>>  create mode 100644 tests/qemu-iotests/193.out
>>>
>>> diff --git a/tests/qemu-iotests/193 b/tests/qemu-iotests/193
>>> new file mode 100755
>>> index 000..500e5df
>>> --- /dev/null
>>> +++ b/tests/qemu-iotests/193
>>> @@ -0,0 +1,86 @@
>>> +#!/bin/bash
>>> +#
>>> +# Test Incremental backup functionality of qemu-backup tool
>>> +#
>>> +# Copyright (C) 2009 Red Hat, Inc.
>> 
>> Year is off, probably the copyright holder too?
>> 
> 
> Yup, please take credit for your own work, Ishani :)
> 
>>> +#
>>> +# 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.
>>> +#
>>> +# You should have received a copy of the GNU General Public License
>>> +# along with this program.  If not, see .
>>> +#
>>> +
>>> +# creator
>>> +owner=chugh.ish...@research.iiit.ac.in
>>> +
>>> +seq=`basename $0`
>>> +echo "QA output created by $seq"
>>> +
>>> +here=`pwd`
>>> +status=1   # failure is the default!
>> 
>> s/\t/ /
>> 
> 
> Fam means to remove the tab here and use spaces instead.
> 
>>> +
>>> +
>>> +# get standard environment, filters and checks
>>> +. ./common.rc
>>> +. ./common.filter
>>> +. ./common.qemu
>>> +
>>> +_supported_fmt generic
>>> +_supported_proto generic
>>> +_supported_os Linux
>>> +
>>> +
>>> +CONFIG_FILE=$TEST_DIR/backup-config
>>> +SOCKET=unix:$TEST_DIR/backup_socket
>>> +size=128M
>>> +
>>> +_make_test_img $size
>>> +export QEMU_BACKUP_CONFIG=$CONFIG_FILE
>>> +qemu_comm_method="monitor"
>>> +echo
>>> +_launch_qemu -drive if=virtio,file=$TEST_IMG -qmp $SOCKET,server,nowait
>>> +$PYTHON ../../contrib/backup/qemu-backup.py guest add --guest adad --qmp
>>> $SOCKET
>>> +$PYTHON ../../contrib/backup/qemu-backup.py drive add --id virtio0 --guest 
>>> adad
>>> --target $TEST_DIR/virtio0
>>> +echo
>>> +echo "== Creating backup =="
>>> +$PYTHON ../../contrib/backup/qemu-backup.py backup --inc --guest adad
>>> +_send_qemu_cmd $QEMU_HANDLE 'quit' ''
>>> +wait=1 _cleanup_qemu
>>> +echo
>>> +echo "== Comparing images =="
>>> +$QEMU_IMG compare $TEST_DIR/virtio0_inc_0 $TEST_IMG
>>> +
>>> +rm $TEST_DIR/virtio0_inc_0
>>> +
>>> +_launch_qemu -drive if=virtio,id=virtio0,file=$TEST_IMG -qmp
>>> $SOCKET,server,nowait
>>> +echo
>>> +echo "== Writing Pattern =="
>>> +_send_qemu_cmd $QEMU_HANDLE 'qemu-io virtio0 "write -P 0x22 0 1M"' 
>>> "(qemu)" |
>>> _filter_qemu_io
>>> +echo
>>> +
>>> +echo "== Creating backup =="
>>> +$PYTHON ../../contrib/backup/qemu-backup.py backup --inc --guest adad
>>> +
>>> +echo "== Writing Pattern =="
>>> +_send_qemu_cmd $QEMU_HANDLE 'qemu-io virtio0 "write -P 0x22 0 1M"' 
>>> "(qemu)" |
>>> _filter_qemu_io
>>> +echo
>>> +$PYTHON ../../contrib/backup/qemu-backup.py backup --inc --guest adad
>>> +_send_qemu_cmd $QEMU_HANDLE 'quit' ''
>>> +wait=1 _cleanup_qemu
>>> +echo
>>> +echo "== Comparing images =="
>>> +$QEMU_IMG compare $TEST_DIR/virtio0_inc_1 $TEST_IMG
>>> +rm $TEST_DIR/virtio0_inc_0
>>> +rm $TEST_DIR/virtio0_inc_1
>>> +rm $CONFIG_FILE
>>> +
>>> +echo "*** done"
>>> +status=0
>>> \ No newline at end of file
>>> diff --git a/tests/qemu-iotests/193.out b/tests/qemu-iotests/193.out
>>> new file mode 100644
>>> index 000..3a836c2
>>> --- /dev/null
>>> +++ b/tests/qemu-iotests/193.out
>>> @@ -0,0 +1,34 @@
>>> +QA output created by 193
>>> +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
>>> +
>>> +Successfully Added Guest
>>> +Successfully Added Drive
>>> +
>>> +== Creating backup ==
>>> +QEMU X.Y.Z monitor - type 'help' for more information
>>> +(qemu) Formatting 'TEST_DIR/virtio0_inc_0', fmt=qcow2 size=134217728
>>> cluster_size=65536 lazy_refcounts=off refcount_bits=16
>>> +quit
>>> +
>>> +== Comparing image

Re: [Qemu-devel] [PATCHv5 03/03] colo-compare: Update the COLO document to add the IOThread configuration

2017-09-06 Thread Zhang Chen



On 08/29/2017 03:22 PM, Wang yong wrote:

From: Wang Yong 

Update colo-proxy.txt,add IOThread configuration.
Later we have to configure IOThread,if not COLO can not work.

Signed-off-by: Wang Yong 
Signed-off-by: Wang Guang 


Reviewed-by: Zhang Chen 


---
  docs/colo-proxy.txt | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/docs/colo-proxy.txt b/docs/colo-proxy.txt
index c4941de..ce3f783 100644
--- a/docs/colo-proxy.txt
+++ b/docs/colo-proxy.txt
@@ -170,10 +170,11 @@ Primary(ip:3.3.3.3):
  -chardev socket,id=compare0-0,host=3.3.3.3,port=9001
  -chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
  -chardev socket,id=compare_out0,host=3.3.3.3,port=9005
+-object iothread,id=iothread1
  -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
  -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
  -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
--object 
colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0
+-object 
colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,iothread=iothread1
  
  Secondary(ip:3.3.3.8):

  -netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down 
script=/etc/qemu-ifdown


--
Thanks
Zhang Chen






Re: [Qemu-devel] [PATCHv5 02/03] colo-compare: Use IOThread to Check old packet regularly and Process pactkets of the primary

2017-09-06 Thread Zhang Chen



On 08/29/2017 03:22 PM, Wang yong wrote:

From: Wang Yong 

Remove the task which check old packet in the comparing thread,
then use IOthread context timer to handle it.

Process pactkets in the IOThread which arrived over the socket.
we use iothread_get_g_main_context to create a new g_main_loop in
the IOThread.then the packets from the primary and the secondary
are processed in the IOThread.

Finally remove the colo-compare thread using the IOThread instead.

Signed-off-by: Wang Yong 
Signed-off-by: Wang Guang 


Reviewed-by: Zhang Chen

Hi~ Jason.
Have any comments to this series?

Thanks
Zhang Chen


---
  net/colo-compare.c | 83 +-
  1 file changed, 45 insertions(+), 38 deletions(-)

diff --git a/net/colo-compare.c b/net/colo-compare.c
index 5fe8e3f..b2a2a13 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -29,6 +29,7 @@
  #include "qemu/sockets.h"
  #include "qapi-visit.h"
  #include "net/colo.h"
+#include "sysemu/iothread.h"
  
  #define TYPE_COLO_COMPARE "colo-compare"

  #define COLO_COMPARE(obj) \
@@ -82,11 +83,10 @@ typedef struct CompareState {
  GQueue conn_list;
  /* hashtable to save connection */
  GHashTable *connection_track_table;
-/* compare thread, a thread for each NIC */
-QemuThread thread;
  
+IOThread *iothread;

  GMainContext *worker_context;
-GMainLoop *compare_loop;
+QEMUTimer *packet_check_timer;
  } CompareState;
  
  typedef struct CompareClass {

@@ -597,22 +597,40 @@ static void compare_sec_chr_in(void *opaque, const 
uint8_t *buf, int size)
   * Check old packet regularly so it can watch for any packets
   * that the secondary hasn't produced equivalents of.
   */
-static gboolean check_old_packet_regular(void *opaque)
+static void check_old_packet_regular(void *opaque)
  {
  CompareState *s = opaque;
  
  /* if have old packet we will notify checkpoint */

  colo_old_packet_check(s);
+timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+REGULAR_PACKET_CHECK_MS);
+}
+
+static void colo_compare_timer_init(CompareState *s)
+{
+AioContext *ctx = iothread_get_aio_context(s->iothread);
  
-return TRUE;

+s->packet_check_timer = aio_timer_new(ctx, QEMU_CLOCK_VIRTUAL,
+SCALE_MS, check_old_packet_regular,
+s);
+timer_mod(s->packet_check_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) +
+REGULAR_PACKET_CHECK_MS);
  }
  
-static void *colo_compare_thread(void *opaque)

+static void colo_compare_timer_del(CompareState *s)
  {
-CompareState *s = opaque;
-GSource *timeout_source;
+if (s->packet_check_timer) {
+timer_del(s->packet_check_timer);
+timer_free(s->packet_check_timer);
+s->packet_check_timer = NULL;
+}
+ }
  
-s->worker_context = g_main_context_new();

+static void colo_compare_iothread(CompareState *s)
+{
+object_ref(OBJECT(s->iothread));
+s->worker_context = iothread_get_g_main_context(s->iothread);
  
  qemu_chr_fe_set_handlers(&s->chr_pri_in, compare_chr_can_read,

   compare_pri_chr_in, NULL, NULL,
@@ -621,20 +639,7 @@ static void *colo_compare_thread(void *opaque)
   compare_sec_chr_in, NULL, NULL,
   s, s->worker_context, true);
  
-s->compare_loop = g_main_loop_new(s->worker_context, FALSE);

-
-/* To kick any packets that the secondary doesn't match */
-timeout_source = g_timeout_source_new(REGULAR_PACKET_CHECK_MS);
-g_source_set_callback(timeout_source,
-  (GSourceFunc)check_old_packet_regular, s, NULL);
-g_source_attach(timeout_source, s->worker_context);
-
-g_main_loop_run(s->compare_loop);
-
-g_source_unref(timeout_source);
-g_main_loop_unref(s->compare_loop);
-g_main_context_unref(s->worker_context);
-return NULL;
+colo_compare_timer_init(s);
  }
  
  static char *compare_get_pri_indev(Object *obj, Error **errp)

@@ -759,12 +764,10 @@ static void colo_compare_complete(UserCreatable *uc, 
Error **errp)
  {
  CompareState *s = COLO_COMPARE(uc);
  Chardev *chr;
-char thread_name[64];
-static int compare_id;
  
-if (!s->pri_indev || !s->sec_indev || !s->outdev) {

+if (!s->pri_indev || !s->sec_indev || !s->outdev || !s->iothread) {
  error_setg(errp, "colo compare needs 'primary_in' ,"
-   "'secondary_in','outdev' property set");
+   "'secondary_in','outdev','iothread' property set");
  return;
  } else if (!strcmp(s->pri_indev, s->outdev) ||
 !strcmp(s->sec_indev, s->outdev) ||
@@ -799,12 +802,7 @@ static void colo_compare_complete(UserCreatable *uc, Error 
**errp)
g_free,
connection_destroy);
  
-sprintf(thr

Re: [Qemu-devel] [PATCH v2 16/19] s390x: allow cpu hotplug via device_add

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> E.g. the following now works:
> device_add host-s390-cpu,id=cpu1,core-id=1
> 
> The system will perform the same checks as when using cpu_add:
> - If the core_id is already in use
> - If the next sequential core_id isn't used
> - If core-id >= max_cpu is specified
> 
> In addition, mixed CPU models are checked. E.g. if starting with
> -cpu host and trying to hotplug "qemu-s390-cpu":
> "Mixed CPU models are not supported on s390x."
> 
> Signed-off-by: David Hildenbrand 

As easy as flipping a switch, right?

Tested the new device_add path, the old cpu-add path and mixed cases
where I alternated adding cpus via both methods -- looking good.

Reviewed-by: Matthew Rosato 

> ---
>  target/s390x/cpu.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
> index 105ff13034..be20c2fb0f 100644
> --- a/target/s390x/cpu.c
> +++ b/target/s390x/cpu.c
> @@ -466,6 +466,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void 
> *data)
>  scc->parent_realize = dc->realize;
>  dc->realize = s390_cpu_realizefn;
>  dc->props = s390x_cpu_properties;
> +dc->user_creatable = true;
> 
>  scc->parent_reset = cc->reset;
>  #if !defined(CONFIG_USER_ONLY)
> 




Re: [Qemu-devel] [PATCH v2 14/19] target/s390x: rename next_cpu_id to next_core_id

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> Adapt to the new term "core_id". While at it, fix the type and drop the
> initialization to 0 (which is superfluous).
> 
> Signed-off-by: David Hildenbrand 

Given the prior patch, this rename makes sense.

Reviewed-by: Matthew Rosato 

> ---
>  target/s390x/cpu-qom.h |  2 +-
>  target/s390x/cpu.c | 11 +--
>  2 files changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/target/s390x/cpu-qom.h b/target/s390x/cpu-qom.h
> index c8fbf8ae03..21ea15e642 100644
> --- a/target/s390x/cpu-qom.h
> +++ b/target/s390x/cpu-qom.h
> @@ -52,7 +52,7 @@ typedef struct S390CPUClass {
>  bool is_migration_safe;
>  const char *desc;
> 
> -int64_t next_cpu_id;
> +uint32_t next_core_id;
> 
>  DeviceRealize parent_realize;
>  void (*parent_reset)(CPUState *cpu);
> diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
> index a2570bbc6b..105ff13034 100644
> --- a/target/s390x/cpu.c
> +++ b/target/s390x/cpu.c
> @@ -197,7 +197,7 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>  }
>  #else
>  /* implicitly set for linux-user only */
> -cpu->env.core_id = scc->next_cpu_id;
> +cpu->env.core_id = scc->next_core_id;
>  #endif
> 
>  if (cpu_exists(cpu->env.core_id)) {
> @@ -205,10 +205,10 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
> **errp)
> cpu->env.core_id);
>  goto out;
>  }
> -if (cpu->env.core_id != scc->next_cpu_id) {
> +if (cpu->env.core_id != scc->next_core_id) {
>  error_setg(&err, "Unable to add CPU: %" PRIu32
> -   ", the next available nr is %" PRIi64, cpu->env.core_id,
> -   scc->next_cpu_id);
> +   ", the next available id is %" PRIu32, cpu->env.core_id,
> +   scc->next_core_id);
>  goto out;
>  }
> 
> @@ -218,7 +218,7 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>  if (err != NULL) {
>  goto out;
>  }
> -scc->next_cpu_id++;
> +scc->next_core_id++;
> 
>  #if !defined(CONFIG_USER_ONLY)
>  qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
> @@ -463,7 +463,6 @@ static void s390_cpu_class_init(ObjectClass *oc, void 
> *data)
>  CPUClass *cc = CPU_CLASS(scc);
>  DeviceClass *dc = DEVICE_CLASS(oc);
> 
> -scc->next_cpu_id = 0;
>  scc->parent_realize = dc->realize;
>  dc->realize = s390_cpu_realizefn;
>  dc->props = s390x_cpu_properties;
> 




Re: [Qemu-devel] [PATCH v2 13/19] target/s390x: use "core-id" for cpu number/address/id handling

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> Some time ago we discussed that using "id" as property name is not the
> right thing to do, as it is a reserved property for other devices and
> will not work with device_add.
> 
> Switch to the term "core-id" instead, and use it as an equivalent to
> "CPU address" mentioned in the PoP. There is no such thing as cpu number,
> so rename env.cpu_num to env.core_id. We use "core-id" as this is the
> common term to use for device_add later on (x86 and ppc).
> 
> We can get rid of cpu->id now. Keep cpu_index and env->core_id in sync.
> cpu_index was already implicitly used by e.g. cpu_exists(), so keeping
> both in sync seems to be the right thing to do.
> 

Rename & removal of 'id' is fine w/ me - in retrospect, it's a shame we
used 'id' in the first place.

> cpu_index will now no longer automatically get set via
> cpu_exec_realizefn(). For now, we were lucky that both implicitly stayed
> in sync.>

Good catch.

> Our new cpu property "core-id" can be a static property. Range checks can
> be avoided by using the correct type and the "setting after realized"
> check is done implicitly.
> 
> device_add will later need the reserved "id" property. Hotplugging a CPU
> on s390x will then be: "device_add host-s390-cpu,id=cpu2,core-id=2".
> 
> Signed-off-by: David Hildenbrand 
> ---

[...]

> diff --git a/target/s390x/translate.c b/target/s390x/translate.c
> index 4b0db7b7bd..b8963f2fe2 100644
> --- a/target/s390x/translate.c
> +++ b/target/s390x/translate.c
> @@ -3822,10 +3822,7 @@ static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
>  static ExitStatus op_stap(DisasContext *s, DisasOps *o)
>  {
>  check_privileged(s);
> -/* ??? Surely cpu address != cpu number.  In any case the previous
> -   version of this stored more than the required half-word, so it
> -   is unlikely this has ever been tested.  */
> -tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
> +tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, core_id));
>  return NO_EXIT;
>  }
> 

Are you sure it's OK to remove this blurb in its entirety?  You are
certainly collapsing the various CPU identifiers, but you aren't
changing the size of the store from when this blurb was put in
(411fea3d) So, "the previous version of this stored more than the
required half-word" seems to be still relevant -- Unless you've gone
ahead and tested it out?

Outside of that nit, I like the changes.

Reviewed-by: Matthew Rosato 




Re: [Qemu-devel] [PATCH v6 29/29] libqtest: Rename qtest_init() to qtest_start()

2017-09-06 Thread Eric Blake
On 09/05/2017 08:10 AM, Thomas Huth wrote:
> On 01.09.2017 20:03, Eric Blake wrote:
>> We already have another qtest_init() in the tree, for the
>> top-level qtest.c device; having two functions with different
>> signatures is confusing.  Rename the libqtest version to
>> qtest_start() to eliminate the duplication.
> 
> This is too much code churn for my taste, and I also do not like the
> idea of naming the function qtest_start() - since this was a function
> with different semantics before your patch 28/29, so this will cause
> confusion for all the people who are used to the old qtest_start()
> function or who want to backport patches that have done after this
> change to a code level before this change.
> 
> If you are really bugged by the qtest_init() name clash, I think it's
> way easier if you rename the qtest_init() in the qtest.c file instead.

Except the qtest_init() in qtest.c really is our normal pattern of
*_init for devices, so that one's named correctly.  Our testsuite is the
one that is using a name different from its normal usage in the rest of
the tree.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [Qemu devel v7 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-06 Thread sundeep subbaraya
Hi Alistair,

On Thu, Sep 7, 2017 at 1:59 AM, Alistair Francis 
wrote:

> On Mon, Aug 28, 2017 at 9:38 AM, Subbaraya Sundeep
>  wrote:
> > Modelled Microsemi's Smartfusion2 SPI controller.
> >
> > Signed-off-by: Subbaraya Sundeep 
> > ---
> >  hw/ssi/Makefile.objs |   1 +
> >  hw/ssi/mss-spi.c | 409 ++
> +
> >  include/hw/ssi/mss-spi.h |  58 +++
> >  3 files changed, 468 insertions(+)
> >  create mode 100644 hw/ssi/mss-spi.c
> >  create mode 100644 include/hw/ssi/mss-spi.h
> >
> > diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
> > index 487add2..f5bcc65 100644
> > --- a/hw/ssi/Makefile.objs
> > +++ b/hw/ssi/Makefile.objs
> > @@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
> >  common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
> >  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
> >  common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
> > +common-obj-$(CONFIG_MSF2) += mss-spi.o
> >
> >  obj-$(CONFIG_OMAP) += omap_spi.o
> >  obj-$(CONFIG_IMX) += imx_spi.o
> > diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
> > new file mode 100644
> > index 000..7209363
> > --- /dev/null
> > +++ b/hw/ssi/mss-spi.c
> > @@ -0,0 +1,409 @@
> > +/*
> > + * Block model of SPI controller present in
> > + * Microsemi's SmartFusion2 and SmartFusion SoCs.
> > + *
> > + * Copyright (C) 2017 Subbaraya Sundeep 
> > + *
> > + * Permission is hereby granted, free of charge, to any person
> obtaining a copy
> > + * of this software and associated documentation files (the
> "Software"), to deal
> > + * in the Software without restriction, including without limitation
> the rights
> > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or
> sell
> > + * copies of the Software, and to permit persons to whom the Software is
> > + * furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be
> included in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
> SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING FROM,
> > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN
> > + * THE SOFTWARE.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/ssi/mss-spi.h"
> > +#include "qemu/log.h"
> > +
> > +#ifndef MSS_SPI_ERR_DEBUG
> > +#define MSS_SPI_ERR_DEBUG   0
> > +#endif
> > +
> > +#define DB_PRINT_L(lvl, fmt, args...) do { \
> > +if (MSS_SPI_ERR_DEBUG >= lvl) { \
> > +qemu_log("%s: " fmt "\n", __func__, ## args); \
> > +} \
> > +} while (0);
> > +
> > +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> > +
> > +#define FIFO_CAPACITY 32
> > +#define FIFO_CAPACITY 32
>
> Double define?
>

Wrong will remove it.

>
> > +
> > +#define R_SPI_CONTROL 0
> > +#define R_SPI_DFSIZE  1
> > +#define R_SPI_STATUS  2
> > +#define R_SPI_INTCLR  3
> > +#define R_SPI_RX  4
> > +#define R_SPI_TX  5
> > +#define R_SPI_CLKGEN  6
> > +#define R_SPI_SS  7
> > +#define R_SPI_MIS 8
> > +#define R_SPI_RIS 9
> > +
> > +#define S_TXDONE (1 << 0)
> > +#define S_RXRDY  (1 << 1)
> > +#define S_RXCHOVRF   (1 << 2)
> > +#define S_RXFIFOFUL  (1 << 4)
> > +#define S_RXFIFOFULNXT   (1 << 5)
> > +#define S_RXFIFOEMP  (1 << 6)
> > +#define S_RXFIFOEMPNXT   (1 << 7)
> > +#define S_TXFIFOFUL  (1 << 8)
> > +#define S_TXFIFOFULNXT   (1 << 9)
> > +#define S_TXFIFOEMP  (1 << 10)
> > +#define S_TXFIFOEMPNXT   (1 << 11)
> > +#define S_FRAMESTART (1 << 12)
> > +#define S_SSEL   (1 << 13)
> > +#define S_ACTIVE (1 << 14)
> > +
> > +#define C_ENABLE (1 << 0)
> > +#define C_MODE   (1 << 1)
> > +#define C_INTRXDATA  (1 << 4)
> > +#define C_INTTXDATA  (1 << 5)
> > +#define C_INTRXOVRFLO(1 << 6)
> > +#define C_SPS(1 << 26)
> > +#define C_BIGFIFO(1 << 29)
> > +#define C_RESET  (1 << 31)
> > +
> > +#define FRAMESZ_MASK 0x1F
> > +#define FMCOUNT_MASK 0x0000
> > +#define FMCOUNT_SHIFT8
> > +
> > +static void txfifo_reset(MSSSpiState *s)
> > +{
> > +fifo32_reset(&s->tx_fifo);
> > +
> > +s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
> > +s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
> > +}
> > +
> > +static void rxfifo_reset(MSSSpiState *s)
> > +{
> > +fifo32_reset(&s->rx_fifo);
> > +
> > +s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
> > +s->regs[R

Re: [Qemu-devel] [PATCH v2 12/19] target/s390x: set cpu->id for linux user when realizing

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> scc->next_cpu_id is updated when realizing. Setting it just before that
> point looks cleaner.
> 
> Signed-off-by: David Hildenbrand 

Reviewed-by: Matthew Rosato 

> ---
>  target/s390x/cpu.c | 11 ---
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
> index 74b3e4fd0d..5f9315fb16 100644
> --- a/target/s390x/cpu.c
> +++ b/target/s390x/cpu.c
> @@ -194,7 +194,11 @@ static void s390_cpu_realizefn(DeviceState *dev, Error 
> **errp)
> ", max allowed: %d", cpu->id, max_cpus - 1);
>  goto out;
>  }
> +#else
> +/* implicitly set for linux-user only */
> +cpu->id = scc->next_cpu_id;
>  #endif
> +
>  if (cpu_exists(cpu->id)) {
>  error_setg(&err, "Unable to add CPU: %" PRIi64
> ", it already exists", cpu->id);
> @@ -306,13 +310,6 @@ static void s390_cpu_initfn(Object *obj)
>  inited = true;
>  s390x_translate_init();
>  }
> -
> -#if defined(CONFIG_USER_ONLY)
> -{
> -S390CPUClass *scc = S390_CPU_GET_CLASS(obj);
> -cpu->id = scc->next_cpu_id;
> -}
> -#endif
>  }
> 
>  static void s390_cpu_finalize(Object *obj)
> 




Re: [Qemu-devel] [PATCH 2/2] i386/cpu/hyperv: support over 64 vcpus for windows guests

2017-09-06 Thread Gonglei (Arei)


> -Original Message-
> From: Eduardo Habkost [mailto:ehabk...@redhat.com]
> Sent: Tuesday, September 05, 2017 9:17 PM
> To: Gonglei (Arei)
> Cc: qemu-devel@nongnu.org; m...@redhat.com; pbonz...@redhat.com;
> r...@twiddle.net; mtosa...@redhat.com; vroze...@redhat.com;
> Huangweidong (C)
> Subject: Re: [PATCH 2/2] i386/cpu/hyperv: support over 64 vcpus for windows
> guests
> 
> On Tue, Sep 05, 2017 at 05:30:05PM +0800, Gonglei wrote:
> > Starting with Windows Server 2012 and Windows 8, if
> > CPUID.4005.EAX contains a value of -1, Windows assumes specific
> > limit to the number of VPs. In this case, Windows Server 2012
> > guest VMs may use more than 64 VPs, up to the maximum supported
> > number of processors applicable to the specific Windows
> > version being used.
> >
> >
> https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/referenc
> e/tlfs
> >
> > For compatibility, Let's introduce a new property for X86CPU,
> > named "hv-cpuid-limits-eax" as Paolo's suggestion, and set it
> > to "on" before machine 2.10.
> >
> > Signed-off-by: Gonglei 
> > ---
> >  include/hw/i386/pc.h |  5 +
> >  target/i386/cpu.c|  1 +
> >  target/i386/cpu.h|  2 ++
> >  target/i386/kvm.c| 18 +-
> >  4 files changed, 25 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > index 8226904..db32e58 100644
> > --- a/include/hw/i386/pc.h
> > +++ b/include/hw/i386/pc.h
> > @@ -371,6 +371,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *,
> uint64_t *);
> >
> >  #define PC_COMPAT_2_10 \
> >  HW_COMPAT_2_10 \
> > +{\
> > +.driver   = TYPE_X86_CPU,\
> > +.property = "hv_cpuid_limits_eax",\
> 
> The property name is hv-cpuid-limits-eax.
> 
Make sense to me.

> > +.value= "on",\
> > +},\
> >
> >  #define PC_COMPAT_2_9 \
> >  HW_COMPAT_2_9 \
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 69676e1..0d47bdd 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -4145,6 +4145,7 @@ static Property x86_cpu_properties[] = {
> >   false),
> >  DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU,
> vmware_cpuid_freq, true),
> >  DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
> > +DEFINE_PROP_BOOL("hv-cpuid-limits-eax", X86CPU,
> hv_cpuid_limits_eax, false),
> 
> The property name "hv-cpuid-limits-eax" doesn't say anything
> about what it does exactly when set to true.
> 
> What about just making it int32?  e.g.:
> 
> DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1)
> [...]
> {\
> .driver   = TYPE_X86_CPU,\
> .property = "x-hv-max-vps",\
> .value= "0x40",\
> },\
> [...]
> c->function = HYPERV_CPUID_IMPLEMENT_LIMITS;
> c->eax = cpu->hv_max_vps;
> 
> 
> (The "x-" prefix indicates that the property is not supposed to
> be a stable user interface.)
> 
I thought about this as well.
but actually we can't assure that users set the x-hv-max-vps an invalid value if
we use this method. Do we really need to expose eax directly?

> 
> >  DEFINE_PROP_END_OF_LIST()
> >  };
> >
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index 525d35d..f8b455a 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -1282,6 +1282,8 @@ struct X86CPU {
> >  int32_t socket_id;
> >  int32_t core_id;
> >  int32_t thread_id;
> > +
> > +bool hv_cpuid_limits_eax;
> >  };
> >
> >  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> > diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> > index 6db7783..cf6ef96 100644
> > --- a/target/i386/kvm.c
> > +++ b/target/i386/kvm.c
> > @@ -751,7 +751,23 @@ int kvm_arch_init_vcpu(CPUState *cs)
> >
> >  c = &cpuid_data.entries[cpuid_i++];
> >  c->function = HYPERV_CPUID_IMPLEMENT_LIMITS;
> > -c->eax = 0x40;
> > +
> > +if (!cpu->hv_cpuid_limits_eax) {
> > +/*
> > + * Starting with Windows Server 2012 and Windows 8, if
> > + * CPUID.4005.EAX contains a value of -1, Windows
> > + * assumes specific limit to the number of VPs. In this case,
> > + * Windows Server 2012 guest VMs may use more than 64
> VPs,
> > + * up to the maximum supported number of processors
> > + * applicable to the specific Windows version being used.
> 
> That was a direct quote from a document, so I recommend citing
> the specific document you quoted.  e.g.:
> 
> /*
>  * From "Requirements for Implementing the Microsoft
>  * Hypervisor Interface":
>  *
> https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/referenc
> e/tlfs
>  *
>  * "Starting with Windows Server 2012 and Windows 8, if
>  * CPUID.4005.EAX contains a value of -1, Windows assumes
>  * specific limit to the number of VPs. In this case, Windows
>  * Server 2012 guest VMs may use more than 64 VPs, up to the
>  * maximum suppo

Re: [Qemu-devel] [PATCH 1/2] pc: add 2.11 machine type

2017-09-06 Thread Gonglei (Arei)


> -Original Message-
> From: Eduardo Habkost [mailto:ehabk...@redhat.com]
> Sent: Tuesday, September 05, 2017 9:21 PM
> To: Gonglei (Arei)
> Cc: qemu-devel@nongnu.org; m...@redhat.com; pbonz...@redhat.com;
> r...@twiddle.net; mtosa...@redhat.com; vroze...@redhat.com;
> Huangweidong (C)
> Subject: Re: [PATCH 1/2] pc: add 2.11 machine type
> 
> On Tue, Sep 05, 2017 at 05:30:04PM +0800, Gonglei wrote:
> > CC: "Michael S. Tsirkin" 
> > CC: Paolo Bonzini 
> > CC: Richard Henderson 
> > CC: Eduardo Habkost 
> > Signed-off-by: Gonglei 
> > ---
> >  hw/i386/pc_piix.c| 15 ---
> >  hw/i386/pc_q35.c | 13 +++--
> >  include/hw/i386/pc.h |  3 +++
> >  3 files changed, 26 insertions(+), 5 deletions(-)
> >
> > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > index 46dfd2c..b03cc04 100644
> > --- a/hw/i386/pc_piix.c
> > +++ b/hw/i386/pc_piix.c
> > @@ -436,21 +436,30 @@ static void
> pc_i440fx_machine_options(MachineClass *m)
> >  m->default_display = "std";
> >  }
> >
> > -static void pc_i440fx_2_10_machine_options(MachineClass *m)
> > +static void pc_i440fx_2_11_machine_options(MachineClass *m)
> >  {
> >  pc_i440fx_machine_options(m);
> >  m->alias = "pc";
> >  m->is_default = 1;
> >  }
> >
> > +DEFINE_I440FX_MACHINE(v2_11, "pc-i440fx-2.11", NULL,
> > +  pc_i440fx_2_11_machine_options);
> > +
> > +static void pc_i440fx_2_10_machine_options(MachineClass *m)
> > +{
> > +pc_i440fx_2_11_machine_options(m);
> > +m->is_default = 0;
> > +m->alias = NULL;
> > +SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
> > +}
> > +
> >  DEFINE_I440FX_MACHINE(v2_10, "pc-i440fx-2.10", NULL,
> >pc_i440fx_2_10_machine_options);
> >
> >  static void pc_i440fx_2_9_machine_options(MachineClass *m)
> >  {
> >  pc_i440fx_2_10_machine_options(m);
> > -m->is_default = 0;
> > -m->alias = NULL;
> >  SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
> >  m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
> >  }
> > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > index 169a214..d6fef8d 100644
> > --- a/hw/i386/pc_q35.c
> > +++ b/hw/i386/pc_q35.c
> > @@ -302,20 +302,29 @@ static void
> pc_q35_machine_options(MachineClass *m)
> >  m->max_cpus = 288;
> >  }
> >
> > -static void pc_q35_2_10_machine_options(MachineClass *m)
> > +static void pc_q35_2_11_machine_options(MachineClass *m)
> >  {
> >  pc_q35_machine_options(m);
> >  m->alias = "q35";
> >  m->numa_auto_assign_ram = numa_legacy_auto_assign_ram;
> >  }
> >
> > +DEFINE_Q35_MACHINE(v2_11, "pc-q35-2.11", NULL,
> > +   pc_q35_2_11_machine_options);
> > +
> > +static void pc_q35_2_10_machine_options(MachineClass *m)
> > +{
> > +pc_q35_2_11_machine_options(m);
> > +m->alias = NULL;
> > +SET_MACHINE_COMPAT(m, PC_COMPAT_2_10);
> > +}
> > +
> >  DEFINE_Q35_MACHINE(v2_10, "pc-q35-2.10", NULL,
> > pc_q35_2_10_machine_options);
> >
> >  static void pc_q35_2_9_machine_options(MachineClass *m)
> >  {
> >  pc_q35_2_10_machine_options(m);
> > -m->alias = NULL;
> >  SET_MACHINE_COMPAT(m, PC_COMPAT_2_9);
> >  }
> >
> > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > index d80859b..8226904 100644
> > --- a/include/hw/i386/pc.h
> > +++ b/include/hw/i386/pc.h
> > @@ -369,6 +369,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
> >  int e820_get_num_entries(void);
> >  bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
> >
> > +#define PC_COMPAT_2_10 \
> > +HW_COMPAT_2_10 \
> > +
> 
> Patch looks good, but I would remove the trailing backslash here.
> 
OK.

> With that changed:
> 
> Reviewed-by: Eduardo Habkost 
> 
Thanks.




Re: [Qemu-devel] [PATCH v2 2/3] hw/arm: Set ignore_memory_transaction_failures for most ARM boards

2017-09-06 Thread Alistair Francis
On Tue, Sep 5, 2017 at 8:53 AM, Peter Maydell  wrote:
> Set the MachineClass flag ignore_memory_transaction_failures
> for almost all ARM boards. This means they retain the legacy
> behaviour that accesses to unimplemented addresses will RAZ/WI
> rather than aborting, when a subsequent commit adds support
> for external aborts.
>
> The exceptions are:
>  * virt -- we know that guests won't try to prod devices
>that we don't describe in the device tree or ACPI tables
>  * mps2 -- this board was written to use unimplemented-device
>for all the ranges with devices we don't yet handle
>
> New boards should not set the flag, but instead be written
> like the mps2.
>
> Signed-off-by: Peter Maydell 
> For the Xilinx boards:
> Reviewed-by: Edgar E. Iglesias 

Reviewed-by: Alistair Francis 

Thanks,
Alistair

> ---
>  hw/arm/aspeed.c | 3 +++
>  hw/arm/collie.c | 1 +
>  hw/arm/cubieboard.c | 1 +
>  hw/arm/digic_boards.c   | 1 +
>  hw/arm/exynos4_boards.c | 2 ++
>  hw/arm/gumstix.c| 2 ++
>  hw/arm/highbank.c   | 2 ++
>  hw/arm/imx25_pdk.c  | 1 +
>  hw/arm/integratorcp.c   | 1 +
>  hw/arm/kzm.c| 1 +
>  hw/arm/mainstone.c  | 1 +
>  hw/arm/musicpal.c   | 1 +
>  hw/arm/netduino2.c  | 1 +
>  hw/arm/nseries.c| 2 ++
>  hw/arm/omap_sx1.c   | 2 ++
>  hw/arm/palm.c   | 1 +
>  hw/arm/raspi.c  | 1 +
>  hw/arm/realview.c   | 4 
>  hw/arm/sabrelite.c  | 1 +
>  hw/arm/spitz.c  | 4 
>  hw/arm/stellaris.c  | 2 ++
>  hw/arm/tosa.c   | 1 +
>  hw/arm/versatilepb.c| 2 ++
>  hw/arm/vexpress.c   | 1 +
>  hw/arm/xilinx_zynq.c| 1 +
>  hw/arm/xlnx-ep108.c | 2 ++
>  hw/arm/z2.c | 1 +
>  27 files changed, 43 insertions(+)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index 0c5635f..ab895ad 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -270,6 +270,7 @@ static void palmetto_bmc_class_init(ObjectClass *oc, void 
> *data)
>  mc->no_floppy = 1;
>  mc->no_cdrom = 1;
>  mc->no_parallel = 1;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  static const TypeInfo palmetto_bmc_type = {
> @@ -302,6 +303,7 @@ static void ast2500_evb_class_init(ObjectClass *oc, void 
> *data)
>  mc->no_floppy = 1;
>  mc->no_cdrom = 1;
>  mc->no_parallel = 1;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  static const TypeInfo ast2500_evb_type = {
> @@ -326,6 +328,7 @@ static void romulus_bmc_class_init(ObjectClass *oc, void 
> *data)
>  mc->no_floppy = 1;
>  mc->no_cdrom = 1;
>  mc->no_parallel = 1;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  static const TypeInfo romulus_bmc_type = {
> diff --git a/hw/arm/collie.c b/hw/arm/collie.c
> index 2e69531..8830192 100644
> --- a/hw/arm/collie.c
> +++ b/hw/arm/collie.c
> @@ -64,6 +64,7 @@ static void collie_machine_init(MachineClass *mc)
>  {
>  mc->desc = "Sharp SL-5500 (Collie) PDA (SA-1110)";
>  mc->init = collie_init;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  DEFINE_MACHINE("collie", collie_machine_init)
> diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
> index b98e1c4..32f1edd 100644
> --- a/hw/arm/cubieboard.c
> +++ b/hw/arm/cubieboard.c
> @@ -86,6 +86,7 @@ static void cubieboard_machine_init(MachineClass *mc)
>  mc->init = cubieboard_init;
>  mc->block_default_type = IF_IDE;
>  mc->units_per_default_bus = 1;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  DEFINE_MACHINE("cubieboard", cubieboard_machine_init)
> diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
> index 520c8e9..9f11dcd 100644
> --- a/hw/arm/digic_boards.c
> +++ b/hw/arm/digic_boards.c
> @@ -155,6 +155,7 @@ static void canon_a1100_machine_init(MachineClass *mc)
>  {
>  mc->desc = "Canon PowerShot A1100 IS";
>  mc->init = &canon_a1100_init;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  DEFINE_MACHINE("canon-a1100", canon_a1100_machine_init)
> diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
> index 7c03ed3..f1441ec 100644
> --- a/hw/arm/exynos4_boards.c
> +++ b/hw/arm/exynos4_boards.c
> @@ -189,6 +189,7 @@ static void nuri_class_init(ObjectClass *oc, void *data)
>  mc->desc = "Samsung NURI board (Exynos4210)";
>  mc->init = nuri_init;
>  mc->max_cpus = EXYNOS4210_NCPUS;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  static const TypeInfo nuri_type = {
> @@ -204,6 +205,7 @@ static void smdkc210_class_init(ObjectClass *oc, void 
> *data)
>  mc->desc = "Samsung SMDKC210 board (Exynos4210)";
>  mc->init = smdkc210_init;
>  mc->max_cpus = EXYNOS4210_NCPUS;
> +mc->ignore_memory_transaction_failures = true;
>  }
>
>  static const TypeInfo smdkc210_type = {
> diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
> index d59d9ba..092ce36 100644
> --- a/hw/arm/gumstix.c
> +++ b/hw/arm/gumstix.c
> @@ -128,6 +128,7 @@ static void connex_class_init(ObjectClass 

Re: [Qemu-devel] [PATCH v2 1/3] boards.h: Define new flag ignore_memory_transaction_failures

2017-09-06 Thread Alistair Francis
On Tue, Sep 5, 2017 at 9:03 AM, Richard Henderson
 wrote:
> On 09/05/2017 08:53 AM, Peter Maydell wrote:
>> Define a new MachineClass field ignore_memory_transaction_failures.
>> If this is flag is true then the CPU will ignore memory transaction
>> failures which should cause the CPU to take an exception due to an
>> access to an unassigned physical address; the transaction will
>> instead return zero (for a read) or be ignored (for a write).  This
>> should be set only by legacy board models which rely on the old
>> RAZ/WI behaviour for handling devices that QEMU does not yet model.
>> New board models should instead use "unimplemented-device" for all
>> memory ranges where the guest will attempt to probe for a device that
>> QEMU doesn't implement and a stub device is required.
>>
>> We need this for ARM boards, where we're about to implement support for
>> generating external aborts on memory transaction failures. Too many
>> of our legacy board models rely on the RAZ/WI behaviour and we
>> would break currently working guests when their "probe for device"
>> code provoked an external abort rather than a RAZ.
>>
>> Signed-off-by: Peter Maydell 
>> ---
>>  include/hw/boards.h | 11 +++
>>  include/qom/cpu.h   |  7 ++-
>>  qom/cpu.c   | 16 
>>  3 files changed, 33 insertions(+), 1 deletion(-)
>
> Reviewed-by: Richard Henderson 

Reviewed-by: Alistair Francis 

Thanks,
Alistair

>
>
> r~
>



Re: [Qemu-devel] [PATCH] trace: Immediately apply per-vCPU state changes if a vCPU is being created

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 18:27:10 +0300, Lluís Vilanova wrote:
> Right now, function trace_event_set_vcpu_state_dynamic() asynchronously 
> enables
> events in the case a vCPU is executing TCG code. If the vCPU is being created
> this makes some events like "guest_cpu_enter" to not be traced.
> 
> Signed-off-by: Lluís Vilanova 
> ---
>  trace/control-target.c |   19 ---
>  1 file changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/trace/control-target.c b/trace/control-target.c
> index 4e36101997..0056da6a46 100644
> --- a/trace/control-target.c
> +++ b/trace/control-target.c
> @@ -88,13 +88,18 @@ void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,
>  clear_bit(vcpu_id, vcpu->trace_dstate_delayed);
>  (*ev->dstate)--;
>  }
> -/*
> - * Delay changes until next TB; we want all TBs to be built from a
> - * single set of dstate values to ensure consistency of generated
> - * tracing code.
> - */
> -async_run_on_cpu(vcpu, trace_event_synchronize_vcpu_state_dynamic,
> - RUN_ON_CPU_NULL);
> +if (vcpu->created) {
> +/*
> + * Delay changes until next TB; we want all TBs to be built from 
> a
> + * single set of dstate values to ensure consistency of generated
> + * tracing code.
> + */
> +async_run_on_cpu(vcpu, 
> trace_event_synchronize_vcpu_state_dynamic,
> + RUN_ON_CPU_NULL);
> +} else {
> +run_on_cpu_data ignored;
> +trace_event_synchronize_vcpu_state_dynamic(vcpu, ignored);

I'd prefer RUN_ON_CPU_NULL here instead of the ignored param.
Other than that,

Reviewed-by: Emilio G. Cota 

E.



Re: [Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 20:59:02 +0300, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova 
> ---
(snip)
> +QI_VPUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
> +{
> +ERROR_IF(!instr_get_state(), "called outside instrumentation");
> +instr_set_event(fini_fn, fn);
> +instr_set_event(fini_data, data);
> +}

Why are these QI_VPUBLIC attributes here? Those are useful for DSO's, not
for executables --by using -rdynamic, all non-static symbols in the
executable are already visible.

> diff --git a/instrument/control.h b/instrument/control.h
> new file mode 100644
> index 00..f2b085f69b
> --- /dev/null
> +++ b/instrument/control.h
(snip)
> + * Instrumentation state of current host thread. Used to ensure 
> instrumentation
> + * clients use QEMU's API only in expected points.
> + */
> +typedef enum {
> +INSTR_STATE_DISABLE,
> +INSTR_STATE_ENABLE,
> +} InstrState;

I find this unnecessarily ugly for the little gain we get, i.e. asserts against
calling API code from QEMU.. seems unlikely to me (although admittedly I think
the qemu-internal API is unnecessarily complex/verbose, so maybe
you're better off with these checks).

(snip)
> +/**
> + * instr_get_event:
> + *
> + * Get value set by instrumentation library.
> + */
> +#define instr_get_event(name)   \
> +atomic_load_acquire(&instr_event__ ## name)
> +
> +/**
> + * instr_get_event:
> + *
> + * Set value from instrumentation library.
> + */
> +#define instr_set_event(name, fn)   \
> +atomic_store_release(&instr_event__ ## name, fn)

This isn't enough to decide whether to call instrumentation, especially for
TCG. We need TB's to know what to call, and update that mask with async
work, just like we do with tracing. Check out my alternative patchset.

Also, a single function pointer cannot work for more than one plugin. But
I see you have an XXX when there's more than one plugin, so it's OK for now.
I used RCU lists for this, which at least gives you a time in the future
at which things become visible/invisible by other threads -- this is important
when unloading an instrumenter, since you don't want to clear important stuff
(e.g. dlclose) before you're sure no further callbacks to it are possible.
[no, the atomic_acquire/release isn't enough!]

(snip)
> diff --git a/instrument/load.c b/instrument/load.c
> index a57401102a..e180f03429 100644
> --- a/instrument/load.c
> +++ b/instrument/load.c
> @@ -11,6 +11,8 @@
>  #include "qemu-common.h"
>  
>  #include 
> +#include "instrument/control.h"
> +#include "instrument/events.h"
>  #include "instrument/load.h"
>  #include "qemu/config-file.h"
>  #include "qemu/error-report.h"
> @@ -105,8 +107,11 @@ InstrLoadError instr_load(const char * path, int argc, 
> const char ** argv,
>  res = INSTR_LOAD_DLERROR;
>  goto err;
>  }
> +instr_set_event(fini_fn, NULL);
>  
> +instr_set_state(INSTR_STATE_ENABLE);
>  main_res = main_cb(argc, argv);
> +instr_set_state(INSTR_STATE_DISABLE);
>  
>  if (main_res != 0) {
>  res = INSTR_LOAD_ERROR;
> @@ -136,6 +141,14 @@ InstrUnloadError instr_unload(int64_t handle_id)
>  goto out;
>  }
>  
> +qi_fini_fn fini_fn = instr_get_event(fini_fn);
> +if (fini_fn) {
> +void *fini_data = instr_get_event(fini_data);
> +fini_fn(fini_data);
> +}
> +
> +instr_set_event(fini_fn, NULL);
> +

Is fini really that useful? Doesn't the tool just die with QEMU once QEMU exits?
At the end of the day, the tool could register its own atexit hook.

E.



Re: [Qemu-devel] [PATCH v6 26/29] fw_cfg-test: Drop dependence on global_qtest

2017-09-06 Thread Eric Blake
On 09/05/2017 06:05 AM, Thomas Huth wrote:
> On 01.09.2017 20:03, Eric Blake wrote:
>> As a general rule, we prefer avoiding implicit global state
>> because it makes code harder to safely copy and paste without
>> thinking about the global state.  It turns out that with the
>> recent changes to libqos, fw_cfg-test was not even using
>> global_qtest any more.  Avoid a pointless strdup while at it.
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  tests/fw_cfg-test.c | 5 +
>>  1 file changed, 1 insertion(+), 4 deletions(-)
>>

>>
> 
> Why don't you merge this with patch 14/29?

Sure.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [Qemu-block] [PATCH v6 16/29] libqos: Use explicit QTestState for virtio operations

2017-09-06 Thread Eric Blake
On 09/05/2017 07:43 AM, Paolo Bonzini wrote:
>>  typedef struct QVirtioDevice {
>>  const QVirtioBus *bus;
>> +QTestState *qts;
>>  /* Device type */
>>  uint16_t device_type;
>>  } QVirtioDevice;
>> @@ -35,12 +36,14 @@ typedef struct QVirtQueue {
>>  uint16_t last_used_idx;
>>  bool indirect;
>>  bool event;
>> +QTestState *qts;
>>  } QVirtQueue;
>>
>>  typedef struct QVRingIndirectDesc {
>>  uint64_t desc; /* This points to an array fo struct vring_desc */
>>  uint16_t index;
>>  uint16_t elem;
>> +QTestState *qts;
>>  } QVRingIndirectDesc;
> 
> Adding QTestState to QVRingIndirectDesc and QVirtQueue sounds somewhat
> ugly to me. I think they should either rather have a pointer to the
> associated QVirtioDevice, or the functions where this is needed
> (qvring_init() for example) should get a "QTestState *" parameter instead.
> 
> 
> I agree with Thomas and even extend it to QVirtioDevice. If there is a
> has-a hierarchy between libqos objects, only the topmost one (such as the
> virtio mmio bus device, and the PCI host bridge---or possibly even the
> machine object exclusively) should have a QTestState. Everyone else can
> access it implicitly through operations on its bus.

[Paolo, gmail is really messing up with your quoting style ;( ]

Okay, so if I understand correctly, at most a QVRingIndirectDesc can
have a pointer back to the QVirtioDevice that owns it, and in turn the
QVirtioDevice has a pointer back to the QPCIBus that the device is on,
and anywhere that needs a QTestState follows the chain back to the
QPCIBus to get it.  I'll play with the idea, as it may still allow for
more compact code than passing an explicit QTestState parameter through
every call.

> 
> Test code on the other hand can use global_qtest implicitly when they
> prepare/read buffers that the devices do DMA from/to.

Not when I'm done - my next series gets rid of implicit global_qtest
everywhere.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v4 11/20] instrument: Track vCPUs

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 21:07:06 +0300, Lluís Vilanova wrote:
> Keep a translation between instrumentation's QICPU and CPUState objects to 
> avoid
> exposing QEMU's internals to instrumentation clients.
> 
> Signed-off-by: Lluís Vilanova 
(snip)
> diff --git a/instrument/control.c b/instrument/control.c
> index 2c2781beeb..83453ea561 100644
> --- a/instrument/control.c
> +++ b/instrument/control.c
> @@ -13,10 +13,32 @@
>  #include "instrument/load.h"
>  #include "instrument/qemu-instr/control.h"
>  #include "instrument/qemu-instr/visibility.h"
> +#include "qom/cpu.h"
> +
>  
>  __thread InstrState instr_cur_state;
>  
>  
> +unsigned int instr_cpus_count;
> +CPUState **instr_cpus;
> +
> +void instr_cpu_add(CPUState *vcpu)
> +{
> +unsigned int idx = vcpu->cpu_index;
> +if (idx >= instr_cpus_count) {
> +instr_cpus_count = idx + 1;
> +instr_cpus = realloc(instr_cpus, sizeof(*instr_cpus) * 
> instr_cpus_count);
> +}
> +instr_cpus[idx] = vcpu;
> +}
> +
> +void instr_cpu_remove(CPUState *vcpu)
> +{
> +unsigned int idx = vcpu->cpu_index;
> +instr_cpus[idx] = NULL;
> +}

instr_cpus_count and instr_cpus are both modified with cpu_list_lock.
However, other readers do not acquire this same lock. This gets messy
when you try to implement something like "vcpu_for_each", which is
very useful when you load an instrumentation tool once the program
is running (otherwise the tool cannot know for sure what the vCPUs
are). This vcpu_for_each would also have to take cpu_list_lock, for
otherwise it'd miss new threads being added. As you can imagine this
gets messy pretty quickly, given that you have your own lock here.
I went with having my own hash table (a list would be fine too),
protected with the same "instr_lock" you have (i.e. the recursive mutex).

An unrelated comment: your usage of get/set/put confuses me. I'd expect those
to work on refcounted items; instead you use them for instance to hide a cast
(cpu_set) or to create/destroy (e.g. handle_get/put).

E.



Re: [Qemu-devel] [PATCH v6 14/29] libqos: Use explicit QTestState for fw_cfg operations

2017-09-06 Thread Eric Blake
On 09/06/2017 04:10 PM, Eric Blake wrote:
>> I'm not a fan of including header files from other header files, so
>> changing the include order in the .c files sounds like the better
>> solution to me.
> 
> Eww. I like headers to be self-contained.  Other than stuff we get from
> osdep.h (which we know is included by EVERY .c file), I prefer that if a
> header uses another type, then it guarantees that an idempotent
> inclusion of a header that declares that type is also present in the
> header file, rather than forcing .c files to know which order to include
> things in.

The qemu tree-wide policy appears to be that a header should be
self-contained (order of inclusion in .c files shouldn't matter).  Also,
if header A only uses 'SomeType *', it can either get the definition of
SomeType from header B, or we can add the typedef to typedef.h at which
point both header A and B get the typedef from there (that is, typedef.h
is great for breaking what would otherwise be cyclic inclusion of
mutually-recursive types across different headers, as well as a way to
speed up compilation when a typedef is sufficient rather than a full
definition).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 20:59:02 +0300, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova 
> ---
>  Makefile   |5 +++
>  configure  |1 +
>  instrument/Makefile.objs   |2 +
>  instrument/control.c   |   28 +
>  instrument/control.h   |   44 +++
>  instrument/control.inc.h   |   25 
>  instrument/error.h |   28 +
>  instrument/events.h|   37 +++
>  instrument/events.inc.h|   11 +++

Am I the only one who finds this control vs. events division confusing?

Also, do we need all these many files, even for the public API?

And why the .inc's?

Thanks,
E.




Re: [Qemu-devel] [PATCH v4 03/20] instrument: Add generic library loader

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 20:34:48 +0300, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova 
> ---
(snip)
> diff --git a/configure b/configure
> index 80dcc91c98..05bd7b1950 100755
> --- a/configure
> +++ b/configure
> @@ -6034,6 +6034,8 @@ fi
>  echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
>  
>  if test "$instrument" = "yes"; then
> +  LDFLAGS="-rdynamic $LDFLAGS"  # limit symbols available to clients

-rdynamic exports all objects to the instrumenters, not the other way around.
You can see it with nm(1).

BTW I'm using ebf447b5b from your qemu-dbi repo. Is that the same as this
patchset? It doesn't compile with --enable-instrument:
$ make
  CC  x86_64-linux-user/instrument/trace.o
/data/src/qemu2/instrument/trace.c:12:30: fatal error: qemu-instr/trace.h: No 
such file or directory
compilation terminated.
/data/src/qemu2/rules.mak:66: recipe for target 'instrument/trace.o' failed
make[1]: *** [instrument/trace.o] Error 1
Makefile:326: recipe for target 'subdir-x86_64-linux-user' failed
make: *** [subdir-x86_64-linux-user] Error 2

Emilio



Re: [Qemu-devel] [PATCH v2 11/19] s390x: allow only 1 CPU with TCG

2017-09-06 Thread Richard Henderson
On 09/06/2017 11:16 AM, Matthew Rosato wrote:
> On 09/04/2017 11:43 AM, David Hildenbrand wrote:
>> Specifying more than 1 CPU (e.g. -smp 5) leads to SIGP errors (the
>> guest tries to bring these CPUs up but fails), because we don't support
>> multiple CPUs on s390x under TCG.
>>
>> Let's bail out if more than 1 is specified, so we don't raise people's
>> hope. Make it a define, so we can easily bump it up later.
>>
>> Signed-off-by: David Hildenbrand 
>> ---
> 
> Makes sense.  Ran the described environment without this patch (errors)
> and again with this patch (graceful exit w/ message).
> 
> Tested-by: Matthew Rosato 

Can someone review

  http://patchwork.ozlabs.org/patch/760010/

which does at least start to add the SIGP support.

Once tcg can bring up 2 cpus, I see no reason it couldn't bring up N.  I don't
see the point of the define.


r~



Re: [Qemu-devel] [PATCH v6 14/29] libqos: Use explicit QTestState for fw_cfg operations

2017-09-06 Thread Eric Blake
On 09/05/2017 06:03 AM, Thomas Huth wrote:
> On 05.09.2017 12:12, Thomas Huth wrote:
>> On 01.09.2017 20:03, Eric Blake wrote:
>>> Drop one more client of global_qtest by teaching all fw_cfg test
>>> functionality (invoked through alloc-pc) to pass in an explicit
>>> QTestState, adjusting all callers.  In particular, fw_cfg-test
>>> had to reorder things to create the test state prior to creating
>>> the fw_cfg.
>>>

>>> +++ b/tests/libqos/fw_cfg.h
>>> @@ -15,10 +15,12 @@
>>>
>>>
>>>  typedef struct QFWCFG QFWCFG;
>>> +typedef struct QTestState QTestState;
>>
>> Not sure, but I slightly remember that typedeffing a struct like this in
>> multiple places can cause compiler warnings or errors with certain
>> versions of GCC or clang? So a file that includes both, fw_cfg.h and
>> libqtest.h will then fail to compile?

Yes, older gcc fails to compile (my off-hand recollection is that it was
a bug in the older gcc, and not a standards-compliance issue to
encounter the same typedef twice, but I could be wrong), ergo the fixup
that you later noticed.

>>
>> I think it would be better to change the include order in the .c files
>> instead, so that libqtest.h is always included before fw_cfg.h.
> 
> Ah, well, I just saw that you also sent a fixup patch for this. Anyway,
> I'm not a fan of including header files from other header files, so
> changing the include order in the .c files sounds like the better
> solution to me.

Eww. I like headers to be self-contained.  Other than stuff we get from
osdep.h (which we know is included by EVERY .c file), I prefer that if a
header uses another type, then it guarantees that an idempotent
inclusion of a header that declares that type is also present in the
header file, rather than forcing .c files to know which order to include
things in.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v6 12/29] libqos: Track QTestState with QPCIBus

2017-09-06 Thread Eric Blake
On 09/05/2017 04:36 AM, Thomas Huth wrote:
> On 01.09.2017 20:03, Eric Blake wrote:
>> When initializing a QPCIBus, track which QTestState the bus is
>> associated with (so that a later patch can then explicitly use
>> that test state for all communication on the bus, rather than
>> blindly relying on global_qtest).  Update the initialization
>> functions to take another parameter, and update all callers to
>> pass in state (for now, most callers get away with passing the
>> current global_qtest as the current state, although this required
>> fixing the order of initialization to ensure qtest_start() is
>> called before qpci_init*() in rtl8139-test, and provided an
>> opportunity to pass in the allocator in e1000e-test).
>>
>> Signed-off-by: Eric Blake 
>> ---
> [...]
>> diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
>> index 6226546c28..c95428e1cb 100644
>> --- a/tests/libqos/libqos.c
>> +++ b/tests/libqos/libqos.c
>> @@ -26,8 +26,8 @@ QOSState *qtest_vboot(QOSOps *ops, const char 
>> *cmdline_fmt, va_list ap)
>>  if (ops->init_allocator) {
>>  qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);
>>  }
>> -if (ops->qpci_init && qs->alloc) {
>> -qs->pcibus = ops->qpci_init(qs->alloc);
>> +if (ops->qpci_init) {
> 
> Why did you remove the check for qs->alloc?
> 
>> +qs->pcibus = ops->qpci_init(qs->qts, qs->alloc);

Because we want to ensure qpci_init() is called to set qs->qts
(presumably, whether or not qs->alloc is set).  Furthermore, only two
files declare a 'static QOSOps' structure in the first place
(libqos-pc.c and libqos-spapr.c); where both files set both the
.init_allocator and .qpci_init callbacks; a little bit of auditing shows
that the .init_allocator() never returns NULL (although that requires
browsing yet more files for malloc-{pc,spapr}.c).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v4 00/20] instrument: Add basic event instrumentation

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 20:22:41 +0300, Lluís Vilanova wrote:
> This series adds an API to add instrumentation events.
> 
> It also provides additional APIs for:
> * Controlling tracing events

hmm didn't Stefan say that tracing should be decoupled from this?

> * Peek/poke guest memory
> 
> There's still missing APIs for (can be added in later series?):
> * Provide something like tracing's per-vCPU trace states (i.e., so that each
>   vCPU can have different instrumentation code). It's still not clear to me if
>   we should extend the per-vCPU bitmap with instrumentation events, or 
> otherwise
>   somehow reuse the bits in tracing events (since they're currently limited).

As I said in the description of my alternative implementation [*], I don't see
much value in having per-vCPU events, as most instrumenters just care about
the guest application/system. I can only think of cases where the instrumenter
is only interested in a guest process (in system-mode), but that'd be ugly
anyway (would need to change both QEMU and the guest kernel to track the pid).

If the need ever arises, we could add __vcpu(cpu_index) registration functions.

[*] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg01446.html

E.



Re: [Qemu-devel] [PATCH v6 12/29] libqos: Track QTestState with QPCIBus

2017-09-06 Thread Eric Blake
On 09/01/2017 02:20 PM, Philippe Mathieu-Daudé wrote:
> Hi Eric,
> 
> On 09/01/2017 03:03 PM, Eric Blake wrote:
>> When initializing a QPCIBus, track which QTestState the bus is
>> associated with (so that a later patch can then explicitly use
>> that test state for all communication on the bus, rather than
>> blindly relying on global_qtest).  Update the initialization
>> functions to take another parameter, and update all callers to
>> pass in state (for now, most callers get away with passing the
>> current global_qtest as the current state, although this required
>> fixing the order of initialization to ensure qtest_start() is
>> called before qpci_init*() in rtl8139-test, and provided an
>> opportunity to pass in the allocator in e1000e-test).
>>

>> +++ b/tests/libqos/pci-pc.c
>> @@ -115,11 +115,14 @@ static void qpci_pc_config_writel(QPCIBus *bus,
>> int devfn, uint8_t offset, uint3
>>   outl(0xcfc, value);
>>   }
>>
>> -QPCIBus *qpci_init_pc(QGuestAllocator *alloc)
>> +QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)
>>   {
>>   QPCIBusPC *ret;
>>
>> +    assert(qts);
>> +
>>   ret = g_malloc(sizeof(*ret));
> 
> I'd rather use g_malloc0() here (safer!)

Pre-existing, but yes, I can touch it while in the area.

> 
>> +    ret->bus.qts = qts;
>>
>>   ret->bus.pio_readb = qpci_pc_pio_readb;
>>   ret->bus.pio_readw = qpci_pc_pio_readw;
> 
> or init qts field in same order than struct:

Okay.

> 
> Either ways:
> Reviewed-by: Philippe Mathieu-Daudé 
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [RFC 2/6] plugin: add initial plugin support

2017-09-06 Thread Emilio G. Cota
On Wed, Sep 06, 2017 at 16:28:44 -0400, Emilio G. Cota wrote:
> --- /dev/null
> +++ b/plugin.c
> @@ -0,0 +1,519 @@
(snip)
> +/*
> + * @lock protects the struct as well as ctx->uninstalling.
> + * The lock must be acquired by all API ops. Since some API ops
> + * call plugin code repeatedly (e.g. vcpu_for_each), we keep
> + * a counter to allow for recursive acquisitions.
> + */
> +QemuMutex lock;

This comment is outdated. The lock is not recursive anymore (it used to be).

E.



[Qemu-devel] [RFC 2/6] plugin: add initial plugin support

2017-09-06 Thread Emilio G. Cota
This is still a work in progress, hence the limited public-facing API.
I wanted to add more events (e.g. memory and basic block callbacks), but
before spending more time on time I'd like to see whether this direction
is appreciated by others.

The goals are to:
- Have a simple implementation that shares nothing with tracing code.

- Make sure we cannot deadlock, particularly under MTTCG. For this,
  we acquire a lock when called from plugin code, and keep
  RCU lists of callbacks so that we do not have to hold the lock
  when calling the callbacks. This is also for performance, since
  some callbacks (e.g. memory access callbacks) might be called very
  frequently.
  * A consequence of this is that we keep our own list of CPUs, so that
we do not have to worry about locking order wrt cpu_list_lock.
  * Some functions such as vcpu_for_each will call plugin code with the
lock held. Instead of making the lock recursive, just document that
the function called by vcpu_for_each cannot call any other plugin API.

- Support as many plugins as the user wants (e.g. -plugin foo -plugin bar),
  just like other tools (e.g. dynamorio) do.

- Support the installation/uninstallation of a plugin any time (i.e. from
  any callback from the guest, or from QAPI/QMP).

- Avoid malicious plugins from abusing the API. This is done by:
  * Adding a qemu_plugin_id_t that all calls need to use. This is a unique
id per plugin.
  * Hiding CPUState * under cpu_index. Plugin code can keep per-vcpu
data by using said index (say to index an array).
  * Only exporting the relevant qemu_plugin symbols to the plugins by
passing --dynamic-file to the linker (when supported), instead of
exporting all symbols with -rdynamic.

- Performance: registering/unregistering callbacks is slow. But this is
  very infrequent; we want performance when calling (or not) callbacks.
  Using RCU is great for this. The only difficulty is when uninstalling
  a plugin, where some callbacks might still be called after the
  uninstall returns. An alternative would be to use r/w locks, but that
  would complicate code quite a bit for very little gain; I suspect most
  plugins will just run until QEMU exits.

Some design decisions:
- I considered registering callbacks per-vcpu, but really I don't see the
  use case for it (would complicate the API and 99% of plugins won't care, so
  I'd rather make that 1% slower by letting them discard unwanted callbacks).

- Using a per-vcpu mask is key to allow for maximum performance/scalability.
  With RCU callbacks and async work we can ensure no events are missed, and
  we keep maximum scalability (again, we assume callbacks are a lot more
  common than callback registration).

- Last, 'plugin' vs. 'instrumentation' naming: I think instrumentation is a
  subset of the functionality that plugins can provide. IOW, in the future
  not all plugins might be considered instrumentation, even if currently
  my goal is to use them for that purpose.

Signed-off-by: Emilio G. Cota 
---
 Makefile.objs |   1 +
 include/exec/exec-all.h   |   2 +
 include/exec/tb-hash-xx.h |  26 ++-
 include/exec/tb-hash.h|   6 +-
 include/exec/tb-lookup.h  |   1 +
 include/qemu/plugin-api.h | 105 ++
 include/qemu/plugin.h |  74 +++
 include/qom/cpu.h |   4 +
 accel/tcg/cpu-exec.c  |   6 +-
 accel/tcg/translate-all.c |   6 +-
 plugin.c  | 519 ++
 qom/cpu.c |   3 +
 tests/qht-bench.c |   2 +-
 qemu-plugins.symbols  |   6 +
 14 files changed, 746 insertions(+), 15 deletions(-)
 create mode 100644 include/qemu/plugin-api.h
 create mode 100644 include/qemu/plugin.h
 create mode 100644 plugin.c
 create mode 100644 qemu-plugins.symbols

diff --git a/Makefile.objs b/Makefile.objs
index 24a4ea0..52cc89c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -84,6 +84,7 @@ endif
 ###
 # Target-independent parts used in system and user emulation
 common-obj-y += cpus-common.o
+common-obj-$(CONFIG_PLUGINS) += plugin.o
 common-obj-y += hw/
 common-obj-y += qom/
 common-obj-y += disas/
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 1d4e977..add9423 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -346,6 +346,8 @@ struct TranslationBlock {
 /* Per-vCPU dynamic tracing state used to generate this TB */
 uint32_t trace_vcpu_dstate;
 
+uint32_t plugin_mask;
+
 struct tb_tc tc;
 
 /* original tb when cflags has CF_NOCACHE */
diff --git a/include/exec/tb-hash-xx.h b/include/exec/tb-hash-xx.h
index 747a9a6..4015d6a 100644
--- a/include/exec/tb-hash-xx.h
+++ b/include/exec/tb-hash-xx.h
@@ -49,7 +49,8 @@
  * contiguous in memory.
  */
 static inline uint32_t
-tb_hash_func7(uint64_t a0, uint64_t b0, uint32_t e, uint32_t f, uint32_t g)
+tb_hash_func8(uint64_t a0, uint64_t b0, uint32_t e, uint32_t f, ui

[Qemu-devel] [RFC 1/6] tcg: keep a pointer to the current TB in TCGContext

2017-09-06 Thread Emilio G. Cota
Instead of just a copy of tb->cflags. This gives access in TCG
to other fields in TB, which will be needed when we implement
callbacks from memory accesses performed by TCG-translated code.

Signed-off-by: Emilio G. Cota 
---
 tcg/tcg.h |  2 +-
 accel/tcg/translate-all.c |  3 ++-
 tcg/tcg-op.c  | 10 +-
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/tcg/tcg.h b/tcg/tcg.h
index cf4eeaf..86ca604 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -676,7 +676,7 @@ struct TCGContext {
 uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_addr if !USE_DIRECT_JUMP 
*/
 
 TCGRegSet reserved_regs;
-uint32_t tb_cflags; /* cflags of the current TB */
+const TranslationBlock *tb;
 intptr_t current_frame_offset;
 intptr_t frame_start;
 intptr_t frame_end;
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 69cc7dc..7332afc 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1600,7 +1600,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 tb->flags = flags;
 tb->cflags = cflags;
 tb->trace_vcpu_dstate = *cpu->trace_dstate;
-tcg_ctx->tb_cflags = cflags;
 
 #ifdef CONFIG_PROFILER
 /* includes aborted translations because of exceptions */
@@ -1610,9 +1609,11 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
 
 tcg_func_start(tcg_ctx);
 
+tcg_ctx->tb = tb;
 tcg_ctx->cpu = ENV_GET_CPU(env);
 gen_intermediate_code(cpu, tb);
 tcg_ctx->cpu = NULL;
+tcg_ctx->tb = NULL;
 
 trace_translate_block(tb, tb->pc, tb->tc.ptr);
 
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 2a8bf90..32449d2 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -150,7 +150,7 @@ void tcg_gen_op6(TCGContext *ctx, TCGOpcode opc, TCGArg a1, 
TCGArg a2,
 
 void tcg_gen_mb(TCGBar mb_type)
 {
-if (tcg_ctx->tb_cflags & CF_PARALLEL) {
+if (tb_cflags(tcg_ctx->tb) & CF_PARALLEL) {
 tcg_gen_op1(tcg_ctx, INDEX_op_mb, mb_type);
 }
 }
@@ -2794,7 +2794,7 @@ void tcg_gen_atomic_cmpxchg_i32(TCGv_i32 retv, TCGv addr, 
TCGv_i32 cmpv,
 {
 memop = tcg_canonicalize_memop(memop, 0, 0);
 
-if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
+if (!(tb_cflags(tcg_ctx->tb) & CF_PARALLEL)) {
 TCGv_i32 t1 = tcg_temp_new_i32();
 TCGv_i32 t2 = tcg_temp_new_i32();
 
@@ -2838,7 +2838,7 @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64 retv, TCGv addr, 
TCGv_i64 cmpv,
 {
 memop = tcg_canonicalize_memop(memop, 1, 0);
 
-if (!(tcg_ctx->tb_cflags & CF_PARALLEL)) {
+if (!(tb_cflags(tcg_ctx->tb) & CF_PARALLEL)) {
 TCGv_i64 t1 = tcg_temp_new_i64();
 TCGv_i64 t2 = tcg_temp_new_i64();
 
@@ -3015,7 +3015,7 @@ static void * const table_##NAME[16] = {  
  \
 void tcg_gen_atomic_##NAME##_i32\
 (TCGv_i32 ret, TCGv addr, TCGv_i32 val, TCGArg idx, TCGMemOp memop) \
 {   \
-if (tcg_ctx->tb_cflags & CF_PARALLEL) { \
+if (tb_cflags(tcg_ctx->tb) & CF_PARALLEL) { \
 do_atomic_op_i32(ret, addr, val, idx, memop, table_##NAME); \
 } else {\
 do_nonatomic_op_i32(ret, addr, val, idx, memop, NEW,\
@@ -3025,7 +3025,7 @@ void tcg_gen_atomic_##NAME##_i32  
  \
 void tcg_gen_atomic_##NAME##_i64\
 (TCGv_i64 ret, TCGv addr, TCGv_i64 val, TCGArg idx, TCGMemOp memop) \
 {   \
-if (tcg_ctx->tb_cflags & CF_PARALLEL) { \
+if (tb_cflags(tcg_ctx->tb) & CF_PARALLEL) { \
 do_atomic_op_i64(ret, addr, val, idx, memop, table_##NAME); \
 } else {\
 do_nonatomic_op_i64(ret, addr, val, idx, memop, NEW,\
-- 
2.7.4




[Qemu-devel] [RFC 0/6] initial plugin support

2017-09-06 Thread Emilio G. Cota
Related threads:
  [PATCH 00/13] instrument: Add basic event instrumentation
  Date: Mon, 24 Jul 2017 20:02:24 +0300
  https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07419.html
and
  [PATCH v4 00/20] instrument: Add basic event instrumentation
  Date: Wed, 6 Sep 2017 20:22:41 +0300
  https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg07419.html

This set does something similar to the instrumentation patches by Lluis,
but with a different implementation (and for now less events).

My focus has been on working on the skeleton of a (pseudo) stable API,
as Stefan requested. Of course more events would have to be added, but
before spending more time on this I'd like to get some feedback on the
core of the design. Patch 2 has all the details.

Note: yes, patch 1 is not used in the series, but this is an RFC. It's there
because it will be needed to get the tb->plugin_mask when deciding whether
to generate a mem_cb helper when generating loads/stores from TCG.

This set applies on top of:
  https://github.com/cota/qemu/tree/tcg-generic-15%2Bmulti-tcg-v4-parallel

The tree can be fetched from:
  https://github.com/cota/qemu/tree/plugins

Thanks,

Emilio
---
 Makefile  |   7 +-
 Makefile.objs |   1 +
 accel/tcg/cpu-exec.c  |   6 +-
 accel/tcg/translate-all.c |   9 +-
 configure |  52 
 include/exec/exec-all.h   |   2 +
 include/exec/tb-hash-xx.h |  26 +-
 include/exec/tb-hash.h|   6 +-
 include/exec/tb-lookup.h  |   1 +
 include/qemu/plugin-api.h | 105 +++
 include/qemu/plugin.h |  74 +
 include/qom/cpu.h |   4 +
 linux-user/main.c |  18 ++
 plugin.c  | 519 
 qemu-options.hx   |  17 ++
 qemu-plugins.symbols  |   6 +
 qom/cpu.c |   3 +
 tcg/tcg-op.c  |  10 +-
 tcg/tcg.h |   2 +-
 tests/qht-bench.c |   2 +-
 vl.c  |  10 +
 21 files changed, 857 insertions(+), 23 deletions(-)



[Qemu-devel] [RFC 6/6] linux-user: support -plugin option

2017-09-06 Thread Emilio G. Cota
From: Lluís Vilanova 

Signed-off-by: Lluís Vilanova 
[ cota: s/instrument/plugin ]
Signed-off-by: Emilio G. Cota 
---
 linux-user/main.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 31c8f1a..211ee02 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -27,6 +27,7 @@
 #include "qemu/config-file.h"
 #include "qemu/cutils.h"
 #include "qemu/help_option.h"
+#include "qemu/plugin.h"
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "tcg.h"
@@ -4014,6 +4015,15 @@ static void handle_arg_trace(const char *arg)
 trace_file = trace_opt_parse(arg);
 }
 
+static struct qemu_plugin_list plugins = QTAILQ_HEAD_INITIALIZER(plugins);
+
+#ifdef CONFIG_PLUGINS
+static void handle_arg_plugin(const char *arg)
+{
+qemu_plugin_opt_parse(arg, &plugins);
+}
+#endif
+
 struct qemu_argument {
 const char *argv;
 const char *env;
@@ -4063,6 +4073,10 @@ static const struct qemu_argument arg_table[] = {
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
+#ifdef CONFIG_PLUGINS
+{"plugin", "QEMU_PLUGIN",  true,  handle_arg_plugin,
+ "",   "[file=][,arg=]"},
+#endif
 {"version","QEMU_VERSION", false, handle_arg_version,
  "",   "display version information and exit"},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -4252,6 +4266,7 @@ int main(int argc, char **argv, char **envp)
 srand(time(NULL));
 
 qemu_add_opts(&qemu_trace_opts);
+qemu_plugin_add_opts();
 
 optind = parse_args(argc, argv);
 
@@ -4259,6 +4274,9 @@ int main(int argc, char **argv, char **envp)
 exit(1);
 }
 trace_init_file(trace_file);
+if (qemu_plugin_load_list(&plugins)) {
+exit(1);
+}
 
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
-- 
2.7.4




[Qemu-devel] [RFC 4/6] Makefile: install qemu-api.h as include/qemu-plugin.h

2017-09-06 Thread Emilio G. Cota
Signed-off-by: Emilio G. Cota 
---
 Makefile | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index ef72148..326867e 100644
--- a/Makefile
+++ b/Makefile
@@ -602,8 +602,10 @@ ifneq (,$(findstring qemu-ga,$(TOOLS)))
 endif
 endif
 
+install-includedir:
+   $(INSTALL_DIR) "$(DESTDIR)$(includedir)"
 
-install: all $(if $(BUILD_DOCS),install-doc) install-datadir 
install-localstatedir
+install: all $(if $(BUILD_DOCS),install-doc) install-datadir 
install-localstatedir install-includedir
 ifneq ($(TOOLS),)
$(call install-prog,$(subst 
qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
 endif
@@ -626,6 +628,9 @@ endif
 ifeq ($(CONFIG_GTK),y)
$(MAKE) -C po $@
 endif
+ifeq ($(CONFIG_PLUGINS),y)
+   $(INSTALL_DATA) $(SRC_PATH)/include/qemu/plugin-api.h 
"$(DESTDIR)$(includedir)/qemu-plugin.h"
+endif
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/keymaps"
set -e; for x in $(KEYMAPS); do \
$(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x 
"$(DESTDIR)$(qemu_datadir)/keymaps"; \
-- 
2.7.4




Re: [Qemu-devel] [Qemu devel v7 PATCH 3/5] msf2: Add Smartfusion2 SPI controller

2017-09-06 Thread Alistair Francis
On Mon, Aug 28, 2017 at 9:38 AM, Subbaraya Sundeep
 wrote:
> Modelled Microsemi's Smartfusion2 SPI controller.
>
> Signed-off-by: Subbaraya Sundeep 
> ---
>  hw/ssi/Makefile.objs |   1 +
>  hw/ssi/mss-spi.c | 409 
> +++
>  include/hw/ssi/mss-spi.h |  58 +++
>  3 files changed, 468 insertions(+)
>  create mode 100644 hw/ssi/mss-spi.c
>  create mode 100644 include/hw/ssi/mss-spi.h
>
> diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
> index 487add2..f5bcc65 100644
> --- a/hw/ssi/Makefile.objs
> +++ b/hw/ssi/Makefile.objs
> @@ -4,6 +4,7 @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
>  common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
>  common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
>  common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
> +common-obj-$(CONFIG_MSF2) += mss-spi.o
>
>  obj-$(CONFIG_OMAP) += omap_spi.o
>  obj-$(CONFIG_IMX) += imx_spi.o
> diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
> new file mode 100644
> index 000..7209363
> --- /dev/null
> +++ b/hw/ssi/mss-spi.c
> @@ -0,0 +1,409 @@
> +/*
> + * Block model of SPI controller present in
> + * Microsemi's SmartFusion2 and SmartFusion SoCs.
> + *
> + * Copyright (C) 2017 Subbaraya Sundeep 
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
> + * of this software and associated documentation files (the "Software"), to 
> deal
> + * in the Software without restriction, including without limitation the 
> rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
> FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/ssi/mss-spi.h"
> +#include "qemu/log.h"
> +
> +#ifndef MSS_SPI_ERR_DEBUG
> +#define MSS_SPI_ERR_DEBUG   0
> +#endif
> +
> +#define DB_PRINT_L(lvl, fmt, args...) do { \
> +if (MSS_SPI_ERR_DEBUG >= lvl) { \
> +qemu_log("%s: " fmt "\n", __func__, ## args); \
> +} \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +#define FIFO_CAPACITY 32
> +#define FIFO_CAPACITY 32

Double define?

> +
> +#define R_SPI_CONTROL 0
> +#define R_SPI_DFSIZE  1
> +#define R_SPI_STATUS  2
> +#define R_SPI_INTCLR  3
> +#define R_SPI_RX  4
> +#define R_SPI_TX  5
> +#define R_SPI_CLKGEN  6
> +#define R_SPI_SS  7
> +#define R_SPI_MIS 8
> +#define R_SPI_RIS 9
> +
> +#define S_TXDONE (1 << 0)
> +#define S_RXRDY  (1 << 1)
> +#define S_RXCHOVRF   (1 << 2)
> +#define S_RXFIFOFUL  (1 << 4)
> +#define S_RXFIFOFULNXT   (1 << 5)
> +#define S_RXFIFOEMP  (1 << 6)
> +#define S_RXFIFOEMPNXT   (1 << 7)
> +#define S_TXFIFOFUL  (1 << 8)
> +#define S_TXFIFOFULNXT   (1 << 9)
> +#define S_TXFIFOEMP  (1 << 10)
> +#define S_TXFIFOEMPNXT   (1 << 11)
> +#define S_FRAMESTART (1 << 12)
> +#define S_SSEL   (1 << 13)
> +#define S_ACTIVE (1 << 14)
> +
> +#define C_ENABLE (1 << 0)
> +#define C_MODE   (1 << 1)
> +#define C_INTRXDATA  (1 << 4)
> +#define C_INTTXDATA  (1 << 5)
> +#define C_INTRXOVRFLO(1 << 6)
> +#define C_SPS(1 << 26)
> +#define C_BIGFIFO(1 << 29)
> +#define C_RESET  (1 << 31)
> +
> +#define FRAMESZ_MASK 0x1F
> +#define FMCOUNT_MASK 0x0000
> +#define FMCOUNT_SHIFT8
> +
> +static void txfifo_reset(MSSSpiState *s)
> +{
> +fifo32_reset(&s->tx_fifo);
> +
> +s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
> +s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
> +}
> +
> +static void rxfifo_reset(MSSSpiState *s)
> +{
> +fifo32_reset(&s->rx_fifo);
> +
> +s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
> +s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
> +}
> +
> +static void set_fifodepth(MSSSpiState *s)
> +{
> +unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
> +
> +if (size <= 8) {
> +s->fifo_depth = 32;
> +} else if (size <= 16) {
> +s->fifo_depth = 16;
> +} else if (size <= 32) {
> +s->fifo_depth = 8;
> +} else {
> +s->f

[Qemu-devel] [RFC 5/6] vl: support -plugin option

2017-09-06 Thread Emilio G. Cota
From: Lluís Vilanova 

Signed-off-by: Lluís Vilanova 
[ cota: s/instrument/plugin ]
Signed-off-by: Emilio G. Cota 
---
 vl.c| 10 ++
 qemu-options.hx | 17 +
 2 files changed, 27 insertions(+)

diff --git a/vl.c b/vl.c
index fb6b2ef..d3d8adc 100644
--- a/vl.c
+++ b/vl.c
@@ -118,6 +118,7 @@ int main(int argc, char **argv)
 
 #include "trace-root.h"
 #include "trace/control.h"
+#include "qemu/plugin.h"
 #include "qemu/queue.h"
 #include "sysemu/arch_init.h"
 
@@ -3031,6 +3032,7 @@ int main(int argc, char **argv, char **envp)
 } BlockdevOptions_queue;
 QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
 = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+struct qemu_plugin_list plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
 
 module_call_init(MODULE_INIT_TRACE);
 
@@ -3058,6 +3060,7 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(&qemu_global_opts);
 qemu_add_opts(&qemu_mon_opts);
 qemu_add_opts(&qemu_trace_opts);
+qemu_plugin_add_opts();
 qemu_add_opts(&qemu_option_rom_opts);
 qemu_add_opts(&qemu_machine_opts);
 qemu_add_opts(&qemu_accel_opts);
@@ -3999,6 +4002,9 @@ int main(int argc, char **argv, char **envp)
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
 break;
+case QEMU_OPTION_plugin:
+qemu_plugin_opt_parse(optarg, &plugin_list);
+break;
 case QEMU_OPTION_readconfig:
 {
 int ret = qemu_read_config_file(optarg);
@@ -4185,6 +4191,10 @@ int main(int argc, char **argv, char **envp)
 }
 trace_init_file(trace_file);
 
+if (qemu_plugin_load_list(&plugin_list)) {
+exit(1);
+}
+
 /* Open the logfile at this point and set the log mask if necessary.
  */
 if (log_file) {
diff --git a/qemu-options.hx b/qemu-options.hx
index 746b5fa..34557e6 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4064,6 +4064,23 @@ HXCOMM HX does not support conditional compilation of 
text.
 @findex -trace
 @include qemu-option-trace.texi
 ETEXI
+DEF("plugin", HAS_ARG, QEMU_OPTION_plugin,
+"-plugin [file=][,arg=]\n"
+"load a plugin\n",
+QEMU_ARCH_ALL)
+STEXI
+@item -plugin file=@var{file}[,arg=@var{string}]
+@findex -plugin
+
+Load a plugin.
+
+@table @option
+@item file=@var{file}
+Load the given plugin from a shared library file.
+@item arg=@var{string}
+Argument string passed to the plugin. (Can be given multiple times.)
+@end table
+ETEXI
 
 HXCOMM Internal use
 DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
-- 
2.7.4




[Qemu-devel] [RFC 3/6] configure: add --enable-plugins

2017-09-06 Thread Emilio G. Cota
For now only add it for ELF platforms, since we rely on the linker's
--dynamic-list flag to pass a list of symbols to be exported to the
executable. An alternative would be to use -rdynamic, but that would
expose all of QEMU's objects to plugins.

I have no experience with non-ELF systems but I suspect adding support
for those should be pretty easy.

Signed-off-by: Emilio G. Cota 
---
 configure | 52 
 1 file changed, 52 insertions(+)

diff --git a/configure b/configure
index 987f59b..45f7af5 100755
--- a/configure
+++ b/configure
@@ -30,6 +30,7 @@ TMPO="${TMPDIR1}/${TMPB}.o"
 TMPCXX="${TMPDIR1}/${TMPB}.cxx"
 TMPE="${TMPDIR1}/${TMPB}.exe"
 TMPMO="${TMPDIR1}/${TMPB}.mo"
+TMPTXT="${TMPDIR1}/${TMPB}.txt"
 
 rm -f config.log
 
@@ -404,6 +405,8 @@ tcmalloc="no"
 jemalloc="no"
 replication="yes"
 vxhs=""
+plugins="no"
+ld_dynamic_list="no"
 
 supported_cpu="no"
 supported_os="no"
@@ -1282,6 +1285,10 @@ for opt do
   ;;
   --enable-vxhs) vxhs="yes"
   ;;
+  --enable-plugins) plugins="yes"
+  ;;
+  --disable-plugins) plugins="no"
+  ;;
   *)
   echo "ERROR: unknown option $opt"
   echo "Try '$0 --help' for more information"
@@ -1442,6 +1449,8 @@ Advanced options (experts only):
xen pv domain builder
   --enable-debug-stack-usage
track the maximum stack usage of stacks created by 
qemu_alloc_stack
+  --enable-plugins
+   enable plugins via shared library loading
 
 Optional features, enabled with --enable-FEATURE and
 disabled with --disable-FEATURE, default is enabled if available:
@@ -4745,6 +4754,42 @@ if compile_prog "" "" ; then
   atomic64=yes
 fi
 
+#
+# See if --dynamic-list is supported by the linker
+
+cat > $TMPTXT < $TMPC <
+void foo(void);
+
+void foo(void)
+{
+  printf("foo\n");
+}
+
+int main(void)
+{
+  foo();
+  return 0;
+}
+EOF
+
+if compile_prog "" "-Wl,--dynamic-list=$TMPTXT" ; then
+  ld_dynamic_list="yes"
+else
+  if test "$plugins" = "yes" ; then
+error_exit \
+"Plugin support requires specifying a set of symbols that " \
+"are exported to plugins. Unfortunately your linker doesn't " \
+"support the flag (--dynamic-list) used for this purpose."
+  fi
+fi
+
 
 # check if getauxval is available.
 
@@ -5388,6 +5433,7 @@ echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
 echo "replication support $replication"
 echo "VxHS block device $vxhs"
+echo "plugin support$plugins"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -6053,6 +6099,12 @@ if test "$vxhs" = "yes" ; then
   echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
 fi
 
+if test "$plugins" = "yes" ; then
+echo "CONFIG_PLUGINS=y" >> $config_host_mak
+LIBS="-ldl $LIBS"
+LDFLAGS="-Wl,--dynamic-list=\$(SRC_PATH)/qemu-plugins.symbols $LDFLAGS"
+fi
+
 if test "$tcg_interpreter" = "yes"; then
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
 elif test "$ARCH" = "sparc64" ; then
-- 
2.7.4




Re: [Qemu-devel] [PATCH v6 11/29] libqtest: Inline qtest_query_target_endianness()

2017-09-06 Thread Eric Blake
On 09/05/2017 04:25 AM, Thomas Huth wrote:
> On 01.09.2017 20:03, Eric Blake wrote:
>> There was only one caller; it's easier to inline things.
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  tests/libqtest.c | 22 ++
>>  1 file changed, 6 insertions(+), 16 deletions(-)
>>

> 
> Ah, well, now that's another way of getting rid of the forward
> declaration in the previous patch - so may I suggest to drop the
> previous patch, and simply do the code inlining here instead?

Will do.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v6 01/29] tests: Improve .gitignore for tests/multiboot

2017-09-06 Thread Eric Blake
On 09/04/2017 09:03 AM, Thomas Huth wrote:
> On 01.09.2017 20:03, Eric Blake wrote:
>> Right now, tests/multiboot is not run by default during 'make check';
>> but when it is run in-tree, it was leaving some junk behind that could
>> accidentally get checked in with a careless 'git add tests'.
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  tests/.gitignore | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/tests/.gitignore b/tests/.gitignore
>> index fed0189a5a..64ecd6683b 100644
>> --- a/tests/.gitignore
>> +++ b/tests/.gitignore
>> @@ -10,6 +10,8 @@ check-qnull
>>  check-qstring
>>  check-qom-interface
>>  check-qom-proplist
>> +multiboot/test.out
> 
> Your patch is of course a good idea ... but that test.out smells quite
> bad ... I guess it should (a) use mktemp for a better file name instead
> so that we can run this in parallel and (b) clean up the temporary file
> once the test has been done?

Indeed, making multiboot better, and run by default under 'make check',
is a better task than just tweaking .gitignore, but one orthogonal
enough to my libqtest changes that I will save this patch (and 2/29) for
another series (or if someone else wants to tackle it first).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v7 06/22] migration: Improve migration thread error handling

2017-09-06 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> We now report errors also when we finish migration, not only on info
> migrate.  We plan to use this error from several places, and we want
> the first error to happen to win, so we add an mutex to order it.
> 
> Signed-off-by: Juan Quintela 

I think this is OK for errors from the migration code itself;
I'd prefer not to lost any multiplelayers of errors we get
from devices (e.g.we see an error about a particular bit, and then
see it's from a PCI device etc)

> diff --git a/migration/ram.c b/migration/ram.c
> index e18b3e2d4f..e0179fc838 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -1789,7 +1789,7 @@ int ram_discard_range(const char *rbname, uint64_t 
> start, size_t length)
>  RAMBlock *rb = qemu_ram_block_by_name(rbname);
>  
>  if (!rb) {
> -error_report("ram_discard_range: Failed to find block '%s'", rbname);
> +error_report("ram_discard_rang0e: Failed to find block '%s'", 
> rbname);

Typo!

Dave

>  goto err;
>  }
>  
> diff --git a/migration/tls.c b/migration/tls.c
> index 596e8790bd..026a008667 100644
> --- a/migration/tls.c
> +++ b/migration/tls.c
> @@ -119,7 +119,6 @@ static void migration_tls_outgoing_handshake(QIOTask 
> *task,
>  if (qio_task_propagate_error(task, &err)) {
>  trace_migration_tls_outgoing_handshake_error(error_get_pretty(err));
>  migrate_fd_error(s, err);
> -error_free(err);
>  } else {
>  trace_migration_tls_outgoing_handshake_complete();
>  migration_channel_connect(s, ioc, NULL);
> -- 
> 2.13.5
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCHv3 1/2] pci: move check for existing devfn into new pci_bus_devfn_available() helper

2017-09-06 Thread Mark Cave-Ayland
On 04/09/17 11:01, Yi Min Zhao wrote:

> I want to ask a question. According to the next patch, you check
> bus->devices[devfn]
> and reserved bit separately. Why not move the reserved bit check here?
> I think bus->devices[devfn] != NULL or revsered bit set means slot is
> unavailable.

Primarily it was to allow callers to distinguish between the two
different cases i.e. the error message can tell you that the reason the
slot was unavailable was because it was reserved, i.e. you can *never*
plug anything into it compared with unavailable where someone has
plugged something into the slot with -device but it could be later
removed, for example with hotplug.


ATB,

Mark.



[Qemu-devel] [PULL 7/8] snapshot/tests: Try loadvm twice

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

It's legal to loadvm twice, modify the existing save/loadvm test
to do it twice.

Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20170825141940.20740-3-dgilb...@redhat.com>
Reviewed-by: Peter Xu 
Signed-off-by: Dr. David Alan Gilbert 
---
 tests/qemu-iotests/068 | 2 +-
 tests/qemu-iotests/068.out | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index cfa0f2aed5..e7fca6a494 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -78,7 +78,7 @@ for extra_args in \
 # Give qemu some time to boot before saving the VM state
 { sleep 1; printf "savevm 0\nquit\n"; } | _qemu $extra_args
 # Now try to continue from that VM state (this should just work)
-echo quit | _qemu $extra_args -loadvm 0
+{ sleep 1; printf "loadvm 0\nloadvm 0\nquit\n"; } | _qemu $extra_args -S
 done
 
 # success, all done
diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out
index aa063cf711..f07a938a38 100644
--- a/tests/qemu-iotests/068.out
+++ b/tests/qemu-iotests/068.out
@@ -7,6 +7,8 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm 0
 (qemu) quit
 QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) loadvm 0
+(qemu) loadvm 0
 (qemu) quit
 
 === Saving and reloading a VM state to/from a qcow2 image (-object 
iothread,id=iothread0 -set device.hba0.iothread=iothread0) ===
@@ -16,5 +18,7 @@ QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) savevm 0
 (qemu) quit
 QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) loadvm 0
+(qemu) loadvm 0
 (qemu) quit
 *** done
-- 
2.13.5




[Qemu-devel] [PATCH] hw/ppc/spapr.c: cleaning up qdev_get_machine() calls

2017-09-06 Thread Daniel Henrique Barboza
This patch removes the qdev_get_machine() calls that are made in
spapr.c in situations where we can get an existing pointer for
the MachineState by either passing it as an argument to the function
or by using other already available pointers.

The following changes were made:

- spapr_node0_size: static function that is called two times:
at spapr_setup_hpt_and_vrma and ppc_spapr_init. In both cases we can
pass an existing MachineState pointer to it.

- spapr_build_fdt: MachineState pointer can be retrieved from
the existing sPAPRMachineState pointer.

- spapr_boot_set: the opaque in the first arg is a sPAPRMachineState
pointer as we can see inside ppc_spapr_init:

qemu_register_boot_set(spapr_boot_set, spapr);

We can get a MachineState pointer from it.

- spapr_machine_device_plug and spapr_machine_device_unplug_request: the
MachineState, sPAPRMachineState, MachineClass and sPAPRMachineClass pointers
can all be retrieved from the HotplugHandler pointer.

Signed-off-by: Daniel Henrique Barboza 
---
 hw/ppc/spapr.c | 19 +--
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cec441c..6ac3390 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -390,10 +390,8 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState 
*spapr)
 return ret;
 }
 
-static hwaddr spapr_node0_size(void)
+static hwaddr spapr_node0_size(MachineState *machine)
 {
-MachineState *machine = MACHINE(qdev_get_machine());
-
 if (nb_numa_nodes) {
 int i;
 for (i = 0; i < nb_numa_nodes; ++i) {
@@ -1027,7 +1025,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr,
  hwaddr rtas_addr,
  hwaddr rtas_size)
 {
-MachineState *machine = MACHINE(qdev_get_machine());
+MachineState *machine = MACHINE(spapr);
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);
 int ret;
@@ -1347,7 +1345,7 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr)
 spapr_reallocate_hpt(spapr, hpt_shift, &error_fatal);
 
 if (spapr->vrma_adjust) {
-spapr->rma_size = kvmppc_rma_size(spapr_node0_size(),
+spapr->rma_size = kvmppc_rma_size(spapr_node0_size(MACHINE(spapr)),
   spapr->htab_shift);
 }
 /* We're setting up a hash table, so that means we're not radix */
@@ -2007,7 +2005,7 @@ static SaveVMHandlers savevm_htab_handlers = {
 static void spapr_boot_set(void *opaque, const char *boot_device,
Error **errp)
 {
-MachineState *machine = MACHINE(qdev_get_machine());
+MachineState *machine = MACHINE(opaque);
 machine->boot_order = g_strdup(boot_device);
 }
 
@@ -2154,7 +2152,7 @@ static void ppc_spapr_init(MachineState *machine)
 MemoryRegion *rma_region;
 void *rma = NULL;
 hwaddr rma_alloc_size;
-hwaddr node0_size = spapr_node0_size();
+hwaddr node0_size = spapr_node0_size(machine);
 long load_limit, fw_size;
 char *filename;
 Error *resize_hpt_err = NULL;
@@ -3198,7 +3196,8 @@ out:
 static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
-sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine());
+MachineState *ms = MACHINE(hotplug_dev);
+sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 int node;
@@ -3247,8 +3246,8 @@ static void spapr_machine_device_plug(HotplugHandler 
*hotplug_dev,
 static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev,
 DeviceState *dev, Error **errp)
 {
-sPAPRMachineState *sms = SPAPR_MACHINE(qdev_get_machine());
-MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
+sPAPRMachineState *sms = SPAPR_MACHINE(OBJECT(hotplug_dev));
+MachineClass *mc = MACHINE_GET_CLASS(sms);
 
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 if (spapr_ovec_test(sms->ov5_cas, OV5_HP_EVT)) {
-- 
2.9.4




[Qemu-devel] [PULL 4/8] host-utils: Simplify pow2ceil()

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: Markus Armbruster 

Cc: Radim Krčmář 
Signed-off-by: Markus Armbruster 
Message-Id: <1501148776-16890-4-git-send-email-arm...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Dr. David Alan Gilbert 
---
 include/qemu/host-utils.h | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 6c6005f5cf..5ac621cf1f 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -381,18 +381,23 @@ static inline uint64_t pow2floor(uint64_t value)
 return 0x8000ull >> clz64(value);
 }
 
-/* round up to the nearest power of 2 (0 if overflow) */
+/*
+ * Return @value rounded up to the nearest power of two modulo 2^64.
+ * This is *zero* for @value > 2^63, so be careful.
+ */
 static inline uint64_t pow2ceil(uint64_t value)
 {
-uint8_t nlz = clz64(value);
-
-if (is_power_of_2(value)) {
-return value;
-}
-if (!nlz) {
-return 0;
+int n = clz64(value - 1);
+
+if (!n) {
+/*
+ * @value - 1 has no leading zeroes, thus @value - 1 >= 2^63
+ * Therefore, either @value == 0 or @value > 2^63.
+ * If it's 0, return 1, else return 0.
+ */
+return !value;
 }
-return 1ULL << (64 - nlz);
+return 0x8000ull >> (n - 1);
 }
 
 /**
-- 
2.13.5




[Qemu-devel] [PULL 6/8] migration: Reset rather than destroy main_thread_load_event

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

migration_incoming_state_destroy doesn't really destroy, it cleans up.
After a loadvm it's called, but the loadvm command can be run twice,
and so destroying an init-once mutex breaks on the second loadvm.

Reported-by: Stafford Horne 
Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20170825141940.20740-2-dgilb...@redhat.com>
Reviewed-by: Peter Xu 
Tested-by: Stafford Horne 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/migration.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/migration/migration.c b/migration/migration.c
index 1a2b3ebd1a..9838ccc885 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -166,7 +166,7 @@ void migration_incoming_state_destroy(void)
 mis->from_src_file = NULL;
 }
 
-qemu_event_destroy(&mis->main_thread_load_event);
+qemu_event_reset(&mis->main_thread_load_event);
 }
 
 static void migrate_generate_event(int new_state)
-- 
2.13.5




[Qemu-devel] [PATCH v4 20/20] instrument: Add API to manipulate guest memory

2017-09-06 Thread Lluís Vilanova
It includes access to the guest's memory and vCPU registers.

Signed-off-by: Lluís Vilanova 
---
 instrument/Makefile.objs  |1 
 instrument/qemu-instr/state.h |  104 +
 instrument/state.c|   72 
 3 files changed, 177 insertions(+)
 create mode 100644 instrument/qemu-instr/state.h
 create mode 100644 instrument/state.c

diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 8258dbfa79..c9bc4e75f4 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -6,3 +6,4 @@ target-obj-y += qmp.o
 
 target-obj-$(CONFIG_INSTRUMENT) += control.o
 target-obj-$(CONFIG_INSTRUMENT) += trace.o
+target-obj-$(CONFIG_INSTRUMENT) += state.o
diff --git a/instrument/qemu-instr/state.h b/instrument/qemu-instr/state.h
new file mode 100644
index 00..0ae6255fe5
--- /dev/null
+++ b/instrument/qemu-instr/state.h
@@ -0,0 +1,104 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * 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 QI__STATE_H
+#define QI__STATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include 
+
+
+/**
+ * qi_mem_read_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to read could be translated.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ *  modified.
+ *
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_virt:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Starting virtual address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of virtual addresses to write could be 
translated.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ *  modified.
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf);
+
+/**
+ * qi_mem_virt_to_phys:
+ * @vcpu: CPU to use for address translation.
+ * @vaddr: Virtual address to translate.
+ * @paddr: Pointer to output physical address.
+ *
+ * Translate a virtual address into a physical address.
+ *
+ * Returns: Whether the address could be translated.
+ */
+bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr);
+
+/**
+ * qi_mem_read_phys:
+ * @paddr: Starting physical address to read from.
+ * @size: Number of bytes to read.
+ * @buf: Buffer to write into.
+ *
+ * Read contents from physical memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination buffer might have been
+ *  modified.
+ * Precondition: The output buffer has at least "size" bytes.
+ */
+bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf);
+
+/**
+ * qi_mem_write_phys:
+ * @paddr: Starting physical address to write into.
+ * @size: Number of bytes to write.
+ * @buf: Buffer with the contents to write from.
+ *
+ * Write contents into virtual memory.
+ *
+ * Returns: Whether the range of physical addresses is valid.
+ *
+ * Warning: Even on error, some of the destination memory might have been
+ *  modified.
+ *
+ * Precondition: The input buffer has at least "size" bytes.
+ */
+bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* QI__STATE_H */
diff --git a/instrument/state.c b/instrument/state.c
new file mode 100644
index 00..4bf99b4882
--- /dev/null
+++ b/instrument/state.c
@@ -0,0 +1,72 @@
+/*
+ * Interface for accessing guest state.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/cpu-all.h"
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/qemu-instr/state.h"
+#include "instrument/qemu-instr/visibility.h"
+
+
+QI_VPUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr,
+ size_t size, void *buf)
+{
+CPUState *vcpu_ = instr_cpu_get(vcpu);
+ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentation");
+ERROR_IF_RET(!vcpu_, false, "invalid QICPU");
+return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 0) == 0;
+}
+
+QI_VPUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr,
+  size_t size, void *buf)
+{
+  

[Qemu-devel] [PULL 3/8] host-utils: Proactively fix pow2floor(), switch to unsigned

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: Markus Armbruster 

The function's stated contract is simple enough: "round down to the
nearest power of 2".  Suggests the domain is the representable numbers
>= 1, because that's the smallest power of two.

The implementation doesn't check for domain errors, but returns
garbage instead:

* For negative arguments, pow2floor() returns -2^63, which is not even
  a power of two, let alone the nearest one.

  What sort of works is passing *unsigned* arguments >= 2^63.  The
  implicit conversion to signed is implementation defined, but
  commonly yields the (negative) two's complement.  pow2floor() then
  returns -2^63.  Callers that convert that back to unsigned get the
  correct value 2^63.

* For a zero argument, pow2floor() shifts right by 64.  Undefined
  behavior.  Common actual behavior is to shift by 0, yielding -2^63.

Fix by switching from int64_t to uint64_t and amending the contract to
map zero to zero.

Callers are fine with that:

* memory_access_size()

  This function makes no sense unless the argument is positive and the
  return value fits into int.

* raw_refresh_limits()

  Passes an int between 1 and BDRV_REQUEST_MAX_BYTES.

* iscsi_refresh_limits()

  Passes an integer between 0 and INT_MAX, converts the result to
  uint32_t.  Passing zero would be undefined behavior, but commonly
  yield zero.  The patch gives us the zero without the undefined
  behavior.

* cache_init()

  Passes a positive int64_t argument.

* xbzrle_cache_resize()

  Passes a positive int64_t argument (>= TARGET_PAGE_SIZE, actually).

* spapr_node0_size()

  Passes a positive uint64_t argument, and converts the result to
  hwaddr, i.e. uint64_t.

* spapr_populate_memory()

  Passes a positive hwaddr argument, and converts the result to
  hwaddr.

Cc: Juan Quintela 
Cc: Dr. David Alan Gilbert 
Cc: Eric Blake 
Cc: Peter Maydell 
Cc: Alexey Kardashevskiy 
Signed-off-by: Markus Armbruster 
Message-Id: <1501148776-16890-3-git-send-email-arm...@redhat.com>
Reviewed-by: Eric Blake 
Signed-off-by: Dr. David Alan Gilbert 
---
 include/qemu/host-utils.h | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 95cf4f4163..6c6005f5cf 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -369,13 +369,16 @@ static inline bool is_power_of_2(uint64_t value)
 return !(value & (value - 1));
 }
 
-/* round down to the nearest power of 2*/
-static inline int64_t pow2floor(int64_t value)
+/**
+ * Return @value rounded down to the nearest power of two or zero.
+ */
+static inline uint64_t pow2floor(uint64_t value)
 {
-if (!is_power_of_2(value)) {
-value = 0x8000ULL >> clz64(value);
+if (!value) {
+/* Avoid undefined shift by 64 */
+return 0;
 }
-return value;
+return 0x8000ull >> clz64(value);
 }
 
 /* round up to the nearest power of 2 (0 if overflow) */
-- 
2.13.5




[Qemu-devel] [PULL 0/8] migration queue

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

The following changes since commit b07d1c2f5607489d4d4a6a65ce36a3e896ac065e:

  Revert "kvm: use DIV_ROUND_UP" (2017-09-05 18:55:40 +0100)

are available in the git repository at:

  git://github.com/dagrh/qemu.git tags/pull-migration-20170906a

for you to fetch changes up to a31fedeed764ce0b0d6097d4334c5770e74641a0:

  migration: dump str in migrate_set_state trace (2017-09-06 16:36:38 +0100)


migration pull 2017-09-06


Dr. David Alan Gilbert (4):
  migration: Report when bdrv_inactivate_all fails
  runstate/migrate: Two more transitions
  migration: Reset rather than destroy main_thread_load_event
  snapshot/tests: Try loadvm twice

Markus Armbruster (3):
  xbzrle: Drop unused cache_resize()
  host-utils: Proactively fix pow2floor(), switch to unsigned
  host-utils: Simplify pow2ceil()

Peter Xu (1):
  migration: dump str in migrate_set_state trace

 include/qemu/host-utils.h  | 36 +
 migration/migration.c  |  5 +++--
 migration/page_cache.c | 56 --
 migration/page_cache.h | 11 -
 migration/savevm.c |  2 ++
 migration/trace-events |  2 +-
 tests/qemu-iotests/068 |  2 +-
 tests/qemu-iotests/068.out |  4 
 vl.c   |  2 ++
 9 files changed, 35 insertions(+), 85 deletions(-)



[Qemu-devel] [PULL 5/8] runstate/migrate: Two more transitions

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

There's a race if someone does a 'stop' near the end of migrate;
the migration process goes through two runstates:
'finish migrate'
'postmigrate'

If the user issues a 'stop' between the two we end up with invalid
state transitions.
Add the transitions as valid.

Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20170804175011.21944-1-dgilb...@redhat.com>
Reviewed-by: Peter Xu 
Reviewed-by: Juan Quintela 
Signed-off-by: Dr. David Alan Gilbert 
---
 vl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/vl.c b/vl.c
index e75757f977..fb1f05b937 100644
--- a/vl.c
+++ b/vl.c
@@ -621,6 +621,7 @@ static const RunStateTransition runstate_transitions_def[] 
= {
 
 { RUN_STATE_PAUSED, RUN_STATE_RUNNING },
 { RUN_STATE_PAUSED, RUN_STATE_FINISH_MIGRATE },
+{ RUN_STATE_PAUSED, RUN_STATE_POSTMIGRATE },
 { RUN_STATE_PAUSED, RUN_STATE_PRELAUNCH },
 { RUN_STATE_PAUSED, RUN_STATE_COLO},
 
@@ -633,6 +634,7 @@ static const RunStateTransition runstate_transitions_def[] 
= {
 { RUN_STATE_PRELAUNCH, RUN_STATE_INMIGRATE },
 
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_RUNNING },
+{ RUN_STATE_FINISH_MIGRATE, RUN_STATE_PAUSED },
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_POSTMIGRATE },
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_PRELAUNCH },
 { RUN_STATE_FINISH_MIGRATE, RUN_STATE_COLO},
-- 
2.13.5




[Qemu-devel] [PULL 8/8] migration: dump str in migrate_set_state trace

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: Peter Xu 

Strings are more readable for debugging.

Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Peter Xu 
Message-Id: <1504081950-2528-5-git-send-email-pet...@redhat.com>
Signed-off-by: Dr. David Alan Gilbert 
  Fixed up merge with 977c73
---
 migration/migration.c  | 3 ++-
 migration/trace-events | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/migration/migration.c b/migration/migration.c
index 9838ccc885..959e8ec88e 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -913,8 +913,9 @@ void qmp_migrate_start_postcopy(Error **errp)
 
 void migrate_set_state(int *state, int old_state, int new_state)
 {
+assert(new_state < MIGRATION_STATUS__MAX);
 if (atomic_cmpxchg(state, old_state, new_state) == old_state) {
-trace_migrate_set_state(new_state);
+trace_migrate_set_state(MigrationStatus_str(new_state));
 migrate_generate_event(new_state);
 }
 }
diff --git a/migration/trace-events b/migration/trace-events
index 7a3b5144ff..d2910a6e7b 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -80,7 +80,7 @@ ram_save_queue_pages(const char *rbname, size_t start, size_t 
len) "%s: start: 0
 # migration/migration.c
 await_return_path_close_on_source_close(void) ""
 await_return_path_close_on_source_joining(void) ""
-migrate_set_state(int new_state) "new state %d"
+migrate_set_state(const char *new_state) "new state %s"
 migrate_fd_cleanup(void) ""
 migrate_fd_error(const char *error_desc) "error=%s"
 migrate_fd_cancel(void) ""
-- 
2.13.5




[Qemu-devel] [PULL 1/8] migration: Report when bdrv_inactivate_all fails

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

If the bdrv_inactivate_all fails near the end of the migration,
the migration will fail and often the only diagnostics in the log
are an I/O error which you can't distinguish from an error on
the socket connection.

Add an error so we know when it's actually a block problem.

Signed-off-by: Dr. David Alan Gilbert 
Message-Id: <20170822170212.27347-1-dgilb...@redhat.com>
Reviewed-by: Peter Xu 
Reviewed-by: Stefan Hajnoczi 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/savevm.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/migration/savevm.c b/migration/savevm.c
index fdd15fa0a7..7a55023d1a 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1157,6 +1157,8 @@ int qemu_savevm_state_complete_precopy(QEMUFile *f, bool 
iterable_only,
  * bdrv_invalidate_cache_all() on the other end won't fail. */
 ret = bdrv_inactivate_all();
 if (ret) {
+error_report("%s: bdrv_inactivate_all() failed (%d)",
+ __func__, ret);
 qemu_file_set_error(f, ret);
 return ret;
 }
-- 
2.13.5




[Qemu-devel] [PULL 2/8] xbzrle: Drop unused cache_resize()

2017-09-06 Thread Dr. David Alan Gilbert (git)
From: Markus Armbruster 

Unused since commit fd8cec XBZRLE: Fix qemu crash when resize the
xbzrle cache.

Cc: Juan Quintela 
Cc: "Dr. David Alan Gilbert" 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Eric Blake 
Reviewed-by: Amit Shah 
Reviewed-by: Juan Quintela 
Signed-off-by: Markus Armbruster 
Message-Id: <1501148776-16890-2-git-send-email-arm...@redhat.com>
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/page_cache.c | 56 --
 migration/page_cache.h | 11 --
 2 files changed, 67 deletions(-)

diff --git a/migration/page_cache.c b/migration/page_cache.c
index 5f8578736e..ba984c4858 100644
--- a/migration/page_cache.c
+++ b/migration/page_cache.c
@@ -178,59 +178,3 @@ int cache_insert(PageCache *cache, uint64_t addr, const 
uint8_t *pdata,
 
 return 0;
 }
-
-int64_t cache_resize(PageCache *cache, int64_t new_num_pages)
-{
-PageCache *new_cache;
-int64_t i;
-
-CacheItem *old_it, *new_it;
-
-g_assert(cache);
-
-/* cache was not inited */
-if (cache->page_cache == NULL) {
-return -1;
-}
-
-/* same size */
-if (pow2floor(new_num_pages) == cache->max_num_items) {
-return cache->max_num_items;
-}
-
-new_cache = cache_init(new_num_pages, cache->page_size);
-if (!(new_cache)) {
-DPRINTF("Error creating new cache\n");
-return -1;
-}
-
-/* move all data from old cache */
-for (i = 0; i < cache->max_num_items; i++) {
-old_it = &cache->page_cache[i];
-if (old_it->it_addr != -1) {
-/* check for collision, if there is, keep MRU page */
-new_it = cache_get_by_addr(new_cache, old_it->it_addr);
-if (new_it->it_data && new_it->it_age >= old_it->it_age) {
-/* keep the MRU page */
-g_free(old_it->it_data);
-} else {
-if (!new_it->it_data) {
-new_cache->num_items++;
-}
-g_free(new_it->it_data);
-new_it->it_data = old_it->it_data;
-new_it->it_age = old_it->it_age;
-new_it->it_addr = old_it->it_addr;
-}
-}
-}
-
-g_free(cache->page_cache);
-cache->page_cache = new_cache->page_cache;
-cache->max_num_items = new_cache->max_num_items;
-cache->num_items = new_cache->num_items;
-
-g_free(new_cache);
-
-return cache->max_num_items;
-}
diff --git a/migration/page_cache.h b/migration/page_cache.h
index 10ed53274c..4fadd0c501 100644
--- a/migration/page_cache.h
+++ b/migration/page_cache.h
@@ -72,15 +72,4 @@ uint8_t *get_cached_data(const PageCache *cache, uint64_t 
addr);
 int cache_insert(PageCache *cache, uint64_t addr, const uint8_t *pdata,
  uint64_t current_age);
 
-/**
- * cache_resize: resize the page cache. In case of size reduction the extra
- * pages will be freed
- *
- * Returns -1 on error new cache size on success
- *
- * @cache pointer to the PageCache struct
- * @num_pages: new page cache size (in pages)
- */
-int64_t cache_resize(PageCache *cache, int64_t num_pages);
-
 #endif
-- 
2.13.5




[Qemu-devel] [PATCH v4 19/20] instrument: Add event 'guest_user_syscall_ret'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/syscall.c  |3 +++
 instrument/control.c|   11 +++
 instrument/events.h |5 +
 instrument/events.inc.h |   13 +
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   13 +
 linux-user/syscall.c|1 +
 stubs/instrument.c  |2 ++
 8 files changed, 49 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 43f8887529..dcfb31f436 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -406,6 +406,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #endif
 if (do_strace)
 print_freebsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
@@ -483,6 +484,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 #endif
 if (do_strace)
 print_netbsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
@@ -560,6 +562,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #endif
 if (do_strace)
 print_openbsd_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
  efault:
diff --git a/instrument/control.c b/instrument/control.c
index 7e84dadf24..f8f368efb0 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -135,3 +135,14 @@ QI_VPUBLIC void qi_event_set_guest_user_syscall(
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_user_syscall, fn);
 }
+
+
+void (*instr_event__guest_user_syscall_ret)(
+QICPU vcpu, uint64_t num, uint64_t ret);
+
+QI_VPUBLIC void qi_event_set_guest_user_syscall_ret(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_user_syscall_ret, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 8c944e1f91..6197ece466 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -75,6 +75,11 @@ static inline void instr_guest_user_syscall(
 CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
 uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
 
+extern void (*instr_event__guest_user_syscall_ret)(
+QICPU vcpu, uint64_t num, uint64_t ret);
+static inline void instr_guest_user_syscall_ret(
+CPUState *vcpu, uint64_t num, uint64_t ret);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index 9c64497533..ca1d789cea 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -93,3 +93,16 @@ static inline void instr_guest_user_syscall(
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_user_syscall_ret(
+CPUState *vcpu, uint64_t num, uint64_t ret)
+{
+void (*cb)(QICPU vcpu, uint64_t num, uint64_t ret)
+= instr_get_event(guest_user_syscall_ret);
+if (cb) {
+instr_set_state(INSTR_STATE_ENABLE);
+QICPU vcpu_ = instr_cpu_set(vcpu);
+(*cb)(vcpu_, num, ret);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index d977049082..decd357105 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -154,6 +154,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
 instr_set_event(guest_mem_before_trans, NULL);
 instr_set_event(guest_mem_before_exec, NULL);
 instr_set_event(guest_user_syscall, NULL);
+instr_set_event(guest_user_syscall_ret, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index cba8ade54e..fd83c86c2b 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -149,6 +149,19 @@ void qi_event_set_guest_user_syscall(
uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
uint64_t arg7, uint64_t arg8));
 
+/*
+ * Finish executing a guest system call in syscall emulation mode.
+ *
+ * @num: System call number.
+ * @ret: System call result value.
+ *
+ * Mode: user
+ * Targets: TCG(all)
+ * Time: exec
+ */
+void qi_event_set_guest_user_syscall_ret(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c0c33d4a75..0f86b6935d 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -12397,6 +12397,7 @@ fail:
 #endif
 if(do_strace)
 print_syscall_ret(num, ret);
+instr_guest_user_syscall_ret(cpu, num, ret);
 trace_guest_user_syscall_ret(cpu, num, ret);
 return ret;
 efault:
diff --git a/s

[Qemu-devel] [PATCH v4 18/20] instrument: Add event 'guest_user_syscall'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/syscall.c  |3 +++
 instrument/control.c|   14 ++
 instrument/events.h |7 +++
 instrument/events.inc.h |   16 
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   15 +++
 linux-user/syscall.c|1 +
 stubs/instrument.c  |3 +++
 8 files changed, 60 insertions(+)

diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 3230f722f3..43f8887529 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -324,6 +324,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #ifdef DEBUG
 gemu_log("freebsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7, arg8);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 
arg7, arg8);
 if(do_strace)
 print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -423,6 +424,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 #ifdef DEBUG
 gemu_log("netbsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 if(do_strace)
 print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
@@ -499,6 +501,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 #ifdef DEBUG
 gemu_log("openbsd syscall %d\n", num);
 #endif
+instr_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6, 0, 
0);
 if(do_strace)
 print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6);
diff --git a/instrument/control.c b/instrument/control.c
index f39e81d7c7..7e84dadf24 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -121,3 +121,17 @@ QI_VPUBLIC void qi_event_set_guest_mem_before_exec(
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_mem_before_exec, fn);
 }
+
+
+void (*instr_event__guest_user_syscall)(
+QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
+QI_VPUBLIC void qi_event_set_guest_user_syscall(
+void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+   uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+   uint64_t arg7, uint64_t arg8))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_user_syscall, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 6507b26867..8c944e1f91 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -68,6 +68,13 @@ extern void (*instr_event__guest_mem_before_exec)(
 static inline void instr_guest_mem_before_exec(
 CPUState *vcpu, uint64_t vaddr, TraceMemInfo info);
 
+extern void (*instr_event__guest_user_syscall)(
+QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+static inline void instr_guest_user_syscall(
+CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index d7a3065ac1..9c64497533 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -77,3 +77,19 @@ static inline void instr_guest_mem_before_exec(
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_user_syscall(
+CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3,
+uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8)
+{
+void (*cb)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2,
+   uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6,
+   uint64_t arg7, uint64_t arg8)
+= instr_get_event(guest_user_syscall);
+if (cb) {
+instr_set_state(INSTR_STATE_ENABLE);
+QICPU vcpu_ = instr_cpu_set(vcpu);
+(*cb)(vcpu_, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index 1df660d5d1..d977049082 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -153,6 +153,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
 instr_set_event(guest_cpu_reset, NULL);
 instr_set_event(guest_mem_before_trans, NULL);
 instr_set_event(guest_mem_before_exec, NULL);
+instr_set_event(guest_user_syscall, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git

[Qemu-devel] [PATCH v4 17/20] instrument: Add event 'guest_mem_before_exec'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 include/exec/cpu_ldst_template.h  |4 +++
 include/exec/cpu_ldst_useronly_template.h |4 +++
 include/exec/helper-gen.h |1 +
 include/exec/helper-proto.h   |1 +
 include/exec/helper-tcg.h |1 +
 instrument/control.c  |   35 +
 instrument/control.h  |   15 
 instrument/events.h   |5 
 instrument/events.inc.h   |   18 ++-
 instrument/helpers.h  |1 +
 instrument/load.c |1 +
 instrument/qemu-instr/control.h   |   21 +
 stubs/instrument.c|2 ++
 13 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 instrument/helpers.h

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index debbabcfb2..8018e8b16a 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -28,6 +28,7 @@
 #include "trace-root.h"
 #endif
 
+#include "instrument/events.h"
 #include "trace/mem.h"
 
 #if DATA_SIZE == 8
@@ -89,6 +90,7 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
@@ -126,6 +128,7 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
@@ -167,6 +170,7 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 
 #if !defined(SOFTMMU_CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
diff --git a/include/exec/cpu_ldst_useronly_template.h 
b/include/exec/cpu_ldst_useronly_template.h
index b0b3fc1b8d..c36c50ae41 100644
--- a/include/exec/cpu_ldst_useronly_template.h
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -27,6 +27,7 @@
 #include "trace-root.h"
 #endif
 
+#include "instrument/events.h"
 #include "trace/mem.h"
 
 #if DATA_SIZE == 8
@@ -62,6 +63,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, 
false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
@@ -81,6 +83,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, true, MO_TE, false);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
@@ -102,6 +105,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr,
 {
 #if !defined(CODE_ACCESS)
 TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, true);
+instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo);
 trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
index 8239ffc77c..f351c3d050 100644
--- a/include/exec/helper-gen.h
+++ b/include/exec/helper-gen.h
@@ -57,6 +57,7 @@ static inline void glue(gen_helper_, 
name)(dh_retvar_decl(ret)  \
 }
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/generated-helpers.h"
 #include "trace/generated-helpers-wrappers.h"
 #include "tcg-runtime.h"
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
index 954bef85ce..8fdd02c132 100644
--- a/include/exec/helper-proto.h
+++ b/include/exec/helper-proto.h
@@ -27,6 +27,7 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), 
dh_ctype(t3), \
 dh_ctype(t4), dh_ctype(t5));
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/generated-helpers.h"
 #include "tcg-runtime.h"
 
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index b0c5bafa99..255e73c3e6 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -40,6 +40,7 @@
 | dh_sizemask(t5, 5) },
 
 #include "helper.h"
+#include "instrument/helpers.h"
 #include "trace/generated-helper

[Qemu-devel] [PATCH v4 16/20] instrument: Add event 'guest_mem_before_trans'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 Makefile.target |1 +
 instrument/control.c|   13 +++-
 instrument/control.h|   36 +-
 instrument/control.inc.h|   16 +++---
 instrument/events.h |   21 +
 instrument/events.inc.h |   19 
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   15 +
 instrument/qemu-instr/types.h   |   64 +++
 stubs/instrument.c  |4 ++
 tcg/tcg-op.c|5 +++
 trace/control.h |   23 ++
 trace/mem.h |   23 --
 13 files changed, 210 insertions(+), 31 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 7f42c45db8..6997b921c9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -196,6 +196,7 @@ $(QEMU_PROG_BUILD): config-devices.mak
 COMMON_LDADDS = ../libqemuutil.a ../libqemustub.a
 
 # build either PROG or PROGW
+$(QEMU_PROG_BUILD): CFLAGS += -DQEMU_TARGET_BUILD=1
 $(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS)
$(call LINK, $(filter-out %.mak, $^))
 ifdef CONFIG_DARWIN
diff --git a/instrument/control.c b/instrument/control.c
index 3cec1028e5..3c3875dc99 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -16,7 +16,7 @@
 #include "qom/cpu.h"
 
 
-__thread InstrState instr_cur_state;
+__thread InstrInfo instr_cur_info;
 
 
 unsigned int instr_cpus_count;
@@ -75,3 +75,14 @@ QI_VPUBLIC void qi_event_set_guest_cpu_reset(void 
(*fn)(QICPU vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_reset, fn);
 }
+
+
+void (*instr_event__guest_mem_before_trans)(
+QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info);
+
+QI_VPUBLIC void qi_event_set_guest_mem_before_trans(
+void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo 
info))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_mem_before_trans, fn);
+}
diff --git a/instrument/control.h b/instrument/control.h
index 0c37692465..d9e3dd3da6 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -56,12 +56,21 @@ typedef enum {
 INSTR_STATE_ENABLE,
 } InstrState;
 
+#define INSTR_MAX_TCG_REGS 16
+
+typedef struct InstrInfo {
+InstrState state;
+unsigned int max;
+void *tcg_regs[INSTR_MAX_TCG_REGS];
+} InstrInfo;
+
 /**
  * instr_set_state:
  *
- * Set the instrumentation state of the current host thread.
+ * Set the instrumentation state of the current host thread, and return its
+ * #InstrInfo.
  */
-static inline void instr_set_state(InstrState state);
+static inline InstrInfo *instr_set_state(InstrState state);
 
 /**
  * instr_get_state:
@@ -70,6 +79,29 @@ static inline void instr_set_state(InstrState state);
  */
 static inline InstrState instr_get_state(void);
 
+/**
+ * instr_tcg_set:
+ * @info: Pointer to #InstrInfo.
+ * @num: Number of TCG register used by instrumentation.
+ * @arg: TCG register.
+ *
+ * Get a suitable QITCGv* from a TCGv* value.
+ */
+#define instr_tcg_set(info, num, arg) \
+({\
+info->tcg_regs[num] = arg;\
+(void *)num;  \
+})
+
+/**
+ * instr_tcg_count:
+ * @info: Pointer to #InstrInfo.
+ * @count: Number of TCG registers used by instrumentation.
+ *
+ * Set the number of TCG registers used by instrumentation.
+ */
+static inline void instr_tcg_count(InstrInfo *info, unsigned int count);
+
 
 #include "instrument/control.inc.h"
 
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
index 18ae6a34cc..e8224319e0 100644
--- a/instrument/control.inc.h
+++ b/instrument/control.inc.h
@@ -15,16 +15,18 @@
 #include 
 
 
-extern __thread InstrState instr_cur_state;
+extern __thread InstrInfo instr_cur_info;
 
-static inline void instr_set_state(InstrState state)
+static inline InstrInfo *instr_set_state(InstrState state)
 {
-atomic_store_release(&instr_cur_state, state);
+InstrInfo *info = &instr_cur_info;
+atomic_store_release(&info->state, state);
+return info;
 }
 
 static inline InstrState instr_get_state(void)
 {
-return atomic_load_acquire(&instr_cur_state);
+return atomic_load_acquire(&instr_cur_info.state);
 }
 
 
@@ -46,3 +48,9 @@ static inline QICPU instr_cpu_set(CPUState *vcpu)
 uintptr_t idx = vcpu->cpu_index;
 return (QICPU )idx;
 }
+
+
+static inline void instr_tcg_count(InstrInfo *info, unsigned int count)
+{
+info->max = count;
+}
diff --git a/instrument/events.h b/instrument/events.h
index 4a0560490a..1cc4dbb052 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -12,6 +12,8 @@
 
 #include "instrument/qemu-instr/control.h"
 #include "instrument/qemu-instr/types.h"
+#include "trace/control.h"
+
 
 /**
  * instr_get_event:
@@ -30,6 +32,20 @@
 atomic_store_release(&instr_event__ ## name, fn)
 
 
+

[Qemu-devel] [PATCH v4 15/20] trace: Introduce a proper structure to describe memory accesses

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 include/exec/cpu_ldst_template.h  |   15 ++
 include/exec/cpu_ldst_useronly_template.h |   15 ++
 tcg/tcg-op.c  |   22 +
 trace/mem-internal.h  |   22 -
 trace/mem.h   |   31 +
 5 files changed, 66 insertions(+), 39 deletions(-)

diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index 4db2302962..debbabcfb2 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -88,9 +88,8 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, false, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
@@ -126,9 +125,8 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, true, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, true, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
@@ -168,9 +166,8 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), 
_ra)(CPUArchState *env,
 TCGMemOpIdx oi;
 
 #if !defined(SOFTMMU_CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(SHIFT, false, MO_TE, true));
+TraceMemInfo meminfo = trace_mem_build_info(SHIFT, false, MO_TE, true);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 
 addr = ptr;
diff --git a/include/exec/cpu_ldst_useronly_template.h 
b/include/exec/cpu_ldst_useronly_template.h
index 7b8c7c506e..b0b3fc1b8d 100644
--- a/include/exec/cpu_ldst_useronly_template.h
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -61,9 +61,8 @@ static inline RES_TYPE
 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, false, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, 
false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(ld, USUFFIX), _p)(g2h(ptr));
 }
@@ -81,9 +80,8 @@ static inline int
 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, true, MO_TE, false));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, true, MO_TE, false);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 return glue(glue(lds, SUFFIX), _p)(g2h(ptr));
 }
@@ -103,9 +101,8 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, 
target_ulong ptr,
   RES_TYPE v)
 {
 #if !defined(CODE_ACCESS)
-trace_guest_mem_before_exec(
-ENV_GET_CPU(env), ptr,
-trace_mem_build_info(DATA_SIZE, false, MO_TE, true));
+TraceMemInfo meminfo = trace_mem_build_info(DATA_SIZE, false, MO_TE, true);
+trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw);
 #endif
 glue(glue(st, SUFFIX), _p)(g2h(ptr), v);
 }
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 87f673ef49..234e300ede 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -2664,22 +2664,26 @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, 
TCGv addr,
 
 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
+TraceMemInfo meminfo;
 memop = tcg_canonicalize_memop(memop, 0, 0);
-trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-   addr, trace_mem_get_info(memop, 0));
+meminfo = trace_mem_get_info(memop, 0);
+trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, 
meminfo.raw);
 gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx);
 }
 
 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
+TraceMemInfo meminfo;
 memop = tcg_canonicalize_memop(memop, 0, 1);
-trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env,
-   addr, trace_mem_get_info(memop, 1));
+meminfo = trace_mem_get_info(memop, 1);
+trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, 
meminfo.raw);
 gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx);
 }
 
 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop)
 {
+TraceMemInfo meminfo;
+
 i

[Qemu-devel] [PATCHv2 0/1] net: Add SunGEM device emulation as found on Apple UniNorth

2017-09-06 Thread Mark Cave-Ayland
This is a reworking of Ben's original implementation of the SunGEM device
from last year: 
https://lists.gnu.org/archive/html/qemu-devel/2016-08/msg02571.html.

The reason for implenting this device is that it allows out-of-the-box
networking for most MacOS 9 and MacOS X OSs running under qemu-system-ppc 
without
having to obtain any external vendor drivers.

The main changes I've made to Ben's original patch are listed below:
- Remove sungem.h file, moving constants into sungem.c as required
- Switch to using tracepoints for debugging
- Split register blocks into separate memory regions
- Use arrays in SunGEMState to hold register values
- Add state-saving support

Signed-off-by: Mark Cave-Ayland 

v2
- Fix tracepoints for trace backends outside of QEMU
- Introduce PCI_BASE_ADDRESS_SPACE_MEMORY instead of using the value 0 directly


Benjamin Herrenschmidt (1):
  net: Add SunGEM device emulation as found on Apple UniNorth

 default-configs/ppc-softmmu.mak |1 +
 hw/net/Makefile.objs|1 +
 hw/net/sungem.c | 1447 +++
 hw/net/trace-events |   44 ++
 hw/pci/pci.c|2 +
 include/hw/pci/pci_ids.h|1 +
 6 files changed, 1496 insertions(+)
 create mode 100644 hw/net/sungem.c

-- 
1.7.10.4




[Qemu-devel] [PATCHv2 1/1] net: Add SunGEM device emulation as found on Apple UniNorth

2017-09-06 Thread Mark Cave-Ayland
From: Benjamin Herrenschmidt 

This adds a simplistic emulation of the Sun GEM ethernet controller
found in Apple ASICs.

Currently we only support the Apple UniNorth 1.x variant, but the
other Apple or Sun variants should mostly be a matter of adding
PCI IDs options.

We have a very primitive emulation of a single Broadcom 5201 PHY
which is supported by the MacOS driver.

This model brings out-of-the-box networking to MacOS 9, and all
versions of OS X I tried with the mac99 platform.

Further improvements from Mark:
- Remove sungem.h file, moving constants into sungem.c as required
- Switch to using tracepoints for debugging
- Split register blocks into separate memory regions
- Use arrays in SunGEMState to hold register values
- Add state-saving support

Signed-off-by: Benjamin Herrenschmidt 
Signed-off-by: Mark Cave-Ayland 
---
 default-configs/ppc-softmmu.mak |1 +
 hw/net/Makefile.objs|1 +
 hw/net/sungem.c | 1447 +++
 hw/net/trace-events |   44 ++
 hw/pci/pci.c|2 +
 include/hw/pci/pci_ids.h|1 +
 6 files changed, 1496 insertions(+)
 create mode 100644 hw/net/sungem.c

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 1f1cd85..c12ba9e 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -17,6 +17,7 @@ CONFIG_PREP_PCI=y
 CONFIG_I82378=y
 CONFIG_PC87312=y
 CONFIG_MACIO=y
+CONFIG_SUNGEM=y
 CONFIG_PCSPK=y
 CONFIG_CS4231A=y
 CONFIG_CUDA=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 5ddaffe..7e87d01 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -27,6 +27,7 @@ common-obj-$(CONFIG_CADENCE) += cadence_gem.o
 common-obj-$(CONFIG_STELLARIS_ENET) += stellaris_enet.o
 common-obj-$(CONFIG_LANCE) += lance.o
 common-obj-$(CONFIG_FTGMAC100) += ftgmac100.o
+common-obj-$(CONFIG_SUNGEM) += sungem.o
 
 obj-$(CONFIG_ETRAXFS) += etraxfs_eth.o
 obj-$(CONFIG_COLDFIRE) += mcf_fec.o
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
new file mode 100644
index 000..dffa0c9
--- /dev/null
+++ b/hw/net/sungem.c
@@ -0,0 +1,1447 @@
+/*
+ * QEMU model of SUN GEM ethernet controller
+ *
+ * As found in Apple ASICs among others
+ *
+ * Copyright 2016 Ben Herrenschmidt
+ * Copyright 2017 Mark Cave-Ayland
+ */
+
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "qemu/log.h"
+#include "net/net.h"
+#include "net/checksum.h"
+#include "hw/net/mii.h"
+#include "sysemu/sysemu.h"
+#include "trace.h"
+/* For crc32 */
+#include 
+
+#define TYPE_SUNGEM "sungem"
+
+#define SUNGEM(obj) OBJECT_CHECK(SunGEMState, (obj), TYPE_SUNGEM)
+
+#define MAX_PACKET_SIZE 9016
+
+#define SUNGEM_MMIO_SIZE0x20
+
+/* Global registers */
+#define SUNGEM_MMIO_GREG_SIZE   0x2000
+
+#define GREG_SEBSTATE 0xUL/* SEB State Register */
+
+#define GREG_STAT 0x000CUL/* Status Register */
+#define GREG_STAT_TXINTME 0x0001/* TX INTME frame transferred */
+#define GREG_STAT_TXALL   0x0002/* All TX frames transferred */
+#define GREG_STAT_TXDONE  0x0004/* One TX frame transferred */
+#define GREG_STAT_RXDONE  0x0010/* One RX frame arrived */
+#define GREG_STAT_RXNOBUF 0x0020/* No free RX buffers available */
+#define GREG_STAT_RXTAGERR0x0040/* RX tag framing is corrupt */
+#define GREG_STAT_TXMAC   0x4000/* TX MAC signalled interrupt */
+#define GREG_STAT_RXMAC   0x8000/* RX MAC signalled interrupt */
+#define GREG_STAT_MAC 0x0001/* MAC Control signalled irq */
+#define GREG_STAT_TXNR0xfff8/* == TXDMA_TXDONE reg val */
+#define GREG_STAT_TXNR_SHIFT  19
+
+/* These interrupts are edge latches in the status register,
+ * reading it (or writing the corresponding bit in IACK) will
+ * clear them
+ */
+#define GREG_STAT_LATCH   (GREG_STAT_TXALL  | GREG_STAT_TXINTME | \
+   GREG_STAT_RXDONE | GREG_STAT_RXDONE |  \
+   GREG_STAT_RXNOBUF | GREG_STAT_RXTAGERR)
+
+#define GREG_IMASK0x0010UL/* Interrupt Mask Register */
+#define GREG_IACK 0x0014UL/* Interrupt ACK Register */
+#define GREG_STAT20x001CUL/* Alias of GREG_STAT */
+#define GREG_PCIESTAT 0x1000UL/* PCI Error Status Register */
+#define GREG_PCIEMASK 0x1004UL/* PCI Error Mask Register */
+
+#define GREG_SWRST0x1010UL/* Software Reset Register */
+#define GREG_SWRST_TXRST  0x0001/* TX Software Reset */
+#define GREG_SWRST_RXRST  0x0002/* RX Software Reset */
+#define GREG_SWRST_RSTOUT 0x0004/* Force RST# pin active */
+
+/* TX DMA Registers */
+#define SUNGEM_MMIO_TXDMA_SIZE   0x1000
+
+#define TXDMA_KICK0xUL/* TX Kick Register */
+
+#define TXDMA_CFG 0x0004UL/* TX Configuration Register */
+#define TXDMA_CFG_ENABLE  0x0001/* Enable TX DMA channel

[Qemu-devel] [PATCH v4 14/20] instrument: Add event 'guest_cpu_reset'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 +
 instrument/events.h |3 +++
 instrument/events.inc.h |   11 +++
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |9 +
 qom/cpu.c   |2 ++
 stubs/instrument.c  |1 +
 7 files changed, 36 insertions(+)

diff --git a/instrument/control.c b/instrument/control.c
index 09ba682483..3cec1028e5 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -66,3 +66,12 @@ QI_VPUBLIC void qi_event_set_guest_cpu_exit(void (*fn)(QICPU 
vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_exit, fn);
 }
+
+
+void (*instr_event__guest_cpu_reset)(QICPU vcpu);
+
+QI_VPUBLIC void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_reset, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index c743cb8180..4a0560490a 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -39,6 +39,9 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu);
 extern void (*instr_event__guest_cpu_exit)(QICPU vcpu);
 static inline void instr_guest_cpu_exit(CPUState *vcpu);
 
+extern void (*instr_event__guest_cpu_reset)(QICPU vcpu);
+static inline void instr_guest_cpu_reset(CPUState *vcpu);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index bcbf0cb32a..2f2cd324aa 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -31,3 +31,14 @@ static inline void instr_guest_cpu_exit(CPUState *vcpu)
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_cpu_reset(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_reset);
+if (cb) {
+QICPU vcpu_ = instr_cpu_set(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index 63b7d564ec..d9310d1979 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -150,6 +150,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
 instr_set_event(fini_fn, NULL);
 instr_set_event(guest_cpu_enter, NULL);
 instr_set_event(guest_cpu_exit, NULL);
+instr_set_event(guest_cpu_reset, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index c37a380ab0..238ea63301 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -89,6 +89,15 @@ void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
  */
 void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu));
 
+/*
+ * Reset the state of a virtual (guest) CPU.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/qom/cpu.c b/qom/cpu.c
index 4f38db0dac..d09cf583eb 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -19,6 +19,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "instrument/events.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "qom/cpu.h"
@@ -271,6 +272,7 @@ void cpu_reset(CPUState *cpu)
 (*klass->reset)(cpu);
 }
 
+instr_guest_cpu_reset(cpu);
 trace_guest_cpu_reset(cpu);
 }
 
diff --git a/stubs/instrument.c b/stubs/instrument.c
index ea8df6d467..74935975da 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -13,3 +13,4 @@
 __thread InstrState instr_cur_state;
 void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
 void (*instr_event__guest_cpu_exit)(QICPU *vcpu);
+void (*instr_event__guest_cpu_reset)(QICPU *vcpu);




Re: [Qemu-devel] [PATCH v2 11/19] s390x: allow only 1 CPU with TCG

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> Specifying more than 1 CPU (e.g. -smp 5) leads to SIGP errors (the
> guest tries to bring these CPUs up but fails), because we don't support
> multiple CPUs on s390x under TCG.
> 
> Let's bail out if more than 1 is specified, so we don't raise people's
> hope. Make it a define, so we can easily bump it up later.
> 
> Signed-off-by: David Hildenbrand 
> ---

Makes sense.  Ran the described environment without this patch (errors)
and again with this patch (graceful exit w/ message).

Tested-by: Matthew Rosato 

>  hw/s390x/s390-virtio-ccw.c | 7 +++
>  target/s390x/cpu.h | 2 ++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index f67b4b5d58..f7ca20d77a 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -23,6 +23,7 @@
>  #include "hw/s390x/css.h"
>  #include "virtio-ccw.h"
>  #include "qemu/config-file.h"
> +#include "qemu/error-report.h"
>  #include "s390-pci-bus.h"
>  #include "hw/s390x/storage-keys.h"
>  #include "hw/s390x/storage-attributes.h"
> @@ -55,6 +56,12 @@ static void s390_init_cpus(MachineState *machine)
>  if (machine->cpu_model == NULL) {
>  machine->cpu_model = s390_default_cpu_model_name();
>  }
> +if (tcg_enabled() && max_cpus > S390_TCG_MAX_CPUS) {
> +error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
> + "supported by TCG (%d) on s390x", max_cpus,
> + S390_TCG_MAX_CPUS);
> +exit(1);
> +}
> 
>  cpu_states = g_new0(S390CPU *, max_cpus);
> 
> diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h
> index 147aceba28..dca6aa9aae 100644
> --- a/target/s390x/cpu.h
> +++ b/target/s390x/cpu.h
> @@ -209,6 +209,8 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState 
> *env)
> 
>  #define ENV_OFFSET offsetof(S390CPU, env)
> 
> +#define S390_TCG_MAX_CPUS 1
> +
>  #ifndef CONFIG_USER_ONLY
>  extern const struct VMStateDescription vmstate_s390_cpu;
>  #endif
> 




[Qemu-devel] [PATCH v4 13/20] instrument: Add event 'guest_cpu_exit'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 +
 instrument/events.h |3 +++
 instrument/events.inc.h |   11 +++
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |9 +
 stubs/instrument.c  |1 +
 trace/control.c |4 +++-
 7 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/instrument/control.c b/instrument/control.c
index ed0d537b88..09ba682483 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -57,3 +57,12 @@ QI_VPUBLIC void qi_event_set_guest_cpu_enter(void 
(*fn)(QICPU vcpu))
 ERROR_IF(!instr_get_state(), "called outside instrumentation");
 instr_set_event(guest_cpu_enter, fn);
 }
+
+
+void (*instr_event__guest_cpu_exit)(QICPU vcpu);
+
+QI_VPUBLIC void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_exit, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 947f120aa9..c743cb8180 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -36,6 +36,9 @@ extern void *instr_event__fini_data;
 extern void (*instr_event__guest_cpu_enter)(QICPU vcpu);
 static inline void instr_guest_cpu_enter(CPUState *vcpu);
 
+extern void (*instr_event__guest_cpu_exit)(QICPU vcpu);
+static inline void instr_guest_cpu_exit(CPUState *vcpu);
+
 
 #include "instrument/events.inc.h"
 
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index 238cce9855..bcbf0cb32a 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -20,3 +20,14 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu)
 instr_set_state(INSTR_STATE_DISABLE);
 }
 }
+
+static inline void instr_guest_cpu_exit(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_exit);
+if (cb) {
+QICPU vcpu_ = instr_cpu_set(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index 0fe878afa8..63b7d564ec 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -149,6 +149,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
 
 instr_set_event(fini_fn, NULL);
 instr_set_event(guest_cpu_enter, NULL);
+instr_set_event(guest_cpu_exit, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index 26d8aa976d..c37a380ab0 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -80,6 +80,15 @@ void qi_set_fini(qi_fini_fn fn, void *data);
  */
 void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
 
+/*
+ * Hot-unplug a virtual (guest) CPU.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/stubs/instrument.c b/stubs/instrument.c
index 658a872e1c..ea8df6d467 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -12,3 +12,4 @@
 
 __thread InstrState instr_cur_state;
 void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
+void (*instr_event__guest_cpu_exit)(QICPU *vcpu);
diff --git a/trace/control.c b/trace/control.c
index 82d8989c4d..946a0af818 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -1,13 +1,14 @@
 /*
  * Interface for configuring and controlling the state of tracing events.
  *
- * Copyright (C) 2011-2016 Lluís Vilanova 
+ * Copyright (C) 2011-2017 Lluís Vilanova 
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
  */
 
 #include "qemu/osdep.h"
+#include "instrument/events.h"
 #include "trace/control.h"
 #include "qemu/help_option.h"
 #ifdef CONFIG_TRACE_SIMPLE
@@ -272,6 +273,7 @@ void trace_fini_vcpu(CPUState *vcpu)
 TraceEventIter iter;
 TraceEvent *ev;
 
+instr_guest_cpu_exit(vcpu);
 trace_guest_cpu_exit(vcpu);
 
 trace_event_iter_init(&iter, NULL);




Re: [Qemu-devel] [PATCH v2 17/19] s390x: CPU hot unplug via device_del cannot work

2017-09-06 Thread Matthew Rosato
On 09/04/2017 11:43 AM, David Hildenbrand wrote:
> device_del on a CPU will currently do nothing. Let's emmit an error
> telling that this is will never work (there is no architecture support
> on s390x). Error message copied from ppc.
> 
> (qemu) device_del cpu1
> device_del cpu1
> CPU hot unplug not supported on this machine
> 
> Signed-off-by: David Hildenbrand 

Architecture discussions aside, this code will work as-is to prevent CPU
unplug.  Add "currently" as Christian suggests and:

Reviewed-by: Matthew Rosato 

> ---
>  hw/s390x/s390-virtio-ccw.c | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 22a8a1b45d..dd149567bb 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -338,6 +338,15 @@ static void s390_machine_device_plug(HotplugHandler 
> *hotplug_dev,
>  }
>  }
> 
> +static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
> +   DeviceState *dev, Error 
> **errp)
> +{
> +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> +error_setg(errp, "CPU hot unplug not supported on this machine");
> +return;
> +}
> +}
> +
>  static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
>  DeviceState *dev)
>  {
> @@ -387,6 +396,7 @@ static void ccw_machine_class_init(ObjectClass *oc, void 
> *data)
>  mc->max_cpus = 248;
>  mc->get_hotplug_handler = s390_get_hotplug_handler;
>  hc->plug = s390_machine_device_plug;
> +hc->unplug_request = s390_machine_device_unplug_request;
>  nc->nmi_monitor_handler = s390_nmi;
>  }
> 




[Qemu-devel] [PATCH v4 12/20] instrument: Add event 'guest_cpu_enter'

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/control.c|9 
 instrument/events.h |5 
 instrument/events.inc.h |   11 ++
 instrument/load.c   |1 +
 instrument/qemu-instr/control.h |   44 +++
 stubs/instrument.c  |1 +
 trace/control-target.c  |2 ++
 7 files changed, 73 insertions(+)

diff --git a/instrument/control.c b/instrument/control.c
index 83453ea561..ed0d537b88 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -48,3 +48,12 @@ QI_VPUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
 instr_set_event(fini_fn, fn);
 instr_set_event(fini_data, data);
 }
+
+
+void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+
+QI_VPUBLIC void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu))
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(guest_cpu_enter, fn);
+}
diff --git a/instrument/events.h b/instrument/events.h
index 82ad0bd827..947f120aa9 100644
--- a/instrument/events.h
+++ b/instrument/events.h
@@ -11,6 +11,7 @@
 #define INSTRUMENT__EVENTS_H
 
 #include "instrument/qemu-instr/control.h"
+#include "instrument/qemu-instr/types.h"
 
 /**
  * instr_get_event:
@@ -32,6 +33,10 @@
 extern qi_fini_fn instr_event__fini_fn;
 extern void *instr_event__fini_data;
 
+extern void (*instr_event__guest_cpu_enter)(QICPU vcpu);
+static inline void instr_guest_cpu_enter(CPUState *vcpu);
+
+
 #include "instrument/events.inc.h"
 
 #endif  /* INSTRUMENT__EVENTS_H */
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
index 8b1ce7fcb2..238cce9855 100644
--- a/instrument/events.inc.h
+++ b/instrument/events.inc.h
@@ -7,5 +7,16 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include "instrument/control.h"
 
 
+static inline void instr_guest_cpu_enter(CPUState *vcpu)
+{
+void (*cb)(QICPU vcpu) = instr_get_event(guest_cpu_enter);
+if (cb) {
+QICPU vcpu_ = instr_cpu_set(vcpu);
+instr_set_state(INSTR_STATE_ENABLE);
+(*cb)(vcpu_);
+instr_set_state(INSTR_STATE_DISABLE);
+}
+}
diff --git a/instrument/load.c b/instrument/load.c
index e180f03429..0fe878afa8 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -148,6 +148,7 @@ InstrUnloadError instr_unload(int64_t handle_id)
 }
 
 instr_set_event(fini_fn, NULL);
+instr_set_event(guest_cpu_enter, NULL);
 
 /* this should never fail */
 if (dlclose(handle->dlhandle) < 0) {
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index f6e289daa0..26d8aa976d 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -16,6 +16,7 @@ extern "C" {
 
 #include 
 #include 
+#include 
 
 
 /**
@@ -36,6 +37,49 @@ typedef void (*qi_fini_fn)(void *arg);
  */
 void qi_set_fini(qi_fini_fn fn, void *data);
 
+
+/*
+ * Set callbacks for available events. Each event has a short description and
+ * various indicators of when it can be triggered:
+ *
+ * - Mode :: user
+ *   Triggered in QEMU user application emulation (e.g., linux-user).
+ *
+ * - Mode :: softmmy
+ *   Triggered in QEMU full-system emulation.
+ *
+ *
+ * - Targets :: all
+ *   Triggered on all targets, both using TCG or native hardware virtualization
+ *   (e.g., KVM).
+ *
+ * - Targets :: TCG()
+ *   Triggered on the given guest target architectures when executing with TCG
+ *   (no native hardware virtualization).
+ *
+ *
+ * - Time :: exec
+ *   Triggered when the guest executes the described operation.
+ *
+ * - Time :: trans
+ *   Triggered when QEMU translates a guest operation. This is only available
+ *   when executing with TCG. Guest instructions are decompiled and translated
+ *   into the intermediate TCG language (when "Time: trans" events are
+ *   triggered). Then, the TCG compiler translates TCG code into the native 
host
+ *   code that QEMU will execute to emulate the guest (when "Time: exec" events
+ *   are triggered). As QEMU uses a cache of translated code, the same
+ *   instruction might be translated more than once (when the cache overflows).
+ */
+
+/*
+ * Hot-plug a new virtual (guest) CPU.
+ *
+ * Mode: user, softmmu
+ * Targets: all
+ * Time: exec
+ */
+void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu));
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/stubs/instrument.c b/stubs/instrument.c
index 6731710fd5..658a872e1c 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -11,3 +11,4 @@
 
 
 __thread InstrState instr_cur_state;
+void (*instr_event__guest_cpu_enter)(QICPU *vcpu);
diff --git a/trace/control-target.c b/trace/control-target.c
index 0056da6a46..e47361cef8 100644
--- a/trace/control-target.c
+++ b/trace/control-target.c
@@ -9,6 +9,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "instrument/events.h"
 #include "trace-root.h"
 #include "trace/control.h"
 #include "translate-all.h"
@@ -147,5 +148,6 @@ void trace_init_vcpu(CPUState *vcpu)
 

Re: [Qemu-devel] [PATCH] target/alpha: Switch to do_transaction_failed() hook

2017-09-06 Thread Richard Henderson
On 09/05/2017 08:54 AM, Peter Maydell wrote:
> On 8 August 2017 at 13:42, Peter Maydell  wrote:
>> Switch the alpha target from the old unassigned_access hook
>> to the new do_transaction_failed hook. This allows us to
>> resolve a ??? in the old hook implementation.
>>
>> The only part of the alpha target that does physical
>> memory accesses is reading the page table -- add a
>> TODO comment there to the effect that we should handle
>> bus faults on page table walks. (Since the palcode
>> doesn't actually do anything useful on a bus fault anyway
>> it's a bit moot for now.)
>>
>> Signed-off-by: Peter Maydell 
>> ---
>> Based-on: 1501867249-1924-1-git-send-email-peter.mayd...@linaro.org
>> This patch sits on top of the series adding the new hook.
> 
> The prerequisites for this patch are now all in git master.

Thanks.  Queued to tgt-axp.


r~




[Qemu-devel] [PATCH v4 11/20] instrument: Track vCPUs

2017-09-06 Thread Lluís Vilanova
Keep a translation between instrumentation's QICPU and CPUState objects to avoid
exposing QEMU's internals to instrumentation clients.

Signed-off-by: Lluís Vilanova 
---
 cpus-common.c|9 +
 instrument/control.c |   22 ++
 instrument/control.h |   32 
 instrument/control.inc.h |   23 +++
 4 files changed, 86 insertions(+)

diff --git a/cpus-common.c b/cpus-common.c
index 59f751ecf9..ec5f46cc3d 100644
--- a/cpus-common.c
+++ b/cpus-common.c
@@ -22,6 +22,9 @@
 #include "exec/cpu-common.h"
 #include "qom/cpu.h"
 #include "sysemu/cpus.h"
+#if defined(CONFIG_INSTRUMENT)
+#include "instrument/control.h"
+#endif
 
 static QemuMutex qemu_cpu_list_lock;
 static QemuCond exclusive_cond;
@@ -84,6 +87,9 @@ void cpu_list_add(CPUState *cpu)
 } else {
 assert(!cpu_index_auto_assigned);
 }
+#if defined(CONFIG_INSTRUMENT)
+instr_cpu_add(cpu);
+#endif
 QTAILQ_INSERT_TAIL(&cpus, cpu, node);
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 
@@ -102,6 +108,9 @@ void cpu_list_remove(CPUState *cpu)
 assert(!(cpu_index_auto_assigned && cpu != QTAILQ_LAST(&cpus, CPUTailQ)));
 
 QTAILQ_REMOVE(&cpus, cpu, node);
+#if defined(CONFIG_INSTRUMENT)
+instr_cpu_remove(cpu);
+#endif
 cpu->cpu_index = UNASSIGNED_CPU_INDEX;
 qemu_mutex_unlock(&qemu_cpu_list_lock);
 }
diff --git a/instrument/control.c b/instrument/control.c
index 2c2781beeb..83453ea561 100644
--- a/instrument/control.c
+++ b/instrument/control.c
@@ -13,10 +13,32 @@
 #include "instrument/load.h"
 #include "instrument/qemu-instr/control.h"
 #include "instrument/qemu-instr/visibility.h"
+#include "qom/cpu.h"
+
 
 __thread InstrState instr_cur_state;
 
 
+unsigned int instr_cpus_count;
+CPUState **instr_cpus;
+
+void instr_cpu_add(CPUState *vcpu)
+{
+unsigned int idx = vcpu->cpu_index;
+if (idx >= instr_cpus_count) {
+instr_cpus_count = idx + 1;
+instr_cpus = realloc(instr_cpus, sizeof(*instr_cpus) * 
instr_cpus_count);
+}
+instr_cpus[idx] = vcpu;
+}
+
+void instr_cpu_remove(CPUState *vcpu)
+{
+unsigned int idx = vcpu->cpu_index;
+instr_cpus[idx] = NULL;
+}
+
+
 qi_fini_fn instr_event__fini_fn;
 void *instr_event__fini_data;
 
diff --git a/instrument/control.h b/instrument/control.h
index f2b085f69b..0c37692465 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -10,6 +10,38 @@
 #ifndef INSTRUMENT__CONTROL_H
 #define INSTRUMENT__CONTROL_H
 
+#include "qemu/typedefs.h"
+#include "instrument/qemu-instr/types.h"
+
+
+/**
+ * instr_cpu_add:
+ *
+ * Make @vcpu available to instrumentation clients.
+ */
+void instr_cpu_add(CPUState *vcpu);
+
+/**
+ * instr_cpu_remove:
+ *
+ * Make @vcpu unavailable to instrumentation clients.
+ */
+void instr_cpu_remove(CPUState *vcpu);
+
+/**
+ * instr_cpu_get:
+ *
+ * Get the #CPUState corresponding to the given #QICPU.
+ */
+static inline CPUState *instr_cpu_get(QICPU vcpu);
+
+/**
+ * instr_cpu_set:
+ *
+ * Get the #QICPU corresponding to the given #CPUState.
+ */
+static inline QICPU instr_cpu_set(CPUState *vcpu);
+
 
 /**
  * InstrState:
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
index 0f649f4caa..18ae6a34cc 100644
--- a/instrument/control.inc.h
+++ b/instrument/control.inc.h
@@ -7,9 +7,12 @@
  * See the COPYING file in the top-level directory.
  */
 
+#include "qemu/osdep.h"
 #include "qemu/atomic.h"
 #include "qemu/compiler.h"
+#include "qom/cpu.h"
 #include 
+#include 
 
 
 extern __thread InstrState instr_cur_state;
@@ -23,3 +26,23 @@ static inline InstrState instr_get_state(void)
 {
 return atomic_load_acquire(&instr_cur_state);
 }
+
+
+extern unsigned int instr_cpus_count;
+extern CPUState **instr_cpus;
+
+static inline CPUState *instr_cpu_get(QICPU vcpu)
+{
+unsigned int idx = (uintptr_t)vcpu;
+if (idx >= instr_cpus_count) {
+return NULL;
+} else {
+return instr_cpus[idx];
+}
+}
+
+static inline QICPU instr_cpu_set(CPUState *vcpu)
+{
+uintptr_t idx = vcpu->cpu_index;
+return (QICPU )idx;
+}




Re: [Qemu-devel] [PATCH v1 2/2] io: include full error message in websocket handshake trace

2017-09-06 Thread Philippe Mathieu-Daudé

On 09/06/2017 07:40 AM, Daniel P. Berrange wrote:

When the websocket handshake fails it is useful to log the real
error message via the trace points for debugging purposes.

Fixes bug: #1715186

Signed-off-by: Daniel P. Berrange 


Reviewed-by: Philippe Mathieu-Daudé 


---
  io/channel-websock.c | 7 ---
  io/trace-events  | 2 +-
  2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/io/channel-websock.c b/io/channel-websock.c
index b9cc5a1371..463c04b0aa 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -503,7 +503,7 @@ static gboolean 
qio_channel_websock_handshake_send(QIOChannel *ioc,
  &err);
  
  if (ret < 0) {

-trace_qio_channel_websock_handshake_fail(ioc);
+trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
  qio_task_set_error(task, err);
  qio_task_complete(task);
  return FALSE;
@@ -512,7 +512,8 @@ static gboolean 
qio_channel_websock_handshake_send(QIOChannel *ioc,
  buffer_advance(&wioc->encoutput, ret);
  if (wioc->encoutput.offset == 0) {
  if (wioc->io_err) {
-trace_qio_channel_websock_handshake_fail(ioc);
+trace_qio_channel_websock_handshake_fail(
+ioc, error_get_pretty(wioc->io_err));
  qio_task_set_error(task, wioc->io_err);
  wioc->io_err = NULL;
  qio_task_complete(task);
@@ -543,7 +544,7 @@ static gboolean qio_channel_websock_handshake_io(QIOChannel 
*ioc,
   * client connection, as most of the time we have an
   * HTTP 4xx err response to send instead
   */
-trace_qio_channel_websock_handshake_fail(ioc);
+trace_qio_channel_websock_handshake_fail(ioc, error_get_pretty(err));
  qio_task_set_error(task, err);
  qio_task_complete(task);
  return FALSE;
diff --git a/io/trace-events b/io/trace-events
index 3d233698d0..6459f71f5b 100644
--- a/io/trace-events
+++ b/io/trace-events
@@ -46,7 +46,7 @@ qio_channel_websock_new_server(void *ioc, void *master) 
"Websock new client ioc=
  qio_channel_websock_handshake_start(void *ioc) "Websock handshake start 
ioc=%p"
  qio_channel_websock_handshake_pending(void *ioc, int status) "Websock handshake 
pending ioc=%p status=%d"
  qio_channel_websock_handshake_reply(void *ioc) "Websock handshake reply 
ioc=%p"
-qio_channel_websock_handshake_fail(void *ioc) "Websock handshake fail ioc=%p"
+qio_channel_websock_handshake_fail(void *ioc, const char *msg) "Websock handshake 
fail ioc=%p err=%s"
  qio_channel_websock_handshake_complete(void *ioc) "Websock handshake complete 
ioc=%p"
  
  # io/channel-command.c






Re: [Qemu-devel] [PATCH v1 1/2] io: send proper HTTP response for websocket errors

2017-09-06 Thread Philippe Mathieu-Daudé

Hi Daniel,

On 09/06/2017 07:40 AM, Daniel P. Berrange wrote:

When any error occurs while processing the websockets handshake,
QEMU just terminates the connection abruptly. This is in violation
of the HTTP specs and does not help the client understand what they
did wrong. This is particularly bad when the client gives the wrong
path, as a "404 Not Found" would be very helpful.

Refactor the handshake code so that it always sends a response to
the client unless there was an I/O error.

Fixes bug: #1715186

Signed-off-by: Daniel P. Berrange 
---
  io/channel-websock.c | 179 ++-
  1 file changed, 134 insertions(+), 45 deletions(-)

diff --git a/io/channel-websock.c b/io/channel-websock.c
index 5a3badbec2..b9cc5a1371 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -44,13 +44,39 @@
  #define QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE "Upgrade"
  #define QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET "websocket"
  
-#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RESPONSE  \

+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
+"Server: QEMU VNC\r\n"   \
+"Date: %s\r\n"


and
"Sec-WebSocket-Version: " \
  QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "\r\n" \

or what about:

#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON(conn)   \
  "Server: QEMU VNC\r\n" \
  "Date: %s\r\n" \
  "Connection: " conn "\r\n" \
  "Sec-WebSocket-Version: "  \
QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "\r\n"

+
+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_OK\
  "HTTP/1.1 101 Switching Protocols\r\n"  \
+QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON\
  "Upgrade: websocket\r\n"\
  "Connection: Upgrade\r\n"   \
  "Sec-WebSocket-Accept: %s\r\n"  \
  "Sec-WebSocket-Protocol: binary\r\n"\
  "\r\n"
+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_NOT_FOUND \
+"HTTP/1.1 404 Not Found\r\n"\
+QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON\
+"Connection: close\r\n" \
+"\r\n"
+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST \
+"HTTP/1.1 400 Bad Request\r\n"\
+QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON  \
+"Connection: close\r\n"   \
+"Sec-WebSocket-Version: 13\r\n"   \


drop


+"\r\n"


or with previous macro:

#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST \
"HTTP/1.1 400 Bad Request\r\n"\
QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON("close") \
"\r\n"


+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_SERVER_ERR \
+"HTTP/1.1 500 Internal Server Error\r\n" \
+QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
+"Connection: close\r\n"  \
+"\r\n"
+#define QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_TOO_LARGE  \
+"HTTP/1.1 403 Request Entity Too Large\r\n"  \
+QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_COMMON \
+"Connection: close\r\n"  \
+"\r\n"
  #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_DELIM "\r\n"
  #define QIO_CHANNEL_WEBSOCK_HANDSHAKE_END "\r\n\r\n"
  #define QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION "13"
@@ -123,8 +149,43 @@ enum {
  QIO_CHANNEL_WEBSOCK_OPCODE_PONG = 0xA
  };
  
+static void qio_channel_websock_handshake_send_res(QIOChannelWebsock *ioc,

+   const char *resmsg,
+   ...)
+{
+va_list vargs;
+char *response = NULL;


NULL not needed


+size_t responselen;
+
+va_start(vargs, resmsg);
+response = g_strdup_vprintf(resmsg, vargs);
+responselen = strlen(response);
+buffer_reserve(&ioc->encoutput, responselen);
+buffer_append(&ioc->encoutput, response, responselen);
+va_end(vargs);
+}
+
+static gchar *qio_channel_websock_date_str(void)
+{
+GTimeZone *utc = g_time_zone_new_utc();
+GDateTime *now = g_date_time_new_now(utc);
+gchar *ret = g_date_time_format(now, "%a, %d %b %Y %H:%M:%S GMT");


assert(ret);


+g_date_time_unref(now);
+g_time_zone_unref(utc);
+return ret;
+}
+
+static void qio_channel_websock_handshake_send_res_err(QIOChannelWebsock *ioc,
+   const char *resdata)
+{
+char *date = qio_channel_websock_date_str();
+qio_channel_websock_handshake_send_res(ioc, resdata, date);
+g_free(date);
+}
+
  static size_t
-qio_channel_websock_extract_headers(char *buffer,
+qio_channel_websock_extract_headers(QIOChannelWebsock *ioc,
+char *buffer,
  QIOChannelWebsockHTTPHeader *hdrs,
  size_t nhdrsalloc,
  Error **errp)
@@ -145,7 +

[Qemu-devel] [PATCH v4 10/20] instrument: Add support for tracing events

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 .gitignore|1 
 Makefile  |3 +
 instrument/Makefile.objs  |1 
 instrument/error.h|6 ++
 instrument/qemu-instr/types.h |   51 +++
 instrument/qemu-instr/types.inc.h |   15 
 instrument/trace.c|  125 +
 trace/control.h   |1 
 8 files changed, 203 insertions(+)
 create mode 100644 instrument/qemu-instr/types.h
 create mode 100644 instrument/qemu-instr/types.inc.h
 create mode 100644 instrument/trace.c

diff --git a/.gitignore b/.gitignore
index cf65316863..5ffcb9a091 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,3 +134,4 @@ trace-dtrace-root.h
 trace-dtrace-root.dtrace
 trace-ust-all.h
 trace-ust-all.c
+!/instrument/*
diff --git a/Makefile b/Makefile
index 6171661458..6f4de75f79 100644
--- a/Makefile
+++ b/Makefile
@@ -592,6 +592,9 @@ endif
 ifdef CONFIG_INSTRUMENT
$(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
$(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/trace.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.inc.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
$(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
 endif
 
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 9b7e1c03aa..8258dbfa79 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -5,3 +5,4 @@ target-obj-$(CONFIG_INSTRUMENT) += load.o
 target-obj-y += qmp.o
 
 target-obj-$(CONFIG_INSTRUMENT) += control.o
+target-obj-$(CONFIG_INSTRUMENT) += trace.o
diff --git a/instrument/error.h b/instrument/error.h
index f8d1dd4b16..7a51d62fdb 100644
--- a/instrument/error.h
+++ b/instrument/error.h
@@ -25,4 +25,10 @@
 return;  \
 }
 
+#define ERROR_IF_RET(cond, ret, msg, args...)   \
+if (unlikely(cond)) {   \
+_ERROR(msg, ##args);\
+return ret; \
+}   \
+
 #endif  /* INSTRUMENT_ERROR_H */
diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h
new file mode 100644
index 00..ea3a032b4f
--- /dev/null
+++ b/instrument/qemu-instr/types.h
@@ -0,0 +1,51 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * 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 QI__TYPES_H
+#define QI__TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * SECTION: types
+ * @section_id: qi-types
+ * @title: Common types
+ */
+
+/**
+ * QITraceEvent:
+ *
+ * Opaque structure defining a tracing event.
+ */
+typedef struct QITraceEvent QITraceEvent;
+
+/**
+ * QITraceEventIter:
+ *
+ * Opaque structure defining a tracing event iterator.
+ */
+typedef struct QITraceEventIter QITraceEventIter;
+
+/**
+ * QICPU:
+ *
+ * Opaque guest CPU pointer.
+ */
+typedef struct QICPU_d *QICPU;
+
+
+#include 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* QI__TYPES_H */
diff --git a/instrument/qemu-instr/types.inc.h 
b/instrument/qemu-instr/types.inc.h
new file mode 100644
index 00..0d99ea59a2
--- /dev/null
+++ b/instrument/qemu-instr/types.inc.h
@@ -0,0 +1,15 @@
+/*
+ * QEMU-specific types for instrumentation clients.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include 
+
+
+struct QITraceEventIter {
+char buffer[(sizeof(size_t) * 2) + sizeof(char *)];
+};
diff --git a/instrument/trace.c b/instrument/trace.c
new file mode 100644
index 00..a73fcdf50a
--- /dev/null
+++ b/instrument/trace.c
@@ -0,0 +1,125 @@
+/*
+ * API for QEMU's tracing events.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "instrument/error.h"
+#include "qemu-instr/trace.h"
+#include "qemu-instr/visibility.h"
+#include "trace/control.h"
+
+
+QI_VPUBLIC
+QITraceEvent *qi_trace_event_name(const char *name)
+{
+ERROR_IF_RET(!name, NULL, "must provide a name");
+return (QITraceEvent *)trace_event_name(name);
+}
+
+QI_VPUBLIC
+void qi_trace_event_iter_init(QITraceEventIter *iter, const char *pattern)
+{
+TraceEventIter *iter_ = (TraceEventIter *)iter;
+ERROR_IF(!iter_, "must provide an iterator");
+trace_event_iter_init(iter_, pattern);
+}
+
+QI

[Qemu-devel] [PATCH v4 09/20] instrument: Add basic control interface

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 Makefile   |5 +++
 configure  |1 +
 instrument/Makefile.objs   |2 +
 instrument/control.c   |   28 +
 instrument/control.h   |   44 +++
 instrument/control.inc.h   |   25 
 instrument/error.h |   28 +
 instrument/events.h|   37 +++
 instrument/events.inc.h|   11 +++
 instrument/load.c  |   13 
 instrument/qemu-instr/control.h|   43 +++
 instrument/qemu-instr/visibility.h |   58 
 stubs/Makefile.objs|1 +
 stubs/instrument.c |   13 
 14 files changed, 309 insertions(+)
 create mode 100644 instrument/control.c
 create mode 100644 instrument/control.h
 create mode 100644 instrument/control.inc.h
 create mode 100644 instrument/error.h
 create mode 100644 instrument/events.h
 create mode 100644 instrument/events.inc.h
 create mode 100644 instrument/qemu-instr/control.h
 create mode 100644 instrument/qemu-instr/visibility.h
 create mode 100644 stubs/instrument.c

diff --git a/Makefile b/Makefile
index 81447b1f08..6171661458 100644
--- a/Makefile
+++ b/Makefile
@@ -589,6 +589,11 @@ ifdef CONFIG_VIRTFS
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
 endif
+ifdef CONFIG_INSTRUMENT
+   $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+   $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility.h 
"$(DESTDIR)$(includedir)/qemu-instr/"
+endif
 
 install-datadir:
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)"
diff --git a/configure b/configure
index 05bd7b1950..3673fc9058 100755
--- a/configure
+++ b/configure
@@ -6038,6 +6038,7 @@ if test "$instrument" = "yes"; then
   LIBS="-ldl $LIBS"
   echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
 fi
+QEMU_INCLUDES="-I\$(SRC_PATH)/instrument $QEMU_INCLUDES"
 
 if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 13a8f60431..9b7e1c03aa 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -3,3 +3,5 @@
 target-obj-y += cmdline.o
 target-obj-$(CONFIG_INSTRUMENT) += load.o
 target-obj-y += qmp.o
+
+target-obj-$(CONFIG_INSTRUMENT) += control.o
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 00..2c2781beeb
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,28 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/events.h"
+#include "instrument/load.h"
+#include "instrument/qemu-instr/control.h"
+#include "instrument/qemu-instr/visibility.h"
+
+__thread InstrState instr_cur_state;
+
+
+qi_fini_fn instr_event__fini_fn;
+void *instr_event__fini_data;
+
+QI_VPUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
+{
+ERROR_IF(!instr_get_state(), "called outside instrumentation");
+instr_set_event(fini_fn, fn);
+instr_set_event(fini_data, data);
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 00..f2b085f69b
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,44 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * 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 INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+
+/**
+ * InstrState:
+ * @INSTR_STATE_DISABLE: Intrumentation API not available.
+ * @INSTR_STATE_ENABLE: Intrumentation API available.
+ *
+ * Instrumentation state of current host thread. Used to ensure instrumentation
+ * clients use QEMU's API only in expected points.
+ */
+typedef enum {
+INSTR_STATE_DISABLE,
+INSTR_STATE_ENABLE,
+} InstrState;
+
+/**
+ * instr_set_state:
+ *
+ * Set the instrumentation state of the current host thread.
+ */
+static inline void instr_set_state(InstrState state);
+
+/**
+ * instr_get_state:
+ *
+ * Get the instrumentation state of the current host thread.
+ */
+static inline InstrState instr_get_state(void);
+
+
+#include "instrument/control.inc.h"
+
+#endif  /* INSTRUMENT__CONTROL_H */
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
new file mode 100644
index 00..0f649f4caa
--- /dev/null
+++ b/instrument/control.inc.h
@@ -0,0 +1,25 @@
+/*
+ * Con

Re: [Qemu-devel] [RFC PATCH 00/56] qapi: Use 'size' for byte counts & offsets

2017-09-06 Thread Markus Armbruster
Kevin Wolf  writes:

> Am 07.08.2017 um 16:45 hat Markus Armbruster geschrieben:
>> Byte sizes, offsets and the like should use QAPI type 'size'
>> (uint64_t).  This rule is more honored in the breach than in the
>> observance.  Fix the obvious offenders.
>> 
>> The series is RFC for at least two reasons:
>> 
>> 1. It's only lightly tested.  Commit message claims like "FOO now
>>works" haven't been verified, yet.
>> 
>> 2. The block layer represents file offsets and sizes as int64_t in
>>many places.  Must not be negative, except for function return
>>values, where it means failure.
>> 
>>If you pass negative values via QMP, things explode.  Rejecting
>>them cleanly would be better, but we do that only haphazardly, as
>>far as I can tell.
>> 
>>Changing the QAPI schema from 'int' (C: int64_t) to 'size' (C:
>>uint64_t) arguably makes things slightly worse: you can't
>>reasonably expect negative offsets and sizes to work, but expecting
>>offsets and sizes between 2^63 and 2^64-1 to work is less
>>unreasonable.  The explosions stay the same.
>> 
>>Perhaps we should have a dedicated QAPI type for file offsets, just
>>like libc has off_t.  Which is also signed, by the way.
>
> I discussed this a bit on IRC with Markus and I'll just reply here with
> some of our findings:
>
> * Having a 63-bit unsigned type makes sense. Not because it's the most
>   accurate type for most places and will catch all invalid arguments,
>   it's probably still too large in most places and individual function
>   needs to keep (or finally introduce) checks for the valid range. But
>   compared to 'int' it doesn't allow us to forget the < 0 check, and
>   compared to 'uint64' the resulting values are immune to careless
>   casting between unsigned and signed C types. These seem to be common
>   bugs, so getting rid of them would be nice.

The block layer at least has the excuse "return negative errno on error,
file offset on success" for using / casting to signed.  Because of that,
it needs (but neglects) to limit QMP file offset arguments to [0,2^63-1]
in QMP command handlers.  Fixing the handlers would be straightforward,
but tedious, and new code would be prone to forget the range check
again.  Being able to leave it to the QAPI core should be convenient.

Do we want a dedicated file offset QAPI type (similar to C has off_t)
for the block layer, or are we fine with using a general 'uint63' type?
I guess the latter, as the block layer seems to be happily using general
int64_t rather than dedicated off_t.

> * 'size' is the right type for sizes, offsets, etc. but the problem is
>   likely to affect other arguments, too. 'size' enables additional
>   syntax in the string visitor, so it is different from the other
>   integer types. This means that we probably want both a 63 bit size
>   type and a 63 bit plain unsigned integer type.

Yes, "want alternate format" is orthogonal to "want only 63 bits".  We
may well run into all four cases.

Aside: creating separate built-in types to enable alternate formats
won't scale to multiple alternate formats.  But it's what we've done for
'uint64' and 'size', and what we now may have to do for 'uint63' and
'size63'.

> * 'int' is an alias for (signed) 'int64'. People don't seem to think
>   much about using 'int' because it's the simplest type. That doesn't
>   make it right to use, though. It may be better to remove the 'int'
>   type and force any definitions to be specific about the signedness and
>   width they need. My intuitive guess is that most places that use 'int'
>   today don't actually want to accept negative numbers.

Hmm.  Perhaps we should make an effort to fix up incorrect uses of
'int', then see how many uses are left.

> * Schema introspection doesn't distinguish between integer types, this
>   is purely internal, so changing a definition from one integer type to
>   another is okay.

Yes.

> Markus, did I forget anything important?

I think that's it.  Thanks!



[Qemu-devel] [PATCH v4 08/20] instrument: [hmp] Add library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 hmp-commands.hx |   28 ++
 monitor.c   |   60 +++
 2 files changed, 88 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1941e19932..703d7262f5 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1858,6 +1858,34 @@ ETEXI
 .sub_table  = info_cmds,
 },
 
+{
+.name   = "instr-load",
+.args_type  = "path:F,args:s?",
+.params = "path [arg]",
+.help   = "load an instrumentation library",
+.cmd= hmp_instr_load,
+},
+
+STEXI
+@item instr-load @var{path} [args=value[,...]]
+@findex instr-load
+Load an instrumentation library.
+ETEXI
+
+{
+.name   = "instr-unload",
+.args_type  = "handle:i",
+.params = "handle",
+.help   = "unload an instrumentation library",
+.cmd= hmp_instr_unload,
+},
+
+STEXI
+@item instr-unload
+@findex instr-unload
+Unload an instrumentation library.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/monitor.c b/monitor.c
index e0f880107f..8a7684f860 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2319,6 +2319,66 @@ int monitor_fd_param(Monitor *mon, const char *fdname, 
Error **errp)
 return fd;
 }
 
+static void hmp_instr_load(Monitor *mon, const QDict *qdict)
+{
+const char *path = qdict_get_str(qdict, "path");
+const char *str = qdict_get_try_str(qdict, "args");
+strList args;
+args.value = (str == NULL) ? NULL : (char *)str;
+args.next = NULL;
+InstrLoadResult *res = qmp_instr_load(path, args.value != NULL,
+  args.value != NULL ? &args : NULL,
+  NULL);
+switch (res->code) {
+case INSTR_LOAD_CODE_OK:
+monitor_printf(mon, "Handle: %"PRId64"\n", res->handle);
+monitor_printf(mon, "OK\n");
+break;
+case INSTR_LOAD_CODE_TOO_MANY:
+monitor_printf(mon, "Too many instrumentation libraries already 
loaded\n");
+break;
+case INSTR_LOAD_CODE_ERROR:
+monitor_printf(mon, "Instrumentation library returned a non-zero value 
during initialization");
+break;
+case INSTR_LOAD_CODE_DLERROR:
+monitor_printf(mon, "Error loading library: %s\n", res->msg);
+break;
+case INSTR_LOAD_CODE_UNAVAILABLE:
+monitor_printf(mon, "Service not available\n");
+break;
+default:
+fprintf(stderr, "Unknown instrumentation load code: %d", res->code);
+exit(1);
+break;
+}
+qapi_free_InstrLoadResult(res);
+}
+
+static void hmp_instr_unload(Monitor *mon, const QDict *qdict)
+{
+int64_t handle = qdict_get_int(qdict, "handle");
+InstrUnloadResult *res = qmp_instr_unload(handle, NULL);
+switch (res->code) {
+case INSTR_UNLOAD_CODE_OK:
+monitor_printf(mon, "OK\n");
+break;
+case INSTR_UNLOAD_CODE_INVALID:
+monitor_printf(mon, "Invalid handle\n");
+break;
+case INSTR_UNLOAD_CODE_DLERROR:
+monitor_printf(mon, "Error unloading library: %s\n", res->msg);
+break;
+case INSTR_UNLOAD_CODE_UNAVAILABLE:
+monitor_printf(mon, "Service not available\n");
+break;
+default:
+fprintf(stderr, "Unknown instrumentation unload code: %d", res->code);
+exit(1);
+break;
+}
+qapi_free_InstrUnloadResult(res);
+}
+
 /* Please update hmp-commands.hx when adding or changing commands */
 static mon_cmd_t info_cmds[] = {
 #include "hmp-commands-info.h"




Re: [Qemu-devel] [PATCH 1/1] net: Add SunGEM device emulation as found on Apple UniNorth

2017-09-06 Thread Mark Cave-Ayland
On 06/09/17 07:56, David Gibson wrote:

 Applied to ppc-for-2.11.
>>>
>>> Until I discovered that it breaks compile with
>>> --enable-trace-backend=ust.   So I've removed it again.
>>
>> Oh that's interesting. I've had --enable-trace-backend=simple as part of
>> my default build for a long while now, so I'm quite surprised that the
>> trace-events are backend sensitive.
>>
>> Any clue as to what the error might be before I go and start installing
>> the relevant libraries?
> 
> Not so far.  I'd investigate myself, but I'm actually really sick
> right now.

Okay, got it - it's because I'd used hwaddr and HWADDR_PRI in
trace-events and of course those types don't exist outside of QEMU.
Switching them over to uint64_t seems to do the trick, so I'll send a v2
shortly.

Hope you feel better soon.


ATB,

Mark.



[Qemu-devel] [PATCH v4 07/20] instrument: [qapi] Add library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 instrument/Makefile.objs |1 
 instrument/load.h|4 ++
 instrument/qmp.c |   88 ++
 qapi-schema.json |3 +
 qapi/instrument.json |   96 ++
 5 files changed, 192 insertions(+)
 create mode 100644 instrument/qmp.c
 create mode 100644 qapi/instrument.json

diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 5ea5c77245..13a8f60431 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -2,3 +2,4 @@
 
 target-obj-y += cmdline.o
 target-obj-$(CONFIG_INSTRUMENT) += load.o
+target-obj-y += qmp.o
diff --git a/instrument/load.h b/instrument/load.h
index 2ddb2c6c19..f8a02e6849 100644
--- a/instrument/load.h
+++ b/instrument/load.h
@@ -25,6 +25,8 @@
  * @INSTR_LOAD_DLERROR: Error with libdl (see dlerror).
  *
  * Error codes for instr_load().
+ *
+ * NOTE: Keep in sync with QAPI's #InstrLoadCode.
  */
 typedef enum {
 INSTR_LOAD_OK,
@@ -40,6 +42,8 @@ typedef enum {
  * @INSTR_UNLOAD_DLERROR: Error with libdl (see dlerror).
  *
  * Error codes for instr_unload().
+ *
+ * NOTE: Keep in sync with QAPI's #InstrUnloadCode.
  */
 typedef enum {
 INSTR_UNLOAD_OK,
diff --git a/instrument/qmp.c b/instrument/qmp.c
new file mode 100644
index 00..c36960c12f
--- /dev/null
+++ b/instrument/qmp.c
@@ -0,0 +1,88 @@
+/*
+ * QMP interface for instrumentation control commands.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qmp-commands.h"
+
+#include 
+
+#include "instrument/load.h"
+
+
+
+InstrLoadResult *qmp_instr_load(const char * path,
+bool have_args, strList * args,
+Error **errp)
+{
+InstrLoadResult *res = g_malloc0(sizeof(*res));
+
+#if defined(CONFIG_INSTRUMENT)
+int argc = 0;
+const char **argv = NULL;
+
+strList *entry = have_args ? args : NULL;
+while (entry != NULL) {
+argv = realloc(argv, sizeof(*argv) * (argc + 1));
+argv[argc] = entry->value;
+argc++;
+entry = entry->next;
+}
+
+InstrLoadError code = instr_load(path, argc, argv, &res->handle);
+switch (code) {
+case INSTR_LOAD_OK:
+res->code = INSTR_LOAD_CODE_OK;
+res->has_handle = true;
+break;
+case INSTR_LOAD_TOO_MANY:
+res->code = INSTR_LOAD_CODE_TOO_MANY;
+break;
+case INSTR_LOAD_ERROR:
+res->code = INSTR_LOAD_CODE_ERROR;
+break;
+case INSTR_LOAD_DLERROR:
+res->has_msg = true;
+res->msg = dlerror();
+res->code = INSTR_LOAD_CODE_DLERROR;
+break;
+}
+#else
+res->code = INSTR_LOAD_CODE_UNAVAILABLE;
+#endif
+
+return res;
+}
+
+InstrUnloadResult *qmp_instr_unload(int64_t handle, Error **errp)
+{
+InstrUnloadResult *res = g_malloc0(sizeof(*res));
+
+#if defined(CONFIG_INSTRUMENT)
+InstrUnloadError code = instr_unload(handle);
+switch (code) {
+case INSTR_UNLOAD_OK:
+res->code = INSTR_UNLOAD_CODE_OK;
+break;
+case INSTR_UNLOAD_INVALID:
+res->code = INSTR_UNLOAD_CODE_INVALID;
+break;
+case INSTR_UNLOAD_DLERROR:
+res->has_msg = true;
+res->msg = dlerror();
+break;
+res->code = INSTR_UNLOAD_CODE_DLERROR;
+}
+#else
+res->code = INSTR_UNLOAD_CODE_UNAVAILABLE;
+#endif
+
+return res;
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index 802ea53d00..5e343be9ff 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -90,6 +90,9 @@
 # QAPI introspection
 { 'include': 'qapi/introspect.json' }
 
+# Instrumentation commands
+{ 'include': 'qapi/instrument.json' }
+
 ##
 # = QMP commands
 ##
diff --git a/qapi/instrument.json b/qapi/instrument.json
new file mode 100644
index 00..ea63fae309
--- /dev/null
+++ b/qapi/instrument.json
@@ -0,0 +1,96 @@
+# *-*- Mode: Python -*-*
+#
+# QAPI instrumentation control commands.
+#
+# Copyright (C) 2012-2017 Lluís Vilanova 
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @InstrLoadCode:
+#
+# Result code of an 'instr-load' command.
+#
+# @ok: Correctly loaded.
+# @too-many: Tried to load too many instrumentation libraries.
+# @error: The library's main() function returned a non-zero value.
+# @dlerror: Error with libdl (see 'msg').
+# @unavailable: Service not available.
+#
+# Since: 2.11
+##
+{ 'enum': 'InstrLoadCode',
+  'data': [ 'ok', 'too-many', 'error', 'dlerror', 'unavailable' ] }
+
+##
+# @InstrLoadResult:
+#
+# Result of an 'instr-load' command.
+#
+# @code: Result code.
+# @msg: Additional error message (for human consumption only; present only in
+#   case of er

[Qemu-devel] [PATCH v4 06/20] instrument: [softmmu] Add command line library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 qemu-options.hx |   19 +++
 vl.c|   15 +++
 2 files changed, 34 insertions(+)

diff --git a/qemu-options.hx b/qemu-options.hx
index 9f6e2adfff..6947388aab 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4077,6 +4077,25 @@ HXCOMM HX does not support conditional compilation of 
text.
 @findex -trace
 @include qemu-option-trace.texi
 ETEXI
+#if defined(CONFIG_INSTRUMENT)
+DEF("instr", HAS_ARG, QEMU_OPTION_instr,
+"-instr [file=][,arg=]\n"
+"load an instrumentation library\n",
+QEMU_ARCH_ALL)
+#endif
+STEXI
+@item -instr file=@var{file}[,arg=@var{string}]
+@findex -instr
+
+Load a dynamic trace instrumentation library.
+
+@table @option
+@item file=@var{file}
+Load the given dynamic trace instrumentation library.
+@item arg=@var{string}
+String argument passed as to the library's @code{qi_init} routine (can be 
given multiple times).
+@end table
+ETEXI
 
 HXCOMM Internal use
 DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index 8e247cc2a2..10dfea3ec7 100644
--- a/vl.c
+++ b/vl.c
@@ -118,6 +118,7 @@ int main(int argc, char **argv)
 
 #include "trace-root.h"
 #include "trace/control.h"
+#include "instrument/cmdline.h"
 #include "qemu/queue.h"
 #include "sysemu/arch_init.h"
 
@@ -3035,6 +3036,9 @@ int main(int argc, char **argv, char **envp)
 } BlockdevOptions_queue;
 QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue
 = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+char *instrument_path = NULL;
+int instrument_argc = 0;
+const char **instrument_argv = NULL;
 
 module_call_init(MODULE_INIT_TRACE);
 
@@ -3062,6 +3066,9 @@ int main(int argc, char **argv, char **envp)
 qemu_add_opts(&qemu_global_opts);
 qemu_add_opts(&qemu_mon_opts);
 qemu_add_opts(&qemu_trace_opts);
+#if defined(CONFIG_INSTRUMENT)
+qemu_add_opts(&qemu_instr_opts);
+#endif
 qemu_add_opts(&qemu_option_rom_opts);
 qemu_add_opts(&qemu_machine_opts);
 qemu_add_opts(&qemu_accel_opts);
@@ -4003,6 +4010,12 @@ int main(int argc, char **argv, char **envp)
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
 break;
+#if defined(CONFIG_INSTRUMENT)
+case QEMU_OPTION_instr:
+instr_opt_parse(optarg, &instrument_path,
+&instrument_argc, &instrument_argv);
+break;
+#endif
 case QEMU_OPTION_readconfig:
 {
 int ret = qemu_read_config_file(optarg);
@@ -4190,6 +4203,8 @@ int main(int argc, char **argv, char **envp)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Open the logfile at this point and set the log mask if necessary.
  */
 if (log_file) {




[Qemu-devel] [PATCH v4 05/20] instrument: [bsd-user] Add command line library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 bsd-user/main.c|   15 +++
 bsd-user/syscall.c |5 +
 2 files changed, 20 insertions(+)

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 8a6706a1c8..2cf75290cd 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,7 @@
 #include "exec/log.h"
 #include "trace/control.h"
 #include "glib-compat.h"
+#include "instrument/cmdline.h"
 
 int singlestep;
 unsigned long mmap_min_addr;
@@ -667,6 +668,11 @@ static void usage(void)
"-B addressset guest_base address to address\n"
"-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD 
(default)\n"
"\n"
+#if defined(CONFIG_INSTRUMENT)
+   "-instr [file=][,arg=]\n"
+   "  load an instrumentation library\n"
+   "\n"
+#endif
"Debug options:\n"
"-d item1[,...]enable logging of specified items\n"
"  (use '-d help' for a list of log items)\n"
@@ -738,6 +744,9 @@ int main(int argc, char **argv)
 envlist_t *envlist = NULL;
 char *trace_file = NULL;
 bsd_type = target_openbsd;
+char *instrument_path = NULL;
+int instrument_argc = 0;
+const char **instrument_argv = NULL;
 
 if (argc <= 1)
 usage();
@@ -756,6 +765,7 @@ int main(int argc, char **argv)
 cpu_model = NULL;
 
 qemu_add_opts(&qemu_trace_opts);
+qemu_add_opts(&qemu_instr_opts);
 
 optind = 1;
 for (;;) {
@@ -843,6 +853,9 @@ int main(int argc, char **argv)
 } else if (!strcmp(r, "trace")) {
 g_free(trace_file);
 trace_file = trace_opt_parse(optarg);
+} else if (!strcmp(r, "instr")) {
+instr_opt_parse(optarg, &instrument_path,
+&instrument_argc, &instrument_argv);
 } else {
 usage();
 }
@@ -872,6 +885,8 @@ int main(int argc, char **argv)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 66492aaf5d..3230f722f3 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -26,6 +26,8 @@
 
 #include "qemu.h"
 #include "qemu-common.h"
+#include "instrument/cmdline.h"
+
 
 //#define DEBUG
 
@@ -332,6 +334,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -430,6 +433,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long 
arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */
@@ -505,6 +509,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, 
abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 /* XXX: should free thread stack and CPU env */
 _exit(arg1);
 ret = 0; /* avoid warning */




[Qemu-devel] [PATCH v4 04/20] instrument: [linux-user] Add command line library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 linux-user/main.c|   19 +++
 linux-user/syscall.c |4 
 2 files changed, 23 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 03666ef657..25253bc28a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -36,6 +36,7 @@
 #include "exec/log.h"
 #include "trace/control.h"
 #include "glib-compat.h"
+#include "instrument/cmdline.h"
 
 char *exec_path;
 
@@ -4017,6 +4018,17 @@ static void handle_arg_trace(const char *arg)
 trace_file = trace_opt_parse(arg);
 }
 
+static char *instrument_path;
+static int instrument_argc;
+static const char **instrument_argv;
+#if defined(CONFIG_INSTRUMENT)
+static void handle_arg_instrument(const char *arg)
+{
+instr_opt_parse(arg, &instrument_path,
+&instrument_argc, &instrument_argv);
+}
+#endif
+
 struct qemu_argument {
 const char *argv;
 const char *env;
@@ -4066,6 +4078,10 @@ static const struct qemu_argument arg_table[] = {
  "",   "Seed for pseudo-random number generator"},
 {"trace",  "QEMU_TRACE",   true,  handle_arg_trace,
  "",   "[[enable=]][,events=][,file=]"},
+#if defined(CONFIG_INSTRUMENT)
+{"instr",  "QEMU_INSTR",   true,  handle_arg_instrument,
+ "",   "[file=][,arg=]"},
+#endif
 {"version","QEMU_VERSION", false, handle_arg_version,
  "",   "display version information and exit"},
 {NULL, NULL, false, NULL, NULL, NULL}
@@ -4257,6 +4273,7 @@ int main(int argc, char **argv, char **envp)
 srand(time(NULL));
 
 qemu_add_opts(&qemu_trace_opts);
+qemu_add_opts(&qemu_instr_opts);
 
 optind = parse_args(argc, argv);
 
@@ -4265,6 +4282,8 @@ int main(int argc, char **argv, char **envp)
 }
 trace_init_file(trace_file);
 
+instr_init(instrument_path, instrument_argc, instrument_argv);
+
 /* Zero out regs */
 memset(regs, 0, sizeof(struct target_pt_regs));
 
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9b6364a266..e73a07fa6f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -115,6 +115,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #include "uname.h"
 
 #include "qemu.h"
+#include "instrument/cmdline.h"
+
 
 #ifndef CLONE_IO
 #define CLONE_IO0x8000  /* Clone io context */
@@ -7765,6 +7767,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 _exit(arg1);
 ret = 0; /* avoid warning */
 break;
@@ -9821,6 +9824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 _mcleanup();
 #endif
 gdb_exit(cpu_env, arg1);
+instr_fini();
 ret = get_errno(exit_group(arg1));
 break;
 #endif




[Qemu-devel] [PATCH v4 03/20] instrument: Add generic library loader

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 MAINTAINERS  |1 
 Makefile.objs|4 +
 configure|2 +
 instrument/Makefile.objs |4 +
 instrument/cmdline.c |  124 
 instrument/cmdline.h |   49 +
 instrument/load.c|  176 ++
 instrument/load.h|   83 ++
 8 files changed, 443 insertions(+)
 create mode 100644 instrument/Makefile.objs
 create mode 100644 instrument/cmdline.c
 create mode 100644 instrument/cmdline.h
 create mode 100644 instrument/load.c
 create mode 100644 instrument/load.h

diff --git a/MAINTAINERS b/MAINTAINERS
index edb313c632..edd2c49078 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1485,6 +1485,7 @@ M: Lluís Vilanova 
 M: Stefan Hajnoczi 
 S: Maintained
 F: docs/instrument.txt
+F: instrument/
 
 Checkpatch
 S: Odd Fixes
diff --git a/Makefile.objs b/Makefile.objs
index 24a4ea08b8..81a9218e14 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -97,6 +97,10 @@ version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
 util-obj-y +=  trace/
 target-obj-y += trace/
 
+##
+# instrument
+target-obj-y += instrument/
+
 ##
 # guest agent
 
diff --git a/configure b/configure
index 80dcc91c98..05bd7b1950 100755
--- a/configure
+++ b/configure
@@ -6034,6 +6034,8 @@ fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 
 if test "$instrument" = "yes"; then
+  LDFLAGS="-rdynamic $LDFLAGS"  # limit symbols available to clients
+  LIBS="-ldl $LIBS"
   echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
 fi
 
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
new file mode 100644
index 00..5ea5c77245
--- /dev/null
+++ b/instrument/Makefile.objs
@@ -0,0 +1,4 @@
+# -*- mode: makefile -*-
+
+target-obj-y += cmdline.o
+target-obj-$(CONFIG_INSTRUMENT) += load.o
diff --git a/instrument/cmdline.c b/instrument/cmdline.c
new file mode 100644
index 00..ec87f96c72
--- /dev/null
+++ b/instrument/cmdline.c
@@ -0,0 +1,124 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 Lluís Vilanova 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "instrument/cmdline.h"
+#include "instrument/load.h"
+#include "qemu/config-file.h"
+#include "qemu/error-report.h"
+
+
+QemuOptsList qemu_instr_opts = {
+.name = "instrument",
+.implied_opt_name = "file",
+.merge_lists = true,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head),
+.desc = {
+{
+.name = "file",
+.type = QEMU_OPT_STRING,
+},{
+.name = "arg",
+.type = QEMU_OPT_STRING,
+},
+{ /* end of list */ }
+},
+};
+
+void instr_opt_parse(const char *optarg, char **path,
+ int *argc, const char ***argv)
+{
+const char *arg;
+QemuOptsIter iter;
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("instrument"),
+ optarg, true);
+if (!opts) {
+exit(1);
+} else {
+#if !defined(CONFIG_INSTRUMENT)
+error_report("instrumentation not enabled on this build");
+exit(1);
+#endif
+}
+
+
+arg = qemu_opt_get(opts, "file");
+if (arg != NULL) {
+g_free(*path);
+*path = g_strdup(arg);
+}
+
+qemu_opt_iter_init(&iter, opts, "arg");
+while ((arg = qemu_opt_iter_next(&iter)) != NULL) {
+*argv = realloc(*argv, sizeof(**argv) * (*argc + 1));
+(*argv)[*argc] = g_strdup(arg);
+(*argc)++;
+}
+
+qemu_opts_del(opts);
+}
+
+void instr_init(const char *path, int argc, const char **argv)
+{
+#if defined(CONFIG_INSTRUMENT)
+InstrLoadError err;
+int64_t handle;
+
+if (path == NULL) {
+return;
+}
+
+if (atexit(instr_fini) != 0) {
+fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+abort();
+}
+
+err = instr_load(path, argc, argv, &handle);
+switch (err) {
+case INSTR_LOAD_OK:
+return;
+case INSTR_LOAD_TOO_MANY:
+error_report("instrument: tried to load too many libraries");
+break;
+case INSTR_LOAD_ERROR:
+error_report("instrument: library initialization returned non-zero");
+break;
+case INSTR_LOAD_DLERROR:
+error_report("instrument: error loading library: %s", dlerror());
+break;
+}
+#else
+error_report("instrument: not available");
+#endif
+
+exit(1);
+}
+
+void instr_fini(void)
+{
+#if defined(CONFIG_INSTRUMENT)
+InstrUnloadError err = instr_unload_all();
+
+switch (err) {
+case INSTR_UNLOAD_OK:
+return;
+case INSTR_UNLOAD_INVALID:
+

[Qemu-devel] [PATCH v4 02/20] instrument: Add configure-time flag

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 configure |9 +
 1 file changed, 9 insertions(+)

diff --git a/configure b/configure
index dd73cce62f..80dcc91c98 100755
--- a/configure
+++ b/configure
@@ -352,6 +352,7 @@ pie=""
 qom_cast_debug="yes"
 trace_backends="log"
 trace_file="trace"
+instrument="no"
 spice=""
 rbd=""
 smartcard=""
@@ -891,6 +892,8 @@ for opt do
   ;;
   --with-trace-file=*) trace_file="$optarg"
   ;;
+  --enable-instrument) instrument="yes"
+  ;;
   --enable-gprof) gprof="yes"
   ;;
   --enable-gcov) gcov="yes"
@@ -1441,6 +1444,7 @@ Advanced options (experts only):
Available backends: $trace_backend_list
   --with-trace-file=NAME   Full PATH,NAME of file to store traces
Default:trace-
+  --enable-instrument  enable event instrumentation
   --disable-slirp  disable SLIRP userspace network connectivity
   --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)
   --oss-libpath to OSS library
@@ -5371,6 +5375,7 @@ echo "Trace backends$trace_backends"
 if have_backend "simple"; then
 echo "Trace output file $trace_file-"
 fi
+echo "instrumentation   $instrument"
 echo "spice support $spice $(echo_version $spice 
$spice_protocol_version/$spice_server_version)"
 echo "rbd support   $rbd"
 echo "xfsctl support$xfs"
@@ -6028,6 +6033,10 @@ if have_backend "syslog"; then
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 
+if test "$instrument" = "yes"; then
+  echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
+fi
+
 if test "$rdma" = "yes" ; then
   echo "CONFIG_RDMA=y" >> $config_host_mak
 fi




[Qemu-devel] [PATCH v4 01/20] instrument: Add documentation

2017-09-06 Thread Lluís Vilanova
Signed-off-by: Lluís Vilanova 
---
 MAINTAINERS |6 ++
 docs/instrument.txt |  174 +++
 2 files changed, 180 insertions(+)
 create mode 100644 docs/instrument.txt

diff --git a/MAINTAINERS b/MAINTAINERS
index ccee28b12d..edb313c632 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1480,6 +1480,12 @@ F: scripts/tracetool/
 F: docs/tracing.txt
 T: git git://github.com/stefanha/qemu.git tracing
 
+Event instrumentation
+M: Lluís Vilanova 
+M: Stefan Hajnoczi 
+S: Maintained
+F: docs/instrument.txt
+
 Checkpatch
 S: Odd Fixes
 F: scripts/checkpatch.pl
diff --git a/docs/instrument.txt b/docs/instrument.txt
new file mode 100644
index 00..c43ca9c6d0
--- /dev/null
+++ b/docs/instrument.txt
@@ -0,0 +1,174 @@
+= Event instrumentation =
+
+== Introduction ==
+
+Event instrumentation allows users to execute their own host-native code on a
+set of pre-defined events provided by QEMU. QEMU also exposes other
+functionality to peek/poke at the guest state (e.g., memory or registers), as
+well as interacting with tracing events. For those familiar with the term, this
+provides dynamic binary instrumentation, works on all QEMU-supported
+architectures, as well as works in both 'user' (standalone application) and
+'system' (full-system emulation) modes.
+
+Look at the headers installed by QEMU on the "qemu-instr" directory for further
+information beyond this document.
+
+
+== Loading an instrumentation library ==
+
+Instrumentation code can be bundled into a dynamic library, which can be later
+loaded into QEMU:
+
+* Using the command-line "-instr" argument.
+
+* Using the "instr-load" and "instr-unload" commands in the HMP and QMP
+  interfaces.
+
+
+== Example ==
+
+1. Configure QEMU with event instrumentation:
+
+# instrument guest_cpu_enter and guest_mem_before
+mkdir -p /path/to/qemu-build
+cd /path/to/qemu-build
+/path/to/qemu-source/configure \
+  --enable-instrument \
+  --prefix=/path/to/qemu-install
+
+2. Build and install QEMU:
+
+make install
+
+3. Create the "Makefile" to build the instrumentation library:
+
+mkdir -p /tmp/my-instrument
+
+cat > /tmp/my-instrument/Makefile < /tmp/my-instrument/instrument.c <
+#include 
+ 
+#include  /* manipulate events */
+#include/* manipulate tracing */
+#include   /* symbol visibility */
+ 
+/* the address for the memory access is not known at translation time */
+void guest_mem_before_trans(QICPU vcpu_trans, QITCGv_cpu vcpu_exec,
+QITCGv vaddr, QIMemInfo info)
+{
+printf("%s: %p %p %p %d %d %d %d\n", __func__, vcpu_trans, vcpu_exec, 
vaddr,
+   1 << info.size_shift, info.sign_extend, info.endianness, 
info.store);
+if (info.store) {
+/* generate at execution time only for memory writes */
+qi_event_gen_guest_mem_before_exec(vcpu_exec, vaddr, info);
+}
+}
+ 
+/* called when QEMU executes a memory access */
+void guest_mem_before_exec(QICPU vcpu, uint64_t vaddr, QIMemInfo info)
+{
+if (info.store) {
+/* if called by TCG code, we'll only get writes (see above) */
+printf("%s: %p %lx %d %d %d %d\n", __func__, vcpu, vaddr,
+   1 << info.size_shift, info.sign_extend, info.endianness, 
info.store);
+}
+}
+ 
+/* called every time QEMU hotplugs a CPU */
+void guest_cpu_enter(QICPU vcpu)
+{
+printf("%s: %p\n", __func__, vcpu);
+ 
+/* disable instrumentation and tracing after the first call */
+static bool found = false;
+if (found) {
+qi_event_set_guest_cpu_enter(NULL);
+QITraceEvent *ev = qi_trace_event_name("guest_cpu_enter");
+assert(ev);
+qi_trace_event_set_state_dynamic(ev, true);
+} else {
+found = true;
+}
+}
+ 
+static void fini(void *data)
+{
+/* diable all tracing events */
+QITraceEventIter iter;
+qi_trace_event_iter_init(&iter, NULL);
+QITraceEvent *ev;
+while ((ev = qi_trace_event_iter_next(&iter)) != NULL) {
+if (qi_trace_event_get_state_static(ev)) {
+qi_trace_event_set_state_dynamic(ev, false);
+}
+}
+ 
+/* instrumentation callbacks are automatically reset by QEMU */
+}
+ 
+/* mandatory initialization function */
+QI_VPUBLIC int main(int argc, const char **argv)
+{
+int i;
+printf("init!\n");
+printf("argc :: %d\n", argc);
+for (i = 0; i < argc; i++) {
+printf("-> %s\n", argv[i]);
+}
+ 
+qi_set_fini(fini, NULL);
+ 
+/* instrument and trace events */
+QITraceEvent *ev;
+ 
+qi_event_set_guest_cpu_enter(guest_cpu_enter);
+ev = qi_trace_event_name("guest_cpu_enter

Re: [Qemu-devel] [PATCH v4 2/3] watchdog.h: Drop local redefinition of actions enum

2017-09-06 Thread Markus Armbruster
Eric Blake  writes:

> On 09/06/2017 06:24 AM, Michal Privoznik wrote:
>> We already have enum that enumerates all the action that a
>
> s/action/actions/
>
>> watchdog can take when hitting its timeout: WatchdogAction.
>> Use that instead of inventing our own.
>> 
>> Signed-off-by: Michal Privoznik 
>> ---
>
>> @@ -77,27 +77,16 @@ int select_watchdog(const char *p)
>>  
>>  int select_watchdog_action(const char *p)
>>  {
>> -if (strcasecmp(p, "reset") == 0)
>> -watchdog_action = WDT_RESET;
>
> The old code was case-insensitive,
>
>> +action = qapi_enum_parse(&WatchdogAction_lookup, p, -1, NULL);
>
> the new code is not.  Do we care?  (I don't, but we could be breaking
> someone's control flow).  Should qapi_enum_parse be taught to be
> case-insensitive?  Or perhaps we answer related questions first: Do we
> have any QAPI enums that have values differing only in case? Do we
> prevent such QAPI definitions, to give us the potential of making the
> parsing insensitive?

Case-sensitive everywhere is fine.  Case-insensitive everywhere also
fine, just not my personal preference.  What's not fine is "guess
whether this part of the interface is case-sensitive or not".

QMP is case-sensitive.  Let's keep it that way.

The -watchdog-action option has a case-insensitive argument.  The
obvious way to remain misfeature-^Wbackwards compatible is converting
the argument to lower case before handing it off to qapi_enum_parse.  I
doubt it matters, but just doing it is less work than debating how far
exactly we want to bend over backwards.

g_ascii_strdown() should do.  It only converts ASCII characters, but
anything else is going to fail in qapi_enum_parse() anyway.



[Qemu-devel] [PATCH v4 00/20] instrument: Add basic event instrumentation

2017-09-06 Thread Lluís Vilanova
This series adds an API to add instrumentation events.

It also provides additional APIs for:
* Controlling tracing events
* Peek/poke guest memory

There's still missing APIs for (can be added in later series?):
* Provide something like tracing's per-vCPU trace states (i.e., so that each
  vCPU can have different instrumentation code). It's still not clear to me if
  we should extend the per-vCPU bitmap with instrumentation events, or otherwise
  somehow reuse the bits in tracing events (since they're currently limited).
* Peek/poke guest registers

The instrumentation code is dynamically loaded as a library into QEMU either
when it starts or later using its remote control interfaces.

Signed-off-by: Lluís Vilanova 
---

Changes in v4
=

* Add missing stub function.


Changes in v3
=

* Use a separate event set for instrumentation (i.e., do not instrument tracing
  events) [Stefan Hajnoczi].
* Add API for peek/poke guest memory.


Changes in v2
=

* Update QEMU version in QAPI [Eric Blake].
* Clarify 'msg' result in QAPI is for humans only.
* Make 'msg' and 'handle' results optional in QAPI.
* Use a list of 'str' in 'instr-load' QAPI command.
* Update MAINTAINERS.
* Add macros for error-reporting in API.


Lluís Vilanova (20):
  instrument: Add documentation
  instrument: Add configure-time flag
  instrument: Add generic library loader
  instrument: [linux-user] Add command line library loader
  instrument: [bsd-user] Add command line library loader
  instrument: [softmmu] Add command line library loader
  instrument: [qapi] Add library loader
  instrument: [hmp] Add library loader
  instrument: Add basic control interface
  instrument: Add support for tracing events
  instrument: Track vCPUs
  instrument: Add event 'guest_cpu_enter'
  instrument: Add event 'guest_cpu_exit'
  instrument: Add event 'guest_cpu_reset'
  trace: Introduce a proper structure to describe memory accesses
  instrument: Add event 'guest_mem_before_trans'
  instrument: Add event 'guest_mem_before_exec'
  instrument: Add event 'guest_user_syscall'
  instrument: Add event 'guest_user_syscall_ret'
  instrument: Add API to manipulate guest memory


 .gitignore|1 
 MAINTAINERS   |7 +
 Makefile  |8 +
 Makefile.objs |4 +
 Makefile.target   |1 
 bsd-user/main.c   |   15 ++
 bsd-user/syscall.c|   11 ++
 configure |   12 ++
 cpus-common.c |9 +
 docs/instrument.txt   |  174 ++
 hmp-commands.hx   |   28 
 include/exec/cpu_ldst_template.h  |   19 +--
 include/exec/cpu_ldst_useronly_template.h |   19 +--
 include/exec/helper-gen.h |1 
 include/exec/helper-proto.h   |1 
 include/exec/helper-tcg.h |1 
 instrument/Makefile.objs  |9 +
 instrument/cmdline.c  |  124 ++
 instrument/cmdline.h  |   49 +++
 instrument/control.c  |  148 ++
 instrument/control.h  |  123 ++
 instrument/control.inc.h  |   56 
 instrument/error.h|   34 +
 instrument/events.h   |   86 +
 instrument/events.inc.h   |  108 
 instrument/helpers.h  |1 
 instrument/load.c |  196 +
 instrument/load.h |   87 +
 instrument/qemu-instr/control.h   |  169 +
 instrument/qemu-instr/state.h |  104 +++
 instrument/qemu-instr/types.h |  115 +
 instrument/qemu-instr/types.inc.h |   15 ++
 instrument/qemu-instr/visibility.h|   58 +
 instrument/qmp.c  |   88 +
 instrument/state.c|   72 +++
 instrument/trace.c|  125 ++
 linux-user/main.c |   19 +++
 linux-user/syscall.c  |6 +
 monitor.c |   60 +
 qapi-schema.json  |3 
 qapi/instrument.json  |   96 ++
 qemu-options.hx   |   19 +++
 qom/cpu.c |2 
 stubs/Makefile.objs   |1 
 stubs/instrument.c|   25 
 tcg/tcg-op.c  |   27 +++-
 trace/control-target.c  

Re: [Qemu-devel] [PATCH v4 3/3] watchdog: Allow setting action on the fly

2017-09-06 Thread Markus Armbruster
Eric Blake  writes:

> On 09/06/2017 06:24 AM, Michal Privoznik wrote:
>> Currently, the only time that users can set watchdog action is at
>> the start as all we expose is this -watchdog-action command line
>> argument. This is suboptimal when users want to plug the device
>> later via monitor. Alternatively, they might want to change the
>> action for already existing device on the fly.
>> 
>> Inspired by: https://bugzilla.redhat.com/show_bug.cgi?id=1447169
>> 
>> Signed-off-by: Michal Privoznik 
>> ---
>>  hw/watchdog/watchdog.c | 8 +++-
>>  qapi-schema.json   | 9 +
>>  2 files changed, 16 insertions(+), 1 deletion(-)
>> 
>
>> +++ b/qapi-schema.json
>> @@ -3143,3 +3143,12 @@
>>  # Since 2.9
>>  ##
>>  { 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
>> +
>> +##
>> +# @watchdog-set-action:
>> +#
>> +# Set watchdog action
>> +#
>> +# Since 2.11
>> +##
>> +{ 'command': 'watchdog-set-action', 'data' : {'action': 'WatchdogAction'} }
>
> Markus went to some effort to sort the documentation output; is plopping
> this at the end of the file the best location?

This patch won't regress any of my work, as I only moved stuff out of
qapi-schema-json, I didn't reorder within.

> Otherwise,
> Reviewed-by: Eric Blake 



[Qemu-devel] [PATCH v3 00/21] instrument: Add basic event instrumentation

2017-09-06 Thread Lluís Vilanova
This series adds an API to add instrumentation events.

It also provides additional APIs for:
* Controlling tracing events
* Peek/poke guest memory

There's still missing APIs for (can be added in later series?):
* Provide something like tracing's per-vCPU trace states (i.e., so that each
  vCPU can have different instrumentation code). It's still not clear to me if
  we should extend the per-vCPU bitmap with instrumentation events, or otherwise
  somehow reuse the bits in tracing events (since they're currently limited).
* Peek/poke guest registers

The instrumentation code is dynamically loaded as a library into QEMU either
when it starts or later using its remote control interfaces.

Signed-off-by: Lluís Vilanova 
---

Changes in v3
=

* Use a separate event set for instrumentation (i.e., do not instrument tracing
  events) [Stefan Hajnoczi].
* Add API for peek/poke guest memory.


Changes in v2
=

* Update QEMU version in QAPI [Eric Blake].
* Clarify 'msg' result in QAPI is for humans only.
* Make 'msg' and 'handle' results optional in QAPI.
* Use a list of 'str' in 'instr-load' QAPI command.
* Update MAINTAINERS.
* Add macros for error-reporting in API.


Lluís Vilanova (21):
  instrument: Add documentation
  instrument: Add configure-time flag
  instrument: Add generic library loader
  instrument: [linux-user] Add command line library loader
  instrument: [bsd-user] Add command line library loader
  instrument: [softmmu] Add command line library loader
  instrument: [qapi] Add library loader
  instrument: [hmp] Add library loader
  instrument: Add basic control interface
  instrument: Add support for tracing events
  instrument: Track vCPUs
  instrument: Add event 'guest_cpu_enter'
  instrument: Add event 'guest_cpu_exit'
  instrument: Add event 'guest_cpu_reset'
  trace: Introduce a proper structure to describe memory accesses
  instrument: Add event 'guest_mem_before_trans'
  instrument: Add event 'guest_mem_before_exec'
  instrument: Add event 'guest_user_syscall'
  instrument: Add event 'guest_user_syscall_ret'
  instrument: Add API to manipulate guest memory
  instrument: Add API to manipulate guest CPU registers


 .gitignore|1 
 MAINTAINERS   |7 +
 Makefile  |8 +
 Makefile.objs |4 +
 Makefile.target   |1 
 bsd-user/main.c   |   15 ++
 bsd-user/syscall.c|   11 ++
 configure |   12 ++
 cpus-common.c |9 +
 docs/instrument.txt   |  174 ++
 hmp-commands.hx   |   28 
 include/exec/cpu_ldst_template.h  |   19 +--
 include/exec/cpu_ldst_useronly_template.h |   19 +--
 include/exec/helper-gen.h |1 
 include/exec/helper-proto.h   |1 
 include/exec/helper-tcg.h |1 
 instrument/Makefile.objs  |9 +
 instrument/cmdline.c  |  124 ++
 instrument/cmdline.h  |   49 +++
 instrument/control.c  |  148 ++
 instrument/control.h  |  123 ++
 instrument/control.inc.h  |   56 
 instrument/error.h|   34 +
 instrument/events.h   |   86 +
 instrument/events.inc.h   |  108 
 instrument/helpers.h  |1 
 instrument/load.c |  196 +
 instrument/load.h |   87 +
 instrument/qemu-instr/control.h   |  169 +
 instrument/qemu-instr/state.h |  190 
 instrument/qemu-instr/types.h |  122 ++
 instrument/qemu-instr/types.inc.h |   15 ++
 instrument/qemu-instr/visibility.h|   58 +
 instrument/qmp.c  |   88 +
 instrument/state.c|  178 ++
 instrument/trace.c|  125 ++
 linux-user/main.c |   19 +++
 linux-user/syscall.c  |6 +
 monitor.c |   60 +
 qapi-schema.json  |3 
 qapi/instrument.json  |   96 ++
 qemu-options.hx   |   19 +++
 qom/cpu.c |2 
 stubs/Makefile.objs   |1 
 stubs/instrument.c|   25 
 tcg/tcg-op.c  |   27 +++-
 trace/c

Re: [Qemu-devel] [PATCH v2 00/19] s390x cleanups and CPU hotplug via device_add

2017-09-06 Thread Matthew Rosato
On 09/06/2017 12:03 PM, David Hildenbrand wrote:
> On 05.09.2017 09:51, Christian Borntraeger wrote:
>> I think we certainly want to have device_add as well (as long as the old
>> interface stays for a while).
>>
>> Adding Matt. Can you have a look at the cpu hotplug bits?
> 
> If there is no further feedback, I'll be sending a new version out
> tomorrow, including the suggested changes. In addition, I'll be
> including support to hotplug VCPUs in random order (2 additional patches).
> 

Hi David, just returning from vacation -- Will look at this set today.

Matt




Re: [Qemu-devel] [PATCH v7 07/22] migration: Make migrate_fd_error() the owner of the Error

2017-09-06 Thread Eric Blake
On 09/06/2017 06:51 AM, Juan Quintela wrote:
> So far, we had to free the error after each caller, so just do it
> here.  Once there, tls.c was leaking the error.

You mention tls.c,

> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/channel.c   |  1 -
>  migration/migration.c | 10 --
>  migration/migration.h |  4 ++--
>  migration/socket.c|  1 -
>  4 files changed, 6 insertions(+), 10 deletions(-)

but don't touch it.  Am I missing something?

>  
> -void migrate_fd_error(MigrationState *s, const Error *error)
> +void migrate_fd_error(MigrationState *s, Error *error)
>  {

No comments at definition,

> +++ b/migration/migration.h
> @@ -163,8 +163,8 @@ bool  migration_has_all_channels(void);
>  
>  uint64_t migrate_max_downtime(void);
>  
> -void migrate_set_error(MigrationState *s, const Error *error);
> -void migrate_fd_error(MigrationState *s, const Error *error);
> +void migrate_set_error(MigrationState *s, Error *error);
> +void migrate_fd_error(MigrationState *s, Error *error);

or at declaration. That would be worth adding at some point, but this
patch isn't making it worse.

The code looks okay in isolation, so if it is only the commit message
that needs fixing,
Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL 30/32] target/arm: Move ss check to init_disas_context

2017-09-06 Thread Richard Henderson
From: Richard Henderson 

We can check for single-step just once.

Reviewed-by: Emilio G. Cota 
Reviewed-by: Lluís Vilanova 
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index dabd5eb89a..0dd24aad90 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11883,6 +11883,11 @@ static int arm_tr_init_disas_context(DisasContextBase 
*dcbase,
 dc->next_page_start =
 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 
+/* If architectural single step active, limit to 1.  */
+if (is_singlestepping(dc)) {
+max_insns = 1;
+}
+
 cpu_F0s = tcg_temp_new_i32();
 cpu_F1s = tcg_temp_new_i32();
 cpu_F0d = tcg_temp_new_i64();
@@ -12037,11 +12042,9 @@ static void arm_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
  * Also stop translation when a page boundary is reached.  This
  * ensures prefetch aborts occur at the right place.  */
 
-if (is_singlestepping(dc)) {
-dc->base.is_jmp = DISAS_TOO_MANY;
-} else if ((dc->pc >= dc->next_page_start) ||
-   ((dc->pc >= dc->next_page_start - 3) &&
-insn_crosses_page(env, dc))) {
+if (dc->pc >= dc->next_page_start ||
+(dc->pc >= dc->next_page_start - 3 &&
+ insn_crosses_page(env, dc))) {
 /* We want to stop the TB if the next insn starts in a new page,
  * or if it spans between this page and the next. This means that
  * if we're looking at the last halfword in the page we need to
-- 
2.13.5




Re: [Qemu-devel] [Qemu-block] [PATCH v2 2/3] block-jobs: Optionally unregister live block operations

2017-09-06 Thread Eric Blake
On 09/06/2017 10:02 AM, Eduardo Habkost wrote:
> On Wed, Sep 06, 2017 at 03:00:41PM +0200, Kevin Wolf wrote:
>> Am 30.08.2017 um 19:01 hat Jeff Cody geschrieben:
>>> From: Jeffrey Cody 
>>>
>>> If configured without live block operations enabled, unregister the
>>> live block operation commands.
>>>
>>> Signed-off-by: Jeff Cody 
>>
>> How sure are we that libvirt will like a qemu that advertises these
>> commands in the schema, but doesn't actually provide them?
> 
> If libvirt wants to know if a command is available, it uses
> 'query-commands', not 'query-qmp-schema'.
> 
> The only query-qmp-schema elements used by latest libvirt are
> gluster-related blockdev-add options (see
> libvirt/src/qemu/qemu_capabilities.c:virQEMUCapsQMPSchemaQueries]]).

Indeed, libvirt is currently just fine with the fact that query-commands
introspection hides disabled commands, even if they are still leaked in
query-qmp-schema.  Besides, Marc-Andre's work on adding #if support to
QAPI should probably also land in 2.11, at which point the hack goes
away (because then we ARE properly hiding things from the schema
introspection).

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3266
Virtualization:  qemu.org | libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL 27/32] target/arm: [tcg,a64] Port to disas_log

2017-09-06 Thread Richard Henderson
From: Lluís Vilanova 

Incrementally paves the way towards using the generic instruction translation
loop.

Reviewed-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Lluís Vilanova 
Message-Id: <150002606914.22386.15524101311003685068.st...@frigg.lan>
[rth: Move tb->size computation and use that result.]
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 723e86c976..1973a36462 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11393,6 +11393,16 @@ static void aarch64_tr_tb_stop(DisasContextBase 
*dcbase, CPUState *cpu)
 }
 }
 
+static void aarch64_tr_disas_log(const DisasContextBase *dcbase,
+  CPUState *cpu)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+
+qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
+log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size,
+ 4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
+}
+
 void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
TranslationBlock *tb)
 {
@@ -11468,18 +11478,17 @@ void gen_intermediate_code_a64(DisasContextBase 
*dcbase, CPUState *cs,
 
 gen_tb_end(tb, dc->base.num_insns);
 
+dc->base.tb->size = dc->pc - dc->base.pc_first;
+dc->base.tb->icount = dc->base.num_insns;
+
 #ifdef DEBUG_DISAS
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
 qemu_log_in_addr_range(dc->base.pc_first)) {
 qemu_log_lock();
 qemu_log("\n");
-qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
-log_target_disas(cs, dc->base.pc_first, dc->pc - dc->base.pc_first,
- 4 | (bswap_code(dc->sctlr_b) ? 2 : 0));
+aarch64_tr_disas_log(&dc->base, cs);
 qemu_log("\n");
 qemu_log_unlock();
 }
 #endif
-dc->base.tb->size = dc->pc - dc->base.pc_first;
-dc->base.tb->icount = dc->base.num_insns;
 }
-- 
2.13.5




[Qemu-devel] [PULL 29/32] target/arm: [a64] Move page and ss checks to init_disas_context

2017-09-06 Thread Richard Henderson
From: Richard Henderson 

Since AArch64 uses a fixed-width ISA, we can pre-compute the number of
insns remaining on the page.  Also, we can check for single-step once.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 25c6622825..9017e30510 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11206,6 +11206,7 @@ static int 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 DisasContext *dc = container_of(dcbase, DisasContext, base);
 CPUARMState *env = cpu->env_ptr;
 ARMCPU *arm_cpu = arm_env_get_cpu(env);
+int bound;
 
 dc->pc = dc->base.pc_first;
 dc->condjmp = 0;
@@ -11254,8 +11255,14 @@ static int 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 dc->is_ldex = false;
 dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
 
-dc->next_page_start =
-(dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+/* Bound the number of insns to execute to those left on the page.  */
+bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
+
+/* If architectural single step active, limit to 1.  */
+if (dc->ss_active) {
+bound = 1;
+}
+max_insns = MIN(max_insns, bound);
 
 init_tmp_a64_array(dc);
 
@@ -11323,12 +11330,6 @@ static void aarch64_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 disas_a64_insn(env, dc);
 }
 
-if (dc->base.is_jmp == DISAS_NEXT) {
-if (dc->ss_active || dc->pc >= dc->next_page_start) {
-dc->base.is_jmp = DISAS_TOO_MANY;
-}
-}
-
 dc->base.pc_next = dc->pc;
 translator_loop_temp_check(&dc->base);
 }
-- 
2.13.5




Re: [Qemu-devel] [PATCH v7 01/22] Revert "io: add new qio_channel_{readv, writev, read, write}_all functions"

2017-09-06 Thread Daniel P. Berrange
On Wed, Sep 06, 2017 at 04:42:18PM +0200, Juan Quintela wrote:
> Eric Blake  wrote:
> > On 09/06/2017 06:51 AM, Juan Quintela wrote:
> >> This reverts commit d4622e55883211072621958d39ddaa73483d201e.
> >
> > But with no reason why?  What bugs are you fixing by reverting this?
> 
> I put it on the cover letter.  I am investigating *why* it fails on me.
> It got the thread handed.

Your functions return the number of bytes written. My impl only
returns the 0 or -1 on the basis that the caller does not need
to know how many bytes were written - its always exactly the
amount asked for. You probably need to adjust your code to take
that into account.

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



[Qemu-devel] [PULL 21/32] target/arm: [tcg, a64] Port to breakpoint_check

2017-09-06 Thread Richard Henderson
From: Lluís Vilanova 

Incrementally paves the way towards using the generic instruction translation
loop.

Reviewed-by: Emilio G. Cota 
Reviewed-by: Richard Henderson 
Signed-off-by: Lluís Vilanova 
Message-Id: <150002461630.22386.14827196109258040543.st...@frigg.lan>
[rth: Use DISAS_TOO_MANY for "execute only one more" after bp.]
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 48 ++
 1 file changed, 31 insertions(+), 17 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 1eab10696c..e94198280d 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -11267,6 +11267,30 @@ static void aarch64_tr_insn_start(DisasContextBase 
*dcbase, CPUState *cpu)
 tcg_gen_insn_start(dc->pc, 0, 0);
 }
 
+static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState 
*cpu,
+const CPUBreakpoint *bp)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+
+if (bp->flags & BP_CPU) {
+gen_a64_set_pc_im(dc->pc);
+gen_helper_check_breakpoints(cpu_env);
+/* End the TB early; it likely won't be executed */
+dc->base.is_jmp = DISAS_TOO_MANY;
+} else {
+gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
+/* The address covered by the breakpoint must be
+   included in [tb->pc, tb->pc + tb->size) in order
+   to for it to be properly cleared -- thus we
+   increment the PC here so that the logic setting
+   tb->size below does the right thing.  */
+dc->pc += 4;
+dc->base.is_jmp = DISAS_NORETURN;
+}
+
+return true;
+}
+
 void gen_intermediate_code_a64(DisasContextBase *dcbase, CPUState *cs,
TranslationBlock *tb)
 {
@@ -11303,25 +11327,15 @@ void gen_intermediate_code_a64(DisasContextBase 
*dcbase, CPUState *cs,
 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
 CPUBreakpoint *bp;
 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
-if (bp->pc == dc->pc) {
-if (bp->flags & BP_CPU) {
-gen_a64_set_pc_im(dc->pc);
-gen_helper_check_breakpoints(cpu_env);
-/* End the TB early; it likely won't be executed */
-dc->base.is_jmp = DISAS_UPDATE;
-} else {
-gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
-/* The address covered by the breakpoint must be
-   included in [dc->base.tb->pc, dc->base.tb->pc + 
dc->base.tb->size) in order
-   to for it to be properly cleared -- thus we
-   increment the PC here so that the logic setting
-   dc->base.tb->size below does the right thing.  */
-dc->pc += 4;
-goto done_generating;
+if (bp->pc == dc->base.pc_next) {
+if (aarch64_tr_breakpoint_check(&dc->base, cs, bp)) {
+break;
 }
-break;
 }
 }
+if (dc->base.is_jmp > DISAS_TOO_MANY) {
+break;
+}
 }
 
 if (dc->base.num_insns == max_insns && (dc->base.tb->cflags & 
CF_LAST_IO)) {
@@ -11392,6 +11406,7 @@ void gen_intermediate_code_a64(DisasContextBase 
*dcbase, CPUState *cs,
 } else {
 switch (dc->base.is_jmp) {
 case DISAS_NEXT:
+case DISAS_TOO_MANY:
 gen_goto_tb(dc, 1, dc->pc);
 break;
 case DISAS_JUMP:
@@ -11429,7 +11444,6 @@ void gen_intermediate_code_a64(DisasContextBase 
*dcbase, CPUState *cs,
 }
 }
 
-done_generating:
 gen_tb_end(tb, dc->base.num_insns);
 
 #ifdef DEBUG_DISAS
-- 
2.13.5




[Qemu-devel] [PULL 22/32] target/arm: [tcg] Port to translate_insn

2017-09-06 Thread Richard Henderson
From: Lluís Vilanova 

Incrementally paves the way towards using the generic instruction translation
loop.

Reviewed-by: Emilio G. Cota 
Signed-off-by: Lluís Vilanova 
Message-Id: <150002485863.22386.13949856269576226529.st...@frigg.lan>
[rth: Adjust for translate_insn interface change.]
Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |   1 +
 target/arm/translate.c | 165 +++--
 2 files changed, 91 insertions(+), 75 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index a804ff65ac..e8dcec51ac 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -9,6 +9,7 @@ typedef struct DisasContext {
 DisasContextBase base;
 
 target_ulong pc;
+target_ulong next_page_start;
 uint32_t insn;
 /* Nonzero if this instruction has been conditionally skipped.  */
 int condjmp;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 2f5f65310d..5737299943 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -11880,6 +11880,8 @@ static int arm_tr_init_disas_context(DisasContextBase 
*dcbase,
 dc->is_ldex = false;
 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
 
+dc->next_page_start =
+(dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 
 cpu_F0s = tcg_temp_new_i32();
 cpu_F1s = tcg_temp_new_i32();
@@ -11973,14 +11975,93 @@ static bool arm_tr_breakpoint_check(DisasContextBase 
*dcbase, CPUState *cpu,
 return true;
 }
 
+static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+{
+DisasContext *dc = container_of(dcbase, DisasContext, base);
+CPUARMState *env = cpu->env_ptr;
+
+#ifdef CONFIG_USER_ONLY
+/* Intercept jump to the magic kernel page.  */
+if (dc->pc >= 0x) {
+/* We always get here via a jump, so know we are not in a
+   conditional execution block.  */
+gen_exception_internal(EXCP_KERNEL_TRAP);
+dc->base.is_jmp = DISAS_NORETURN;
+return;
+}
+#endif
+
+if (dc->ss_active && !dc->pstate_ss) {
+/* Singlestep state is Active-pending.
+ * If we're in this state at the start of a TB then either
+ *  a) we just took an exception to an EL which is being debugged
+ * and this is the first insn in the exception handler
+ *  b) debug exceptions were masked and we just unmasked them
+ * without changing EL (eg by clearing PSTATE.D)
+ * In either case we're going to take a swstep exception in the
+ * "did not step an insn" case, and so the syndrome ISV and EX
+ * bits should be zero.
+ */
+assert(dc->base.num_insns == 1);
+gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
+  default_exception_el(dc));
+dc->base.is_jmp = DISAS_NORETURN;
+return;
+}
+
+if (dc->thumb) {
+disas_thumb_insn(env, dc);
+if (dc->condexec_mask) {
+dc->condexec_cond = (dc->condexec_cond & 0xe)
+| ((dc->condexec_mask >> 4) & 1);
+dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
+if (dc->condexec_mask == 0) {
+dc->condexec_cond = 0;
+}
+}
+} else {
+unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
+dc->pc += 4;
+disas_arm_insn(dc, insn);
+}
+
+if (dc->condjmp && !dc->base.is_jmp) {
+gen_set_label(dc->condlabel);
+dc->condjmp = 0;
+}
+
+if (dc->base.is_jmp == DISAS_NEXT) {
+/* Translation stops when a conditional branch is encountered.
+ * Otherwise the subsequent code could get translated several times.
+ * Also stop translation when a page boundary is reached.  This
+ * ensures prefetch aborts occur at the right place.  */
+
+if (is_singlestepping(dc)) {
+dc->base.is_jmp = DISAS_TOO_MANY;
+} else if ((dc->pc >= dc->next_page_start) ||
+   ((dc->pc >= dc->next_page_start - 3) &&
+insn_crosses_page(env, dc))) {
+/* We want to stop the TB if the next insn starts in a new page,
+ * or if it spans between this page and the next. This means that
+ * if we're looking at the last halfword in the page we need to
+ * see if it's a 16-bit Thumb insn (which will fit in this TB)
+ * or a 32-bit Thumb insn (which won't).
+ * This is to avoid generating a silly TB with a single 16-bit insn
+ * in it at the end of this page (which would execute correctly
+ * but isn't very efficient).
+ */
+dc->base.is_jmp = DISAS_TOO_MANY;
+}
+}
+
+dc->base.pc_next = dc->pc;
+}
+
 /* generate intermediate code for basic block 'tb'.  */
 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
 {
-CPUARMState *env = cs->env_ptr;

Re: [Qemu-devel] [PATCH 5/5] s390x/ccs: add ccw-tester emulated device

2017-09-06 Thread Halil Pasic


On 09/06/2017 05:20 PM, Cornelia Huck wrote:
> On Wed, 6 Sep 2017 16:24:13 +0200
> Halil Pasic  wrote:
> 
>> On 09/06/2017 03:18 PM, Cornelia Huck wrote:
>>> On Tue,  5 Sep 2017 13:16:45 +0200
>>> Halil Pasic  wrote:
>>>   
 Add a fake device meant for testing the correctness of our css emulation.

 What we currently have is writing a Fibonacci sequence of uint32_t to the
 device via ccw write. The write is going to fail if it ain't a Fibonacci
 and indicate a device exception in scsw together with the proper residual
 count.

 Of course lot's of invalid inputs (besides basic data processing) can be
 tested with that as well.

 Usage:
 1) fire up a qemu with something like -device ccw-tester,devno=fe.0.0001
on the command line
 2) exercise the device from the guest

 Signed-off-by: Halil Pasic 
 ---

 It may not make sense to merge this work in the current form, as it is
 solely for test purposes.
 ---
  hw/s390x/Makefile.objs |   1 +
  hw/s390x/ccw-tester.c  | 179 
 +
  2 files changed, 180 insertions(+)
  create mode 100644 hw/s390x/ccw-tester.c  
>>>
>>> The main problem here is that you want to exercise a middle layer (the
>>> css code) and need to write boilerplate code on both host and guest
>>> side in order to be able to do so.
>>>   
>>
>> Nod.
>>
>>> In general, a device that accepts arbitrary channel programs looks
>>> useful for testing purposes. I would split out processing of expected
>>> responses out, though, so that it can be more easily reused for
>>> different use cases.
>>>   
>>
>> I'm not sure what do you mean here. Could you clarify please?
> 
> Maybe doing things like logging received ccws and responses etc. and
> and then comparing against an expected outcome. You should be able to
> write test cases for different sets of things to be tested. I know this
> is awfully vague :)

Yes it does sound awfully vague :). In my case different tests are
actually done in the kernel module implementing a driver for this
device. I compare the expected outcome and the actual outcome there.
This device is just a back-end lending itself to experimentation.

> 
>>
>>> (I dimly recall other test devices...)
>>>   
>>
>> What's on your mind? How do these relate to our problem? Can you
>> give me some pointers?
> 
> I was thinking of precedent for test devices... but as said, I only
> recall this very dimly.
> 
>>
>>> For the guest tester: Can that be done via the qtest infrastructure
>>> somehow?
>>>   
>>
>> Well, for now I have the out-of-tree Linux kernel module provided in the
>> cover letter of the series (you did not comment on that one yet).
> 
> Yes, I saw that, but have not yet looked at it. If there is a way to do
> it without too many extra parts, I'd prefer that.
> 

Well, I think the module is almost as economical with extra parts as it
can get: it uses the kernel infrastructure and does not do a whole lot
of things on top.

I think it's worth a look. I hope it will also give answers to some
of the implicit questions I see above. Yes, tests done in the driver
are currently very few. Both with and without indirect data access
we first let a device consume a Fibonacci sequence and verify that
the IO has succeeded. Then we deliberately change an element in the
sequence so it ain't the next Fibonacci number. And check for unit
exception and proper residual count. With that we are sure that
the data was properly consumed up until the given element. For IDA
we the shorten the sequence so it does not contain the 'broken'
element, and expect completion again. As you see this is a sufficient
test for the good path for single CCW programs.

Extending to testing chaining (different concern), or responses
to broken channel programs (e.g. ORB flags, bad addresses, tic
rules) should be quite straightforward.

>>
>> I think for building trust regarding my IDA implementation it should be
>> able to do the job. Don't you agree?
> 
> There's nothing wrong with your test. But we really should try to move
> to some kind of unified testing that is hopefully self-contained so
> that interested people can just play with it within the context of qemu.
> 
>>
>> Just a couple of hours ago Janosch (cc-ing Janosch) came to my office,
>> and told be that he is working on CCW-tests for zonk (a minimal kernel
>> for testing -- internal tool AFAIR).
>>
>> By qtest you mean libqtest/libqos? I'm not familiar with that and have no
>> idea what do we have for s390x. I see on libqos-s390x file in test/libqos
>> for starters.
> 
> Yes, that was what I was thinking about. Integrating into what is
> already there is what we should aim for.
> 
> [For things that are done via kvm, kvm unit tests are good. But I think
> we can do css tests completely within qemu.]
> 

I agree fully, the point is somebody needs to make it happen. I would
be very sad if forced to make it happen

  1   2   3   4   >