Re: [Qemu-devel] [PATCH RFC v5 3/7] qemu_init_vcpu: add a new Error parameter to propagate

2018-10-11 Thread Fei Li




On 10/11/2018 09:19 PM, Markus Armbruster wrote:

Fei Li  writes:


The caller of qemu_init_vcpu() already passed the **errp to handle

Which caller?  There are many.  Or do you mean "The callers"?

Oh, sorry, I mean "The callers" :)



errors. In view of this, add a new Error parameter to the following
call trace to propagate the error and let the further caller check it.

Which "call trace"?

Actually, I want to say all functions called by qemu_init_vcpu()..



Besides, make qemu_init_vcpu() return a Boolean value to let its
callers know whether it succeeds.

Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
---
  accel/tcg/user-exec-stub.c  |  2 +-
  cpus.c  | 34 +-
  include/qom/cpu.h   |  2 +-
  target/alpha/cpu.c  |  4 +++-
  target/arm/cpu.c|  4 +++-
  target/cris/cpu.c   |  4 +++-
  target/hppa/cpu.c   |  4 +++-
  target/i386/cpu.c   |  4 +++-
  target/lm32/cpu.c   |  4 +++-
  target/m68k/cpu.c   |  4 +++-
  target/microblaze/cpu.c |  4 +++-
  target/mips/cpu.c   |  4 +++-
  target/moxie/cpu.c  |  4 +++-
  target/nios2/cpu.c  |  4 +++-
  target/openrisc/cpu.c   |  4 +++-
  target/ppc/translate_init.inc.c |  4 +++-
  target/riscv/cpu.c  |  4 +++-
  target/s390x/cpu.c  |  4 +++-
  target/sh4/cpu.c|  4 +++-
  target/sparc/cpu.c  |  4 +++-
  target/tilegx/cpu.c |  4 +++-
  target/tricore/cpu.c|  4 +++-
  target/unicore32/cpu.c  |  4 +++-
  target/xtensa/cpu.c |  4 +++-
  24 files changed, 86 insertions(+), 36 deletions(-)

diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c
index a32b4496af..38f6b928d4 100644
--- a/accel/tcg/user-exec-stub.c
+++ b/accel/tcg/user-exec-stub.c
@@ -10,7 +10,7 @@ void cpu_resume(CPUState *cpu)
  {
  }
  
-void qemu_init_vcpu(CPUState *cpu)

+bool qemu_init_vcpu(CPUState *cpu, Error **errp)
  {

You need to return a value here.  Sure you compile-tested this?

Oops! I forget the TCG case.. The `return true` should be added.
Thanks for pointing this out!



  }
  
diff --git a/cpus.c b/cpus.c

index 361678e459..c4db70607e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1918,7 +1918,7 @@ void cpu_remove_sync(CPUState *cpu)
  /* For temporary buffers for forming a name */
  #define VCPU_THREAD_NAME_SIZE 16
  
-static void qemu_tcg_init_vcpu(CPUState *cpu)

+static void qemu_tcg_init_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  static QemuCond *single_tcg_halt_cond;
@@ -1974,7 +1974,7 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
  }
  }
  
-static void qemu_hax_start_vcpu(CPUState *cpu)

+static void qemu_hax_start_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  
@@ -1991,7 +1991,7 @@ static void qemu_hax_start_vcpu(CPUState *cpu)

  #endif
  }
  
-static void qemu_kvm_start_vcpu(CPUState *cpu)

+static void qemu_kvm_start_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  
@@ -2004,7 +2004,7 @@ static void qemu_kvm_start_vcpu(CPUState *cpu)

 cpu, QEMU_THREAD_JOINABLE);
  }
  
-static void qemu_hvf_start_vcpu(CPUState *cpu)

+static void qemu_hvf_start_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  
@@ -2022,7 +2022,7 @@ static void qemu_hvf_start_vcpu(CPUState *cpu)

 cpu, QEMU_THREAD_JOINABLE);
  }
  
-static void qemu_whpx_start_vcpu(CPUState *cpu)

+static void qemu_whpx_start_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  
@@ -2038,7 +2038,7 @@ static void qemu_whpx_start_vcpu(CPUState *cpu)

  #endif
  }
  
-static void qemu_dummy_start_vcpu(CPUState *cpu)

+static void qemu_dummy_start_vcpu(CPUState *cpu, Error **errp)
  {
  char thread_name[VCPU_THREAD_NAME_SIZE];
  
@@ -2051,11 +2051,12 @@ static void qemu_dummy_start_vcpu(CPUState *cpu)

 QEMU_THREAD_JOINABLE);
  }
  
-void qemu_init_vcpu(CPUState *cpu)

+bool qemu_init_vcpu(CPUState *cpu, Error **errp)
  {
  cpu->nr_cores = smp_cores;
  cpu->nr_threads = smp_threads;
  cpu->stopped = true;
+Error *local_err = NULL;
  
  if (!cpu->as) {

  /* If the target cpu hasn't set up any address spaces itself,
@@ -2066,22 +2067,29 @@ void qemu_init_vcpu(CPUState *cpu)
  }
  
  if (kvm_enabled()) {

-qemu_kvm_start_vcpu(cpu);
+qemu_kvm_start_vcpu(cpu, _err);
  } else if (hax_enabled()) {
-qemu_hax_start_vcpu(cpu);
+qemu_hax_start_vcpu(cpu, _err);
  } else if (hvf_enabled()) {
-qemu_hvf_start_vcpu(cpu);
+qemu_hvf_start_vcpu(cpu, _err);
  } else if (tcg_enabled()) {
-qemu_tcg_init_vcpu(cpu);
+qemu_tcg_init_vcpu(cpu, _err);
  } 

Re: [Qemu-devel] [PATCH 30/31] blockdev: Convert drive_new() to Error

2018-10-11 Thread Markus Armbruster
Copying Marc-André for a possible connection to his recent work on
improving help.  Marc-André, search for "format=help".  Just in case you
have further observations to offer.

Max Reitz  writes:

> On 08.10.18 19:31, Markus Armbruster wrote:
>> Calling error_report() from within a a function that takes an Error **
>> argument is suspicious.  drive_new() does that, and its caller
>> drive_init_func() then exit()s.
>
> I'm afraid I don't quite follow you here.  There is no function here
> that takes an Error ** already and then calls error_report().  There is
> however drive_new() that does not take an Error **, consequentially
> calls error_report(), and there is its caller drive_init_func() which
> does take an Error ** but does not set it.
>
> So while I fully agree with you to make drive_new() take an Error **
> (and thus effectively fix drive_init_func()), I don't quite understand
> this explanation.
>
> (Furthermore, drive_init_func() does not exit().  It's main() that
> exit()s after calling drive_init_func().)
  
You're right.

There's about a dozen patches cleaning up pretty much the same thing,
and I reused the same commit message with the appropriate variations.  I
failed to vary this instance appropriately.  Sorry!

I'll fix this for v2.

>> Its caller main(), via
>> qemu_opts_foreach(), is fine with it, but clean it up anyway:
>> 
>> * Convert drive_new() to Error
>> 
>> * Update add_init_drive() to report the error received from
>>   drive_new().
>> 
>> * Make main() pass _fatal through qemu_opts_foreach(),
>>   drive_init_func() to drive_new()
>> 
>> * Make default_drive() pass _abort through qemu_opts_foreach(),
>>   drive_init_func() to drive_new()
>> 
>> Cc: Kevin Wolf 
>> Cc: Max Reitz 
>> Signed-off-by: Markus Armbruster 
>> ---
>>  blockdev.c| 27 ++-
>>  device-hotplug.c  |  5 -
>>  include/sysemu/blockdev.h |  3 ++-
>>  vl.c  | 11 ---
>>  4 files changed, 24 insertions(+), 22 deletions(-)
>> 
>> diff --git a/blockdev.c b/blockdev.c
>> index a8755bd908..574adbcb7f 100644
>> --- a/blockdev.c
>> +++ b/blockdev.c
>> @@ -759,7 +759,8 @@ QemuOptsList qemu_legacy_drive_opts = {
>
> [...]
>
>> @@ -991,7 +992,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, 
>> BlockInterfaceType block_default_type)
>>  bs_opts = NULL;
>>  if (!blk) {
>>  if (local_err) {
>> -error_report_err(local_err);
>> +error_propagate(errp, local_err);
>>  }
>
> Wait, what would be the case where blockdev_init() returns NULL but
> *errp remains unse——— oh no.
>
> There is only one case which is someone specified "format=help".  Hm.  I
> suppose you are as unhappy as me about the fact that because of this
> drive_new() cannot guarantee that *errp is set in case of an error.

That's an ugly interface wart we have in a few places.  In a nutshell, either

* succeed and return a value indicating success

* fail, set an error, and return a value indicating failure

* print help, leave error alone, and return a value indicating failure

> I think it's ""fine"" (*gnashing teeth*) to keep it this way, but it
> means that callers need to continue to check the return value and not
> *errp alone.

Yes, they need to check both.

Note that -device and -machine use a technique I consider cleaner:
there's a separate function FOO_help_func() to deal with providing help
before we do the actual work.  If the user asked for help,
FOO_help_func() prints some, and returns 1.  Else it returns 0.  This
lets main() call exit(0) after help.

>>  goto fail;
>>  } else {
>> diff --git a/device-hotplug.c b/device-hotplug.c
>> index cd427e2c76..6090d5f1e9 100644
>> --- a/device-hotplug.c
>> +++ b/device-hotplug.c
>> @@ -28,6 +28,7 @@
>>  #include "sysemu/block-backend.h"
>>  #include "sysemu/blockdev.h"
>>  #include "qapi/qmp/qdict.h"
>> +#include "qapi/error.h"
>>  #include "qemu/config-file.h"
>>  #include "qemu/option.h"
>>  #include "sysemu/sysemu.h"
>> @@ -36,6 +37,7 @@
>>  
>>  static DriveInfo *add_init_drive(const char *optstr)
>>  {
>> +Error *err = NULL;
>>  DriveInfo *dinfo;
>>  QemuOpts *opts;
>>  MachineClass *mc;
>> @@ -45,8 +47,9 @@ static DriveInfo *add_init_drive(const char *optstr)
>>  return NULL;
>>  
>>  mc = MACHINE_GET_CLASS(current_machine);
>> -dinfo = drive_new(opts, mc->block_default_type);
>> +dinfo = drive_new(opts, mc->block_default_type, );
>>  if (!dinfo) {
>> +error_report_err(err);
>>  qemu_opts_del(opts);
>>  return NULL;
>>  }
>> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
>> index 24954b94e0..d34c4920dc 100644
>> --- a/include/sysemu/blockdev.h
>> +++ b/include/sysemu/blockdev.h
>> @@ -54,7 +54,8 @@ DriveInfo *drive_get_next(BlockInterfaceType type);
>>  QemuOpts *drive_def(const char *optstr);
>>  QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
>>  

Re: [Qemu-devel] [PATCH RFC v5 2/7] ui/vnc.c: polish vnc_init_func

2018-10-11 Thread Fei Li




On 10/11/2018 09:13 PM, Markus Armbruster wrote:

Fei Li  writes:


Add a new Error parameter for vnc_display_init() to handle errors
in its caller: vnc_init_func(), just like vnc_display_open() does.
And let the call trace propagate the Error.

Besides, make vnc_start_worker_thread() return a bool to indicate
whether it succeeds instead of returning nothing.

Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
---
  include/ui/console.h |  2 +-
  ui/vnc-jobs.c|  9 ++---
  ui/vnc-jobs.h|  2 +-
  ui/vnc.c | 12 +---
  4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index fb969caf70..c17803c530 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -453,7 +453,7 @@ void qemu_display_early_init(DisplayOptions *opts);
  void qemu_display_init(DisplayState *ds, DisplayOptions *opts);
  
  /* vnc.c */

-void vnc_display_init(const char *id);
+void vnc_display_init(const char *id, Error **errp);
  void vnc_display_open(const char *id, Error **errp);
  void vnc_display_add_client(const char *id, int csock, bool skipauth);
  int vnc_display_password(const char *id, const char *password);
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index 929391f85d..8807d7217c 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -331,15 +331,18 @@ static bool vnc_worker_thread_running(void)
  return queue; /* Check global queue */
  }
  
-void vnc_start_worker_thread(void)

+bool vnc_start_worker_thread(Error **errp)
  {
  VncJobQueue *q;
  
-if (vnc_worker_thread_running())

-return ;
+if (vnc_worker_thread_running()) {
+goto out;
+}
  
  q = vnc_queue_init();

  qemu_thread_create(>thread, "vnc_worker", vnc_worker_thread, q,
 QEMU_THREAD_DETACHED);
  queue = q; /* Set global queue */
+out:
+return true;
  }

This function cannot fail.  Why convert it to Error, and complicate its
caller?

[Issue1]
Actually, this is to pave the way for patch 7/7, in case 
qemu_thread_create() fails.

Patch 7/7 is long enough, thus I wrote the patch 1/2/3 separately to mainly
connects the broken errp for callers who initially have the errp.

[I am back... If the other codes in this patches be squashed, maybe 
merge [Issue1]

into patch 7/7 looks more intuitive.]

diff --git a/ui/vnc-jobs.h b/ui/vnc-jobs.h
index 59f66bcc35..14640593db 100644
--- a/ui/vnc-jobs.h
+++ b/ui/vnc-jobs.h
@@ -37,7 +37,7 @@ void vnc_job_push(VncJob *job);
  void vnc_jobs_join(VncState *vs);
  
  void vnc_jobs_consume_buffer(VncState *vs);

-void vnc_start_worker_thread(void);
+bool vnc_start_worker_thread(Error **errp);
  
  /* Locks */

  static inline int vnc_trylock_display(VncDisplay *vd)
diff --git a/ui/vnc.c b/ui/vnc.c
index cf221c83cc..f3806e76db 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3205,7 +3205,7 @@ static const DisplayChangeListenerOps dcl_ops = {
  .dpy_cursor_define= vnc_dpy_cursor_define,
  };
  
-void vnc_display_init(const char *id)

+void vnc_display_init(const char *id, Error **errp)
  {
  VncDisplay *vd;
  

if (vnc_display_find(id) != NULL) {
return;
}
vd = g_malloc0(sizeof(*vd));

vd->id = strdup(id);
QTAILQ_INSERT_TAIL(_displays, vd, next);

QTAILQ_INIT(>clients);
vd->expires = TIME_MAX;

if (keyboard_layout) {
trace_vnc_key_map_init(keyboard_layout);
vd->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);
} else {
vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
}

if (!vd->kbd_layout) {
exit(1);

Uh, init_keyboard_layout() reports errors to stderr, and the exit(1)
here makes them fatal.  Okay before this patch, but inappropriate
afterwards.  I'm afraid you have to convert init_keyboard_layout() to
Error first.

[Issue2]
Right. But I notice the returned kbd_layout_t *kbd_layout is a static 
value and also
will be used by others, how about passing the errp parameter to 
init_keyboard_layout()

as follows? And for its other callers, just pass NULL.

@@ -3222,13 +3222,13 @@ void vnc_display_init(const char *id, Error **errp)

 if (keyboard_layout) {
 trace_vnc_key_map_init(keyboard_layout);
-    vd->kbd_layout = init_keyboard_layout(name2keysym, 
keyboard_layout);
+    vd->kbd_layout = init_keyboard_layout(name2keysym, 
keyboard_layout, errp);

 } else {
-    vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us");
+    vd->kbd_layout = init_keyboard_layout(name2keysym, "en-us", errp);
 }

 if (!vd->kbd_layout) {
-    exit(1);
+    return;
 }



}

vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;

@@ -3235,7 +3235,9 @@ void vnc_display_init(const char *id)
  vd->connections_limit = 32;
  
  qemu_mutex_init(>mutex);

-vnc_start_worker_thread();
+if (!vnc_start_worker_thread(errp)) {
+return;
+}
  

Re: [Qemu-devel] [PATCH RFC v5 1/7] Fix segmentation fault when qemu_signal_init fails

2018-10-11 Thread Fei Li




On 10/11/2018 06:02 PM, Markus Armbruster wrote:

Fei Li  writes:


Currently, when qemu_signal_init() fails it only returns a non-zero
value but without propagating any Error. But its callers need a
non-null err when runs error_report_err(err), or else 0->msg occurs.

The bug is in qemu_init_main_loop():

 ret = qemu_signal_init();
 if (ret) {
 return ret;
 }

Fails without setting an error, unlike the other failures.  Its callers
crash then.

Thanks!

To avoid such segmentation fault, add a new Error parameter to make
the call trace to propagate the err to the final caller.

Signed-off-by: Fei Li 
Reviewed-by: Fam Zheng 
---
  include/qemu/osdep.h | 2 +-
  util/compatfd.c  | 9 ++---
  util/main-loop.c | 9 -
  3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 4f8559e550..f1f56763a0 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -421,7 +421,7 @@ struct qemu_signalfd_siginfo {
   additional fields in the future) */
  };
  
-int qemu_signalfd(const sigset_t *mask);

+int qemu_signalfd(const sigset_t *mask, Error **errp);
  void sigaction_invoke(struct sigaction *action,
struct qemu_signalfd_siginfo *info);
  #endif
diff --git a/util/compatfd.c b/util/compatfd.c
index 980bd33e52..d3ed890405 100644
--- a/util/compatfd.c
+++ b/util/compatfd.c
@@ -16,6 +16,7 @@
  #include "qemu/osdep.h"
  #include "qemu-common.h"
  #include "qemu/thread.h"
+#include "qapi/error.h"
  
  #include 
  
@@ -65,7 +66,7 @@ static void *sigwait_compat(void *opaque)

  }
  }
  
-static int qemu_signalfd_compat(const sigset_t *mask)

+static int qemu_signalfd_compat(const sigset_t *mask, Error **errp)
  {
  struct sigfd_compat_info *info;
  QemuThread thread;
@@ -73,11 +74,13 @@ static int qemu_signalfd_compat(const sigset_t *mask)
  
  info = malloc(sizeof(*info));

  if (info == NULL) {
+error_setg(errp, "Failed to allocate signalfd memory");
  errno = ENOMEM;
  return -1;
  }
  
  if (pipe(fds) == -1) {

+error_setg(errp, "Failed to create signalfd pipe");
  free(info);
  return -1;
  }
@@ -94,7 +97,7 @@ static int qemu_signalfd_compat(const sigset_t *mask)
  return fds[0];
  }
  
-int qemu_signalfd(const sigset_t *mask)

+int qemu_signalfd(const sigset_t *mask, Error **errp)
  {
  #if defined(CONFIG_SIGNALFD)
  int ret;
@@ -106,5 +109,5 @@ int qemu_signalfd(const sigset_t *mask)
  }
  #endif
  
-return qemu_signalfd_compat(mask);

+return qemu_signalfd_compat(mask, errp);
  }

I think this takes the Error conversion too far.

qemu_signalfd() is like the signalfd() system call, only portable, and
setting FD_CLOEXEC.  In particular, it reports failure just like a
system call: it sets errno and returns -1.  I'd prefer to keep it that
way.  Instead...


diff --git a/util/main-loop.c b/util/main-loop.c
index affe0403c5..9671b6d226 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -71,7 +71,7 @@ static void sigfd_handler(void *opaque)
  }
  }
  
-static int qemu_signal_init(void)

+static int qemu_signal_init(Error **errp)
  {
  int sigfd;
  sigset_t set;
@@ -94,9 +94,8 @@ static int qemu_signal_init(void)
  pthread_sigmask(SIG_BLOCK, , NULL);
  
  sigdelset(, SIG_IPI);

-sigfd = qemu_signalfd();
+sigfd = qemu_signalfd(, errp);
  if (sigfd == -1) {
-fprintf(stderr, "failed to create signalfd\n");
  return -errno;
  }
  

... change this function so:

pthread_sigmask(SIG_BLOCK, , NULL);

sigdelset(, SIG_IPI);

sigfd = qemu_signalfd();
if (sigfd == -1) {
   -fprintf(stderr, "failed to create signalfd\n");
   +error_setg_errno(errp, errno, "failed to create signalfd");
return -errno;
}

Does this make sense?
Yes, it looks more concise if we only have this patch, but triggers one 
errno-set

issue after applying patch 7/7, which adds a Error **errp parameter for
qemu_thread_create() to let its callers handle the error instead of 
exit() directly

to add the robustness.

For the patch series' current implementation, the  modified 
qemu_thread_create()
in 7/7 patch returns a Boolean value to indicate whether it succeeds and 
set the
error reason into the passed errp, and did not set the errno. Actually 
another

similar errno-set issue has been talked in last patch. :)
If we set the errno in future qemu_thread_create(), we need to 
distinguish the Linux
and Windows implementation. For Linux, we can use error_setg_errno() to 
set errno.

But for Windows, I am not sure if we can use

"errno = GetLastError()"

to set errno, as this seems a little weird. Do you have any idea about this?

BTW, if we have a decent errno-set way for Windows, I will adopt your above
proposal for this patch.

Have a nice day, thanks for the review :)
Fei

@@ -109,7 +108,7 

[Qemu-devel] [PATCH] migration: avoid segmentfault when take a snapshot of a VM which being migrated

2018-10-11 Thread jialina01
During an active background migraion, snapshot will trigger a
segmentfault. As snapshot clears the "current_migration" struct
and updates "to_dst_file" before it finds out that there is a
migration task, Migration accesses the null pointer in
"current_migration" struct and qemu crashes eventually.

Signed-off-by: jialina01 
Signed-off-by: chaiwen 
Signed-off-by: zhangyu 
---
 migration/savevm.c | 14 +-
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/migration/savevm.c b/migration/savevm.c
index 2d10e45582..9cb97ca343 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1319,21 +1319,18 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
 MigrationState *ms = migrate_get_current();
 MigrationStatus status;
 
-migrate_init(ms);
-
-ms->to_dst_file = f;
-
 if (migration_is_blocked(errp)) {
-ret = -EINVAL;
-goto done;
+return -EINVAL;
 }
 
 if (migrate_use_block()) {
 error_setg(errp, "Block migration and snapshots are incompatible");
-ret = -EINVAL;
-goto done;
+return -EINVAL;
 }
 
+migrate_init(ms);
+ms->to_dst_file = f;
+
 qemu_mutex_unlock_iothread();
 qemu_savevm_state_header(f);
 qemu_savevm_state_setup(f);
@@ -1355,7 +1352,6 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
 error_setg_errno(errp, -ret, "Error while writing VM state");
 }
 
-done:
 if (ret != 0) {
 status = MIGRATION_STATUS_FAILED;
 } else {
-- 
2.13.2.windows.1




[Qemu-devel] [PATCH] vfio-pci: make vfio-pci device more QOM conventional

2018-10-11 Thread Li Qiang
Define a TYPE_VFIO_PCI and drop DO_UPCAST.

Signed-off-by: Li Qiang 
---
 hw/vfio/pci.c | 29 +++--
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 866f0deeb7..3f232aedff 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -37,6 +37,9 @@
 
 #define MSIX_CAP_LENGTH 12
 
+#define TYPE_VFIO_PCI "vfio-pci"
+#define PCI_VFIO(obj)OBJECT_CHECK(VFIOPCIDevice, obj, TYPE_VFIO_PCI)
+
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
 static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
 
@@ -222,7 +225,7 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev)
 
 static void vfio_intx_update(PCIDevice *pdev)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 PCIINTxRoute route;
 Error *err = NULL;
 
@@ -477,7 +480,7 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, 
MSIMessage msg,
 static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
MSIMessage *msg, IOHandler *handler)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 VFIOMSIVector *vector;
 int ret;
 
@@ -574,7 +577,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
 
 static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 VFIOMSIVector *vector = >msi_vectors[nr];
 
 trace_vfio_msix_vector_release(vdev->vbasedev.name, nr);
@@ -1086,7 +1089,7 @@ static const MemoryRegionOps vfio_vga_ops = {
  */
 static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 VFIORegion *region = >bars[bar].region;
 MemoryRegion *mmap_mr, *region_mr, *base_mr;
 PCIIORegion *r;
@@ -1132,7 +1135,7 @@ static void vfio_sub_page_bar_update_mapping(PCIDevice 
*pdev, int bar)
  */
 uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;
 
 memcpy(_bits, vdev->emulated_config_bits + addr, len);
@@ -1165,7 +1168,7 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t 
addr, int len)
 void vfio_pci_write_config(PCIDevice *pdev,
uint32_t addr, uint32_t val, int len)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 uint32_t val_le = cpu_to_le32(val);
 
 trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len);
@@ -2801,7 +2804,7 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice 
*vdev)
 
 static void vfio_realize(PCIDevice *pdev, Error **errp)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 VFIODevice *vbasedev_iter;
 VFIOGroup *group;
 char *tmp, *subsys, group_path[PATH_MAX], *group_name;
@@ -3084,8 +3087,7 @@ error:
 
 static void vfio_instance_finalize(Object *obj)
 {
-PCIDevice *pci_dev = PCI_DEVICE(obj);
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pci_dev);
+VFIOPCIDevice *vdev = PCI_VFIO(obj);
 VFIOGroup *group = vdev->vbasedev.group;
 
 vfio_display_finalize(vdev);
@@ -3105,7 +3107,7 @@ static void vfio_instance_finalize(Object *obj)
 
 static void vfio_exitfn(PCIDevice *pdev)
 {
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(pdev);
 
 vfio_unregister_req_notifier(vdev);
 vfio_unregister_err_notifier(vdev);
@@ -3120,8 +3122,7 @@ static void vfio_exitfn(PCIDevice *pdev)
 
 static void vfio_pci_reset(DeviceState *dev)
 {
-PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);
+VFIOPCIDevice *vdev = PCI_VFIO(dev);
 
 trace_vfio_pci_reset(vdev->vbasedev.name);
 
@@ -3161,7 +3162,7 @@ post_reset:
 static void vfio_instance_init(Object *obj)
 {
 PCIDevice *pci_dev = PCI_DEVICE(obj);
-VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, PCI_DEVICE(obj));
+VFIOPCIDevice *vdev = PCI_VFIO(obj);
 
 device_add_bootindex_property(obj, >bootindex,
   "bootindex", NULL,
@@ -3245,7 +3246,7 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, 
void *data)
 }
 
 static const TypeInfo vfio_pci_dev_info = {
-.name = "vfio-pci",
+.name = TYPE_VFIO_PCI,
 .parent = TYPE_PCI_DEVICE,
 .instance_size = sizeof(VFIOPCIDevice),
 .class_init = vfio_pci_dev_class_init,
-- 
2.11.0




[Qemu-devel] [RFC 0/5] Improve balloon handling of pagesizes other than 4kiB

2018-10-11 Thread David Gibson
The virtio-balloon devices was never really thought out for cases
other than 4kiB pagesize on both guest and host.  It works in some
cases, but in others can be ineffectual or even cause guest memory
corruption.

This series makes a handful of preliminary cleanups, then makes a
change to safely, though not perfectly, handle cases with non 4kiB
pagesizes.

David Gibson (5):
  virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate
  virtio-balloon: Corrections to address verification
  virtio-balloon: Rework ballon_page() interface
  virtio-balloon: Use ram_block_discard_range() instead of raw madvise()
  virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size

 hw/virtio/virtio-balloon.c | 100 -
 include/hw/virtio/virtio-balloon.h |   3 +
 2 files changed, 87 insertions(+), 16 deletions(-)

-- 
2.17.1




[Qemu-devel] [RFC 4/5] virtio-balloon: Use ram_block_discard_range() instead of raw madvise()

2018-10-11 Thread David Gibson
Currently, virtio-balloon uses madvise() with MADV_DONTNEED to actually
discard RAM pages inserted into the balloon.  This is basically a Linux
only interface (MADV_DONTNEED exists on some other platforms, but doesn't
always have the same semantics).  It also doesn't work on hugepages and has
some other limitations.

It turns out that postcopy also needs to discard chunks of memory, and uses
a better interface for it: ram_block_discard_range().  It doesn't cover
every case, but it covers more than going direct to madvise() and this
gives us a single place to update for more possibilities in future.

There are some subtleties here to maintain the current balloon behaviour:

* For now, we just ignore requests to balloon in a hugepage backed region.
  That matches current behaviour, because MADV_DONTNEED on a hugepage would
  simply fail, and we ignore the error.

* If host page size is > BALLOON_PAGE_SIZE we can frequently call this on
  non-host-page-aligned addresses.  These would also fail in madvise(),
  which we then ignored.  ram_block_discard_range() error_report()s calls
  on unaligned addresses, so we explicitly check that case to avoid
  spamming the logs.

* We now call ram_block_discard_range() with the *host* page size, whereas
  we previously called madvise() with BALLOON_PAGE_SIZE.  Surprisingly,
  this also matches existing behaviour.  Although the kernel fails madvise
  on unaligned addresses, it will round unaligned sizes *up* to the host
  page size.  Yes, this means that if BALLOON_PAGE_SIZE < guest page size
  we can incorrectly discard more memory than the guest asked us to.  I'm
  planning to address that soon.

Errors other than the ones discussed above, will now be reported by
ram_block_discard_range(), rather than silently ignored, which means we
have a much better chance of seeing when something is going wrong.

Signed-off-by: David Gibson 
---
 hw/virtio/virtio-balloon.c | 24 +++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 7229afad6e..4435905c87 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -37,7 +37,29 @@ static void balloon_inflate_page(VirtIOBalloon *balloon,
  MemoryRegion *mr, hwaddr offset)
 {
 void *addr = memory_region_get_ram_ptr(mr) + offset;
-qemu_madvise(addr, BALLOON_PAGE_SIZE, QEMU_MADV_DONTNEED);
+RAMBlock *rb;
+size_t rb_page_size;
+ram_addr_t ram_offset;
+
+/* XXX is there a better way to get to the RAMBlock than via a
+ * host address? */
+rb = qemu_ram_block_from_host(addr, false, _offset);
+rb_page_size = qemu_ram_pagesize(rb);
+
+/* Silently ignore hugepage RAM blocks */
+if (rb_page_size != getpagesize()) {
+return;
+}
+
+/* Silently ignore unaligned requests */
+if (ram_offset & (rb_page_size - 1)) {
+return;
+}
+
+ram_block_discard_range(rb, ram_offset, rb_page_size);
+/* We ignore errors from ram_block_discard_range(), because it has
+ * already reported them, and failing to discard a balloon page is
+ * not fatal */
 }
 
 static const char *balloon_stat_names[] = {
-- 
2.17.1




[Qemu-devel] [RFC 3/5] virtio-balloon: Rework ballon_page() interface

2018-10-11 Thread David Gibson
This replaces the balloon_page() internal interface with
ballon_inflate_page(), with a slightly different interface.  The new
interface will make future alterations simpler.

Signed-off-by: David Gibson 
---
 hw/virtio/virtio-balloon.c | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index e8611aab0e..7229afad6e 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -33,11 +33,11 @@
 
 #define BALLOON_PAGE_SIZE  (1 << VIRTIO_BALLOON_PFN_SHIFT)
 
-static void balloon_page(void *addr, int deflate)
+static void balloon_inflate_page(VirtIOBalloon *balloon,
+ MemoryRegion *mr, hwaddr offset)
 {
-if (!qemu_balloon_is_inhibited() && !deflate) {
-qemu_madvise(addr, BALLOON_PAGE_SIZE, QEMU_MADV_DONTNEED);
-}
+void *addr = memory_region_get_ram_ptr(mr) + offset;
+qemu_madvise(addr, BALLOON_PAGE_SIZE, QEMU_MADV_DONTNEED);
 }
 
 static const char *balloon_stat_names[] = {
@@ -222,7 +222,6 @@ static void virtio_balloon_handle_output(VirtIODevice 
*vdev, VirtQueue *vq)
 
 while (iov_to_buf(elem->out_sg, elem->out_num, offset, , 4) == 4) {
 hwaddr pa;
-hwaddr addr;
 int p = virtio_ldl_p(vdev, );
 
 pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
@@ -244,11 +243,9 @@ static void virtio_balloon_handle_output(VirtIODevice 
*vdev, VirtQueue *vq)
 
 trace_virtio_balloon_handle_output(memory_region_name(section.mr),
pa);
-/* Using memory_region_get_ram_ptr is bending the rules a bit, but
-   should be OK because we only want a single page.  */
-addr = section.offset_within_region;
-balloon_page(memory_region_get_ram_ptr(section.mr) + addr,
- !!(vq == s->dvq));
+if (!qemu_balloon_is_inhibited() && vq != s->dvq) {
+balloon_inflate_page(s, section.mr, 
section.offset_within_region);
+}
 memory_region_unref(section.mr);
 }
 
-- 
2.17.1




[Qemu-devel] [RFC 2/5] virtio-balloon: Corrections to address verification

2018-10-11 Thread David Gibson
The virtio-balloon device's verification of the address given to it by the
guest has a number of faults:
* The addresses here are guest physical addresses, which should be
  'hwaddr' rather than 'ram_addr_t' (the distinction is admittedly
  pretty subtle and confusing)
* We don't check for section.mr being NULL, which is the main way that
  memory_region_find() reports basic failures.  We really need to check
  that before looking at any other section fields, because
  memory_region_find() doesn't initialize them on the failure path
* We're passing a length of '1' to memory_region_find(), but really the
  guest is requesting that we put the entire page into the balloon,
  so it makes more sense to call it with BALLOON_PAGE_SIZE

Signed-off-by: David Gibson 
---
 hw/virtio/virtio-balloon.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 6ec4bcf4e1..e8611aab0e 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -221,17 +221,20 @@ static void virtio_balloon_handle_output(VirtIODevice 
*vdev, VirtQueue *vq)
 }
 
 while (iov_to_buf(elem->out_sg, elem->out_num, offset, , 4) == 4) {
-ram_addr_t pa;
-ram_addr_t addr;
+hwaddr pa;
+hwaddr addr;
 int p = virtio_ldl_p(vdev, );
 
-pa = (ram_addr_t) p << VIRTIO_BALLOON_PFN_SHIFT;
+pa = (hwaddr) p << VIRTIO_BALLOON_PFN_SHIFT;
 offset += 4;
 
-/* FIXME: remove get_system_memory(), but how? */
-section = memory_region_find(get_system_memory(), pa, 1);
-if (!int128_nz(section.size) ||
-!memory_region_is_ram(section.mr) ||
+section = memory_region_find(get_system_memory(), pa,
+ BALLOON_PAGE_SIZE);
+if (!section.mr) {
+trace_virtio_balloon_bad_addr(pa);
+continue;
+}
+if (!memory_region_is_ram(section.mr) ||
 memory_region_is_rom(section.mr) ||
 memory_region_is_romd(section.mr)) {
 trace_virtio_balloon_bad_addr(pa);
-- 
2.17.1




[Qemu-devel] [RFC 5/5] virtio-balloon: Safely handle BALLOON_PAGE_SIZE < host page size

2018-10-11 Thread David Gibson
The virtio-balloon always works in units of 4kiB (BALLOON_PAGE_SIZE), but
on the host side, we can only actually discard memory in units of the host
page size.

At present we handle this very badly: we silently ignore balloon requests
that aren't host page aligned, and for requests that are host page aligned
we discard the entire host page.  The latter potentially corrupts guest
memory if its page size is smaller than the host's.

We could just disable the balloon if the host page size is not 4kiB, but
that would break a the special case where host and guest have the same page
size, but that's larger than 4kiB.  Thius case currently works by accident:
when the guest puts its page into the balloon, it will submit balloon
requests for each 4kiB subpage.  Most will be ignored, but the one which
happens to be host page aligned will discard the whole lot.

This occurs in practice routinely for POWER KVM systems, since both host
and guest typically use 64kiB pages.

To make this safe, without breaking that useful case, we need to
accumulate 4kiB balloon requests until we have a whole contiguous host page
at which point we can discard it.

We could in principle do that across all guest memory, but it would require
a large bitmap to track.  This patch represents a compromise: instead we
track ballooned subpages for a single contiguous host page at a time.  This
means that if the guest discards all 4kiB chunks of a host page in
succession, we will discard it.  In particular that means the balloon will
continue to work for the (host page size) == (guest page size) > 4kiB case.

If the guest scatters 4kiB requests across different host pages, we don't
discard anything, and issue a warning.  Not ideal, but at least we don't
corrupt guest memory as the previous version could.

Signed-off-by: David Gibson 
---
 hw/virtio/virtio-balloon.c | 67 +-
 include/hw/virtio/virtio-balloon.h |  3 ++
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 4435905c87..39573ef2e3 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -33,33 +33,80 @@
 
 #define BALLOON_PAGE_SIZE  (1 << VIRTIO_BALLOON_PFN_SHIFT)
 
+typedef struct PartiallyBalloonedPage {
+RAMBlock *rb;
+ram_addr_t base;
+unsigned long bitmap[];
+} PartiallyBalloonedPage;
+
 static void balloon_inflate_page(VirtIOBalloon *balloon,
  MemoryRegion *mr, hwaddr offset)
 {
 void *addr = memory_region_get_ram_ptr(mr) + offset;
 RAMBlock *rb;
 size_t rb_page_size;
-ram_addr_t ram_offset;
+int subpages;
+ram_addr_t ram_offset, host_page_base;
 
 /* XXX is there a better way to get to the RAMBlock than via a
  * host address? */
 rb = qemu_ram_block_from_host(addr, false, _offset);
 rb_page_size = qemu_ram_pagesize(rb);
+host_page_base = ram_offset & ~(rb_page_size - 1);
+
+if (rb_page_size == BALLOON_PAGE_SIZE) {
+/* Easy case */
 
-/* Silently ignore hugepage RAM blocks */
-if (rb_page_size != getpagesize()) {
+ram_block_discard_range(rb, ram_offset, rb_page_size);
+/* We ignore errors from ram_block_discard_range(), because it
+ * has already reported them, and failing to discard a balloon
+ * page is not fatal */
 return;
 }
 
-/* Silently ignore unaligned requests */
-if (ram_offset & (rb_page_size - 1)) {
-return;
+/* Hard case
+ *
+ * We've put a piece of a larger host page into the balloon - we
+ * need to keep track until we have a whole host page to
+ * discard
+ */
+subpages = rb_page_size / BALLOON_PAGE_SIZE;
+
+if (balloon->pbp
+&& (rb != balloon->pbp->rb
+|| host_page_base != balloon->pbp->base)) {
+/* We've partially ballooned part of a host page, but now
+ * we're trying to balloon part of a different one.  Too hard,
+ * give up on the old partial page */
+warn_report("Unable to insert a partial page into virtio-balloon");
+free(balloon->pbp);
+balloon->pbp = NULL;
 }
 
-ram_block_discard_range(rb, ram_offset, rb_page_size);
-/* We ignore errors from ram_block_discard_range(), because it has
- * already reported them, and failing to discard a balloon page is
- * not fatal */
+if (!balloon->pbp) {
+/* Starting on a new host page */
+size_t bitlen = BITS_TO_LONGS(subpages) * sizeof(unsigned long);
+balloon->pbp = g_malloc0(sizeof(PartiallyBalloonedPage) + bitlen);
+balloon->pbp->rb = rb;
+balloon->pbp->base = host_page_base;
+}
+
+bitmap_set(balloon->pbp->bitmap,
+   (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE,
+   subpages);
+
+if (bitmap_full(balloon->pbp->bitmap, subpages)) {
+/* We've accumulated a full host page, we can actually discard
+ * it 

[Qemu-devel] [RFC 1/5] virtio-balloon: Remove unnecessary MADV_WILLNEED on deflate

2018-10-11 Thread David Gibson
When the balloon is inflated, we discard memory place in it using madvise()
with MADV_DONTNEED.  And when we deflate it we use MADV_WILLNEED, which
sounds like it makes sense but is actually unnecessary.

The misleadingly named MADV_DONTNEED just discards the memory in question,
it doesn't set any persistent state on it in-kernel; all that's necessary
to bring the memory back is to touch it.  MADV_WILLNEED in contrast
specifically says that the memory will be used soon and faults it in.

Memory that's being given back to the guest by deflating the balloon
*might* be used soon, but it equally could just sit around in the guest's
pools until it actually needs it.  And, over the general timescale that
memory ballooning operates, it seems unlikely that one extra fault for the
guest will be a vast performance issue.

So, simplify the balloon's operation by dropping the madvise() on deflate.

Signed-off-by: David Gibson 
---
 hw/virtio/virtio-balloon.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 1728e4f83a..6ec4bcf4e1 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -35,9 +35,8 @@
 
 static void balloon_page(void *addr, int deflate)
 {
-if (!qemu_balloon_is_inhibited()) {
-qemu_madvise(addr, BALLOON_PAGE_SIZE,
-deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
+if (!qemu_balloon_is_inhibited() && !deflate) {
+qemu_madvise(addr, BALLOON_PAGE_SIZE, QEMU_MADV_DONTNEED);
 }
 }
 
-- 
2.17.1




Re: [Qemu-devel] [PATCH 1/1] i386: Add new model of Cascadelake-Server

2018-10-11 Thread Liu, Jingqi
> -Original Message-
> From: Eduardo Habkost [mailto:ehabk...@redhat.com]
> Sent: Thursday, October 11, 2018 4:35 AM
> To: Liu, Jingqi 
> Cc: Xu, Tao3 ; pbonz...@redhat.com; r...@twiddle.net;
> qemu-devel@nongnu.org; Robert Hoo 
> Subject: Re: [PATCH 1/1] i386: Add new model of Cascadelake-Server
> 
> On Wed, Oct 10, 2018 at 01:49:56AM +, Liu, Jingqi wrote:
> > Hi Eduardo/Paolo,
> >
> > Do you have any comments about this patch ?
> 
> Thanks for the reminder and sorry for the delay.  I was waiting for MSR 
> features
> to be merged before including this CPU model.
> 
> But considering that it's taking a while until we sort out the details, I'll 
> review
> this so it can be merged first if necessary.

Hi Eduardo,
I think this patch doesn't depend on the MSR features.
Could you help to speed up to review it since this feature is requested by CSP?
They want it to be merged asap.

Thanks a lot,
Jingqi
> 
> >
> > Thanks
> > Jingqi
> >
> > > -Original Message-
> > > From: Xu, Tao3
> > > Sent: Wednesday, September 19, 2018 11:11 AM
> > > To: pbonz...@redhat.com; r...@twiddle.net; ehabk...@redhat.com
> > > Cc: qemu-devel@nongnu.org; Liu, Jingqi ; Xu,
> > > Tao3 
> > > Subject: [PATCH 1/1] i386: Add new model of Cascadelake-Server
> > >
> > > New CPU models mostly inherit features from ancestor Skylake-Server,
> > > while addin new features: AVX512_VNNI, Intel PT.
> > > SSBD support for speculative execution side channel mitigations.
> > >
> > > Note:
> > >
> > > On Cascadelake, some capabilities (RDCL_NO, IBRS_ALL, RSBA,
> > > SKIP_L1DFL_VMENTRY and SSB_NO) are enumerated by MSR.
> > > These features rely on MSR based feature support patch.
> > > Will be added later after that patch's in.
> > > http://lists.nongnu.org/archive/html/qemu-devel/2018-09/msg00074.htm
> > > l
> > >
> > > Signed-off-by: Tao Xu 
> > > ---
> > >  target/i386/cpu.c | 54
> > > +++
> > >  1 file changed, 54 insertions(+)
> > >
> > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c index
> > > f24295e6e4..670898f32d 100644
> > > --- a/target/i386/cpu.c
> > > +++ b/target/i386/cpu.c
> > > @@ -2386,6 +2386,60 @@ static X86CPUDefinition builtin_x86_defs[] = {
> > >  .xlevel = 0x8008,
> > >  .model_id = "Intel Xeon Processor (Skylake, IBRS)",
> > >  },
> > > +{
> > > +.name = "Cascadelake-Server",
> > > +.level = 0xd,
> > > +.vendor = CPUID_VENDOR_INTEL,
> > > +.family = 6,
> > > +.model = 85,
> > > +.stepping = 5,
> > > +.features[FEAT_1_EDX] =
> > > +CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR |
> CPUID_MMX |
> > > +CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV |
> > > CPUID_MCA |
> > > +CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8
> |
> > > +CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
> > > +CPUID_DE | CPUID_FP87,
> > > +.features[FEAT_1_ECX] =
> > > +CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
> > > +CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
> > > +CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
> > > +CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
> > > +CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA |
> > > CPUID_EXT_MOVBE |
> > > +CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
> > > +.features[FEAT_8000_0001_EDX] =
> > > +CPUID_EXT2_LM | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP |
> > > +CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
> > > +.features[FEAT_8000_0001_ECX] =
> > > +CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM |
> > > CPUID_EXT3_3DNOWPREFETCH,
> > > +.features[FEAT_7_0_EBX] =
> > > +CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
> > > +CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 |
> > > + CPUID_7_0_EBX_SMEP
> > > |
> > > +CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS |
> > > CPUID_7_0_EBX_INVPCID |
> > > +CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED |
> > > CPUID_7_0_EBX_ADX |
> > > +CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX |
> > > CPUID_7_0_EBX_CLWB |
> > > +CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> > > +CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
> > > +CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
> > > +CPUID_7_0_EBX_INTEL_PT,
> > > +.features[FEAT_7_0_ECX] =
> > > +CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
> > > +CPUID_7_0_ECX_AVX512VNNI,
> > > +.features[FEAT_7_0_EDX] =
> > > +CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> > > +/* Missing: XSAVES (not supported by some Linux versions,
> > > +* including v4.1 to v4.12).
> > > +* KVM doesn't yet expose any XSAVES state save component,
> > > +* and the only one 

[Qemu-devel] [PULL 0/2] Block patches

2018-10-11 Thread Fam Zheng
The following changes since commit 75e50c80e051423a6f55a34ee4a1eec842444a5b:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-10-10' into 
staging (2018-10-11 10:43:37 +0100)

are available in the Git repository at:

  git://github.com/famz/qemu.git tags/block-pull-request

for you to fetch changes up to 6388147296cd4c841a7d4409ba622c200332a8c7:

  nvme: correct locking around completion (2018-10-12 09:46:14 +0800)


Block patches

One fix from Marc-André for iothread.
One fix from Paolo on nvme:// driver.



Marc-André Lureau (1):
  iothread: fix crash with invalid properties

Paolo Bonzini (1):
  nvme: correct locking around completion

 block/nvme.c | 2 --
 iothread.c   | 9 ++---
 2 files changed, 6 insertions(+), 5 deletions(-)

-- 
2.17.1




[Qemu-devel] [PULL 1/2] iothread: fix crash with invalid properties

2018-10-11 Thread Fam Zheng
From: Marc-André Lureau 

-object iothread,id=foo,? will crash qemu:

qemu-system-x86_64:qemu-thread-posix.c:128: qemu_cond_destroy: Assertion 
`cond->initialized' failed.

Use thread_id != -1 to check if iothread_complete() finished
successfully and the mutex/cond have been initialized.

Signed-off-by: Marc-André Lureau 
Message-Id: <20180821100716.13803-1-marcandre.lur...@redhat.com>
Signed-off-by: Fam Zheng 
---
 iothread.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/iothread.c b/iothread.c
index aff1281257..2fb1cdf55d 100644
--- a/iothread.c
+++ b/iothread.c
@@ -110,6 +110,7 @@ static void iothread_instance_init(Object *obj)
 IOThread *iothread = IOTHREAD(obj);
 
 iothread->poll_max_ns = IOTHREAD_POLL_MAX_NS_DEFAULT;
+iothread->thread_id = -1;
 }
 
 static void iothread_instance_finalize(Object *obj)
@@ -117,6 +118,11 @@ static void iothread_instance_finalize(Object *obj)
 IOThread *iothread = IOTHREAD(obj);
 
 iothread_stop(iothread);
+
+if (iothread->thread_id != -1) {
+qemu_cond_destroy(>init_done_cond);
+qemu_mutex_destroy(>init_done_lock);
+}
 /*
  * Before glib2 2.33.10, there is a glib2 bug that GSource context
  * pointer may not be cleared even if the context has already been
@@ -135,8 +141,6 @@ static void iothread_instance_finalize(Object *obj)
 g_main_context_unref(iothread->worker_context);
 iothread->worker_context = NULL;
 }
-qemu_cond_destroy(>init_done_cond);
-qemu_mutex_destroy(>init_done_lock);
 }
 
 static void iothread_complete(UserCreatable *obj, Error **errp)
@@ -147,7 +151,6 @@ static void iothread_complete(UserCreatable *obj, Error 
**errp)
 
 iothread->stopping = false;
 iothread->running = true;
-iothread->thread_id = -1;
 iothread->ctx = aio_context_new(_error);
 if (!iothread->ctx) {
 error_propagate(errp, local_error);
-- 
2.17.1




[Qemu-devel] [PULL 2/2] nvme: correct locking around completion

2018-10-11 Thread Fam Zheng
From: Paolo Bonzini 

nvme_poll_queues is already protected by q->lock, and
AIO callbacks are invoked outside the AioContext lock.
So remove the acquire/release pair in nvme_handle_event.

Signed-off-by: Paolo Bonzini 
Message-Id: <20180814062739.19640-1-pbonz...@redhat.com>
Signed-off-by: Fam Zheng 
---
 block/nvme.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/block/nvme.c b/block/nvme.c
index 781d77d6d2..29294038fc 100644
--- a/block/nvme.c
+++ b/block/nvme.c
@@ -489,10 +489,8 @@ static void nvme_handle_event(EventNotifier *n)
 BDRVNVMeState *s = container_of(n, BDRVNVMeState, irq_notifier);
 
 trace_nvme_handle_event(s);
-aio_context_acquire(s->aio_context);
 event_notifier_test_and_clear(n);
 nvme_poll_queues(s);
-aio_context_release(s->aio_context);
 }
 
 static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
-- 
2.17.1




Re: [Qemu-devel] [PATCH 0/7] target/ppc: Some cleanups to fp exceptions

2018-10-11 Thread David Gibson
On Thu, Oct 11, 2018 at 04:41:52PM -0700, Richard Henderson wrote:
1;5202;0c> There are a few bugs here, primarily wrt usage of GETPC().
> But there is opportunity to share more code between paths
> that operate on different floating point types.
> 
> This is not everything that could be done, but it's a good start.
> Better for this not to hang out on a branch for another release.

Applied to ppc-for-3.1, thanks.

> 
> 
> r~
> 
> 
> Richard Henderson (7):
>   target/ppc: Split up float_invalid_op_excp
>   target/ppc: Remove float_check_status
>   target/ppc: Introduce fp number classification
>   target/ppc: Split out float_invalid_op_addsub
>   target/ppc: Split out float_invalid_op_mul
>   target/ppc: Split out float_invalid_op_div
>   target/ppc: Split out float_invalid_cvt
> 
>  target/ppc/fpu_helper.c | 661 
>  1 file changed, 327 insertions(+), 334 deletions(-)
> 

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


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH 4/4] audio: use existing macros istead ofhardcoded strings

2018-10-11 Thread maozy




On 10/11/18 7:05 PM, Peter Maydell wrote:

On 11 October 2018 at 11:45, Philippe Mathieu-Daudé  wrote:

On 11/10/2018 11:00, Mao Zhongyi wrote:

Cc: Jan Kiszka 
Cc: Peter Maydell 
Cc: Gerd Hoffmann 
To: qemu-...@nongnu.org

Signed-off-by: Mao Zhongyi 
---
  hw/arm/musicpal.c  | 16 
  hw/audio/marvell_88w8618.c |  3 +--
  include/hw/audio/wm8750.h  |  1 +
  3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index ac266f9253..6425f1d50f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -406,7 +406,7 @@ static void mv88w8618_eth_realize(DeviceState *dev, Error 
**errp)
  }

  static const VMStateDescription mv88w8618_eth_vmsd = {
-.name = "mv88w8618_eth",
+.name = TYPE_MV88W8618_ETH,


I understand TYPE_device name might changed, but once used,
VMStateDescription shouldn't, else this would break migration.
Thus I wouldn't recommend using TYPE_name in VMStateDescription.name.

Since I'm not sure I cc'ed the migration maintainers.


Yes, that's the usual approach -- the vmstate struct names
aren't inherently the same as the QOM type names, and so
we keep them decoupled to avoid accidentally breaking migration.


OK, I got it, will fix it in the next, thanks for the clarification.

thanks
Mao



thanks
-- PMM







Re: [Qemu-devel] [PATCH 1/4] wm8750: remove duplicate macro

2018-10-11 Thread maozy




On 10/11/18 6:39 PM, Philippe Mathieu-Daudé wrote:

Hi Mao,

On 11/10/2018 11:00, Mao Zhongyi wrote:

The header file wm8750.h contains '#define TYPE_WM8750 "wm8750"'
macro, but '#define CODEC "wm8750"' macro is redefined in wm8750.c,
just remove the local CODEC macro and replace it with TYPE_WM8750.

Cc: Gerd Hoffmann 

Signed-off-by: Mao Zhongyi 
---
  hw/audio/wm8750.c | 18 --
  1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c
index f4aa838f62..4be3602079 100644
--- a/hw/audio/wm8750.c
+++ b/hw/audio/wm8750.c
@@ -15,8 +15,6 @@
  #define IN_PORT_N 3
  #define OUT_PORT_N3
  
-#define CODEC		"wm8750"

-
  typedef struct {
  int adc;
  int adc_hz;
@@ -204,11 +202,11 @@ static void wm8750_set_format(WM8750State *s)
  in_fmt.fmt = AUD_FMT_S16;
  
  s->adc_voice[0] = AUD_open_in(>card, s->adc_voice[0],

-CODEC ".input1", s, wm8750_audio_in_cb, _fmt);
+TYPE_WM8750 ".input1", s, wm8750_audio_in_cb, _fmt);


I don't think this is correct. The TYPE_name could change, but the CODEC
shouldn't change. Both definitions are different.


OK, I will remove this patch.

Thanks,
Mao



Regards,

Phil.


  s->adc_voice[1] = AUD_open_in(>card, s->adc_voice[1],
-CODEC ".input2", s, wm8750_audio_in_cb, _fmt);
+TYPE_WM8750 ".input2", s, wm8750_audio_in_cb, _fmt);
  s->adc_voice[2] = AUD_open_in(>card, s->adc_voice[2],
-CODEC ".input3", s, wm8750_audio_in_cb, _fmt);
+TYPE_WM8750 ".input3", s, wm8750_audio_in_cb, _fmt);
  
  /* Setup output */

  out_fmt.endianness = 0;
@@ -217,12 +215,12 @@ static void wm8750_set_format(WM8750State *s)
  out_fmt.fmt = AUD_FMT_S16;
  
  s->dac_voice[0] = AUD_open_out(>card, s->dac_voice[0],

-CODEC ".speaker", s, wm8750_audio_out_cb, _fmt);
+TYPE_WM8750 ".speaker", s, wm8750_audio_out_cb, _fmt);
  s->dac_voice[1] = AUD_open_out(>card, s->dac_voice[1],
-CODEC ".headphone", s, wm8750_audio_out_cb, _fmt);
+TYPE_WM8750 ".headphone", s, wm8750_audio_out_cb, 
_fmt);
  /* MONOMIX is also in stereo for simplicity */
  s->dac_voice[2] = AUD_open_out(>card, s->dac_voice[2],
-CODEC ".monomix", s, wm8750_audio_out_cb, _fmt);
+TYPE_WM8750 ".monomix", s, wm8750_audio_out_cb, _fmt);
  /* no sense emulating OUT3 which is a mix of other outputs */
  
  wm8750_vol_update(s);

@@ -584,7 +582,7 @@ static int wm8750_post_load(void *opaque, int version_id)
  }
  
  static const VMStateDescription vmstate_wm8750 = {

-.name = CODEC,
+.name = TYPE_WM8750,
  .version_id = 0,
  .minimum_version_id = 0,
  .pre_save = wm8750_pre_save,
@@ -621,7 +619,7 @@ static void wm8750_realize(DeviceState *dev, Error **errp)
  {
  WM8750State *s = WM8750(dev);
  
-AUD_register_card(CODEC, >card);

+AUD_register_card(TYPE_WM8750, >card);
  wm8750_reset(I2C_SLAVE(s));
  }
  









Re: [Qemu-devel] [PATCH v2 01/11] hw/ipmi: Remove unnecessary declarations

2018-10-11 Thread Corey Minyard

On 10/11/2018 07:22 PM, Philippe Mathieu-Daudé wrote:

Signed-off-by: Philippe Mathieu-Daudé 
---
  hw/ipmi/ipmi_bmc_extern.c | 4 
  1 file changed, 4 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index bf0b7ee0f5..8c78b9804b 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -85,10 +85,6 @@ typedef struct IPMIBmcExtern {
  bool send_reset;
  } IPMIBmcExtern;
  
-static int can_receive(void *opaque);

-static void receive(void *opaque, const uint8_t *buf, int size);
-static void chr_event(void *opaque, int event);
-
  static unsigned char
  ipmb_checksum(const unsigned char *data, int size, unsigned char start)
  {


Looks good to me.  Thanks.

Acked-by: Corey Minyard 




[Qemu-devel] [PATCH v2 10/11] chardev: Let qemu_chr_be_* use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Since IOCanReadHandler now returns an unsigned value, the assertion
does not make sense anymore.  We choose however to keep a "fail-safe"
assertion to catch undesired overflows.

Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char.c  | 17 +
 include/chardev/char.h  |  9 +
 include/sysemu/replay.h |  8 
 replay/replay-char.c|  8 
 stubs/replay.c  |  8 
 5 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/chardev/char.c b/chardev/char.c
index 608c2569f4..ef6d07e132 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -100,7 +100,7 @@ static void qemu_chr_write_log(Chardev *s, const uint8_t 
*buf, size_t len)
 
 static int qemu_chr_write_buffer(Chardev *s,
  const uint8_t *buf, int len,
- int *offset, bool write_all)
+ size_t *offset, bool write_all)
 {
 ChardevClass *cc = CHARDEV_GET_CLASS(s);
 int res = 0;
@@ -132,9 +132,10 @@ static int qemu_chr_write_buffer(Chardev *s,
 return res;
 }
 
-int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all)
+size_t qemu_chr_write(Chardev *s, const uint8_t *buf, size_t len,
+  bool write_all)
 {
-int offset = 0;
+size_t offset = 0;
 int res;
 
 if (qemu_chr_replay(s) && replay_mode == REPLAY_MODE_PLAY) {
@@ -156,21 +157,21 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int 
len, bool write_all)
 return offset;
 }
 
-int qemu_chr_be_can_write(Chardev *s)
+size_t qemu_chr_be_can_write(Chardev *s)
 {
 CharBackend *be = s->be;
-int res;
+size_t res;
 
 if (!be || !be->chr_can_read) {
 return 0;
 }
 
 res = be->chr_can_read(be->opaque);
-assert(res >= 0);
+assert((ssize_t)res >= 0); /* "fail-safe" assertion */
 return res;
 }
 
-void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len)
+void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, size_t len)
 {
 CharBackend *be = s->be;
 
@@ -179,7 +180,7 @@ void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int 
len)
 }
 }
 
-void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len)
+void qemu_chr_be_write(Chardev *s, uint8_t *buf, size_t len)
 {
 if (qemu_chr_replay(s)) {
 if (replay_mode == REPLAY_MODE_PLAY) {
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 091a514022..65f93adbd6 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -163,7 +163,7 @@ Chardev *qemu_chr_new_noreplay(const char *label, const 
char *filename,
  *
  * Returns: the number of bytes the front end can receive via 
@qemu_chr_be_write
  */
-int qemu_chr_be_can_write(Chardev *s);
+size_t qemu_chr_be_can_write(Chardev *s);
 
 /**
  * qemu_chr_be_write:
@@ -174,7 +174,7 @@ int qemu_chr_be_can_write(Chardev *s);
  * the caller should call @qemu_chr_be_can_write to determine how much data
  * the front end can currently accept.
  */
-void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len);
+void qemu_chr_be_write(Chardev *s, uint8_t *buf, size_t len);
 
 /**
  * qemu_chr_be_write_impl:
@@ -183,7 +183,7 @@ void qemu_chr_be_write(Chardev *s, uint8_t *buf, int len);
  *
  * Implementation of back end writing. Used by replay module.
  */
-void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len);
+void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, size_t len);
 
 /**
  * qemu_chr_be_update_read_handlers:
@@ -211,7 +211,8 @@ void qemu_chr_set_feature(Chardev *chr,
   ChardevFeature feature);
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename,
 bool permit_mux_mon);
-int qemu_chr_write(Chardev *s, const uint8_t *buf, int len, bool write_all);
+size_t qemu_chr_write(Chardev *s, const uint8_t *buf, size_t len,
+  bool write_all);
 #define qemu_chr_write_all(s, buf, len) qemu_chr_write(s, buf, len, true)
 int qemu_chr_wait_connected(Chardev *chr, Error **errp);
 
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index 7f7a594eca..0856b66888 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -148,17 +148,17 @@ uint64_t blkreplay_next_id(void);
 /*! Registers char driver to save it's events */
 void replay_register_char_driver(struct Chardev *chr);
 /*! Saves write to char device event to the log */
-void replay_chr_be_write(struct Chardev *s, uint8_t *buf, int len);
+void replay_chr_be_write(struct Chardev *s, uint8_t *buf, size_t len);
 /*! Writes char write return value to the replay log. */
-void replay_char_write_event_save(int res, int offset);
+void replay_char_write_event_save(int res, size_t offset);
 /*! Reads char write return value from the replay log. */
-void replay_char_write_event_load(int *res, int *offset);
+void replay_char_write_event_load(int *res, size_t *offset);
 /*! Reads information about read_all character event. */
 int 

[Qemu-devel] [PATCH v2 05/11] chardev: Let chr_sync_read() use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Note than tcp_chr_recv() already use size_t.

Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char-socket.c  | 2 +-
 include/chardev/char.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 76cc3c48b0..7e627b243e 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -494,7 +494,7 @@ static gboolean tcp_chr_hup(QIOChannel *channel,
 return G_SOURCE_REMOVE;
 }
 
-static int tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, int len)
+static size_t tcp_chr_sync_read(Chardev *chr, const uint8_t *buf, size_t len)
 {
 SocketChardev *s = SOCKET_CHARDEV(chr);
 int size;
diff --git a/include/chardev/char.h b/include/chardev/char.h
index 7becd8c80c..ef4509bfa3 100644
--- a/include/chardev/char.h
+++ b/include/chardev/char.h
@@ -251,7 +251,7 @@ typedef struct ChardevClass {
  bool *be_opened, Error **errp);
 
 int (*chr_write)(Chardev *s, const uint8_t *buf, int len);
-int (*chr_sync_read)(Chardev *s, const uint8_t *buf, int len);
+size_t (*chr_sync_read)(Chardev *s, const uint8_t *buf, size_t len);
 GSource *(*chr_add_watch)(Chardev *s, GIOCondition cond);
 void (*chr_update_read_handler)(Chardev *s);
 int (*chr_ioctl)(Chardev *s, int cmd, void *arg);
-- 
2.17.1




[Qemu-devel] [PATCH v2 11/11] chardev: FDChardev::max_size be unsigned

2018-10-11 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char-fd.c | 2 +-
 include/chardev/char-fd.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/chardev/char-fd.c b/chardev/char-fd.c
index bb426fa4b1..900da2f935 100644
--- a/chardev/char-fd.c
+++ b/chardev/char-fd.c
@@ -43,7 +43,7 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition 
cond, void *opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 FDChardev *s = FD_CHARDEV(opaque);
-int len;
+size_t len;
 uint8_t buf[CHR_READ_BUF_LEN];
 ssize_t ret;
 
diff --git a/include/chardev/char-fd.h b/include/chardev/char-fd.h
index e7c2b176f9..36c6b89cee 100644
--- a/include/chardev/char-fd.h
+++ b/include/chardev/char-fd.h
@@ -31,7 +31,7 @@ typedef struct FDChardev {
 Chardev parent;
 
 QIOChannel *ioc_in, *ioc_out;
-int max_size;
+size_t max_size;
 } FDChardev;
 
 #define TYPE_CHARDEV_FD "chardev-fd"
-- 
2.17.1




[Qemu-devel] [PATCH v2 08/11] chardev: Let IOCanReadHandler use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 backends/rng-egd.c  | 4 ++--
 chardev/char-mux.c  | 2 +-
 gdbstub.c   | 2 +-
 hw/arm/pxa2xx.c | 2 +-
 hw/arm/strongarm.c  | 2 +-
 hw/char/bcm2835_aux.c   | 2 +-
 hw/char/cadence_uart.c  | 4 ++--
 hw/char/cmsdk-apb-uart.c| 2 +-
 hw/char/digic-uart.c| 2 +-
 hw/char/escc.c  | 6 +++---
 hw/char/etraxfs_ser.c   | 2 +-
 hw/char/exynos4210_uart.c   | 2 +-
 hw/char/grlib_apbuart.c | 2 +-
 hw/char/imx_serial.c| 2 +-
 hw/char/ipoctal232.c| 4 ++--
 hw/char/lm32_juart.c| 2 +-
 hw/char/lm32_uart.c | 2 +-
 hw/char/mcf_uart.c  | 2 +-
 hw/char/milkymist-uart.c| 2 +-
 hw/char/parallel.c  | 2 +-
 hw/char/pl011.c | 4 ++--
 hw/char/sclpconsole-lm.c| 2 +-
 hw/char/sclpconsole.c   | 4 ++--
 hw/char/serial.c| 4 ++--
 hw/char/sh_serial.c | 4 ++--
 hw/char/spapr_vty.c | 2 +-
 hw/char/stm32f2xx_usart.c   | 2 +-
 hw/char/terminal3270.c  | 2 +-
 hw/char/virtio-console.c| 2 +-
 hw/char/xen_console.c   | 2 +-
 hw/char/xilinx_uartlite.c   | 2 +-
 hw/ipmi/ipmi_bmc_extern.c   | 2 +-
 hw/misc/ivshmem.c   | 2 +-
 hw/riscv/riscv_htif.c   | 2 +-
 hw/riscv/sifive_uart.c  | 2 +-
 hw/usb/ccid-card-passthru.c | 2 +-
 hw/usb/dev-serial.c | 2 +-
 hw/usb/redirect.c   | 2 +-
 include/qemu/main-loop.h| 2 +-
 monitor.c   | 2 +-
 net/colo-compare.c  | 2 +-
 net/filter-mirror.c | 2 +-
 net/slirp.c | 2 +-
 qtest.c | 2 +-
 target/xtensa/xtensa-semi.c | 2 +-
 45 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index b51c01f664..4a9a92a8e7 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -48,11 +48,11 @@ static void rng_egd_request_entropy(RngBackend *b, 
RngRequest *req)
 }
 }
 
-static int rng_egd_chr_can_read(void *opaque)
+static size_t rng_egd_chr_can_read(void *opaque)
 {
 RngEgd *s = RNG_EGD(opaque);
 RngRequest *req;
-int size = 0;
+size_t size = 0;
 
 QSIMPLEQ_FOREACH(req, >parent.requests, next) {
 size += req->size - req->offset;
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index d8d6eaa646..98db12cf77 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -192,7 +192,7 @@ static void mux_chr_accept_input(Chardev *chr)
 }
 }
 
-static int mux_chr_can_read(void *opaque)
+static size_t mux_chr_can_read(void *opaque)
 {
 MuxChardev *d = MUX_CHARDEV(opaque);
 int m = d->focus;
diff --git a/gdbstub.c b/gdbstub.c
index a2fc3682ce..86d1fa62f8 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1916,7 +1916,7 @@ void gdbserver_fork(CPUState *cpu)
 cpu_watchpoint_remove_all(cpu, BP_GDB);
 }
 #else
-static int gdb_chr_can_receive(void *opaque)
+static size_t gdb_chr_can_receive(void *opaque)
 {
   /* We can handle an arbitrarily large amount of data.
Pick the maximum packet size, which is as good as anything.  */
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 75b6aa2772..a72d9bd4fe 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1923,7 +1923,7 @@ static const MemoryRegionOps pxa2xx_fir_ops = {
 .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static int pxa2xx_fir_is_empty(void *opaque)
+static size_t pxa2xx_fir_is_empty(void *opaque)
 {
 PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
 return (s->rx_len < 64);
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 40db4e5e0a..6fdd4da3d0 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1058,7 +1058,7 @@ static void strongarm_uart_rx_push(StrongARMUARTState *s, 
uint16_t c)
 s->rx_fifo[(s->rx_start + 11) % 12] |= RX_FIFO_ROR;
 }
 
-static int strongarm_uart_can_receive(void *opaque)
+static size_t strongarm_uart_can_receive(void *opaque)
 {
 StrongARMUARTState *s = opaque;
 
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index cb26df40f8..5dd1b652c0 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -211,7 +211,7 @@ static void bcm2835_aux_write(void *opaque, hwaddr offset, 
uint64_t value,
 bcm2835_aux_update(s);
 }
 
-static int bcm2835_aux_can_receive(void *opaque)
+static size_t bcm2835_aux_can_receive(void *opaque)
 {
 BCM2835AuxState *s = opaque;
 
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index eb5cc974a1..5835362038 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -216,10 +216,10 @@ static void uart_parameters_setup(CadenceUARTState *s)
 qemu_chr_fe_ioctl(>chr, CHR_IOCTL_SERIAL_SET_PARAMS, );
 }
 
-static int uart_can_receive(void *opaque)
+static size_t uart_can_receive(void *opaque)
 {
 CadenceUARTState *s = opaque;
-int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
+size_t ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
 uint32_t 

[Qemu-devel] [PATCH v2 04/11] chardev: Assert backend's chr_can_read() is positive

2018-10-11 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/chardev/char.c b/chardev/char.c
index e115166995..952f9c9bcc 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -159,12 +159,15 @@ int qemu_chr_write(Chardev *s, const uint8_t *buf, int 
len, bool write_all)
 int qemu_chr_be_can_write(Chardev *s)
 {
 CharBackend *be = s->be;
+int res;
 
 if (!be || !be->chr_can_read) {
 return 0;
 }
 
-return be->chr_can_read(be->opaque);
+res = be->chr_can_read(be->opaque);
+assert(res >= 0);
+return res;
 }
 
 void qemu_chr_be_write_impl(Chardev *s, uint8_t *buf, int len)
-- 
2.17.1




[Qemu-devel] [PATCH v2 09/11] chardev: Let qemu_chr_fe_* use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char-fe.c | 8 
 chardev/char-win-stdio.c  | 2 +-
 chardev/char-win.c| 2 +-
 include/chardev/char-fe.h | 6 +++---
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/chardev/char-fe.c b/chardev/char-fe.c
index a8931f7afd..b732f6566b 100644
--- a/chardev/char-fe.c
+++ b/chardev/char-fe.c
@@ -31,7 +31,7 @@
 #include "chardev/char-io.h"
 #include "chardev/char-mux.h"
 
-int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len)
+size_t qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, size_t len)
 {
 Chardev *s = be->chr;
 
@@ -42,7 +42,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, 
int len)
 return qemu_chr_write(s, buf, len, false);
 }
 
-int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len)
+size_t qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, size_t len)
 {
 Chardev *s = be->chr;
 
@@ -53,10 +53,10 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t 
*buf, int len)
 return qemu_chr_write(s, buf, len, true);
 }
 
-int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len)
+size_t qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, size_t len)
 {
 Chardev *s = be->chr;
-int offset = 0;
+size_t offset = 0;
 int res;
 
 if (!s || !CHARDEV_GET_CLASS(s)->chr_sync_read) {
diff --git a/chardev/char-win-stdio.c b/chardev/char-win-stdio.c
index efcf7827eb..6b1a97144b 100644
--- a/chardev/char-win-stdio.c
+++ b/chardev/char-win-stdio.c
@@ -221,7 +221,7 @@ static void char_win_stdio_finalize(Object *obj)
 }
 }
 
-static int win_stdio_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t win_stdio_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 HANDLE  hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 DWORD   dwSize;
diff --git a/chardev/char-win.c b/chardev/char-win.c
index 05518e0958..7ea7d0a371 100644
--- a/chardev/char-win.c
+++ b/chardev/char-win.c
@@ -152,7 +152,7 @@ int win_chr_pipe_poll(void *opaque)
 }
 
 /* Called with chr_write_lock held.  */
-static int win_chr_write(Chardev *chr, const uint8_t *buf, int len1)
+static size_t win_chr_write(Chardev *chr, const uint8_t *buf, size_t len1)
 {
 WinChardev *s = WIN_CHARDEV(chr);
 DWORD len, ret, size, err;
diff --git a/include/chardev/char-fe.h b/include/chardev/char-fe.h
index 46c997d352..2f95c890d8 100644
--- a/include/chardev/char-fe.h
+++ b/include/chardev/char-fe.h
@@ -184,7 +184,7 @@ guint qemu_chr_fe_add_watch(CharBackend *be, GIOCondition 
cond,
  *
  * Returns: the number of bytes consumed (0 if no associated Chardev)
  */
-int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, int len);
+size_t qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, size_t len);
 
 /**
  * qemu_chr_fe_write_all:
@@ -198,7 +198,7 @@ int qemu_chr_fe_write(CharBackend *be, const uint8_t *buf, 
int len);
  *
  * Returns: the number of bytes consumed (0 if no associated Chardev)
  */
-int qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, int len);
+size_t qemu_chr_fe_write_all(CharBackend *be, const uint8_t *buf, size_t len);
 
 /**
  * qemu_chr_fe_read_all:
@@ -209,7 +209,7 @@ int qemu_chr_fe_write_all(CharBackend *be, const uint8_t 
*buf, int len);
  *
  * Returns: the number of bytes read (0 if no associated Chardev)
  */
-int qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, int len);
+size_t qemu_chr_fe_read_all(CharBackend *be, uint8_t *buf, size_t len);
 
 /**
  * qemu_chr_fe_ioctl:
-- 
2.17.1




[Qemu-devel] [PATCH v2 06/11] chardev: Let chr_write use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/baum.c | 2 +-
 chardev/char-fd.c  | 2 +-
 chardev/char-mux.c | 2 +-
 chardev/char-pty.c | 2 +-
 chardev/char-ringbuf.c | 4 ++--
 chardev/char-socket.c  | 2 +-
 chardev/char-udp.c | 2 +-
 chardev/char.c | 2 +-
 chardev/msmouse.c  | 2 +-
 chardev/spice.c| 2 +-
 chardev/testdev.c  | 2 +-
 chardev/wctablet.c | 4 ++--
 gdbstub.c  | 2 +-
 hw/bt/hci-csr.c| 4 ++--
 include/chardev/char.h | 2 +-
 ui/console.c   | 2 +-
 ui/gtk.c   | 2 +-
 17 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/chardev/baum.c b/chardev/baum.c
index 78b0c87625..5367d82f53 100644
--- a/chardev/baum.c
+++ b/chardev/baum.c
@@ -479,7 +479,7 @@ static int baum_eat_packet(BaumChardev *baum, const uint8_t 
*buf, int len)
 }
 
 /* The other end is writing some data.  Store it and try to interpret */
-static int baum_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t baum_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 BaumChardev *baum = BAUM_CHARDEV(chr);
 int tocopy, cur, eaten, orig_len = len;
diff --git a/chardev/char-fd.c b/chardev/char-fd.c
index 2421d8e216..bb426fa4b1 100644
--- a/chardev/char-fd.c
+++ b/chardev/char-fd.c
@@ -32,7 +32,7 @@
 #include "chardev/char-io.h"
 
 /* Called with chr_write_lock held.  */
-static int fd_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t fd_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 FDChardev *s = FD_CHARDEV(chr);
 
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 6055e76293..3ca732d3a8 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -33,7 +33,7 @@
 /* MUX driver for serial I/O splitting */
 
 /* Called with chr_write_lock held.  */
-static int mux_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t mux_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 MuxChardev *d = MUX_CHARDEV(chr);
 int ret;
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index 626ca30cb3..a2b78b44d8 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -125,7 +125,7 @@ static void pty_chr_update_read_handler(Chardev *chr)
 }
 
 /* Called with chr_write_lock held.  */
-static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t char_pty_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 PtyChardev *s = PTY_CHARDEV(chr);
 
diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 87832e2792..b805a585e3 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -49,12 +49,12 @@ static size_t ringbuf_count(const Chardev *chr)
 return d->prod - d->cons;
 }
 
-static int ringbuf_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t ringbuf_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 RingBufChardev *d = RINGBUF_CHARDEV(chr);
 int i;
 
-if (!buf || (len < 0)) {
+if (!buf) {
 return -1;
 }
 
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 7e627b243e..7c7fb06d48 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -124,7 +124,7 @@ static gboolean tcp_chr_read_poll(void *opaque);
 static void tcp_chr_disconnect(Chardev *chr);
 
 /* Called with chr_write_lock held.  */
-static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t tcp_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 SocketChardev *s = SOCKET_CHARDEV(chr);
 
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index b6e399e983..577d049d78 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -45,7 +45,7 @@ typedef struct {
 #define UDP_CHARDEV(obj) OBJECT_CHECK(UdpChardev, (obj), TYPE_CHARDEV_UDP)
 
 /* Called with chr_write_lock held.  */
-static int udp_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t udp_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 UdpChardev *s = UDP_CHARDEV(chr);
 
diff --git a/chardev/char.c b/chardev/char.c
index 952f9c9bcc..608c2569f4 100644
--- a/chardev/char.c
+++ b/chardev/char.c
@@ -245,7 +245,7 @@ static void char_init(Object *obj)
 qemu_mutex_init(>chr_write_lock);
 }
 
-static int null_chr_write(Chardev *chr, const uint8_t *buf, int len)
+static size_t null_chr_write(Chardev *chr, const uint8_t *buf, size_t len)
 {
 return len;
 }
diff --git a/chardev/msmouse.c b/chardev/msmouse.c
index 0ffd137ce8..0aad738cae 100644
--- a/chardev/msmouse.c
+++ b/chardev/msmouse.c
@@ -133,7 +133,7 @@ static void msmouse_input_sync(DeviceState *dev)
 msmouse_chr_accept_input(chr);
 }
 
-static int msmouse_chr_write(struct Chardev *s, const uint8_t *buf, int len)
+static size_t msmouse_chr_write(struct Chardev *s, const uint8_t *buf, size_t 
len)
 {
 /* Ignore writes to mouse port */
 return len;
diff --git a/chardev/spice.c b/chardev/spice.c
index e66e3ad568..a9e7b4e374 100644
--- 

[Qemu-devel] [PATCH v2 02/11] target/xtensa: Remove unnecessary declarations

2018-10-11 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/xtensa/xtensa-semi.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target/xtensa/xtensa-semi.c b/target/xtensa/xtensa-semi.c
index 2f76216276..e389069f0b 100644
--- a/target/xtensa/xtensa-semi.c
+++ b/target/xtensa/xtensa-semi.c
@@ -161,7 +161,6 @@ typedef struct XtensaSimConsole {
 
 static XtensaSimConsole *sim_console;
 
-static IOCanReadHandler sim_console_can_read;
 static int sim_console_can_read(void *opaque)
 {
 XtensaSimConsole *p = opaque;
@@ -169,7 +168,6 @@ static int sim_console_can_read(void *opaque)
 return sizeof(p->input.buffer) - p->input.offset;
 }
 
-static IOReadHandler sim_console_read;
 static void sim_console_read(void *opaque, const uint8_t *buf, int size)
 {
 XtensaSimConsole *p = opaque;
-- 
2.17.1




[Qemu-devel] [PATCH v2 03/11] chardev: Simplify IOWatchPoll::fd_can_read as a GSourceFunc

2018-10-11 Thread Philippe Mathieu-Daudé
IOWatchPoll::fd_can_read() simply returns a boolean value.

Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
---
 chardev/char-fd.c | 4 ++--
 chardev/char-io.c | 4 ++--
 chardev/char-pty.c| 4 ++--
 chardev/char-socket.c | 6 +++---
 chardev/char-udp.c| 4 ++--
 include/chardev/char-io.h | 2 +-
 6 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/chardev/char-fd.c b/chardev/char-fd.c
index 2c9b2ce567..2421d8e216 100644
--- a/chardev/char-fd.c
+++ b/chardev/char-fd.c
@@ -69,13 +69,13 @@ static gboolean fd_chr_read(QIOChannel *chan, GIOCondition 
cond, void *opaque)
 return TRUE;
 }
 
-static int fd_chr_read_poll(void *opaque)
+static gboolean fd_chr_read_poll(void *opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 FDChardev *s = FD_CHARDEV(opaque);
 
 s->max_size = qemu_chr_be_can_write(chr);
-return s->max_size;
+return s->max_size > 0;
 }
 
 static GSource *fd_chr_add_watch(Chardev *chr, GIOCondition cond)
diff --git a/chardev/char-io.c b/chardev/char-io.c
index 8ced184160..a264d4e7fd 100644
--- a/chardev/char-io.c
+++ b/chardev/char-io.c
@@ -30,7 +30,7 @@ typedef struct IOWatchPoll {
 QIOChannel *ioc;
 GSource *src;
 
-IOCanReadHandler *fd_can_read;
+GSourceFunc fd_can_read;
 GSourceFunc fd_read;
 void *opaque;
 } IOWatchPoll;
@@ -76,7 +76,7 @@ static GSourceFuncs io_watch_poll_funcs = {
 
 GSource *io_add_watch_poll(Chardev *chr,
 QIOChannel *ioc,
-IOCanReadHandler *fd_can_read,
+GSourceFunc fd_can_read,
 QIOChannelFunc fd_read,
 gpointer user_data,
 GMainContext *context)
diff --git a/chardev/char-pty.c b/chardev/char-pty.c
index e8d9a53476..626ca30cb3 100644
--- a/chardev/char-pty.c
+++ b/chardev/char-pty.c
@@ -148,13 +148,13 @@ static GSource *pty_chr_add_watch(Chardev *chr, 
GIOCondition cond)
 return qio_channel_create_watch(s->ioc, cond);
 }
 
-static int pty_chr_read_poll(void *opaque)
+static gboolean pty_chr_read_poll(void *opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 PtyChardev *s = PTY_CHARDEV(opaque);
 
 s->read_bytes = qemu_chr_be_can_write(chr);
-return s->read_bytes;
+return s->read_bytes > 0;
 }
 
 static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index a75b46d9fe..76cc3c48b0 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -120,7 +120,7 @@ static void tcp_chr_accept(QIONetListener *listener,
QIOChannelSocket *cioc,
void *opaque);
 
-static int tcp_chr_read_poll(void *opaque);
+static gboolean tcp_chr_read_poll(void *opaque);
 static void tcp_chr_disconnect(Chardev *chr);
 
 /* Called with chr_write_lock held.  */
@@ -157,7 +157,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, 
int len)
 }
 }
 
-static int tcp_chr_read_poll(void *opaque)
+static gboolean tcp_chr_read_poll(void *opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 SocketChardev *s = SOCKET_CHARDEV(opaque);
@@ -165,7 +165,7 @@ static int tcp_chr_read_poll(void *opaque)
 return 0;
 }
 s->max_size = qemu_chr_be_can_write(chr);
-return s->max_size;
+return s->max_size > 0;
 }
 
 static void tcp_chr_process_IAC_bytes(Chardev *chr,
diff --git a/chardev/char-udp.c b/chardev/char-udp.c
index 097a2f0f42..b6e399e983 100644
--- a/chardev/char-udp.c
+++ b/chardev/char-udp.c
@@ -65,7 +65,7 @@ static void udp_chr_flush_buffer(UdpChardev *s)
 }
 }
 
-static int udp_chr_read_poll(void *opaque)
+static gboolean udp_chr_read_poll(void *opaque)
 {
 Chardev *chr = CHARDEV(opaque);
 UdpChardev *s = UDP_CHARDEV(opaque);
@@ -77,7 +77,7 @@ static int udp_chr_read_poll(void *opaque)
  */
 udp_chr_flush_buffer(s);
 
-return s->max_size;
+return s->max_size > 0;
 }
 
 static gboolean udp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
diff --git a/include/chardev/char-io.h b/include/chardev/char-io.h
index 9638da5100..a173874538 100644
--- a/include/chardev/char-io.h
+++ b/include/chardev/char-io.h
@@ -31,7 +31,7 @@
 /* Can only be used for read */
 GSource *io_add_watch_poll(Chardev *chr,
 QIOChannel *ioc,
-IOCanReadHandler *fd_can_read,
+GSourceFunc fd_can_read,
 QIOChannelFunc fd_read,
 gpointer user_data,
 GMainContext *context);
-- 
2.17.1




[Qemu-devel] [PATCH v2 07/11] chardev: Let IOReadHandler use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
The number of bytes can not be negative nor zero.

Fixed 2 format string:
- hw/char/spapr_vty.c
- hw/usb/ccid-card-passthru.c

Suggested-by: Paolo Bonzini 
Signed-off-by: Philippe Mathieu-Daudé 
Acked-by: Alberto Garcia 
---
 backends/rng-egd.c  | 2 +-
 chardev/char-mux.c  | 2 +-
 gdbstub.c   | 2 +-
 hw/arm/pxa2xx.c | 2 +-
 hw/arm/strongarm.c  | 3 ++-
 hw/char/bcm2835_aux.c   | 2 +-
 hw/char/cadence_uart.c  | 2 +-
 hw/char/cmsdk-apb-uart.c| 2 +-
 hw/char/digic-uart.c| 2 +-
 hw/char/escc.c  | 2 +-
 hw/char/etraxfs_ser.c   | 2 +-
 hw/char/exynos4210_uart.c   | 3 ++-
 hw/char/grlib_apbuart.c | 2 +-
 hw/char/imx_serial.c| 2 +-
 hw/char/ipoctal232.c| 2 +-
 hw/char/lm32_juart.c| 2 +-
 hw/char/lm32_uart.c | 2 +-
 hw/char/mcf_uart.c  | 2 +-
 hw/char/milkymist-uart.c| 2 +-
 hw/char/pl011.c | 2 +-
 hw/char/sclpconsole-lm.c| 2 +-
 hw/char/sclpconsole.c   | 2 +-
 hw/char/serial.c| 4 ++--
 hw/char/sh_serial.c | 2 +-
 hw/char/spapr_vty.c | 4 ++--
 hw/char/stm32f2xx_usart.c   | 3 ++-
 hw/char/terminal3270.c  | 2 +-
 hw/char/virtio-console.c| 2 +-
 hw/char/xen_console.c   | 2 +-
 hw/char/xilinx_uartlite.c   | 2 +-
 hw/ipmi/ipmi_bmc_extern.c   | 2 +-
 hw/misc/ivshmem.c   | 4 ++--
 hw/riscv/riscv_htif.c   | 2 +-
 hw/riscv/sifive_uart.c  | 2 +-
 hw/usb/ccid-card-passthru.c | 4 ++--
 hw/usb/dev-serial.c | 2 +-
 hw/usb/redirect.c   | 2 +-
 include/qemu/main-loop.h| 2 +-
 monitor.c   | 4 ++--
 net/colo-compare.c  | 4 ++--
 net/filter-mirror.c | 2 +-
 net/slirp.c | 2 +-
 qtest.c | 2 +-
 target/xtensa/xtensa-semi.c | 2 +-
 44 files changed, 53 insertions(+), 50 deletions(-)

diff --git a/backends/rng-egd.c b/backends/rng-egd.c
index d2b9ce6cbf..b51c01f664 100644
--- a/backends/rng-egd.c
+++ b/backends/rng-egd.c
@@ -61,7 +61,7 @@ static int rng_egd_chr_can_read(void *opaque)
 return size;
 }
 
-static void rng_egd_chr_read(void *opaque, const uint8_t *buf, int size)
+static void rng_egd_chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
 RngEgd *s = RNG_EGD(opaque);
 size_t buf_offset = 0;
diff --git a/chardev/char-mux.c b/chardev/char-mux.c
index 3ca732d3a8..d8d6eaa646 100644
--- a/chardev/char-mux.c
+++ b/chardev/char-mux.c
@@ -209,7 +209,7 @@ static int mux_chr_can_read(void *opaque)
 return 0;
 }
 
-static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
+static void mux_chr_read(void *opaque, const uint8_t *buf, size_t size)
 {
 Chardev *chr = CHARDEV(opaque);
 MuxChardev *d = MUX_CHARDEV(opaque);
diff --git a/gdbstub.c b/gdbstub.c
index 1cfcc1..a2fc3682ce 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1923,7 +1923,7 @@ static int gdb_chr_can_receive(void *opaque)
   return MAX_PACKET_LENGTH;
 }
 
-static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
+static void gdb_chr_receive(void *opaque, const uint8_t *buf, size_t size)
 {
 int i;
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index f598a1c053..75b6aa2772 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1929,7 +1929,7 @@ static int pxa2xx_fir_is_empty(void *opaque)
 return (s->rx_len < 64);
 }
 
-static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, int size)
+static void pxa2xx_fir_rx(void *opaque, const uint8_t *buf, size_t size)
 {
 PXA2xxFIrState *s = (PXA2xxFIrState *) opaque;
 if (!(s->control[0] & (1 << 4)))   /* RXE */
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index ec2627374d..40db4e5e0a 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1072,7 +1072,8 @@ static int strongarm_uart_can_receive(void *opaque)
 return 1;
 }
 
-static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
+static void strongarm_uart_receive(void *opaque, const uint8_t *buf,
+   size_t size)
 {
 StrongARMUARTState *s = opaque;
 int i;
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 0364596c55..cb26df40f8 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -235,7 +235,7 @@ static void bcm2835_aux_put_fifo(void *opaque, uint8_t 
value)
 bcm2835_aux_update(s);
 }
 
-static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, int size)
+static void bcm2835_aux_receive(void *opaque, const uint8_t *buf, size_t size)
 {
 bcm2835_aux_put_fifo(opaque, *buf);
 }
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index fbdbd463bb..eb5cc974a1 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -332,7 +332,7 @@ static void uart_write_tx_fifo(CadenceUARTState *s, const 
uint8_t *buf,
 cadence_uart_xmit(NULL, G_IO_OUT, s);
 }
 
-static void uart_receive(void *opaque, const uint8_t *buf, int size)
+static void uart_receive(void *opaque, const 

[Qemu-devel] [PATCH v2 00/11] chardev: Convert IO handlers to use unsigned type

2018-10-11 Thread Philippe Mathieu-Daudé
Hi Paolo,

Here are the changes you suggested in
https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg02294.html

First two simple cleanups while here,
then slowly convert backends then frontends.

Regards,

Phil.

Philippe Mathieu-Daudé (11):
  hw/ipmi: Remove unnecessary declarations
  target/xtensa: Remove unnecessary declarations
  chardev: Simplify IOWatchPoll::fd_can_read as a GSourceFunc
  chardev: Assert backend's chr_can_read() is positive
  chardev: Let chr_sync_read() use unsigned type
  chardev: Let chr_write use unsigned type
  chardev: Let IOReadHandler use unsigned type
  chardev: Let IOCanReadHandler use unsigned type
  chardev: Let qemu_chr_fe_* use unsigned type
  chardev: Let qemu_chr_be_* use unsigned type
  chardev: FDChardev::max_size be unsigned

 backends/rng-egd.c  |  6 +++---
 chardev/baum.c  |  2 +-
 chardev/char-fd.c   |  8 
 chardev/char-fe.c   |  8 
 chardev/char-io.c   |  4 ++--
 chardev/char-mux.c  |  6 +++---
 chardev/char-pty.c  |  6 +++---
 chardev/char-ringbuf.c  |  4 ++--
 chardev/char-socket.c   | 10 +-
 chardev/char-udp.c  |  6 +++---
 chardev/char-win-stdio.c|  2 +-
 chardev/char-win.c  |  2 +-
 chardev/char.c  | 20 
 chardev/msmouse.c   |  2 +-
 chardev/spice.c |  2 +-
 chardev/testdev.c   |  2 +-
 chardev/wctablet.c  |  4 ++--
 gdbstub.c   |  6 +++---
 hw/arm/pxa2xx.c |  4 ++--
 hw/arm/strongarm.c  |  5 +++--
 hw/bt/hci-csr.c |  4 ++--
 hw/char/bcm2835_aux.c   |  4 ++--
 hw/char/cadence_uart.c  |  6 +++---
 hw/char/cmsdk-apb-uart.c|  4 ++--
 hw/char/digic-uart.c|  4 ++--
 hw/char/escc.c  |  8 
 hw/char/etraxfs_ser.c   |  4 ++--
 hw/char/exynos4210_uart.c   |  5 +++--
 hw/char/grlib_apbuart.c |  4 ++--
 hw/char/imx_serial.c|  4 ++--
 hw/char/ipoctal232.c|  6 +++---
 hw/char/lm32_juart.c|  4 ++--
 hw/char/lm32_uart.c |  4 ++--
 hw/char/mcf_uart.c  |  4 ++--
 hw/char/milkymist-uart.c|  4 ++--
 hw/char/parallel.c  |  2 +-
 hw/char/pl011.c |  6 +++---
 hw/char/sclpconsole-lm.c|  4 ++--
 hw/char/sclpconsole.c   |  6 +++---
 hw/char/serial.c|  8 
 hw/char/sh_serial.c |  6 +++---
 hw/char/spapr_vty.c |  6 +++---
 hw/char/stm32f2xx_usart.c   |  5 +++--
 hw/char/terminal3270.c  |  4 ++--
 hw/char/virtio-console.c|  4 ++--
 hw/char/xen_console.c   |  4 ++--
 hw/char/xilinx_uartlite.c   |  4 ++--
 hw/ipmi/ipmi_bmc_extern.c   |  8 ++--
 hw/misc/ivshmem.c   |  6 +++---
 hw/riscv/riscv_htif.c   |  4 ++--
 hw/riscv/sifive_uart.c  |  4 ++--
 hw/usb/ccid-card-passthru.c |  6 +++---
 hw/usb/dev-serial.c |  4 ++--
 hw/usb/redirect.c   |  4 ++--
 include/chardev/char-fd.h   |  2 +-
 include/chardev/char-fe.h   |  6 +++---
 include/chardev/char-io.h   |  2 +-
 include/chardev/char.h  | 13 +++--
 include/qemu/main-loop.h|  4 ++--
 include/sysemu/replay.h |  8 
 monitor.c   |  6 +++---
 net/colo-compare.c  |  6 +++---
 net/filter-mirror.c |  4 ++--
 net/slirp.c |  4 ++--
 qtest.c |  4 ++--
 replay/replay-char.c|  8 
 stubs/replay.c  |  8 
 target/xtensa/xtensa-semi.c |  6 ++
 ui/console.c|  2 +-
 ui/gtk.c|  2 +-
 70 files changed, 180 insertions(+), 178 deletions(-)

-- 
2.17.1




[Qemu-devel] [PATCH v2 01/11] hw/ipmi: Remove unnecessary declarations

2018-10-11 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/ipmi/ipmi_bmc_extern.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index bf0b7ee0f5..8c78b9804b 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -85,10 +85,6 @@ typedef struct IPMIBmcExtern {
 bool send_reset;
 } IPMIBmcExtern;
 
-static int can_receive(void *opaque);
-static void receive(void *opaque, const uint8_t *buf, int size);
-static void chr_event(void *opaque, int event);
-
 static unsigned char
 ipmb_checksum(const unsigned char *data, int size, unsigned char start)
 {
-- 
2.17.1




[Qemu-devel] [PATCH] gdbstub: Remove unused include

2018-10-11 Thread Philippe Mathieu-Daudé
Signed-off-by: Philippe Mathieu-Daudé 
---
 gdbstub.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gdbstub.c b/gdbstub.c
index c8478de8f5..c4e4f9f082 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -20,7 +20,6 @@
 #include "qapi/error.h"
 #include "qemu/error-report.h"
 #include "qemu/cutils.h"
-#include "cpu.h"
 #include "trace-root.h"
 #ifdef CONFIG_USER_ONLY
 #include "qemu.h"
-- 
2.17.1




Re: [Qemu-devel] [PATCH] spapr_pci: rename some structured types

2018-10-11 Thread David Gibson
On Thu, Oct 11, 2018 at 03:04:08PM +0200, Greg Kurz wrote:
> On Thu, 11 Oct 2018 13:02:50 +0200
> Philippe Mathieu-Daudé  wrote:
> 
> > Hi Greg,
> > 
> > On 11/10/2018 09:00, Greg Kurz wrote:
> > > According to CODING_STYLE, structured types names are expected to be
> > > in CamelCase. PCI is dropped from the name for better
> > readability.

I'd prefer you didn't drop PCI from the name.  These specifically
*are* PCI MSIs, whereas lots of PAPR documentation (particularly for
the interrupt controller) uses MSIs to indicate general message
interrupts, such as those from VIO and firmware event reporting.

> > > 
> > > While here, this also converts a call to g_malloc(n * sizeofi(foo)) to  
> > 
> 
> Oops finger slipped on its way to the left parenthesis :)
> 
> > sizeof(foo)
> > 
> > > g_new(n, foo), which is a recommended good practice.  
> > 
> > Clearly 2 different patches...
> > 
> 
> You're right in theory. I added the g_new conversion in the same patch
> for simplicity mostly. I'll let David decide :)

I'd prefer them separate.

> 
> > > 
> > > Signed-off-by: Greg Kurz 
> > > ---
> > >  hw/ppc/spapr_pci.c  |   22 +++---
> > >  include/hw/pci-host/spapr.h |   12 ++--
> > >  2 files changed, 17 insertions(+), 17 deletions(-)
> > > 
> > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> > > index c2271e6ed462..bfb959f2b065 100644
> > > --- a/hw/ppc/spapr_pci.c
> > > +++ b/hw/ppc/spapr_pci.c
> > > @@ -277,7 +277,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
> > > sPAPRMachineState *spapr,
> > >  unsigned int irq, max_irqs = 0;
> > >  sPAPRPHBState *phb = NULL;
> > >  PCIDevice *pdev = NULL;
> > > -spapr_pci_msi *msi;
> > > +sPAPRMSI *msi;  
> > 
> > In CamelCase this should be "SpaprMsi"...
> > I however agree sPAPRMSI is nicer, the code is also easier to
> > review.

Yeah.. it's kind of a mangled combination of CamelCase with what's
been done elsewhere in the spapr code.

> > 
> > >  int *config_addr_key;
> > >  Error *err = NULL;
> > >  int i;
> > > @@ -325,7 +325,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
> > > sPAPRMachineState *spapr,
> > >  return;
> > >  }
> > >  
> > > -msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, _addr);
> > > +msi = (sPAPRMSI *) g_hash_table_lookup(phb->msi, _addr);
> > >  
> > >  /* Releasing MSIs */
> > >  if (!req_num) {
> > > @@ -414,7 +414,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, 
> > > sPAPRMachineState *spapr,
> > >   irq, req_num);
> > >  
> > >  /* Add MSI device to cache */
> > > -msi = g_new(spapr_pci_msi, 1);
> > > +msi = g_new(sPAPRMSI, 1);
> > >  msi->first_irq = irq;
> > >  msi->num = req_num;
> > >  config_addr_key = g_new(int, 1);
> > > @@ -445,7 +445,7 @@ static void 
> > > rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
> > >  unsigned int intr_src_num = -1, ioa_intr_num = rtas_ld(args, 3);
> > >  sPAPRPHBState *phb = NULL;
> > >  PCIDevice *pdev = NULL;
> > > -spapr_pci_msi *msi;
> > > +sPAPRMSI *msi;
> > >  
> > >  /* Find sPAPRPHBState */
> > >  phb = spapr_pci_find_phb(spapr, buid);
> > > @@ -458,7 +458,7 @@ static void 
> > > rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
> > >  }
> > >  
> > >  /* Find device descriptor and start IRQ */
> > > -msi = (spapr_pci_msi *) g_hash_table_lookup(phb->msi, _addr);
> > > +msi = (sPAPRMSI *) g_hash_table_lookup(phb->msi, _addr);
> > >  if (!msi || !msi->first_irq || !msi->num || (ioa_intr_num >= 
> > > msi->num)) {
> > >  trace_spapr_pci_msi("Failed to return vector", config_addr);
> > >  rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
> > > @@ -1849,9 +1849,9 @@ static const VMStateDescription 
> > > vmstate_spapr_pci_msi = {
> > >  .version_id = 1,
> > >  .minimum_version_id = 1,
> > >  .fields = (VMStateField []) {
> > > -VMSTATE_UINT32(key, spapr_pci_msi_mig),
> > > -VMSTATE_UINT32(value.first_irq, spapr_pci_msi_mig),
> > > -VMSTATE_UINT32(value.num, spapr_pci_msi_mig),
> > > +VMSTATE_UINT32(key, sPAPRMSIMig),
> > > +VMSTATE_UINT32(value.first_irq, sPAPRMSIMig),
> > > +VMSTATE_UINT32(value.num, sPAPRMSIMig),
> > >  VMSTATE_END_OF_LIST()
> > >  },
> > >  };
> > > @@ -1883,12 +1883,12 @@ static int spapr_pci_pre_save(void *opaque)
> > >  if (!sphb->msi_devs_num) {
> > >  return 0;
> > >  }
> > > -sphb->msi_devs = g_malloc(sphb->msi_devs_num * 
> > > sizeof(spapr_pci_msi_mig));
> > > +sphb->msi_devs = g_new(sPAPRMSIMig, sphb->msi_devs_num);
> > >  
> > >  g_hash_table_iter_init(, sphb->msi);
> > >  for (i = 0; g_hash_table_iter_next(, , ); ++i) {
> > >  sphb->msi_devs[i].key = *(uint32_t *) key;
> > > -sphb->msi_devs[i].value = *(spapr_pci_msi *) value;
> > > +sphb->msi_devs[i].value = *(sPAPRMSI *) value;
> > >  }
> > >  
> > >  

Re: [Qemu-devel] [PATCH v1 0/5] Misc RISC-V patches

2018-10-11 Thread Palmer Dabbelt

On Thu, 11 Oct 2018 02:34:16 PDT (-0700), peter.mayd...@linaro.org wrote:

On 10 October 2018 at 19:22, Palmer Dabbelt  wrote:

On Wed, 10 Oct 2018 11:10:07 PDT (-0700), peter.mayd...@linaro.org wrote:


On 10 October 2018 at 18:49, Palmer Dabbelt  wrote:


we should really
get the ball rolling on our big patch backlog.



Yes, please do. Softfreeze is not all that far away and I
would strongly prefer not to get an enormous sized pull
request at the last minute. The ideal pattern is that
code changes come in at a steady rate across the whole
of the 'open' part of the development cycle.



Ya, sorry, we've been a bit out of it.  If I understand correctly, the soft
freeze is the 30th?  If so it's really time to get started, and it looks
like Michael is busy so I'll have to go figure this out.


Alistair's done the last couple of riscv pullrequests, so it might
be simpler if he keeps doing that, but I'll let you sort that out
between yourselves.


Ah, great.  I'm always happy to have other people do things, I just feel kind 
of bad: I'm a maintainer and I'm putting the burden on someone else to submit a 
PR.


If Alistair is happy submitting PRs than I'm happy to have him do it :).



Re: [Qemu-devel] [PATCH v2 2/3] tests/vm: Do not abuse parallelism when KVM is not available

2018-10-11 Thread Philippe Mathieu-Daudé
On Thu, Oct 11, 2018 at 4:46 AM Fam Zheng  wrote:
> On Mon, 10/01 01:23, Philippe Mathieu-Daudé wrote:
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> > v2: Add get_default_jobs (Fam suggestion)
> > ---
> >  tests/vm/basevm.py | 13 ++---
> >  1 file changed, 10 insertions(+), 3 deletions(-)
> >
> > diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
> > index 5a5fa09752..fc203e9f53 100755
> > --- a/tests/vm/basevm.py
> > +++ b/tests/vm/basevm.py
> > @@ -202,6 +202,13 @@ class BaseVM(object):
> >  return self._guest.qmp(*args, **kwargs)
> >
> >  def parse_args(vm_name):
> > +
> > +def get_default_jobs():
> > +if kvm_available():
> > +return multiprocessing.cpu_count() / 2
> > +else:
> > +return 1
> > +
> >  parser = optparse.OptionParser(
> >  description="VM test utility.  Exit codes: "
> >  "0 = success, "
> > @@ -214,7 +221,7 @@ def parse_args(vm_name):
> >help="image file name")
> >  parser.add_option("--force", "-f", action="store_true",
> >help="force build image even if image exists")
> > -parser.add_option("--jobs", type=int, 
> > default=multiprocessing.cpu_count() / 2,
> > +parser.add_option("--jobs", type=int, default=get_default_jobs(),
> >help="number of virtual CPUs")
> >  parser.add_option("--verbose", "-V", action="store_true",
> >help="Pass V=1 to builds within the guest")
> > @@ -237,7 +244,7 @@ def main(vmcls):
> >  return 1
> >  logging.basicConfig(level=(logging.DEBUG if args.debug
> > else logging.WARN))
> > -vm = vmcls(debug=args.debug, vcpus=args.jobs)
> > +vm = vmcls(debug=args.debug, vcpus=args.jobs if kvm_available() 
> > else 0)
>
> What's wrong with just using args.jobs? It defaults to 1 if kvm_available()
> returns false, so I don't think we need another condition here.

You are right, I missed that.

>
> >  if args.build_image:
> >  if os.path.exists(args.image) and not args.force:
> >  sys.stderr.writelines(["Image file exists: %s\n" % 
> > args.image,
> > @@ -248,7 +255,7 @@ def main(vmcls):
> >  vm.add_source_dir(args.build_qemu)
> >  cmd = [vm.BUILD_SCRIPT.format(
> > configure_opts = " ".join(argv),
> > -   jobs=args.jobs,
> > +   jobs=args.jobs if kvm_available() else 1,
>
> Again, can't we just use args.jobs?
>
> > verbose = "V=1" if args.verbose else "")]
> >  else:
> >  cmd = argv
> > --
> > 2.19.0
> >
>
> Fam



[Qemu-devel] [PATCH 7/7] target/ppc: Split out float_invalid_cvt

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 67 +
 1 file changed, 28 insertions(+), 39 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 127c08bcec..2ed4f42275 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -750,30 +750,30 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, 
float64 arg2)
 return ret;
 }
 
+static void float_invalid_cvt(CPUPPCState *env, bool set_fprc,
+  uintptr_t retaddr, int class1)
+{
+float_invalid_op_vxcvi(env, set_fprc, retaddr);
+if (class1 & is_snan) {
+float_invalid_op_vxsnan(env, retaddr);
+}
+}
 
 #define FPU_FCTI(op, cvt, nanval)  \
-uint64_t helper_##op(CPUPPCState *env, uint64_t arg)   \
+uint64_t helper_##op(CPUPPCState *env, float64 arg)\
 {  \
-CPU_DoubleU farg;  \
+uint64_t ret = float64_to_##cvt(arg, >fp_status); \
+int status = get_float_exception_flags(>fp_status);   \
\
-farg.ll = arg; \
-farg.ll = float64_to_##cvt(farg.d, >fp_status);   \
-   \
-if (unlikely(env->fp_status.float_exception_flags)) {  \
-if (float64_is_any_nan(arg)) { \
-float_invalid_op_vxcvi(env, 1, GETPC());   \
-if (float64_is_signaling_nan(arg, >fp_status)) {  \
-float_invalid_op_vxsnan(env, GETPC()); \
-}  \
-farg.ll = nanval;  \
-} else if (env->fp_status.float_exception_flags &  \
-   float_flag_invalid) {   \
-float_invalid_op_vxcvi(env, 1, GETPC());   \
+if (unlikely(status)) {\
+if (status & float_flag_invalid) { \
+float_invalid_cvt(env, 1, GETPC(), float64_classify(arg)); \
+ret = nanval;  \
 }  \
 do_float_check_status(env, GETPC());   \
 }  \
-return farg.ll;\
- }
+return ret;\
+}
 
 FPU_FCTI(fctiw, int32, 0x8000U)
 FPU_FCTI(fctiwz, int32_round_to_zero, 0x8000U)
@@ -2965,6 +2965,7 @@ uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
 #define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan)  \
 void helper_##op(CPUPPCState *env, uint32_t opcode)  \
 {\
+int all_flags = env->fp_status.float_exception_flags, flags; \
 ppc_vsr_t xt, xb;\
 int i;   \
  \
@@ -2972,22 +2973,18 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) 
 \
 getVSR(xT(opcode), , env);\
  \
 for (i = 0; i < nels; i++) { \
-if (unlikely(stp##_is_any_nan(xb.sfld))) {   \
-if (stp##_is_signaling_nan(xb.sfld, >fp_status)) {  \
-float_invalid_op_vxsnan(env, GETPC());   \
-}\
-float_invalid_op_vxcvi(env, 0, GETPC()); \
+env->fp_status.float_exception_flags = 0;\
+xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, >fp_status);  \
+flags = env->fp_status.float_exception_flags;\
+if (unlikely(flags & float_flag_invalid)) {  \
+float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb.sfld)); \
 xt.tfld = rnan;  \
-} else { \
-xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld,  

[Qemu-devel] [PATCH 1/7] target/ppc: Split up float_invalid_op_excp

2018-10-11 Thread Richard Henderson
The always_inline trick only works if the function is always
called from the outer-most helper.  But it isn't, so pass in
the outer-most return address.  There's no need for a switch
statement whose argument is always a constant.  Unravel the
switch and goto via more helpers.

Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 344 +---
 1 file changed, 181 insertions(+), 163 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index b9bb1b856e..6ec5227dd5 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -170,96 +170,120 @@ COMPUTE_FPRF(float64)
 COMPUTE_FPRF(float128)
 
 /* Floating-point invalid operations exception */
-static inline __attribute__((__always_inline__))
-uint64_t float_invalid_op_excp(CPUPPCState *env, int op, int set_fpcc)
+static void finish_invalid_op_excp(CPUPPCState *env, int op, uintptr_t retaddr)
 {
-CPUState *cs = CPU(ppc_env_get_cpu(env));
-uint64_t ret = 0;
-int ve;
+/* Update the floating-point invalid operation summary */
+env->fpscr |= 1 << FPSCR_VX;
+/* Update the floating-point exception summary */
+env->fpscr |= FP_FX;
+if (fpscr_ve != 0) {
+/* Update the floating-point enabled exception summary */
+env->fpscr |= 1 << FPSCR_FEX;
+if (fp_exceptions_enabled(env)) {
+raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
+   POWERPC_EXCP_FP | op, retaddr);
+}
+}
+}
 
-ve = fpscr_ve;
-switch (op) {
-case POWERPC_EXCP_FP_VXSNAN:
-env->fpscr |= 1 << FPSCR_VXSNAN;
-break;
-case POWERPC_EXCP_FP_VXSOFT:
-env->fpscr |= 1 << FPSCR_VXSOFT;
-break;
-case POWERPC_EXCP_FP_VXISI:
-/* Magnitude subtraction of infinities */
-env->fpscr |= 1 << FPSCR_VXISI;
-goto update_arith;
-case POWERPC_EXCP_FP_VXIDI:
-/* Division of infinity by infinity */
-env->fpscr |= 1 << FPSCR_VXIDI;
-goto update_arith;
-case POWERPC_EXCP_FP_VXZDZ:
-/* Division of zero by zero */
-env->fpscr |= 1 << FPSCR_VXZDZ;
-goto update_arith;
-case POWERPC_EXCP_FP_VXIMZ:
-/* Multiplication of zero by infinity */
-env->fpscr |= 1 << FPSCR_VXIMZ;
-goto update_arith;
-case POWERPC_EXCP_FP_VXVC:
-/* Ordered comparison of NaN */
-env->fpscr |= 1 << FPSCR_VXVC;
+static void finish_invalid_op_arith(CPUPPCState *env, int op,
+bool set_fpcc, uintptr_t retaddr)
+{
+env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
+if (fpscr_ve == 0) {
 if (set_fpcc) {
 env->fpscr &= ~(0xF << FPSCR_FPCC);
 env->fpscr |= 0x11 << FPSCR_FPCC;
 }
-/* We must update the target FPR before raising the exception */
-if (ve != 0) {
-cs->exception_index = POWERPC_EXCP_PROGRAM;
-env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
-/* Update the floating-point enabled exception summary */
-env->fpscr |= 1 << FPSCR_FEX;
-/* Exception is differed */
-ve = 0;
-}
-break;
-case POWERPC_EXCP_FP_VXSQRT:
-/* Square root of a negative number */
-env->fpscr |= 1 << FPSCR_VXSQRT;
-update_arith:
-env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
-if (ve == 0) {
-/* Set the result to quiet NaN */
-ret = 0x7FF8ULL;
-if (set_fpcc) {
-env->fpscr &= ~(0xF << FPSCR_FPCC);
-env->fpscr |= 0x11 << FPSCR_FPCC;
-}
-}
-break;
-case POWERPC_EXCP_FP_VXCVI:
-/* Invalid conversion */
-env->fpscr |= 1 << FPSCR_VXCVI;
-env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
-if (ve == 0) {
-/* Set the result to quiet NaN */
-ret = 0x7FF8ULL;
-if (set_fpcc) {
-env->fpscr &= ~(0xF << FPSCR_FPCC);
-env->fpscr |= 0x11 << FPSCR_FPCC;
-}
-}
-break;
+}
+finish_invalid_op_excp(env, op, retaddr);
+}
+
+/* Signalling NaN */
+static void float_invalid_op_vxsnan(CPUPPCState *env, uintptr_t retaddr)
+{
+env->fpscr |= 1 << FPSCR_VXSNAN;
+finish_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, retaddr);
+}
+
+/* Magnitude subtraction of infinities */
+static void float_invalid_op_vxisi(CPUPPCState *env, bool set_fpcc,
+   uintptr_t retaddr)
+{
+env->fpscr |= 1 << FPSCR_VXISI;
+finish_invalid_op_arith(env, POWERPC_EXCP_FP_VXISI, set_fpcc, retaddr);
+}
+
+/* Division of infinity by infinity */
+static void float_invalid_op_vxidi(CPUPPCState *env, bool set_fpcc,
+   uintptr_t retaddr)
+{
+env->fpscr |= 1 << FPSCR_VXIDI;
+finish_invalid_op_arith(env, 

[Qemu-devel] [PATCH 6/7] target/ppc: Split out float_invalid_op_div

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 52 +++--
 1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ef251d062f..127c08bcec 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -715,6 +715,21 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, 
float64 arg2)
 return ret;
 }
 
+static void float_invalid_op_div(CPUPPCState *env, bool set_fprc,
+ uintptr_t retaddr, int classes)
+{
+classes &= ~is_neg;
+if (classes == is_inf) {
+/* Division of infinity by infinity */
+float_invalid_op_vxidi(env, set_fprc, retaddr);
+} else if (classes == is_zero) {
+/* Division of zero by zero */
+float_invalid_op_vxzdz(env, set_fprc, retaddr);
+} else if (classes & is_snan) {
+float_invalid_op_vxsnan(env, retaddr);
+}
+}
+
 /* fdiv - fdiv. */
 float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
 {
@@ -723,18 +738,9 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, 
float64 arg2)
 
 if (unlikely(status)) {
 if (status & float_flag_invalid) {
-/* Determine what kind of invalid operation was seen.  */
-if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
-/* Division of infinity by infinity */
-float_invalid_op_vxidi(env, 1, GETPC());
-} else if (float64_is_zero(arg1) && float64_is_zero(arg2)) {
-/* Division of zero by zero */
-float_invalid_op_vxzdz(env, 1, GETPC());
-} else if (float64_is_signaling_nan(arg1, >fp_status) ||
-   float64_is_signaling_nan(arg2, >fp_status)) {
-/* sNaN division */
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_div(env, 1, GETPC(),
+ float64_classify(arg1) |
+ float64_classify(arg2));
 }
 if (status & float_flag_divbyzero) {
 float_zero_divide_excp(env, GETPC());
@@ -1969,14 +1975,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)  
 \
 env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
   \
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
-if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) {   \
-float_invalid_op_vxidi(env, sfprf, GETPC());  \
-} else if (tp##_is_zero(xa.fld) && tp##_is_zero(xb.fld)) {\
-float_invalid_op_vxzdz(env, sfprf, GETPC());  \
-} else if (tp##_is_signaling_nan(xa.fld, ) ||   \
-   tp##_is_signaling_nan(xb.fld, )) {   \
-float_invalid_op_vxsnan(env, GETPC());\
-} \
+float_invalid_op_div(env, sfprf, GETPC(), \
+ tp##_classify(xa.fld) |  \
+ tp##_classify(xb.fld));  \
 } \
 if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {   \
 float_zero_divide_excp(env, GETPC()); \
@@ -2020,14 +2021,9 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
 env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
-float_invalid_op_vxidi(env, 1, GETPC());
-} else if (float128_is_zero(xa.f128) && float128_is_zero(xb.f128)) {
-float_invalid_op_vxzdz(env, 1, GETPC());
-} else if (float128_is_signaling_nan(xa.f128, ) ||
-   float128_is_signaling_nan(xb.f128, )) {
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_div(env, 1, GETPC(),
+ float128_classify(xa.f128) |
+ float128_classify(xb.f128));
 }
 if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
 float_zero_divide_excp(env, GETPC());
-- 
2.17.1




[Qemu-devel] [PATCH 4/7] target/ppc: Split out float_invalid_op_addsub

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 60 ++---
 1 file changed, 26 insertions(+), 34 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 9ae55b1e93..111ce12a37 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -648,6 +648,17 @@ void helper_reset_fpstatus(CPUPPCState *env)
 set_float_exception_flags(0, >fp_status);
 }
 
+static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc,
+uintptr_t retaddr, int classes)
+{
+if ((classes & ~is_neg) == is_inf) {
+/* Magnitude subtraction of infinities */
+float_invalid_op_vxisi(env, set_fpcc, retaddr);
+} else if (classes & is_snan) {
+float_invalid_op_vxsnan(env, retaddr);
+}
+}
+
 /* fadd - fadd. */
 float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
 {
@@ -655,14 +666,9 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, 
float64 arg2)
 int status = get_float_exception_flags(>fp_status);
 
 if (unlikely(status & float_flag_invalid)) {
-if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
-/* Magnitude subtraction of infinities */
-float_invalid_op_vxisi(env, 1, GETPC());
-} else if (float64_is_signaling_nan(arg1, >fp_status) ||
-   float64_is_signaling_nan(arg2, >fp_status)) {
-/* sNaN addition */
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_addsub(env, 1, GETPC(),
+float64_classify(arg1) |
+float64_classify(arg2));
 }
 
 return ret;
@@ -675,14 +681,9 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, 
float64 arg2)
 int status = get_float_exception_flags(>fp_status);
 
 if (unlikely(status & float_flag_invalid)) {
-if (float64_is_infinity(arg1) && float64_is_infinity(arg2)) {
-/* Magnitude subtraction of infinities */
-float_invalid_op_vxisi(env, 1, GETPC());
-} else if (float64_is_signaling_nan(arg1, >fp_status) ||
-   float64_is_signaling_nan(arg2, >fp_status)) {
-/* sNaN addition */
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_addsub(env, 1, GETPC(),
+float64_classify(arg1) |
+float64_classify(arg2));
 }
 
 return ret;
@@ -1803,12 +1804,9 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)
\
 env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
  \
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {\
-if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) {  \
-float_invalid_op_vxisi(env, sfprf, GETPC()); \
-} else if (tp##_is_signaling_nan(xa.fld, ) ||  \
-   tp##_is_signaling_nan(xb.fld, )) {  \
-float_invalid_op_vxsnan(env, GETPC());   \
-}\
+float_invalid_op_addsub(env, sfprf, GETPC(), \
+tp##_classify(xa.fld) |  \
+tp##_classify(xb.fld));  \
 }\
  \
 if (r2sp) {  \
@@ -1852,12 +1850,9 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
 env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
-float_invalid_op_vxisi(env, 1, GETPC());
-} else if (float128_is_signaling_nan(xa.f128, ) ||
-   float128_is_signaling_nan(xb.f128, )) {
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_addsub(env, 1, GETPC(),
+float128_classify(xa.f128) |
+float128_classify(xb.f128));
 }
 
 helper_compute_fprf_float128(env, xt.f128);
@@ -3518,12 +3513,9 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
 env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-if (float128_is_infinity(xa.f128) && float128_is_infinity(xb.f128)) {
-float_invalid_op_vxisi(env, 1, GETPC());
-} else if (float128_is_signaling_nan(xa.f128, ) ||
-

[Qemu-devel] [PATCH 5/7] target/ppc: Split out float_invalid_op_mul

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 43 +++--
 1 file changed, 20 insertions(+), 23 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 111ce12a37..ef251d062f 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -689,6 +689,17 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, 
float64 arg2)
 return ret;
 }
 
+static void float_invalid_op_mul(CPUPPCState *env, bool set_fprc,
+ uintptr_t retaddr, int classes)
+{
+if ((classes & (is_zero | is_inf)) == (is_zero | is_inf)) {
+/* Multiplication of zero by infinity */
+float_invalid_op_vximz(env, set_fprc, retaddr);
+} else if (classes & is_snan) {
+float_invalid_op_vxsnan(env, retaddr);
+}
+}
+
 /* fmul - fmul. */
 float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
 {
@@ -696,15 +707,9 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, 
float64 arg2)
 int status = get_float_exception_flags(>fp_status);
 
 if (unlikely(status & float_flag_invalid)) {
-if ((float64_is_infinity(arg1) && float64_is_zero(arg2)) ||
-(float64_is_zero(arg1) && float64_is_infinity(arg2))) {
-/* Multiplication of zero by infinity */
-float_invalid_op_vximz(env, 1, GETPC());
-} else if (float64_is_signaling_nan(arg1, >fp_status) ||
-   float64_is_signaling_nan(arg2, >fp_status)) {
-/* sNaN multiplication */
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_mul(env, 1, GETPC(),
+ float64_classify(arg1) |
+ float64_classify(arg2));
 }
 
 return ret;
@@ -1886,13 +1891,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)  
\
 env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
  \
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {\
-if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) ||\
-(tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) {\
-float_invalid_op_vximz(env, sfprf, GETPC()); \
-} else if (tp##_is_signaling_nan(xa.fld, ) ||  \
-   tp##_is_signaling_nan(xb.fld, )) {  \
-float_invalid_op_vxsnan(env, GETPC());   \
-}\
+float_invalid_op_mul(env, sfprf, GETPC(),\
+ tp##_classify(xa.fld) | \
+ tp##_classify(xb.fld)); \
 }\
  \
 if (r2sp) {  \
@@ -1933,13 +1934,9 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
 env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
 if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-if ((float128_is_infinity(xa.f128) && float128_is_zero(xb.f128)) ||
-(float128_is_infinity(xb.f128) && float128_is_zero(xa.f128))) {
-float_invalid_op_vximz(env, 1, GETPC());
-} else if (float128_is_signaling_nan(xa.f128, ) ||
-   float128_is_signaling_nan(xb.f128, )) {
-float_invalid_op_vxsnan(env, GETPC());
-}
+float_invalid_op_mul(env, 1, GETPC(),
+ float128_classify(xa.f128) |
+ float128_classify(xb.f128));
 }
 helper_compute_fprf_float128(env, xt.f128);
 
-- 
2.17.1




[Qemu-devel] [PATCH 2/7] target/ppc: Remove float_check_status

2018-10-11 Thread Richard Henderson
Use do_float_check_status directly, so that we don't get confused
about which return address we're using.  And definitely don't use
helper_float_check_status.

Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 77 +++--
 1 file changed, 35 insertions(+), 42 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 6ec5227dd5..c9198f826d 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -630,13 +630,6 @@ static void do_float_check_status(CPUPPCState *env, 
uintptr_t raddr)
 }
 }
 
-static inline  __attribute__((__always_inline__))
-void float_check_status(CPUPPCState *env)
-{
-/* GETPC() works here because this is inline */
-do_float_check_status(env, GETPC());
-}
-
 void helper_float_check_status(CPUPPCState *env)
 {
 do_float_check_status(env, GETPC());
@@ -757,7 +750,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)
   \
float_flag_invalid) {   \
 float_invalid_op_vxcvi(env, 1, GETPC());   \
 }  \
-float_check_status(env);   \
+do_float_check_status(env, GETPC());   \
 }  \
 return farg.ll;\
  }
@@ -782,7 +775,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)   \
 } else {   \
 farg.d = cvtr(arg, >fp_status);   \
 }  \
-float_check_status(env);   \
+do_float_check_status(env, GETPC());   \
 return farg.ll;\
 }
 
@@ -815,7 +808,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t 
arg,
 env->fp_status.float_exception_flags &= ~float_flag_inexact;
 }
 }
-float_check_status(env);
+do_float_check_status(env, GETPC());
 return farg.ll;
 }
 
@@ -885,7 +878,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,   
\
 float64_maddsub_update_excp(env, arg1, arg2, arg3,  \
 madd_flags, GETPC());   \
 }   \
-float_check_status(env);\
+do_float_check_status(env, GETPC());\
 }   \
 return ret; \
 }
@@ -1819,7 +1812,7 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) 
   \
 }\
 }\
 putVSR(xT(opcode), , env);\
-float_check_status(env); \
+do_float_check_status(env, GETPC()); \
 }
 
 VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0)
@@ -1862,7 +1855,7 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
 helper_compute_fprf_float128(env, xt.f128);
 
 putVSR(rD(opcode) + 32, , env);
-float_check_status(env);
+do_float_check_status(env, GETPC());
 }
 
 /* VSX_MUL - VSX floating point multiply
@@ -1909,7 +1902,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)   
   \
 }\
  \
 putVSR(xT(opcode), , env);\
-float_check_status(env); \
+do_float_check_status(env, GETPC()); \
 }
 
 VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0)
@@ -1948,7 +1941,7 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
 helper_compute_fprf_float128(env, xt.f128);
 
 putVSR(rD(opcode) + 32, , env);
-float_check_status(env);
+do_float_check_status(env, GETPC());
 }
 
 /* VSX_DIV - VSX floating point divide
@@ -1999,7 +1992,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)   
\
 } \
   \
 putVSR(xT(opcode), , env); \
-float_check_status(env);  \
+do_float_check_status(env, GETPC());

[Qemu-devel] [PATCH 0/7] target/ppc: Some cleanups to fp exceptions

2018-10-11 Thread Richard Henderson
There are a few bugs here, primarily wrt usage of GETPC().
But there is opportunity to share more code between paths
that operate on different floating point types.

This is not everything that could be done, but it's a good start.
Better for this not to hang out on a branch for another release.


r~


Richard Henderson (7):
  target/ppc: Split up float_invalid_op_excp
  target/ppc: Remove float_check_status
  target/ppc: Introduce fp number classification
  target/ppc: Split out float_invalid_op_addsub
  target/ppc: Split out float_invalid_op_mul
  target/ppc: Split out float_invalid_op_div
  target/ppc: Split out float_invalid_cvt

 target/ppc/fpu_helper.c | 661 
 1 file changed, 327 insertions(+), 334 deletions(-)

-- 
2.17.1




[Qemu-devel] [PATCH 3/7] target/ppc: Introduce fp number classification

2018-10-11 Thread Richard Henderson
Having a separate, logical classifiation of numbers will
unify more error paths for different formats.

Signed-off-by: Richard Henderson 
---
 target/ppc/fpu_helper.c | 94 ++---
 1 file changed, 51 insertions(+), 43 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index c9198f826d..9ae55b1e93 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -114,54 +114,62 @@ static inline int ppc_float64_get_unbiased_exp(float64 f)
 return ((f >> 52) & 0x7FF) - 1023;
 }
 
-#define COMPUTE_FPRF(tp)   \
-void helper_compute_fprf_##tp(CPUPPCState *env, tp arg)\
+/* Classify a floating-point number.  */
+enum {
+is_normal   = 1,
+is_zero = 2,
+is_denormal = 4,
+is_inf  = 8,
+is_qnan = 16,
+is_snan = 32,
+is_neg  = 64,
+};
+
+#define COMPUTE_CLASS(tp)  \
+static int tp##_classify(tp arg)   \
 {  \
-int isneg; \
-int fprf;  \
-   \
-isneg = tp##_is_neg(arg);  \
+int ret = tp##_is_neg(arg) * is_neg;   \
 if (unlikely(tp##_is_any_nan(arg))) {  \
-if (tp##_is_signaling_nan(arg, >fp_status)) { \
-/* Signaling NaN: flags are undefined */   \
-fprf = 0x00;   \
-} else {   \
-/* Quiet NaN */\
-fprf = 0x11;   \
-}  \
+float_status dummy = { };  /* snan_bit_is_one = 0 */   \
+ret |= (tp##_is_signaling_nan(arg, ) \
+? is_snan : is_qnan);  \
 } else if (unlikely(tp##_is_infinity(arg))) {  \
-/* +/- infinity */ \
-if (isneg) {   \
-fprf = 0x09;   \
-} else {   \
-fprf = 0x05;   \
-}  \
+ret |= is_inf; \
+} else if (tp##_is_zero(arg)) {\
+ret |= is_zero;\
+} else if (tp##_is_zero_or_denormal(arg)) {\
+ret |= is_denormal;\
 } else {   \
-if (tp##_is_zero(arg)) {   \
-/* +/- zero */ \
-if (isneg) {   \
-fprf = 0x12;   \
-} else {   \
-fprf = 0x02;   \
-}  \
-} else {   \
-if (tp##_is_zero_or_denormal(arg)) {   \
-/* Denormalized numbers */ \
-fprf = 0x10;   \
-} else {   \
-/* Normalized numbers */   \
-fprf = 0x00;   \
-}  \
-if (isneg) {   \
-fprf |= 0x08;  \
-} else {   \
-fprf |= 0x04;  \
-}  \
-}  \
+ret |= is_normal;  \
 }  \
-/* We update FPSCR_FPRF */ \
-env->fpscr &= ~(0x1F << FPSCR_FPRF);   \
-env->fpscr |= fprf << FPSCR_FPRF;  \
+return ret;\
+}
+
+COMPUTE_CLASS(float16)
+COMPUTE_CLASS(float32)
+COMPUTE_CLASS(float64)
+COMPUTE_CLASS(float128)
+
+static void set_fprf_from_class(CPUPPCState *env, int class)
+{
+static const uint8_t fprf[6][2] = {
+{ 

Re: [Qemu-devel] [PATCH 02/20] target/arm: Don't call tcg_clear_temp_count

2018-10-11 Thread Philippe Mathieu-Daudé
On 11/10/2018 22:51, Richard Henderson wrote:
> This is done generically in translator_loop.
> 
> Reported-by: Laurent Desnogues 
> Signed-off-by: Richard Henderson 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  target/arm/translate-a64.c | 1 -
>  target/arm/translate.c | 1 -
>  2 files changed, 2 deletions(-)
> 
> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
> index 76b5ca3606..ac9723c1b9 100644
> --- a/target/arm/translate-a64.c
> +++ b/target/arm/translate-a64.c
> @@ -13899,7 +13899,6 @@ static void 
> aarch64_tr_init_disas_context(DisasContextBase *dcbase,
>  
>  static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
>  {
> -tcg_clear_temp_count();
>  }
>  
>  static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> diff --git a/target/arm/translate.c b/target/arm/translate.c
> index 426db7828a..736880ee71 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -12701,7 +12701,6 @@ static void arm_tr_tb_start(DisasContextBase *dcbase, 
> CPUState *cpu)
>  tcg_gen_movi_i32(tmp, 0);
>  store_cpu_field(tmp, condexec_bits);
>  }
> -tcg_clear_temp_count();
>  }
>  
>  static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> 



Re: [Qemu-devel] [PATCH 05/20] target/arm: Mark some arrays const

2018-10-11 Thread Philippe Mathieu-Daudé
On 11/10/2018 22:51, Richard Henderson wrote:
> Signed-off-by: Richard Henderson 

Reviewed-by: Philippe Mathieu-Daudé 

> ---
>  target/arm/translate.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/target/arm/translate.c b/target/arm/translate.c
> index 736880ee71..d59ffa1c67 100644
> --- a/target/arm/translate.c
> +++ b/target/arm/translate.c
> @@ -72,7 +72,7 @@ static TCGv_i64 cpu_F0d, cpu_F1d;
>  
>  #include "exec/gen-icount.h"
>  
> -static const char *regnames[] =
> +static const char * const regnames[] =
>  { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
>"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
>  
> @@ -4907,7 +4907,7 @@ static struct {
>  int nregs;
>  int interleave;
>  int spacing;
> -} neon_ls_element_type[11] = {
> +} const neon_ls_element_type[11] = {
>  {4, 4, 1},
>  {4, 4, 2},
>  {4, 1, 1},
> @@ -13089,7 +13089,7 @@ void gen_intermediate_code(CPUState *cpu, 
> TranslationBlock *tb)
>  translator_loop(ops, , cpu, tb);
>  }
>  
> -static const char *cpu_mode_names[16] = {
> +static const char * const cpu_mode_names[16] = {
>"usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
>"???", "???", "hyp", "und", "???", "???", "???", "sys"
>  };
> 



Re: [Qemu-devel] [RFC v3 1/5] tcg: Add tlb_index and tlb_entry helpers

2018-10-11 Thread Richard Henderson
On 10/9/18 10:51 AM, Emilio G. Cota wrote:
> From: Richard Henderson 
> 
> Isolate the computation of an index from an address into a
> helper before we change that function.
> 
> Reviewed-by: Alex Bennée 
> Signed-off-by: Richard Henderson 
> [ cota: convert tlb_vaddr_to_host; use atomic_read on addr_write ]
> Signed-off-by: Emilio G. Cota 
> ---
>  accel/tcg/softmmu_template.h | 68 
>  include/exec/cpu_ldst.h  | 19 +++--
>  include/exec/cpu_ldst_template.h | 25 ++--
>  accel/tcg/cputlb.c   | 61 +---
>  4 files changed, 90 insertions(+), 83 deletions(-)

Queued.


r~



Re: [Qemu-devel] [PATCH v5 0/6] per-TLB lock

2018-10-11 Thread Richard Henderson
On 10/9/18 10:45 AM, Emilio G. Cota wrote:
> v4: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg01421.html
> 
> Changes since v4:
> 
> - Add two patches to remove early calls to tlb_flush.
> 
> You can fetch the series from:
>   https://github.com/cota/qemu/tree/tlb-lock-v5

Queued, thanks.


r~



Re: [Qemu-devel] [PATCH 0/4] some TCG fixes

2018-10-11 Thread Richard Henderson
On 10/10/18 7:48 AM, Emilio G. Cota wrote:
> The first patch we've seen before -- I'm taking it from the
> atomic interrupt_request series.
> 
> The other three patches are related to TCG profiling. One
> of them is a build fix that I suspect has gone unnoticed
> due to its dependence on CONFIG_PROFILER.
> 
> The series is checkpatch-clean. You can fetch it from:
>   https://github.com/cota/qemu/tree/tcg-profile

Queued, thanks.


r~



Re: [Qemu-devel] [PATCH] vl: Print error when using incorrect backend for debugcon

2018-10-11 Thread Marc-André Lureau
On Thu, Oct 11, 2018 at 9:13 PM Philippe Mathieu-Daudé
 wrote:
>
> When using an incorrect backend for the debugcon, QEMU exits silently
> without any error indication, which is confusing.
> Add a message that the character backend is invalid.
>
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: Marc-André Lureau 

> ---
>  vl.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/vl.c b/vl.c
> index 4e25c78bff..61305b5891 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2466,6 +2466,7 @@ static int debugcon_parse(const char *devname)
>  QemuOpts *opts;
>
>  if (!qemu_chr_new_mux_mon("debugcon", devname)) {
> +error_report("invalid character backend '%s'", devname);
>  exit(1);
>  }
>  opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1, NULL);
> --
> 2.17.1
>



Re: [Qemu-devel] [PATCH] oslib-posix: Use MAP_STACK in qemu_alloc_stack() on OpenBSD

2018-10-11 Thread Brad Smith
On Thu, Oct 11, 2018 at 09:31:23PM +0200, Kamil Rytarowski wrote:
> On 11.10.2018 16:25, Brad Smith wrote:
> > On 10/11/2018 5:41 AM, Kamil Rytarowski wrote:
> > 
> >> On 11.10.2018 11:36, Peter Maydell wrote:
> >>> On 11 October 2018 at 00:55, Brad Smith  wrote:
>  And from FreeBSD...
> 
>  ?? MAP_STACK MAP_STACK implies MAP_ANON, and offset of 0.?? The 
>  fd
>  argument must be -1 and prot must include at least
>  PROT_READ and PROT_WRITE.
> 
>  This option creates a memory region that grows to at
>  most len bytes in size, starting from the stack top
>  and growing down.?? The stack top is the starting
>  address returned by the call, plus len bytes.?? The
>  bottom of the stack at maximum growth is the starting
>  address returned by the call.
> 
>  Stacks created with MAP_STACK automatically grow.
>  Guards prevent inadvertent use of the regions into
>  which those stacks can grow without requiring mapping
>  the whole stack in advance.
> >>> Hmm. That "automatically growing" part sounds like
> >>> behaviour we definitely do not want for our use case.
> >>> So we're going to need to make this OS-specific :-(
> >>>
> >> I propose to restrict MAP_STACK it to OpenBSD (with a comment in the
> >> code). Once it will be needed by someone else will be able to enable it
> >> for other OSes.
> > 
> > I was going to propose doing something like that but you had replied
> > before I did.
> > What sort of comment did you have in mind?
> > 
> 
> Why do we want it only on OpenBSD and its either unneeded or meaning
> something else on other OSes.
> 
> #ifdef __OpenBSD__
> flags |= MAP_STACK;
> #endif

How about the following?


diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index fbd0dc8c57..7814e61114 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -596,6 +596,7 @@ pid_t qemu_fork(Error **errp)
 void *qemu_alloc_stack(size_t *sz)
 {
 void *ptr, *guardpage;
+int flags;
 #ifdef CONFIG_DEBUG_STACK_USAGE
 void *ptr2;
 #endif
@@ -610,8 +611,15 @@ void *qemu_alloc_stack(size_t *sz)
 /* allocate one extra page for the guard page */
 *sz += pagesz;
 
-ptr = mmap(NULL, *sz, PROT_READ | PROT_WRITE,
-   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+flags = MAP_PRIVATE | MAP_ANONYMOUS;
+#if defined(MAP_STACK) && defined(__OpenBSD__)
+/* Only enable MAP_STACK on OpenBSD. Other OS's such
+   as Linux/FreeBSD/NetBSD have a flag with the same
+   name but have differing functionality. */
+flags |= MAP_STACK;
+#endif
+
+ptr = mmap(NULL, *sz, PROT_READ | PROT_WRITE, flags, -1, 0);
 if (ptr == MAP_FAILED) {
 perror("failed to allocate memory for stack");
 abort();



Re: [Qemu-devel] [PATCH v2 2/2] hw/vfio/display: add ramfb support

2018-10-11 Thread Alex Williamson
On Mon, 17 Sep 2018 08:17:29 +0200
Gerd Hoffmann  wrote:

> So we have a boot display when using a vgpu as primary display.
> 
> ramfb depends on a fw_cfg file.  fw_cfg files can not be added and
> removed at runtime, therefore a ramfb-enabled vfio device can't be
> hotplugged.
> 
> Add a nohotplug variant of the vfio-pci device (as child class).  Add
> the ramfb property to the nohotplug variant only.  So to enable the vgpu
> display with boot support use this:
> 
>   -device vfio-pci-nohotplug,display=on,ramfb=on,sysfsdev=...
> 
> Signed-off-by: Gerd Hoffmann 
> ---
>  hw/vfio/pci.h |  1 +
>  include/hw/vfio/vfio-common.h |  2 ++
>  hw/vfio/display.c | 12 
>  hw/vfio/pci.c | 25 +
>  4 files changed, 40 insertions(+)
> 
> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> index 52b065421a..904e286586 100644
> --- a/hw/vfio/pci.h
> +++ b/hw/vfio/pci.h
> @@ -149,6 +149,7 @@ typedef struct VFIOPCIDevice {
>  #define VFIO_FEATURE_ENABLE_IGD_OPREGION \
>  (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT)
>  OnOffAuto display;
> +bool enable_ramfb;
>  int32_t bootindex;
>  uint32_t igd_gms;
>  OffAutoPCIBAR msix_relo;

Hi Gerd,

One tiny nit here, we can move this new bool down in the struct with
the rest of the bools for better alignment.  I can change that on
commit.  However, I'm not having luck getting ramfb to work; the
display is only getting initialized once the guest driver loads.  This
is a 440FX/SeaBIOS VM, it looks like you've already updated bios.bin in
qemu.git with ramfb support, but I also see the same results with
bios.bin from your seabios.git package.  I'm using libvirt to launch
the guest with a wrapper around qemu-system-x86_64 to replace vfio-pci
with vfio-pci-nohotplug, resulting in a command line including:

-bios /usr/share/seabios.git/bios.bin \
-spice 
port=0,disable-ticketing,gl=on,rendernode=/dev/dri/by-path/pci-:00:02.0-render,seamless-migration=on
 \
-device 
vfio-pci-nohotplug,id=hostdev0,sysfsdev=...,display=on,bus=pci.0,addr=0x9 \
-set device.hostdev0.x-igd-opregion=on \
-set device.hostdev0.ramfb=on \

Relevant XML blobs:


  
  


  


  

  
  

...
  




  

This is a Windows 10 VM, but as I understand this ramfb support, I
think I'm still supposed to see SeaBIOS boot messages and perhaps even
the Windows boot animation before the guest driver takes over, is that
correct?  What am I missing?  Thanks,

Alex



[Qemu-devel] [PATCH 15/20] target/arm: Use gvec for NEON_3R_VML

2018-10-11 Thread Richard Henderson
Move mla_op and mls_op expanders from translate-a64.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |   2 +
 target/arm/translate-a64.c | 106 -
 target/arm/translate.c | 134 -
 3 files changed, 120 insertions(+), 122 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index ef44f0a5e5..d11d504301 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -195,6 +195,8 @@ static inline TCGv_i32 get_ahp_flag(void)
 extern const GVecGen3 bsl_op;
 extern const GVecGen3 bit_op;
 extern const GVecGen3 bif_op;
+extern const GVecGen3 mla_op[4];
+extern const GVecGen3 mls_op[4];
 extern const GVecGen2i ssra_op[4];
 extern const GVecGen2i usra_op[4];
 extern const GVecGen2i sri_op[4];
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f47c132e6c..94f7127c0e 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -10410,66 +10410,6 @@ static void disas_simd_3same_float(DisasContext *s, 
uint32_t insn)
 }
 }
 
-static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-gen_helper_neon_mul_u8(a, a, b);
-gen_helper_neon_add_u8(d, d, a);
-}
-
-static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-gen_helper_neon_mul_u16(a, a, b);
-gen_helper_neon_add_u16(d, d, a);
-}
-
-static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-tcg_gen_mul_i32(a, a, b);
-tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
-tcg_gen_mul_i64(a, a, b);
-tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
-tcg_gen_mul_vec(vece, a, a, b);
-tcg_gen_add_vec(vece, d, d, a);
-}
-
-static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-gen_helper_neon_mul_u8(a, a, b);
-gen_helper_neon_sub_u8(d, d, a);
-}
-
-static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-gen_helper_neon_mul_u16(a, a, b);
-gen_helper_neon_sub_u16(d, d, a);
-}
-
-static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-tcg_gen_mul_i32(a, a, b);
-tcg_gen_sub_i32(d, d, a);
-}
-
-static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
-tcg_gen_mul_i64(a, a, b);
-tcg_gen_sub_i64(d, d, a);
-}
-
-static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
-tcg_gen_mul_vec(vece, a, a, b);
-tcg_gen_sub_vec(vece, d, d, a);
-}
-
 /* Integer op subgroup of C3.6.16. */
 static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
 {
@@ -10488,52 +10428,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
   .prefer_i64 = TCG_TARGET_REG_BITS == 64,
   .vece = MO_64 },
 };
-static const GVecGen3 mla_op[4] = {
-{ .fni4 = gen_mla8_i32,
-  .fniv = gen_mla_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_8 },
-{ .fni4 = gen_mla16_i32,
-  .fniv = gen_mla_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_16 },
-{ .fni4 = gen_mla32_i32,
-  .fniv = gen_mla_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_32 },
-{ .fni8 = gen_mla64_i64,
-  .fniv = gen_mla_vec,
-  .opc = INDEX_op_mul_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .load_dest = true,
-  .vece = MO_64 },
-};
-static const GVecGen3 mls_op[4] = {
-{ .fni4 = gen_mls8_i32,
-  .fniv = gen_mls_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_8 },
-{ .fni4 = gen_mls16_i32,
-  .fniv = gen_mls_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_16 },
-{ .fni4 = gen_mls32_i32,
-  .fniv = gen_mls_vec,
-  .opc = INDEX_op_mul_vec,
-  .load_dest = true,
-  .vece = MO_32 },
-{ .fni8 = gen_mls64_i64,
-  .fniv = gen_mls_vec,
-  .opc = INDEX_op_mul_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .load_dest = true,
-  .vece = MO_64 },
-};
 
 int is_q = extract32(insn, 30, 1);
 int u = extract32(insn, 29, 1);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 104b49543d..5008a24ffd 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5468,7 +5468,7 @@ static void gen_neon_narrow_op(int op, int u, int size,
 #define NEON_3R_VABA 15
 #define NEON_3R_VADD_VSUB 16
 #define NEON_3R_VTST_VCEQ 17
-#define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
+#define NEON_3R_VML 18 /* VMLA, VMLS */
 #define NEON_3R_VMUL 19
 #define NEON_3R_VPMAX 20
 #define NEON_3R_VPMIN 21
@@ -6032,6 +6032,117 @@ const GVecGen2i sli_op[4] = {
   .vece = MO_64 },
 };
 
+static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 

Re: [Qemu-devel] [PATCH v1 0/5] Misc RISC-V patches

2018-10-11 Thread Michael Clark
Hi All,

On Thu, Oct 11, 2018 at 7:22 AM Palmer Dabbelt  wrote:

> On Wed, 10 Oct 2018 11:10:07 PDT (-0700), peter.mayd...@linaro.org wrote:
> > On 10 October 2018 at 18:49, Palmer Dabbelt  wrote:
> >> we should really
> >> get the ball rolling on our big patch backlog.
> >
> > Yes, please do. Softfreeze is not all that far away and I
> > would strongly prefer not to get an enormous sized pull
> > request at the last minute. The ideal pattern is that
> > code changes come in at a steady rate across the whole
> > of the 'open' part of the development cycle.
>
> Ya, sorry, we've been a bit out of it.  If I understand correctly, the
> soft
> freeze is the 30th?  If so it's really time to get started, and it looks
> like
> Michael is busy so I'll have to go figure this out.
>

Yes. I should think twice about the Signed-off-by: on my commits. I need to
run a regression on this out-of-order subset. I currently only run tests on
the top of the riscv-qemu tree in-order, and when I rebase against master.
If the commits need any significant effort to rebase because they are taken
in some random order then the testing will be invalidated. i.e. I haven't
checked the dependencies for these commits.

I am happy to review whoever posts the contents of the tree. I can test
apply the PRs against the riscv-qemu tree and if they give us lumps, we'll
reject, including my own changes (if rebased).

Alastair, I suggest you confer with Debian and Fedora folk. Don't break the
Linux distros... I'm petrified that we might break Debian.

Palmer, I disagree with idea, I would like to maintain the soft-fork until
we have the CI running our regression test suite (currently manual)

Peter, I have to pull in your remote wholesale. I don't cherry-pick from
your tree. I think this is truly dumb. This might serve the needs of some
folk running Linux but we have emulation fidelity fixes for the RISC-V
community as a whole. Alastair is the only person not submitting his
patches via the (sub)maintainer tree. BTW Who is the RISC-V port
maintainer? Puzzled.

Here is the pull queue. But I'm not ready to make a PR until we have the CI
running the regression. I certainly don't want rebases of random commits to
the riscv-qemu tree coming in when we pull.

- https://github.com/riscv/riscv-qemu/tree/qemu-for-upstream

That said, they have sign-off. There are plenty of other "RISC-V"
maintainers. Do what you think is wise.

Most important thing here is the Debian builders and other RISC-V virtual
machines in production. Having the Debian folk or some other helpful tester
running the entire tree. Pulling it in one go means we don't have a
bisection problem interspersed with a whole lot of other random patches.
You may not have all of the interrupt related changes that require
extensive parallel burn-in tests (GCC bootstrap). i.e. we do significantly
more than "make check" when we pull changes into our tree.

Thanks and Regards,
Michael.


[Qemu-devel] [PATCH 16/20] target/arm: Use gvec for NEON_3R_VTST_VCEQ, NEON_3R_VCGT, NEON_3R_VCGE

2018-10-11 Thread Richard Henderson
Move cmtst_op expanders from translate-a64.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |  2 +
 target/arm/translate-a64.c | 38 --
 target/arm/translate.c | 81 +++---
 3 files changed, 60 insertions(+), 61 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index d11d504301..eb7ecbebe5 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -197,10 +197,12 @@ extern const GVecGen3 bit_op;
 extern const GVecGen3 bif_op;
 extern const GVecGen3 mla_op[4];
 extern const GVecGen3 mls_op[4];
+extern const GVecGen3 cmtst_op[4];
 extern const GVecGen2i ssra_op[4];
 extern const GVecGen2i usra_op[4];
 extern const GVecGen2i sri_op[4];
 extern const GVecGen2i sli_op[4];
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 
 #define FORWARD_FEATURE(NAME) \
 static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 94f7127c0e..b6f54e66fb 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -8031,28 +8031,6 @@ static void 
disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
 }
 }
 
-/* CMTST : test is "if (X & Y != 0)". */
-static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
-{
-tcg_gen_and_i32(d, a, b);
-tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
-tcg_gen_neg_i32(d, d);
-}
-
-static void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
-{
-tcg_gen_and_i64(d, a, b);
-tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
-tcg_gen_neg_i64(d, d);
-}
-
-static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-{
-tcg_gen_and_vec(vece, d, a, b);
-tcg_gen_dupi_vec(vece, a, 0);
-tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
-}
-
 static void handle_3same_64(DisasContext *s, int opcode, bool u,
 TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
 {
@@ -10413,22 +10391,6 @@ static void disas_simd_3same_float(DisasContext *s, 
uint32_t insn)
 /* Integer op subgroup of C3.6.16. */
 static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
 {
-static const GVecGen3 cmtst_op[4] = {
-{ .fni4 = gen_helper_neon_tst_u8,
-  .fniv = gen_cmtst_vec,
-  .vece = MO_8 },
-{ .fni4 = gen_helper_neon_tst_u16,
-  .fniv = gen_cmtst_vec,
-  .vece = MO_16 },
-{ .fni4 = gen_cmtst_i32,
-  .fniv = gen_cmtst_vec,
-  .vece = MO_32 },
-{ .fni8 = gen_cmtst_i64,
-  .fniv = gen_cmtst_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .vece = MO_64 },
-};
-
 int is_q = extract32(insn, 30, 1);
 int u = extract32(insn, 29, 1);
 int size = extract32(insn, 22, 2);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 5008a24ffd..a9bd93bba1 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6143,6 +6143,44 @@ const GVecGen3 mls_op[4] = {
   .vece = MO_64 },
 };
 
+/* CMTST : test is "if (X & Y != 0)". */
+static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+tcg_gen_and_i32(d, a, b);
+tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
+tcg_gen_neg_i32(d, d);
+}
+
+void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+tcg_gen_and_i64(d, a, b);
+tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
+tcg_gen_neg_i64(d, d);
+}
+
+static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+tcg_gen_and_vec(vece, d, a, b);
+tcg_gen_dupi_vec(vece, a, 0);
+tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
+}
+
+const GVecGen3 cmtst_op[4] = {
+{ .fni4 = gen_helper_neon_tst_u8,
+  .fniv = gen_cmtst_vec,
+  .vece = MO_8 },
+{ .fni4 = gen_helper_neon_tst_u16,
+  .fniv = gen_cmtst_vec,
+  .vece = MO_16 },
+{ .fni4 = gen_cmtst_i32,
+  .fniv = gen_cmtst_vec,
+  .vece = MO_32 },
+{ .fni8 = gen_cmtst_i64,
+  .fniv = gen_cmtst_vec,
+  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
+  .vece = MO_64 },
+};
+
 /* Translate a NEON data processing instruction.  Return nonzero if the
instruction is invalid.
We process data in a mixture of 32-bit and 64-bit chunks.
@@ -6349,6 +6387,26 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
u ? _op[size] : _op[size]);
 return 0;
+
+case NEON_3R_VTST_VCEQ:
+if (u) { /* VCEQ */
+tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+} else { /* VTST */
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
+   vec_size, vec_size, _op[size]);
+}
+return 0;
+
+case NEON_3R_VCGT:
+tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
+   

[Qemu-devel] [PATCH 10/20] target/arm: Use gvec for NEON_2RM_VMN, NEON_2RM_VNEG

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4dcd7123e9..fae132791a 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7501,6 +7501,14 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_ptr(ptr1);
 tcg_temp_free_ptr(ptr2);
 break;
+
+case NEON_2RM_VMVN:
+tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
+break;
+case NEON_2RM_VNEG:
+tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
+break;
+
 default:
 elementwise:
 for (pass = 0; pass < (q ? 4 : 2); pass++) {
@@ -7541,9 +7549,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 case NEON_2RM_VCNT:
 gen_helper_neon_cnt_u8(tmp, tmp);
 break;
-case NEON_2RM_VMVN:
-tcg_gen_not_i32(tmp, tmp);
-break;
 case NEON_2RM_VQABS:
 switch (size) {
 case 0:
@@ -7616,11 +7621,6 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 default: abort();
 }
 break;
-case NEON_2RM_VNEG:
-tmp2 = tcg_const_i32(0);
-gen_neon_rsb(size, tmp, tmp2);
-tcg_temp_free_i32(tmp2);
-break;
 case NEON_2RM_VCGT0_F:
 {
 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
-- 
2.17.1




[Qemu-devel] [PATCH 14/20] target/arm: Use gvec for VSRI, VSLI

2018-10-11 Thread Richard Henderson
Move shi_op and sli_op expanders from translate-a64.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |   2 +
 target/arm/translate-a64.c | 152 +--
 target/arm/translate.c | 244 ++---
 3 files changed, 179 insertions(+), 219 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 8487b349ef..ef44f0a5e5 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -197,6 +197,8 @@ extern const GVecGen3 bit_op;
 extern const GVecGen3 bif_op;
 extern const GVecGen2i ssra_op[4];
 extern const GVecGen2i usra_op[4];
+extern const GVecGen2i sri_op[4];
+extern const GVecGen2i sli_op[4];
 
 #define FORWARD_FEATURE(NAME) \
 static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 1a9ae6d5f4..f47c132e6c 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -9392,85 +9392,10 @@ static void disas_simd_scalar_two_reg_misc(DisasContext 
*s, uint32_t insn)
 }
 }
 
-static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-uint64_t mask = dup_const(MO_8, 0xff >> shift);
-TCGv_i64 t = tcg_temp_new_i64();
-
-tcg_gen_shri_i64(t, a, shift);
-tcg_gen_andi_i64(t, t, mask);
-tcg_gen_andi_i64(d, d, ~mask);
-tcg_gen_or_i64(d, d, t);
-tcg_temp_free_i64(t);
-}
-
-static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-uint64_t mask = dup_const(MO_16, 0x >> shift);
-TCGv_i64 t = tcg_temp_new_i64();
-
-tcg_gen_shri_i64(t, a, shift);
-tcg_gen_andi_i64(t, t, mask);
-tcg_gen_andi_i64(d, d, ~mask);
-tcg_gen_or_i64(d, d, t);
-tcg_temp_free_i64(t);
-}
-
-static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
-tcg_gen_shri_i32(a, a, shift);
-tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
-}
-
-static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_shri_i64(a, a, shift);
-tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
-}
-
-static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
-uint64_t mask = (2ull << ((8 << vece) - 1)) - 1;
-TCGv_vec t = tcg_temp_new_vec_matching(d);
-TCGv_vec m = tcg_temp_new_vec_matching(d);
-
-tcg_gen_dupi_vec(vece, m, mask ^ (mask >> sh));
-tcg_gen_shri_vec(vece, t, a, sh);
-tcg_gen_and_vec(vece, d, d, m);
-tcg_gen_or_vec(vece, d, d, t);
-
-tcg_temp_free_vec(t);
-tcg_temp_free_vec(m);
-}
-
 /* SSHR[RA]/USHR[RA] - Vector shift right (optional rounding/accumulate) */
 static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
  int immh, int immb, int opcode, int rn, int 
rd)
 {
-static const GVecGen2i sri_op[4] = {
-{ .fni8 = gen_shr8_ins_i64,
-  .fniv = gen_shr_ins_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_8 },
-{ .fni8 = gen_shr16_ins_i64,
-  .fniv = gen_shr_ins_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_16 },
-{ .fni4 = gen_shr32_ins_i32,
-  .fniv = gen_shr_ins_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_32 },
-{ .fni8 = gen_shr64_ins_i64,
-  .fniv = gen_shr_ins_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_64 },
-};
-
 int size = 32 - clz32(immh) - 1;
 int immhb = immh << 3 | immb;
 int shift = 2 * (8 << size) - immhb;
@@ -9566,85 +9491,10 @@ static void handle_vec_simd_shri(DisasContext *s, bool 
is_q, bool is_u,
 clear_vec_high(s, is_q, rd);
 }
 
-static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-uint64_t mask = dup_const(MO_8, 0xff << shift);
-TCGv_i64 t = tcg_temp_new_i64();
-
-tcg_gen_shli_i64(t, a, shift);
-tcg_gen_andi_i64(t, t, mask);
-tcg_gen_andi_i64(d, d, ~mask);
-tcg_gen_or_i64(d, d, t);
-tcg_temp_free_i64(t);
-}
-
-static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-uint64_t mask = dup_const(MO_16, 0x << shift);
-TCGv_i64 t = tcg_temp_new_i64();
-
-tcg_gen_shli_i64(t, a, shift);
-tcg_gen_andi_i64(t, t, mask);
-tcg_gen_andi_i64(d, d, ~mask);
-tcg_gen_or_i64(d, d, t);
-tcg_temp_free_i64(t);
-}
-
-static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
-tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
-}
-
-static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
-}
-
-static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
-uint64_t mask = (1ull << sh) - 1;
-TCGv_vec t = tcg_temp_new_vec_matching(d);
-TCGv_vec m = tcg_temp_new_vec_matching(d);
-
-tcg_gen_dupi_vec(vece, m, mask);

[Qemu-devel] [PATCH 19/20] target/arm: Promote consecutive memory ops for aa32

2018-10-11 Thread Richard Henderson
For a sequence of loads or stores from a single register,
little-endian operations can be promoted to an 8-byte op.
This can reduce the number of operations by a factor of 8.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 12a744b3c3..09f2d648b7 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5011,6 +5011,16 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 if (size == 3 && (interleave | spacing) != 1) {
 return 1;
 }
+/* For our purposes, bytes are always little-endian.  */
+if (size == 0) {
+endian = MO_LE;
+}
+/* Consecutive little-endian elements from a single register
+ * can be promoted to a larger little-endian operation.
+ */
+if (interleave == 1 && endian == MO_LE) {
+size = 3;
+}
 tmp64 = tcg_temp_new_i64();
 addr = tcg_temp_new_i32();
 tmp2 = tcg_const_i32(1 << size);
-- 
2.17.1




[Qemu-devel] [PATCH 20/20] target/arm: Reorg NEON VLD/VST single element to one lane

2018-10-11 Thread Richard Henderson
Instead of shifts and masks, use direct loads and stores from
the neon register file.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 92 +++---
 1 file changed, 50 insertions(+), 42 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 09f2d648b7..0b21c2d201 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1611,6 +1611,25 @@ static TCGv_i32 neon_load_reg(int reg, int pass)
 return tmp;
 }
 
+static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
+{
+long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
+
+switch (mop) {
+case MO_UB:
+tcg_gen_ld8u_i32(var, cpu_env, offset);
+break;
+case MO_UW:
+tcg_gen_ld16u_i32(var, cpu_env, offset);
+break;
+case MO_UL:
+tcg_gen_ld_i32(var, cpu_env, offset);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
 {
 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
@@ -1639,6 +1658,25 @@ static void neon_store_reg(int reg, int pass, TCGv_i32 
var)
 tcg_temp_free_i32(var);
 }
 
+static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
+{
+long offset = neon_element_offset(reg, ele, size);
+
+switch (size) {
+case MO_8:
+tcg_gen_st8_i32(var, cpu_env, offset);
+break;
+case MO_16:
+tcg_gen_st16_i32(var, cpu_env, offset);
+break;
+case MO_32:
+tcg_gen_st_i32(var, cpu_env, offset);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
 {
 long offset = neon_element_offset(reg, ele, size);
@@ -4954,9 +4992,7 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 int stride;
 int size;
 int reg;
-int pass;
 int load;
-int shift;
 int n;
 int vec_size;
 int mmu_idx;
@@ -5104,18 +5140,18 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 } else {
 /* Single element.  */
 int idx = (insn >> 4) & 0xf;
-pass = (insn >> 7) & 1;
+int reg_idx;
 switch (size) {
 case 0:
-shift = ((insn >> 5) & 3) * 8;
+reg_idx = (insn >> 5) & 7;
 stride = 1;
 break;
 case 1:
-shift = ((insn >> 6) & 1) * 16;
+reg_idx = (insn >> 6) & 3;
 stride = (insn & (1 << 5)) ? 2 : 1;
 break;
 case 2:
-shift = 0;
+reg_idx = (insn >> 7) & 1;
 stride = (insn & (1 << 6)) ? 2 : 1;
 break;
 default:
@@ -5155,52 +5191,24 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
  */
 return 1;
 }
+tmp = tcg_temp_new_i32();
 addr = tcg_temp_new_i32();
 load_reg_var(s, addr, rn);
 for (reg = 0; reg < nregs; reg++) {
 if (load) {
-tmp = tcg_temp_new_i32();
-switch (size) {
-case 0:
-gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
-break;
-case 1:
-gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
-break;
-case 2:
-gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
-break;
-default: /* Avoid compiler warnings.  */
-abort();
-}
-if (size != 2) {
-tmp2 = neon_load_reg(rd, pass);
-tcg_gen_deposit_i32(tmp, tmp2, tmp,
-shift, size ? 16 : 8);
-tcg_temp_free_i32(tmp2);
-}
-neon_store_reg(rd, pass, tmp);
+gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
+s->be_data | size);
+neon_store_element(rd, reg_idx, size, tmp);
 } else { /* Store */
-tmp = neon_load_reg(rd, pass);
-if (shift)
-tcg_gen_shri_i32(tmp, tmp, shift);
-switch (size) {
-case 0:
-gen_aa32_st8(s, tmp, addr, get_mem_index(s));
-break;
-case 1:
-gen_aa32_st16(s, tmp, addr, get_mem_index(s));
-break;
-case 2:
-gen_aa32_st32(s, tmp, addr, get_mem_index(s));
-break;
-

[Qemu-devel] [PATCH 04/20] target/arm: Promote consecutive memory ops for aa64

2018-10-11 Thread Richard Henderson
For a sequence of loads or stores from a single register,
little-endian operations can be promoted to an 8-byte op.
This can reduce the number of operations by a factor of 8.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 66 +++---
 1 file changed, 40 insertions(+), 26 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index fff99ca303..2f4041462e 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1200,25 +1200,23 @@ static void write_vec_element_i32(DisasContext *s, 
TCGv_i32 tcg_src,
 
 /* Store from vector register to memory */
 static void do_vec_st(DisasContext *s, int srcidx, int element,
-  TCGv_i64 tcg_addr, int size)
+  TCGv_i64 tcg_addr, int size, TCGMemOp endian)
 {
-TCGMemOp memop = s->be_data + size;
 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
 
 read_vec_element(s, tcg_tmp, srcidx, element, size);
-tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
+tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
 
 tcg_temp_free_i64(tcg_tmp);
 }
 
 /* Load from memory to vector register */
 static void do_vec_ld(DisasContext *s, int destidx, int element,
-  TCGv_i64 tcg_addr, int size)
+  TCGv_i64 tcg_addr, int size, TCGMemOp endian)
 {
-TCGMemOp memop = s->be_data + size;
 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
 
-tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), memop);
+tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
 write_vec_element(s, tcg_tmp, destidx, element, size);
 
 tcg_temp_free_i64(tcg_tmp);
@@ -3013,9 +3011,10 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 bool is_postidx = extract32(insn, 23, 1);
 bool is_q = extract32(insn, 30, 1);
 TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
+TCGMemOp endian = s->be_data;
 
-int ebytes = 1 << size;
-int elements = (is_q ? 128 : 64) / (8 << size);
+int ebytes;   /* bytes per element */
+int elements; /* elements per vector */
 int rpt;/* num iterations */
 int selem;  /* structure elements */
 int r;
@@ -3074,6 +3073,20 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 gen_check_sp_alignment(s);
 }
 
+/* For our purposes, bytes are always little-endian.  */
+if (size == 0) {
+endian = MO_LE;
+}
+
+/* Consecutive little-endian elements from a single register
+ * can be promoted to a larger little-endian operation.
+ */
+if (selem == 1 && endian == MO_LE) {
+size = 3;
+}
+ebytes = 1 << size;
+elements = (is_q ? 16 : 8) / ebytes;
+
 tcg_rn = cpu_reg_sp(s, rn);
 tcg_addr = tcg_temp_new_i64();
 tcg_gen_mov_i64(tcg_addr, tcg_rn);
@@ -3082,32 +3095,33 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 for (r = 0; r < rpt; r++) {
 int e;
 for (e = 0; e < elements; e++) {
-int tt = (rt + r) % 32;
 int xs;
 for (xs = 0; xs < selem; xs++) {
+int tt = (rt + r + xs) % 32;
 if (is_store) {
-do_vec_st(s, tt, e, tcg_addr, size);
+do_vec_st(s, tt, e, tcg_addr, size, endian);
 } else {
-do_vec_ld(s, tt, e, tcg_addr, size);
-
-/* For non-quad operations, setting a slice of the low
- * 64 bits of the register clears the high 64 bits (in
- * the ARM ARM pseudocode this is implicit in the fact
- * that 'rval' is a 64 bit wide variable).
- * For quad operations, we might still need to zero the
- * high bits of SVE.  We optimize by noticing that we only
- * need to do this the first time we touch a register.
- */
-if (e == 0 && (r == 0 || xs == selem - 1)) {
-clear_vec_high(s, is_q, tt);
-}
+do_vec_ld(s, tt, e, tcg_addr, size, endian);
 }
 tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
-tt = (tt + 1) % 32;
 }
 }
 }
 
+if (!is_store) {
+/* For non-quad operations, setting a slice of the low
+ * 64 bits of the register clears the high 64 bits (in
+ * the ARM ARM pseudocode this is implicit in the fact
+ * that 'rval' is a 64 bit wide variable).
+ * For quad operations, we might still need to zero the
+ * high bits of SVE.
+ */
+for (r = 0; r < rpt * selem; r++) {
+int tt = (rt + r) % 32;
+clear_vec_high(s, is_q, tt);
+}
+}
+
 if (is_postidx) {
 int rm = extract32(insn, 16, 5);
 if (rm == 

[Qemu-devel] [PATCH 13/20] target/arm: Use gvec for VSRA

2018-10-11 Thread Richard Henderson
Move ssra_op and usra_op expanders from translate-a64.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |   2 +
 target/arm/translate-a64.c | 106 
 target/arm/translate.c | 139 ++---
 3 files changed, 130 insertions(+), 117 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index 7cc2685104..8487b349ef 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -195,6 +195,8 @@ static inline TCGv_i32 get_ahp_flag(void)
 extern const GVecGen3 bsl_op;
 extern const GVecGen3 bit_op;
 extern const GVecGen3 bif_op;
+extern const GVecGen2i ssra_op[4];
+extern const GVecGen2i usra_op[4];
 
 #define FORWARD_FEATURE(NAME) \
 static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index a115546a6a..1a9ae6d5f4 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -9392,66 +9392,6 @@ static void disas_simd_scalar_two_reg_misc(DisasContext 
*s, uint32_t insn)
 }
 }
 
-static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_vec_sar8i_i64(a, a, shift);
-tcg_gen_vec_add8_i64(d, d, a);
-}
-
-static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_vec_sar16i_i64(a, a, shift);
-tcg_gen_vec_add16_i64(d, d, a);
-}
-
-static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
-tcg_gen_sari_i32(a, a, shift);
-tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_sari_i64(a, a, shift);
-tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
-tcg_gen_sari_vec(vece, a, a, sh);
-tcg_gen_add_vec(vece, d, d, a);
-}
-
-static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_vec_shr8i_i64(a, a, shift);
-tcg_gen_vec_add8_i64(d, d, a);
-}
-
-static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_vec_shr16i_i64(a, a, shift);
-tcg_gen_vec_add16_i64(d, d, a);
-}
-
-static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
-{
-tcg_gen_shri_i32(a, a, shift);
-tcg_gen_add_i32(d, d, a);
-}
-
-static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
-{
-tcg_gen_shri_i64(a, a, shift);
-tcg_gen_add_i64(d, d, a);
-}
-
-static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
-{
-tcg_gen_shri_vec(vece, a, a, sh);
-tcg_gen_add_vec(vece, d, d, a);
-}
-
 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
 {
 uint64_t mask = dup_const(MO_8, 0xff >> shift);
@@ -9507,52 +9447,6 @@ static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, 
TCGv_vec a, int64_t sh)
 static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
  int immh, int immb, int opcode, int rn, int 
rd)
 {
-static const GVecGen2i ssra_op[4] = {
-{ .fni8 = gen_ssra8_i64,
-  .fniv = gen_ssra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_sari_vec,
-  .vece = MO_8 },
-{ .fni8 = gen_ssra16_i64,
-  .fniv = gen_ssra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_sari_vec,
-  .vece = MO_16 },
-{ .fni4 = gen_ssra32_i32,
-  .fniv = gen_ssra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_sari_vec,
-  .vece = MO_32 },
-{ .fni8 = gen_ssra64_i64,
-  .fniv = gen_ssra_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .load_dest = true,
-  .opc = INDEX_op_sari_vec,
-  .vece = MO_64 },
-};
-static const GVecGen2i usra_op[4] = {
-{ .fni8 = gen_usra8_i64,
-  .fniv = gen_usra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_8, },
-{ .fni8 = gen_usra16_i64,
-  .fniv = gen_usra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_16, },
-{ .fni4 = gen_usra32_i32,
-  .fniv = gen_usra_vec,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_32, },
-{ .fni8 = gen_usra64_i64,
-  .fniv = gen_usra_vec,
-  .prefer_i64 = TCG_TARGET_REG_BITS == 64,
-  .load_dest = true,
-  .opc = INDEX_op_shri_vec,
-  .vece = MO_64, },
-};
 static const GVecGen2i sri_op[4] = {
 { .fni8 = gen_shr8_ins_i64,
   .fniv = gen_shr_ins_vec,
diff --git a/target/arm/translate.c b/target/arm/translate.c
index a16f323d52..da95851370 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5770,6 +5770,113 @@ const GVecGen3 bif_op = {
 .load_dest = true
 };
 
+static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+tcg_gen_vec_sar8i_i64(a, a, shift);
+tcg_gen_vec_add8_i64(d, d, a);
+}
+
+static void 

[Qemu-devel] [PATCH 12/20] target/arm: Use gvec for VSHR, VSHL

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 70 +-
 1 file changed, 48 insertions(+), 22 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index e195efcc55..a16f323d52 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6373,8 +6373,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 size--;
 }
 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
-/* To avoid excessive duplication of ops we implement shift
-   by immediate using the variable shift operations.  */
 if (op < 8) {
 /* Shift by immediate:
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
@@ -6386,37 +6384,62 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 }
 /* Right shifts are encoded as N - shift, where N is the
element size in bits.  */
-if (op <= 4)
+if (op <= 4) {
 shift = shift - (1 << (size + 3));
+}
+
+switch (op) {
+case 0:  /* VSHR */
+/* Right shift comes here negative.  */
+shift = -shift;
+/* Shifts larger than the element size are architecturally
+ * valid.  Unsigned results in all zeros; signed results
+ * in all sign bits.
+ */
+if (!u) {
+tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
+  MIN(shift, (8 << size) - 1),
+  vec_size, vec_size);
+} else if (shift >= 8 << size) {
+tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
+} else {
+tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
+  vec_size, vec_size);
+}
+return 0;
+
+case 5: /* VSHL, VSLI */
+if (!u) { /* VSHL */
+/* Shifts larger than the element size are
+ * architecturally valid and results in zero.
+ */
+if (shift >= 8 << size) {
+tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
+} else {
+tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
+  vec_size, vec_size);
+}
+return 0;
+}
+break;
+}
+
 if (size == 3) {
 count = q + 1;
 } else {
 count = q ? 4: 2;
 }
-switch (size) {
-case 0:
-imm = (uint8_t) shift;
-imm |= imm << 8;
-imm |= imm << 16;
-break;
-case 1:
-imm = (uint16_t) shift;
-imm |= imm << 16;
-break;
-case 2:
-case 3:
-imm = shift;
-break;
-default:
-abort();
-}
+
+/* To avoid excessive duplication of ops we implement shift
+ * by immediate using the variable shift operations.
+  */
+imm = dup_const(size, shift);
 
 for (pass = 0; pass < count; pass++) {
 if (size == 3) {
 neon_load_reg64(cpu_V0, rm + pass);
 tcg_gen_movi_i64(cpu_V1, imm);
 switch (op) {
-case 0:  /* VSHR */
 case 1:  /* VSRA */
 if (u)
 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, 
cpu_V1);
@@ -6447,6 +6470,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
  cpu_V0, cpu_V1);
 }
 break;
+default:
+g_assert_not_reached();
 }
 if (op == 1 || op == 3) {
 /* Accumulate.  */
@@ -6475,7 +6500,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 tmp2 = tcg_temp_new_i32();
 tcg_gen_movi_i32(tmp2, imm);
 switch (op) {
-case 0:  /* VSHR */
 case 1:  /* VSRA */
 

[Qemu-devel] [PATCH 07/20] target/arm: Use gvec for NEON VMOV, VMVN, VBIC & VORR (immediate)

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 67 --
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4ac526e298..109689a286 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -6641,7 +6641,8 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 return 1;
 }
 } else { /* (insn & 0x00380080) == 0 */
-int invert;
+int invert, reg_ofs, vec_size;
+
 if (q && (rd & 1)) {
 return 1;
 }
@@ -6681,8 +6682,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t 
insn)
 break;
 case 14:
 imm |= (imm << 8) | (imm << 16) | (imm << 24);
-if (invert)
+if (invert) {
 imm = ~imm;
+}
 break;
 case 15:
 if (invert) {
@@ -6692,36 +6694,45 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
   | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
 break;
 }
-if (invert)
+if (invert) {
 imm = ~imm;
+}
 
-for (pass = 0; pass < (q ? 4 : 2); pass++) {
-if (op & 1 && op < 12) {
-tmp = neon_load_reg(rd, pass);
-if (invert) {
-/* The immediate value has already been inverted, so
-   BIC becomes AND.  */
-tcg_gen_andi_i32(tmp, tmp, imm);
-} else {
-tcg_gen_ori_i32(tmp, tmp, imm);
-}
+reg_ofs = neon_reg_offset(rd, 0);
+vec_size = q ? 16 : 8;
+
+if (op & 1 && op < 12) {
+if (invert) {
+/* The immediate value has already been inverted,
+ * so BIC becomes AND.
+ */
+tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
+  vec_size, vec_size);
 } else {
-/* VMOV, VMVN.  */
-tmp = tcg_temp_new_i32();
-if (op == 14 && invert) {
-int n;
-uint32_t val;
-val = 0;
-for (n = 0; n < 4; n++) {
-if (imm & (1 << (n + (pass & 1) * 4)))
-val |= 0xff << (n * 8);
-}
-tcg_gen_movi_i32(tmp, val);
-} else {
-tcg_gen_movi_i32(tmp, imm);
-}
+tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
+ vec_size, vec_size);
+}
+} else {
+/* VMOV, VMVN.  */
+if (op == 14 && invert) {
+TCGv_i64 t64 = tcg_temp_new_i64();
+
+for (pass = 0; pass <= q; ++pass) {
+uint64_t val = 0;
+int n;
+
+for (n = 0; n < 8; n++) {
+if (imm & (1 << (n + pass * 8))) {
+val |= 0xffull << (n * 8);
+}
+}
+tcg_gen_movi_i64(t64, val);
+neon_store_reg64(t64, rd + pass);
+}
+tcg_temp_free_i64(t64);
+} else {
+tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
 }
-neon_store_reg(rd, pass, tmp);
 }
 }
 } else { /* (insn & 0x00800010 == 0x0080) */
-- 
2.17.1




[Qemu-devel] [PATCH 18/20] target/arm: Reorg NEON VLD/VST all elements

2018-10-11 Thread Richard Henderson
Instead of shifts and masks, use direct loads and stores from the neon
register file.  Mirror the iteration structure of the ARM pseudocode
more closely.  Correct the parameters of the VLD2 A2 insn.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 170 ++---
 1 file changed, 74 insertions(+), 96 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 1e79a1eec0..12a744b3c3 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1611,12 +1611,56 @@ static TCGv_i32 neon_load_reg(int reg, int pass)
 return tmp;
 }
 
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
+{
+long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
+
+switch (mop) {
+case MO_UB:
+tcg_gen_ld8u_i64(var, cpu_env, offset);
+break;
+case MO_UW:
+tcg_gen_ld16u_i64(var, cpu_env, offset);
+break;
+case MO_UL:
+tcg_gen_ld32u_i64(var, cpu_env, offset);
+break;
+case MO_Q:
+tcg_gen_ld_i64(var, cpu_env, offset);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
 {
 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
 tcg_temp_free_i32(var);
 }
 
+static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
+{
+long offset = neon_element_offset(reg, ele, size);
+
+switch (size) {
+case MO_8:
+tcg_gen_st8_i64(var, cpu_env, offset);
+break;
+case MO_16:
+tcg_gen_st16_i64(var, cpu_env, offset);
+break;
+case MO_32:
+tcg_gen_st32_i64(var, cpu_env, offset);
+break;
+case MO_64:
+tcg_gen_st_i64(var, cpu_env, offset);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 static inline void neon_load_reg64(TCGv_i64 var, int reg)
 {
 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
@@ -4885,16 +4929,16 @@ static struct {
 int interleave;
 int spacing;
 } const neon_ls_element_type[11] = {
-{4, 4, 1},
-{4, 4, 2},
+{1, 4, 1},
+{1, 4, 2},
 {4, 1, 1},
-{4, 2, 1},
-{3, 3, 1},
-{3, 3, 2},
+{2, 2, 2},
+{1, 3, 1},
+{1, 3, 2},
 {3, 1, 1},
 {1, 1, 1},
-{2, 2, 1},
-{2, 2, 2},
+{1, 2, 1},
+{1, 2, 2},
 {2, 1, 1}
 };
 
@@ -4915,6 +4959,8 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 int shift;
 int n;
 int vec_size;
+int mmu_idx;
+TCGMemOp endian;
 TCGv_i32 addr;
 TCGv_i32 tmp;
 TCGv_i32 tmp2;
@@ -4936,6 +4982,8 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 rn = (insn >> 16) & 0xf;
 rm = insn & 0xf;
 load = (insn & (1 << 21)) != 0;
+endian = s->be_data;
+mmu_idx = get_mem_index(s);
 if ((insn & (1 << 23)) == 0) {
 /* Load store all elements.  */
 op = (insn >> 8) & 0xf;
@@ -4960,104 +5008,34 @@ static int disas_neon_ls_insn(DisasContext *s, 
uint32_t insn)
 nregs = neon_ls_element_type[op].nregs;
 interleave = neon_ls_element_type[op].interleave;
 spacing = neon_ls_element_type[op].spacing;
-if (size == 3 && (interleave | spacing) != 1)
+if (size == 3 && (interleave | spacing) != 1) {
 return 1;
+}
+tmp64 = tcg_temp_new_i64();
 addr = tcg_temp_new_i32();
+tmp2 = tcg_const_i32(1 << size);
 load_reg_var(s, addr, rn);
-stride = (1 << size) * interleave;
 for (reg = 0; reg < nregs; reg++) {
-if (interleave > 2 || (interleave == 2 && nregs == 2)) {
-load_reg_var(s, addr, rn);
-tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
-} else if (interleave == 2 && nregs == 4 && reg == 2) {
-load_reg_var(s, addr, rn);
-tcg_gen_addi_i32(addr, addr, 1 << size);
-}
-if (size == 3) {
-tmp64 = tcg_temp_new_i64();
-if (load) {
-gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
-neon_store_reg64(tmp64, rd);
-} else {
-neon_load_reg64(tmp64, rd);
-gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
-}
-tcg_temp_free_i64(tmp64);
-tcg_gen_addi_i32(addr, addr, stride);
-} else {
-for (pass = 0; pass < 2; pass++) {
-if (size == 2) {
-if (load) {
-tmp = tcg_temp_new_i32();
-gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
-neon_store_reg(rd, pass, tmp);
-} else {
-tmp = neon_load_reg(rd, pass);
-gen_aa32_st32(s, tmp, addr, get_mem_index(s));
- 

[Qemu-devel] [PATCH 06/20] target/arm: Use gvec for NEON VDUP

2018-10-11 Thread Richard Henderson
Also introduces neon_element_offset to find the env offset
of a specific element within a neon register.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 63 --
 1 file changed, 36 insertions(+), 27 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index d59ffa1c67..4ac526e298 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -1585,6 +1585,25 @@ neon_reg_offset (int reg, int n)
 return vfp_reg_offset(0, sreg);
 }
 
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
+ * where 0 is the least significant end of the register.
+ */
+static inline long
+neon_element_offset(int reg, int element, TCGMemOp size)
+{
+int element_size = 1 << size;
+int ofs = element * element_size;
+#ifdef HOST_WORDS_BIGENDIAN
+/* Calculate the offset assuming fully little-endian,
+ * then XOR to account for the order of the 8-byte units.
+ */
+if (element_size < 8) {
+ofs ^= 8 - element_size;
+}
+#endif
+return neon_reg_offset(reg, 0) + ofs;
+}
+
 static TCGv_i32 neon_load_reg(int reg, int pass)
 {
 TCGv_i32 tmp = tcg_temp_new_i32();
@@ -3432,17 +3451,10 @@ static int disas_vfp_insn(DisasContext *s, uint32_t 
insn)
 tmp = load_reg(s, rd);
 if (insn & (1 << 23)) {
 /* VDUP */
-if (size == 0) {
-gen_neon_dup_u8(tmp, 0);
-} else if (size == 1) {
-gen_neon_dup_low16(tmp);
-}
-for (n = 0; n <= pass * 2; n++) {
-tmp2 = tcg_temp_new_i32();
-tcg_gen_mov_i32(tmp2, tmp);
-neon_store_reg(rn, n, tmp2);
-}
-neon_store_reg(rn, n, tmp);
+int vec_size = pass ? 16 : 8;
+tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
+ vec_size, vec_size, tmp);
+tcg_temp_free_i32(tmp);
 } else {
 /* VMOV */
 switch (size) {
@@ -7755,28 +7767,25 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 tcg_temp_free_i32(tmp);
 } else if ((insn & 0x380) == 0) {
 /* VDUP */
+int element;
+TCGMemOp size;
+
 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
 return 1;
 }
-if (insn & (1 << 19)) {
-tmp = neon_load_reg(rm, 1);
-} else {
-tmp = neon_load_reg(rm, 0);
-}
 if (insn & (1 << 16)) {
-gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
+size = MO_8;
+element = (insn >> 17) & 7;
 } else if (insn & (1 << 17)) {
-if ((insn >> 18) & 1)
-gen_neon_dup_high16(tmp);
-else
-gen_neon_dup_low16(tmp);
+size = MO_16;
+element = (insn >> 18) & 3;
+} else {
+size = MO_32;
+element = (insn >> 19) & 1;
 }
-for (pass = 0; pass < (q ? 4 : 2); pass++) {
-tmp2 = tcg_temp_new_i32();
-tcg_gen_mov_i32(tmp2, tmp);
-neon_store_reg(rd, pass, tmp2);
-}
-tcg_temp_free_i32(tmp);
+tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
+ neon_element_offset(rm, element, size),
+ q ? 16 : 8, q ? 16 : 8);
 } else {
 return 1;
 }
-- 
2.17.1




[Qemu-devel] [PATCH 11/20] target/arm: Use gvec for NEON_3R_VMUL

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 31 +++
 1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index fae132791a..e195efcc55 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5959,6 +5959,19 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
  vec_size, vec_size);
 }
 return 0;
+
+case NEON_3R_VMUL: /* VMUL */
+if (u) {
+/* Polynomial case allows only P8 and is handled below.  */
+if (size != 0) {
+return 1;
+}
+} else {
+tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+return 0;
+}
+break;
 }
 if (size == 3) {
 /* 64-bit element instructions. */
@@ -6065,12 +6078,6 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 return 1;
 }
 break;
-case NEON_3R_VMUL:
-if (u && (size != 0)) {
-/* UNDEF on invalid size for polynomial subcase */
-return 1;
-}
-break;
 case NEON_3R_VFM_VQRDMLSH:
 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
 return 1;
@@ -6183,16 +6190,8 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 }
 break;
 case NEON_3R_VMUL:
-if (u) { /* polynomial */
-gen_helper_neon_mul_p8(tmp, tmp, tmp2);
-} else { /* Integer */
-switch (size) {
-case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
-case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
-case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
-default: abort();
-}
-}
+/* VMUL.P8; other cases already eliminated.  */
+gen_helper_neon_mul_p8(tmp, tmp, tmp2);
 break;
 case NEON_3R_VPMAX:
 GEN_NEON_INTEGER_OP(pmax);
-- 
2.17.1




[Qemu-devel] [PATCH 08/20] target/arm: Use gvec for NEON_3R_LOGIC insns

2018-10-11 Thread Richard Henderson
Move expanders for VBSL, VBIT, and VBIF from translate-a64.c.

Signed-off-by: Richard Henderson 
---
 target/arm/translate.h |   6 +-
 target/arm/translate-a64.c |  61 --
 target/arm/translate.c | 162 +++--
 3 files changed, 123 insertions(+), 106 deletions(-)

diff --git a/target/arm/translate.h b/target/arm/translate.h
index ad911de98c..7cc2685104 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -191,6 +191,11 @@ static inline TCGv_i32 get_ahp_flag(void)
 return ret;
 }
 
+/* Vector operations shared between ARM and AArch64.  */
+extern const GVecGen3 bsl_op;
+extern const GVecGen3 bit_op;
+extern const GVecGen3 bif_op;
+
 #define FORWARD_FEATURE(NAME) \
 static inline bool aa32_dc_feature_##NAME(DisasContext *dc) \
 { return aa32_feature_##NAME(dc->cpu); }
@@ -209,5 +214,4 @@ FORWARD_FEATURE(dp)
 FORWARD_FEATURE(fp16_arith)
 
 #undef FORWARD_FEATURE
-
 #endif /* TARGET_ARM_TRANSLATE_H */
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 2f4041462e..a115546a6a 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -10392,70 +10392,9 @@ static void disas_simd_three_reg_diff(DisasContext *s, 
uint32_t insn)
 }
 }
 
-static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
-tcg_gen_xor_i64(rn, rn, rm);
-tcg_gen_and_i64(rn, rn, rd);
-tcg_gen_xor_i64(rd, rm, rn);
-}
-
-static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
-tcg_gen_xor_i64(rn, rn, rd);
-tcg_gen_and_i64(rn, rn, rm);
-tcg_gen_xor_i64(rd, rd, rn);
-}
-
-static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
-{
-tcg_gen_xor_i64(rn, rn, rd);
-tcg_gen_andc_i64(rn, rn, rm);
-tcg_gen_xor_i64(rd, rd, rn);
-}
-
-static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
-tcg_gen_xor_vec(vece, rn, rn, rm);
-tcg_gen_and_vec(vece, rn, rn, rd);
-tcg_gen_xor_vec(vece, rd, rm, rn);
-}
-
-static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
-tcg_gen_xor_vec(vece, rn, rn, rd);
-tcg_gen_and_vec(vece, rn, rn, rm);
-tcg_gen_xor_vec(vece, rd, rd, rn);
-}
-
-static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
-{
-tcg_gen_xor_vec(vece, rn, rn, rd);
-tcg_gen_andc_vec(vece, rn, rn, rm);
-tcg_gen_xor_vec(vece, rd, rd, rn);
-}
-
 /* Logic op (opcode == 3) subgroup of C3.6.16. */
 static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
 {
-static const GVecGen3 bsl_op = {
-.fni8 = gen_bsl_i64,
-.fniv = gen_bsl_vec,
-.prefer_i64 = TCG_TARGET_REG_BITS == 64,
-.load_dest = true
-};
-static const GVecGen3 bit_op = {
-.fni8 = gen_bit_i64,
-.fniv = gen_bit_vec,
-.prefer_i64 = TCG_TARGET_REG_BITS == 64,
-.load_dest = true
-};
-static const GVecGen3 bif_op = {
-.fni8 = gen_bif_i64,
-.fniv = gen_bif_vec,
-.prefer_i64 = TCG_TARGET_REG_BITS == 64,
-.load_dest = true
-};
-
 int rd = extract32(insn, 0, 5);
 int rn = extract32(insn, 5, 5);
 int rm = extract32(insn, 16, 5);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 109689a286..4ab9f69b01 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5262,14 +5262,6 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 return 0;
 }
 
-/* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
-static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
-{
-tcg_gen_and_i32(t, t, c);
-tcg_gen_andc_i32(f, f, c);
-tcg_gen_or_i32(dest, t, f);
-}
-
 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
 {
 switch (size) {
@@ -5712,6 +5704,73 @@ static int do_v81_helper(DisasContext *s, 
gen_helper_gvec_3_ptr *fn,
 return 1;
 }
 
+/*
+ * Expanders for VBitOps_VBIF, VBIT, VBSL.
+ */
+static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+tcg_gen_xor_i64(rn, rn, rm);
+tcg_gen_and_i64(rn, rn, rd);
+tcg_gen_xor_i64(rd, rm, rn);
+}
+
+static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+tcg_gen_xor_i64(rn, rn, rd);
+tcg_gen_and_i64(rn, rn, rm);
+tcg_gen_xor_i64(rd, rd, rn);
+}
+
+static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
+{
+tcg_gen_xor_i64(rn, rn, rd);
+tcg_gen_andc_i64(rn, rn, rm);
+tcg_gen_xor_i64(rd, rd, rn);
+}
+
+static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+tcg_gen_xor_vec(vece, rn, rn, rm);
+tcg_gen_and_vec(vece, rn, rn, rd);
+tcg_gen_xor_vec(vece, rd, rm, rn);
+}
+
+static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+tcg_gen_xor_vec(vece, rn, rn, rd);
+tcg_gen_and_vec(vece, rn, rn, rm);
+tcg_gen_xor_vec(vece, rd, rd, rn);
+}
+
+static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
+{
+

[Qemu-devel] [PATCH 05/20] target/arm: Mark some arrays const

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 736880ee71..d59ffa1c67 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -72,7 +72,7 @@ static TCGv_i64 cpu_F0d, cpu_F1d;
 
 #include "exec/gen-icount.h"
 
-static const char *regnames[] =
+static const char * const regnames[] =
 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
 
@@ -4907,7 +4907,7 @@ static struct {
 int nregs;
 int interleave;
 int spacing;
-} neon_ls_element_type[11] = {
+} const neon_ls_element_type[11] = {
 {4, 4, 1},
 {4, 4, 2},
 {4, 1, 1},
@@ -13089,7 +13089,7 @@ void gen_intermediate_code(CPUState *cpu, 
TranslationBlock *tb)
 translator_loop(ops, , cpu, tb);
 }
 
-static const char *cpu_mode_names[16] = {
+static const char * const cpu_mode_names[16] = {
   "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
   "???", "???", "hyp", "und", "???", "???", "???", "sys"
 };
-- 
2.17.1




[Qemu-devel] [PATCH 03/20] target/arm: Use tcg_gen_gvec_dup_i64 for LD[1-4]R

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 28 +++-
 1 file changed, 3 insertions(+), 25 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index ac9723c1b9..fff99ca303 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3217,36 +3217,14 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 for (xs = 0; xs < selem; xs++) {
 if (replicate) {
 /* Load and replicate to all elements */
-uint64_t mulconst;
 TCGv_i64 tcg_tmp = tcg_temp_new_i64();
 
 tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr,
 get_mem_index(s), s->be_data + scale);
-switch (scale) {
-case 0:
-mulconst = 0x0101010101010101ULL;
-break;
-case 1:
-mulconst = 0x0001000100010001ULL;
-break;
-case 2:
-mulconst = 0x00010001ULL;
-break;
-case 3:
-mulconst = 0;
-break;
-default:
-g_assert_not_reached();
-}
-if (mulconst) {
-tcg_gen_muli_i64(tcg_tmp, tcg_tmp, mulconst);
-}
-write_vec_element(s, tcg_tmp, rt, 0, MO_64);
-if (is_q) {
-write_vec_element(s, tcg_tmp, rt, 1, MO_64);
-}
+tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
+ (is_q + 1) * 8, vec_full_reg_size(s),
+ tcg_tmp);
 tcg_temp_free_i64(tcg_tmp);
-clear_vec_high(s, is_q, rt);
 } else {
 /* Load/store one element per register */
 if (is_load) {
-- 
2.17.1




[Qemu-devel] [PATCH 09/20] target/arm: Use gvec for NEON_3R_VADD_VSUB insns

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 29 ++---
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 4ab9f69b01..4dcd7123e9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -5949,6 +5949,16 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 break;
 }
 return 0;
+
+case NEON_3R_VADD_VSUB:
+if (u) {
+tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+} else {
+tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
+ vec_size, vec_size);
+}
+return 0;
 }
 if (size == 3) {
 /* 64-bit element instructions. */
@@ -6006,13 +6016,6 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
   cpu_V1, cpu_V0);
 }
 break;
-case NEON_3R_VADD_VSUB:
-if (u) {
-tcg_gen_sub_i64(CPU_V001);
-} else {
-tcg_gen_add_i64(CPU_V001);
-}
-break;
 default:
 abort();
 }
@@ -6147,18 +6150,6 @@ static int disas_neon_data_insn(DisasContext *s, 
uint32_t insn)
 tmp2 = neon_load_reg(rd, pass);
 gen_neon_add(size, tmp, tmp2);
 break;
-case NEON_3R_VADD_VSUB:
-if (!u) { /* VADD */
-gen_neon_add(size, tmp, tmp2);
-} else { /* VSUB */
-switch (size) {
-case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
-case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
-case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
-default: abort();
-}
-}
-break;
 case NEON_3R_VTST_VCEQ:
 if (!u) { /* VTST */
 switch (size) {
-- 
2.17.1




[Qemu-devel] [PATCH 17/20] target/arm: Use gvec for NEON VLD all lanes

2018-10-11 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate.c | 81 ++
 1 file changed, 26 insertions(+), 55 deletions(-)

diff --git a/target/arm/translate.c b/target/arm/translate.c
index a9bd93bba1..1e79a1eec0 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2993,19 +2993,6 @@ static void gen_vfp_msr(TCGv_i32 tmp)
 tcg_temp_free_i32(tmp);
 }
 
-static void gen_neon_dup_u8(TCGv_i32 var, int shift)
-{
-TCGv_i32 tmp = tcg_temp_new_i32();
-if (shift)
-tcg_gen_shri_i32(var, var, shift);
-tcg_gen_ext8u_i32(var, var);
-tcg_gen_shli_i32(tmp, var, 8);
-tcg_gen_or_i32(var, var, tmp);
-tcg_gen_shli_i32(tmp, var, 16);
-tcg_gen_or_i32(var, var, tmp);
-tcg_temp_free_i32(tmp);
-}
-
 static void gen_neon_dup_low16(TCGv_i32 var)
 {
 TCGv_i32 tmp = tcg_temp_new_i32();
@@ -3024,28 +3011,6 @@ static void gen_neon_dup_high16(TCGv_i32 var)
 tcg_temp_free_i32(tmp);
 }
 
-static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int 
size)
-{
-/* Load a single Neon element and replicate into a 32 bit TCG reg */
-TCGv_i32 tmp = tcg_temp_new_i32();
-switch (size) {
-case 0:
-gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
-gen_neon_dup_u8(tmp, 0);
-break;
-case 1:
-gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
-gen_neon_dup_low16(tmp);
-break;
-case 2:
-gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
-break;
-default: /* Avoid compiler warnings.  */
-abort();
-}
-return tmp;
-}
-
 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
uint32_t dp)
 {
@@ -4949,6 +4914,7 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 int load;
 int shift;
 int n;
+int vec_size;
 TCGv_i32 addr;
 TCGv_i32 tmp;
 TCGv_i32 tmp2;
@@ -5118,28 +5084,33 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t 
insn)
 }
 addr = tcg_temp_new_i32();
 load_reg_var(s, addr, rn);
-if (nregs == 1) {
-/* VLD1 to all lanes: bit 5 indicates how many Dregs to write 
*/
-tmp = gen_load_and_replicate(s, addr, size);
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
-if (insn & (1 << 5)) {
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
-}
-tcg_temp_free_i32(tmp);
-} else {
-/* VLD2/3/4 to all lanes: bit 5 indicates register stride */
-stride = (insn & (1 << 5)) ? 2 : 1;
-for (reg = 0; reg < nregs; reg++) {
-tmp = gen_load_and_replicate(s, addr, size);
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
-tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
-tcg_temp_free_i32(tmp);
-tcg_gen_addi_i32(addr, addr, 1 << size);
-rd += stride;
+
+/* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
+ * VLD2/3/4 to all lanes: bit 5 indicates register stride.
+ */
+stride = insn & (1 << 5) ? 2 : 1;
+vec_size = nregs == 1 ? stride * 8 : 8;
+
+tmp = tcg_temp_new_i32();
+for (reg = 0; reg < nregs; reg++) {
+gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
+s->be_data | size);
+if ((rd & 1) && vec_size == 16) {
+/* We cannot write 16 bytes at once because the
+ * destination is unaligned.
+ */
+tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
+ 8, 8, tmp);
+tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
+ neon_reg_offset(rd, 0), 8, 8);
+} else {
+tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
+ vec_size, vec_size, tmp);
 }
+tcg_gen_addi_i32(addr, addr, 1 << size);
+rd += stride;
 }
+tcg_temp_free_i32(tmp);
 tcg_temp_free_i32(addr);
 stride = (1 << size) * nregs;
 } else {
-- 
2.17.1




[Qemu-devel] [PATCH 01/20] target/arm: Hoist address increment for vector memory ops

2018-10-11 Thread Richard Henderson
From: Richard Henderson 

This can reduce the number of opcodes required for certain
complex forms of load-multiple (e.g. ld4.16b).

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c403b12eb9..76b5ca3606 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -3012,7 +3012,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 bool is_store = !extract32(insn, 22, 1);
 bool is_postidx = extract32(insn, 23, 1);
 bool is_q = extract32(insn, 30, 1);
-TCGv_i64 tcg_addr, tcg_rn;
+TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
 
 int ebytes = 1 << size;
 int elements = (is_q ? 128 : 64) / (8 << size);
@@ -3077,6 +3077,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 tcg_rn = cpu_reg_sp(s, rn);
 tcg_addr = tcg_temp_new_i64();
 tcg_gen_mov_i64(tcg_addr, tcg_rn);
+tcg_ebytes = tcg_const_i64(ebytes);
 
 for (r = 0; r < rpt; r++) {
 int e;
@@ -3101,7 +3102,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 clear_vec_high(s, is_q, tt);
 }
 }
-tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
+tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
 tt = (tt + 1) % 32;
 }
 }
@@ -3115,6 +3116,7 @@ static void disas_ldst_multiple_struct(DisasContext *s, 
uint32_t insn)
 tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
 }
 }
+tcg_temp_free_i64(tcg_ebytes);
 tcg_temp_free_i64(tcg_addr);
 }
 
@@ -3157,7 +3159,7 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 bool replicate = false;
 int index = is_q << 3 | S << 2 | size;
 int ebytes, xs;
-TCGv_i64 tcg_addr, tcg_rn;
+TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
 
 switch (scale) {
 case 3:
@@ -3210,6 +3212,7 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 tcg_rn = cpu_reg_sp(s, rn);
 tcg_addr = tcg_temp_new_i64();
 tcg_gen_mov_i64(tcg_addr, tcg_rn);
+tcg_ebytes = tcg_const_i64(ebytes);
 
 for (xs = 0; xs < selem; xs++) {
 if (replicate) {
@@ -3252,7 +3255,7 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 do_vec_st(s, rt, index, tcg_addr, scale);
 }
 }
-tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
+tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_ebytes);
 rt = (rt + 1) % 32;
 }
 
@@ -3264,6 +3267,7 @@ static void disas_ldst_single_struct(DisasContext *s, 
uint32_t insn)
 tcg_gen_add_i64(tcg_rn, tcg_rn, cpu_reg(s, rm));
 }
 }
+tcg_temp_free_i64(tcg_ebytes);
 tcg_temp_free_i64(tcg_addr);
 }
 
-- 
2.17.1




[Qemu-devel] [PATCH 00/20] target/arm: Convert some neon insns to gvec

2018-10-11 Thread Richard Henderson
The conversion to gvec is by no means complete, but it brings aa32
to parity with the work already done for aa64.  Plus some misc changes,
at least one of which has been sitting on a branch for 2 years.  ;-P

I've run the result through Alex's aarch32-all.tar.xz RISU tests.
There are no regressions, though there are pre-existing failures.
Our aa32 translator could use some additional work, no surprise.


r~


Richard Henderson (20):
  target/arm: Hoist address increment for vector memory ops
  target/arm: Don't call tcg_clear_temp_count
  target/arm: Use tcg_gen_gvec_dup_i64 for LD[1-4]R
  target/arm: Promote consecutive memory ops for aa64
  target/arm: Mark some arrays const
  target/arm: Use gvec for NEON VDUP
  target/arm: Use gvec for NEON VMOV, VMVN, VBIC & VORR (immediate)
  target/arm: Use gvec for NEON_3R_LOGIC insns
  target/arm: Use gvec for NEON_3R_VADD_VSUB insns
  target/arm: Use gvec for NEON_2RM_VMN, NEON_2RM_VNEG
  target/arm: Use gvec for NEON_3R_VMUL
  target/arm: Use gvec for VSHR, VSHL
  target/arm: Use gvec for VSRA
  target/arm: Use gvec for VSRI, VSLI
  target/arm: Use gvec for NEON_3R_VML
  target/arm: Use gvec for NEON_3R_VTST_VCEQ, NEON_3R_VCGT, NEON_3R_VCGE
  target/arm: Use gvec for NEON VLD all lanes
  target/arm: Reorg NEON VLD/VST all elements
  target/arm: Promote consecutive memory ops for aa32
  target/arm: Reorg NEON VLD/VST single element to one lane

 target/arm/translate.h |   14 +-
 target/arm/translate-a64.c |  570 ++-
 target/arm/translate.c | 1390 
 3 files changed, 979 insertions(+), 995 deletions(-)

-- 
2.17.1




[Qemu-devel] [PATCH 02/20] target/arm: Don't call tcg_clear_temp_count

2018-10-11 Thread Richard Henderson
This is done generically in translator_loop.

Reported-by: Laurent Desnogues 
Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 1 -
 target/arm/translate.c | 1 -
 2 files changed, 2 deletions(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 76b5ca3606..ac9723c1b9 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -13899,7 +13899,6 @@ static void 
aarch64_tr_init_disas_context(DisasContextBase *dcbase,
 
 static void aarch64_tr_tb_start(DisasContextBase *db, CPUState *cpu)
 {
-tcg_clear_temp_count();
 }
 
 static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 426db7828a..736880ee71 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -12701,7 +12701,6 @@ static void arm_tr_tb_start(DisasContextBase *dcbase, 
CPUState *cpu)
 tcg_gen_movi_i32(tmp, 0);
 store_cpu_field(tmp, condexec_bits);
 }
-tcg_clear_temp_count();
 }
 
 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
-- 
2.17.1




[Qemu-devel] [PULL 10/10] RISC-V: Don't add NULL bootargs to device-tree

2018-10-11 Thread Alistair Francis
From: Michael Clark 

Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 4 +++-
 hw/riscv/spike.c| 6 --
 hw/riscv/virt.c | 4 +++-
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 4e273119c3..0c51c61082 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -259,7 +259,9 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
-qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+if (cmdline) {
+qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+}
 g_free(nodename);
 }
 
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index be5ef85e81..8a712ed490 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -156,8 +156,10 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 g_free(cells);
 g_free(nodename);
 
-qemu_fdt_add_subnode(fdt, "/chosen");
-qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+if (cmdline) {
+qemu_fdt_add_subnode(fdt, "/chosen");
+qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+}
  }
 
 static void spike_v1_10_0_board_init(MachineState *machine)
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 3f30eb74d2..62add47667 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -284,7 +284,9 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 
 qemu_fdt_add_subnode(fdt, "/chosen");
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
-qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+if (cmdline) {
+qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
+}
 g_free(nodename);
 
 return fdt;
-- 
2.17.1



[Qemu-devel] [PULL 09/10] RISC-V: Add missing free for plic_hart_config

2018-10-11 Thread Alistair Francis
From: Michael Clark 

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Alistair Francis 
---
 hw/riscv/virt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 6d91810bcf..3f30eb74d2 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -457,6 +457,8 @@ static void riscv_virt_board_init(MachineState *machine)
 serial_mm_init(system_memory, memmap[VIRT_UART0].base,
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
 serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+g_free(plic_hart_config);
 }
 
 static void riscv_virt_board_machine_init(MachineClass *mc)
-- 
2.17.1



[Qemu-devel] [PULL 07/10] RISC-V: Move non-ops from op_helper to cpu_helper

2018-10-11 Thread Alistair Francis
From: Michael Clark 

This patch makes op_helper.c contain only instruction
operation helpers used by translate.c and moves any
unrelated cpu helpers into cpu_helper.c. No logic is
changed by this patch.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Alistair Francis 
---
 target/riscv/Makefile.objs  |  2 +-
 target/riscv/{helper.c => cpu_helper.c} | 35 -
 target/riscv/op_helper.c| 34 
 3 files changed, 35 insertions(+), 36 deletions(-)
 rename target/riscv/{helper.c => cpu_helper.c} (95%)

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index abd0a7cde3..fcc5d34c1f 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o fpu_helper.o gdbstub.o 
pmp.o
diff --git a/target/riscv/helper.c b/target/riscv/cpu_helper.c
similarity index 95%
rename from target/riscv/helper.c
rename to target/riscv/cpu_helper.c
index 63b3386b76..86f9f4730c 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1,5 +1,5 @@
 /*
- * RISC-V emulation helpers for qemu.
+ * RISC-V CPU helpers for qemu.
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
@@ -72,6 +72,39 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 #if !defined(CONFIG_USER_ONLY)
 
+/* iothread_mutex must be held */
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
+{
+CPURISCVState *env = >env;
+uint32_t old, new, cmp = atomic_read(>mip);
+
+do {
+old = cmp;
+new = (old & ~mask) | (value & mask);
+cmp = atomic_cmpxchg(>mip, old, new);
+} while (old != cmp);
+
+if (new && !old) {
+cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+} else if (!new && old) {
+cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+return old;
+}
+
+void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
+{
+if (newpriv > PRV_M) {
+g_assert_not_reached();
+}
+if (newpriv == PRV_H) {
+newpriv = PRV_U;
+}
+/* tlb_flush is unnecessary as mode is contained in mmu_idx */
+env->priv = newpriv;
+}
+
 /* get_physical_address - get the physical address for this virtual address
  *
  * Do a page table walk to obtain the physical address corresponding to a
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index d0883d329b..495390ab1c 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -654,39 +654,6 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong 
src,
 
 #ifndef CONFIG_USER_ONLY
 
-/* iothread_mutex must be held */
-uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
-{
-CPURISCVState *env = >env;
-uint32_t old, new, cmp = atomic_read(>mip);
-
-do {
-old = cmp;
-new = (old & ~mask) | (value & mask);
-cmp = atomic_cmpxchg(>mip, old, new);
-} while (old != cmp);
-
-if (new && !old) {
-cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-} else if (!new && old) {
-cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-return old;
-}
-
-void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
-{
-if (newpriv > PRV_M) {
-g_assert_not_reached();
-}
-if (newpriv == PRV_H) {
-newpriv = PRV_U;
-}
-/* tlb_flush is unnecessary as mode is contained in mmu_idx */
-env->priv = newpriv;
-}
-
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
 if (!(env->priv >= PRV_S)) {
@@ -737,7 +704,6 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 return retpc;
 }
 
-
 void helper_wfi(CPURISCVState *env)
 {
 CPUState *cs = CPU(riscv_env_get_cpu(env));
-- 
2.17.1



[Qemu-devel] [PULL 08/10] RISC-V: Update CSR and interrupt definitions

2018-10-11 Thread Alistair Francis
From: Michael Clark 

* Add user-mode CSR defininitions.
* Reorder CSR definitions to match the specification.
* Change H mode interrupt comment to 'reserved'.
* Remove unused X_COP interrupt.
* Add user-mode interrupts.
* Remove erroneous until comments on machine mode interrupts.
* Move together paging mode and page table bit definitions.
* Move together interrupt and exception cause definitions.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c   |   6 +-
 target/riscv/cpu_bits.h  | 683 +--
 target/riscv/op_helper.c |   2 +-
 3 files changed, 370 insertions(+), 321 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d630e8fd6c..a025a0a3ba 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -74,8 +74,10 @@ const char * const riscv_intr_names[] = {
 "s_external",
 "h_external",
 "m_external",
-"coprocessor",
-"host"
+"reserved",
+"reserved",
+"reserved",
+"reserved"
 };
 
 typedef struct RISCVCPUInfo {
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 12b4757088..5439f4719e 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -6,242 +6,283 @@
  (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
  (target_ulong)(mask)))
 
-#define PGSHIFT 12
-
-#define FSR_RD_SHIFT 5
-#define FSR_RD   (0x7 << FSR_RD_SHIFT)
-
-#define FPEXC_NX 0x01
-#define FPEXC_UF 0x02
-#define FPEXC_OF 0x04
-#define FPEXC_DZ 0x08
-#define FPEXC_NV 0x10
-
-#define FSR_AEXC_SHIFT 0
-#define FSR_NVA  (FPEXC_NV << FSR_AEXC_SHIFT)
-#define FSR_OFA  (FPEXC_OF << FSR_AEXC_SHIFT)
-#define FSR_UFA  (FPEXC_UF << FSR_AEXC_SHIFT)
-#define FSR_DZA  (FPEXC_DZ << FSR_AEXC_SHIFT)
-#define FSR_NXA  (FPEXC_NX << FSR_AEXC_SHIFT)
-#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
-
-/* CSR numbers */
-#define CSR_FFLAGS 0x1
-#define CSR_FRM 0x2
-#define CSR_FCSR 0x3
-#define CSR_CYCLE 0xc00
-#define CSR_TIME 0xc01
-#define CSR_INSTRET 0xc02
-#define CSR_HPMCOUNTER3 0xc03
-#define CSR_HPMCOUNTER4 0xc04
-#define CSR_HPMCOUNTER5 0xc05
-#define CSR_HPMCOUNTER6 0xc06
-#define CSR_HPMCOUNTER7 0xc07
-#define CSR_HPMCOUNTER8 0xc08
-#define CSR_HPMCOUNTER9 0xc09
-#define CSR_HPMCOUNTER10 0xc0a
-#define CSR_HPMCOUNTER11 0xc0b
-#define CSR_HPMCOUNTER12 0xc0c
-#define CSR_HPMCOUNTER13 0xc0d
-#define CSR_HPMCOUNTER14 0xc0e
-#define CSR_HPMCOUNTER15 0xc0f
-#define CSR_HPMCOUNTER16 0xc10
-#define CSR_HPMCOUNTER17 0xc11
-#define CSR_HPMCOUNTER18 0xc12
-#define CSR_HPMCOUNTER19 0xc13
-#define CSR_HPMCOUNTER20 0xc14
-#define CSR_HPMCOUNTER21 0xc15
-#define CSR_HPMCOUNTER22 0xc16
-#define CSR_HPMCOUNTER23 0xc17
-#define CSR_HPMCOUNTER24 0xc18
-#define CSR_HPMCOUNTER25 0xc19
-#define CSR_HPMCOUNTER26 0xc1a
-#define CSR_HPMCOUNTER27 0xc1b
-#define CSR_HPMCOUNTER28 0xc1c
-#define CSR_HPMCOUNTER29 0xc1d
-#define CSR_HPMCOUNTER30 0xc1e
-#define CSR_HPMCOUNTER31 0xc1f
-#define CSR_SSTATUS 0x100
-#define CSR_SIE 0x104
-#define CSR_STVEC 0x105
-#define CSR_SCOUNTEREN 0x106
-#define CSR_SSCRATCH 0x140
-#define CSR_SEPC 0x141
-#define CSR_SCAUSE 0x142
-#define CSR_SBADADDR 0x143
-#define CSR_SIP 0x144
-#define CSR_SPTBR 0x180
-#define CSR_SATP 0x180
-#define CSR_MSTATUS 0x300
-#define CSR_MISA 0x301
-#define CSR_MEDELEG 0x302
-#define CSR_MIDELEG 0x303
-#define CSR_MIE 0x304
-#define CSR_MTVEC 0x305
-#define CSR_MCOUNTEREN 0x306
-#define CSR_MSCRATCH 0x340
-#define CSR_MEPC 0x341
-#define CSR_MCAUSE 0x342
-#define CSR_MBADADDR 0x343
-#define CSR_MIP 0x344
-#define CSR_PMPCFG0 0x3a0
-#define CSR_PMPCFG1 0x3a1
-#define CSR_PMPCFG2 0x3a2
-#define CSR_PMPCFG3 0x3a3
-#define CSR_PMPADDR0 0x3b0
-#define CSR_PMPADDR1 0x3b1
-#define CSR_PMPADDR2 0x3b2
-#define CSR_PMPADDR3 0x3b3
-#define CSR_PMPADDR4 0x3b4
-#define CSR_PMPADDR5 0x3b5
-#define CSR_PMPADDR6 0x3b6
-#define CSR_PMPADDR7 0x3b7
-#define CSR_PMPADDR8 0x3b8
-#define CSR_PMPADDR9 0x3b9
-#define CSR_PMPADDR10 0x3ba
-#define CSR_PMPADDR11 0x3bb
-#define CSR_PMPADDR12 0x3bc
-#define CSR_PMPADDR13 0x3bd
-#define CSR_PMPADDR14 0x3be
-#define CSR_PMPADDR15 0x3bf
-#define CSR_TSELECT 0x7a0
-#define CSR_TDATA1 0x7a1
-#define CSR_TDATA2 0x7a2
-#define CSR_TDATA3 0x7a3
-#define CSR_DCSR 0x7b0
-#define CSR_DPC 0x7b1
-#define CSR_DSCRATCH 0x7b2
-#define CSR_MCYCLE 0xb00
-#define CSR_MINSTRET 0xb02
-#define CSR_MHPMCOUNTER3 0xb03
-#define CSR_MHPMCOUNTER4 0xb04
-#define CSR_MHPMCOUNTER5 0xb05
-#define CSR_MHPMCOUNTER6 0xb06
-#define CSR_MHPMCOUNTER7 0xb07
-#define CSR_MHPMCOUNTER8 0xb08
-#define CSR_MHPMCOUNTER9 0xb09
-#define CSR_MHPMCOUNTER10 0xb0a
-#define CSR_MHPMCOUNTER11 0xb0b
-#define CSR_MHPMCOUNTER12 0xb0c
-#define CSR_MHPMCOUNTER13 0xb0d
-#define CSR_MHPMCOUNTER14 0xb0e
-#define CSR_MHPMCOUNTER15 0xb0f
-#define CSR_MHPMCOUNTER16 0xb10
-#define CSR_MHPMCOUNTER17 

[Qemu-devel] [PULL 02/10] hw/riscv/virt: Connect the gpex PCIe

2018-10-11 Thread Alistair Francis
Connect the gpex PCIe device based on the device tree included in the
HiFive Unleashed ROM.

Signed-off-by: Alistair Francis 
---
 default-configs/riscv32-softmmu.mak |  6 ++-
 default-configs/riscv64-softmmu.mak |  6 ++-
 hw/riscv/virt.c | 58 +
 include/hw/riscv/virt.h |  4 +-
 4 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/default-configs/riscv64-softmmu.mak 
b/default-configs/riscv64-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 005169eabc..9bd2c10581 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -39,6 +39,8 @@
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "exec/address-spaces.h"
+#include "hw/pci/pci.h"
+#include "hw/pci-host/gpex.h"
 #include "elf.h"
 
 #include 
@@ -55,6 +57,7 @@ static const struct MemmapEntry {
 [VIRT_UART0] ={ 0x1000,  0x100 },
 [VIRT_VIRTIO] =   { 0x10001000, 0x1000 },
 [VIRT_DRAM] = { 0x8000,0x0 },
+[VIRT_PCIE] = { 0x20, 0x400 },
 };
 
 static uint64_t load_kernel(const char *kernel_filename)
@@ -233,6 +236,32 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 }
 
+nodename = g_strdup_printf("/pci@%lx",
+(long) memmap[VIRT_PCIE].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x3);
+qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0x2);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"pci-host-ecam-generic");
+qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
+qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0x0, 0x0,
+   memmap[VIRT_PCIE].size);
+qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
+qemu_fdt_setprop_cells(fdt, nodename, "ranges", 0x200, 0x0,
+   0x4000, 0x0, 0x4000, 0x0, 0x2000);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
+g_free(nodename);
+
+nodename = g_strdup_printf("/pci@%lx/interrupt-controller",
+(long) memmap[VIRT_PCIE].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x00);
+qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/test@%lx",
 (long)memmap[VIRT_TEST].base);
 qemu_fdt_add_subnode(fdt, nodename);
@@ -260,6 +289,31 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 return fdt;
 }
 
+
+static inline DeviceState *
+gpex_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
+ hwaddr cfg_base, uint64_t cfg_size,
+ hwaddr mmio_base, uint64_t mmio_size,
+ qemu_irq irq, bool link_up)
+{
+DeviceState *dev;
+MemoryRegion *cfg, *mmio;
+
+dev = qdev_create(NULL, TYPE_GPEX_HOST);
+
+qdev_init_nofail(dev);
+
+cfg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+memory_region_add_subregion_overlap(sys_mem, cfg_base, cfg, 0);
+
+mmio = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+memory_region_add_subregion_overlap(sys_mem, 0, mmio, 0);
+
+sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
+
+return dev;
+}
+
 static void riscv_virt_board_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = virt_memmap;
@@ -382,6 +436,10 @@ static void riscv_virt_board_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
 }
 
+gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
+   memmap[VIRT_PCIE].size, 0x4000, 0x2000,
+   qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
+
 serial_mm_init(system_memory, memmap[VIRT_UART0].base,
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
 serial_hd(0), 

[Qemu-devel] [PULL 06/10] RISC-V: Allow setting and clearing multiple irqs

2018-10-11 Thread Alistair Francis
From: Michael Clark 

Change the API of riscv_set_local_interrupt to take a
write mask and value to allow setting and clearing of
multiple local interrupts atomically in a single call.
Rename the new function to riscv_cpu_update_mip.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
Reviewed-by: Palmer Dabbelt 
Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_clint.c  |  8 
 hw/riscv/sifive_plic.c   |  4 ++--
 target/riscv/cpu.h   | 22 +-
 target/riscv/op_helper.c | 24 +++-
 4 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index 7cc606e065..0d2fd52487 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -47,12 +47,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 if (cpu->env.timecmp <= rtc_r) {
 /* if we're setting an MTIMECMP value in the "past",
immediately raise the timer interrupt */
-riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
 return;
 }
 
 /* otherwise, set up the future timer interrupt */
-riscv_set_local_interrupt(cpu, MIP_MTIP, 0);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
 diff = cpu->env.timecmp - rtc_r;
 /* back to ns (note args switched in muldiv64) */
 next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -67,7 +67,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 static void sifive_clint_timer_cb(void *opaque)
 {
 RISCVCPU *cpu = opaque;
-riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
 }
 
 /* CPU wants to read rtc or timecmp register */
@@ -132,7 +132,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, 
uint64_t value,
 if (!env) {
 error_report("clint: invalid timecmp hartid: %zu", hartid);
 } else if ((addr & 0x3) == 0) {
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MSIP, value != 0);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, 
BOOL_TO_MASK(value));
 } else {
 error_report("clint: invalid sip write: %08x", (uint32_t)addr);
 }
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index f635e6ff67..9cf9a1f986 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -142,10 +142,10 @@ static void sifive_plic_update(SiFivePLICState *plic)
 int level = sifive_plic_irqs_pending(plic, addrid);
 switch (mode) {
 case PLICMode_M:
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, 
BOOL_TO_MASK(level));
 break;
 case PLICMode_S:
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_SEIP, level);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, 
BOOL_TO_MASK(level));
 break;
 default:
 break;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d4f36295f0..4ee09b9cff 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -126,13 +126,18 @@ struct CPURISCVState {
 
 target_ulong mhartid;
 target_ulong mstatus;
+
 /*
  * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads and other vCPUs, so hold the iothread mutex before
- * operating on it.  CPU_INTERRUPT_HARD should be in effect iff this is
- * non-zero.  Use riscv_cpu_set_local_interrupt.
+ * by I/O threads. It should be read with atomic_read. It should be updated
+ * using riscv_cpu_update_mip with the iothread mutex held. The iothread
+ * mutex must be held because mip must be consistent with the CPU inturrept
+ * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
+ * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
+ * mip is 32-bits to allow atomic_read on 32-bit hosts.
  */
-uint32_t mip;/* allow atomic_read for >= 32-bit hosts */
+uint32_t mip;
+
 target_ulong mie;
 target_ulong mideleg;
 
@@ -247,7 +252,6 @@ void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 uintptr_t retaddr);
 int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
   int rw, int mmu_idx);
-
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
@@ -255,6 +259,10 @@ void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
 
+#ifndef CONFIG_USER_ONLY
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
+#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
+#endif
 

[Qemu-devel] [PULL 05/10] hw/riscv/virt: Connect a VirtIO net PCIe device

2018-10-11 Thread Alistair Francis
Signed-off-by: Alistair Francis 
---
 default-configs/riscv32-softmmu.mak |  1 +
 default-configs/riscv64-softmmu.mak |  1 +
 hw/riscv/virt.c | 20 +---
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak 
b/default-configs/riscv64-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 62a953aa2b..6d91810bcf 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -36,6 +36,7 @@
 #include "hw/riscv/sifive_test.h"
 #include "hw/riscv/virt.h"
 #include "chardev/char.h"
+#include "net/net.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "exec/address-spaces.h"
@@ -322,6 +323,8 @@ static void riscv_virt_board_init(MachineState *machine)
 MemoryRegion *system_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
 MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+DeviceState *dev;
+PCIBus *pci_bus;
 char *plic_hart_config;
 size_t plic_hart_config_len;
 int i;
@@ -436,9 +439,20 @@ static void riscv_virt_board_init(MachineState *machine)
 qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
 }
 
-gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
-   memmap[VIRT_PCIE].size, 0x4000, 0x2000,
-   qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
+dev = gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
+ memmap[VIRT_PCIE].size, 0x4000, 0x2000,
+ qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
+pci_bus = PCI_HOST_BRIDGE(dev)->bus;
+
+for (i = 0; i < nb_nics; i++) {
+NICInfo *nd = _table[i];
+
+if (!nd->model) {
+nd->model = g_strdup("virtio");
+}
+
+pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
+}
 
 serial_mm_init(system_memory, memmap[VIRT_UART0].base,
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
-- 
2.17.1




[Qemu-devel] [PULL 01/10] hw/riscv/virt: Increase the number of interrupts

2018-10-11 Thread Alistair Francis
Increase the number of interrupts to match the HiFive Unleashed board.

Signed-off-by: Alistair Francis 
---
 include/hw/riscv/virt.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 91163d6cbf..7cb2742070 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -45,7 +45,7 @@ enum {
 UART0_IRQ = 10,
 VIRTIO_IRQ = 1, /* 1 to 8 */
 VIRTIO_COUNT = 8,
-VIRTIO_NDEV = 10
+VIRTIO_NDEV = 0x35
 };
 
 enum {
-- 
2.17.1




[Qemu-devel] [PULL 04/10] hw/riscv/sifive_u: Connect the Xilinx PCIe

2018-10-11 Thread Alistair Francis
Connect the Xilinx PCIe device based on the information in the device
tree stored in the ROM of the HiFish Unleashed board.

Signed-off-by: Alistair Francis 
---
 hw/riscv/sifive_u.c | 64 +
 include/hw/riscv/sifive_u.h |  4 ++-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 862f8ff5f7..4e273119c3 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -45,6 +45,8 @@
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "exec/address-spaces.h"
+#include "hw/pci/pci.h"
+#include "hw/pci-host/xilinx-pcie.h"
 #include "elf.h"
 
 #include 
@@ -61,6 +63,7 @@ static const struct MemmapEntry {
 [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
 [SIFIVE_U_DRAM] = { 0x8000,0x0 },
 [SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
+[SIFIVE_U_PCIE] = { 0x20, 0x400 },
 };
 
 #define GEM_REVISION0x10070109
@@ -218,6 +221,32 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
 g_free(nodename);
 
+nodename = g_strdup_printf("/pci@%lx",
+(long) memmap[SIFIVE_U_PCIE].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x3);
+qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0x2);
+qemu_fdt_setprop_string(fdt, nodename, "compatible",
+"xlnx,axi-pcie-host-1.00.a");
+qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
+qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0x0, 0x0,
+   memmap[SIFIVE_U_PCIE].size);
+qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
+qemu_fdt_setprop_cells(fdt, nodename, "ranges", 0x200, 0x0,
+   0x4000, 0x0, 0x4000, 0x0, 0x2000);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
+qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_PCIE_IRQ);
+g_free(nodename);
+
+nodename = g_strdup_printf("/pci@%lx/interrupt-controller",
+(long) memmap[SIFIVE_U_PCIE].base);
+qemu_fdt_add_subnode(fdt, nodename);
+qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x00);
+qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+g_free(nodename);
+
 nodename = g_strdup_printf("/soc/uart@%lx",
 (long)memmap[SIFIVE_U_UART0].base);
 qemu_fdt_add_subnode(fdt, nodename);
@@ -234,6 +263,37 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 }
 
+static inline DeviceState *
+xilinx_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
+ hwaddr cfg_base, uint64_t cfg_size,
+ hwaddr mmio_base, uint64_t mmio_size,
+ qemu_irq irq, bool link_up)
+{
+DeviceState *dev;
+MemoryRegion *cfg, *mmio;
+
+dev = qdev_create(NULL, TYPE_XILINX_PCIE_HOST);
+
+qdev_prop_set_uint32(dev, "bus_nr", bus_nr);
+qdev_prop_set_uint64(dev, "cfg_base", cfg_base);
+qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
+qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
+qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
+qdev_prop_set_bit(dev, "link_up", link_up);
+
+qdev_init_nofail(dev);
+
+cfg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+memory_region_add_subregion_overlap(sys_mem, cfg_base, cfg, 0);
+
+mmio = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+memory_region_add_subregion_overlap(sys_mem, 0, mmio, 0);
+
+qdev_connect_gpio_out_named(dev, "interrupt_out", 0, irq);
+
+return dev;
+}
+
 static void riscv_sifive_u_init(MachineState *machine)
 {
 const struct MemmapEntry *memmap = sifive_u_memmap;
@@ -373,6 +433,10 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, 
Error **errp)
 sysbus_mmio_map(SYS_BUS_DEVICE(>gem), 0, memmap[SIFIVE_U_GEM].base);
 sysbus_connect_irq(SYS_BUS_DEVICE(>gem), 0,
plic_gpios[SIFIVE_U_GEM_IRQ]);
+
+xilinx_pcie_init(system_memory, 0, memmap[SIFIVE_U_PCIE].base,
+ memmap[SIFIVE_U_PCIE].size, 0x4000, 0x2000,
+ qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_PCIE_IRQ), 
true);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e8b4d9ffa3..e7292ea83b 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -53,12 +53,14 @@ enum {
 SIFIVE_U_UART0,
 SIFIVE_U_UART1,
 SIFIVE_U_DRAM,
-SIFIVE_U_GEM
+SIFIVE_U_GEM,
+SIFIVE_U_PCIE
 };
 
 enum {
 SIFIVE_U_UART0_IRQ = 3,
 SIFIVE_U_UART1_IRQ = 4,
+SIFIVE_U_PCIE_IRQ = 

[Qemu-devel] [PULL 03/10] riscv: Enable VGA and PCIE_VGA

2018-10-11 Thread Alistair Francis
Enable compile support for VGA devices. This allows the user to conenct
a display by adding '-device bochs-display -display sdl' to their
command line argument.

Signed-off-by: Alistair Francis 
---
 default-configs/riscv32-softmmu.mak | 3 +++
 default-configs/riscv64-softmmu.mak | 3 +++
 hw/riscv/virt.c | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/default-configs/riscv32-softmmu.mak 
b/default-configs/riscv32-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak 
b/default-configs/riscv64-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 9bd2c10581..62a953aa2b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -437,8 +437,8 @@ static void riscv_virt_board_init(MachineState *machine)
 }
 
 gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
-   memmap[VIRT_PCIE].size, 0x4000, 0x2000,
-   qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
+   memmap[VIRT_PCIE].size, 0x4000, 0x2000,
+   qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
 
 serial_mm_init(system_memory, memmap[VIRT_UART0].base,
 0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
-- 
2.17.1




[Qemu-devel] [PULL 00/10] riscv-pullreq queue

2018-10-11 Thread Alistair Francis
The following changes since commit 75e50c80e051423a6f55a34ee4a1eec842444a5b:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-10-10' into 
staging (2018-10-11 10:43:37 +0100)

are available in the Git repository at:

  g...@github.com:alistair23/qemu.git tags/pull-riscv-pullreq-20181011

for you to fetch changes up to f39e645c5f5e9f2b3d41e9c1ad84caae1829cce2:

  RISC-V: Don't add NULL bootargs to device-tree (2018-10-11 10:30:26 -0700)


riscv: Connect PCIe and apply some misc patches

Connect PCIe to the RISC-V virt machine and SiFive U machines.

There are also some patches that I have cherry picked from Michael's RISC-V
tree that are ready to be applied.


Alistair Francis (5):
  hw/riscv/virt: Increase the number of interrupts
  hw/riscv/virt: Connect the gpex PCIe
  riscv: Enable VGA and PCIE_VGA
  hw/riscv/sifive_u: Connect the Xilinx PCIe
  hw/riscv/virt: Connect a VirtIO net PCIe device

Michael Clark (5):
  RISC-V: Allow setting and clearing multiple irqs
  RISC-V: Move non-ops from op_helper to cpu_helper
  RISC-V: Update CSR and interrupt definitions
  RISC-V: Add missing free for plic_hart_config
  RISC-V: Don't add NULL bootargs to device-tree

 default-configs/riscv32-softmmu.mak |  10 +-
 default-configs/riscv64-softmmu.mak |  10 +-
 hw/riscv/sifive_clint.c |   8 +-
 hw/riscv/sifive_plic.c  |   4 +-
 hw/riscv/sifive_u.c |  68 +++-
 hw/riscv/spike.c|   6 +-
 hw/riscv/virt.c |  78 +++-
 include/hw/riscv/sifive_u.h |   4 +-
 include/hw/riscv/virt.h |   6 +-
 target/riscv/Makefile.objs  |   2 +-
 target/riscv/cpu.c  |   6 +-
 target/riscv/cpu.h  |  22 +-
 target/riscv/cpu_bits.h | 683 +---
 target/riscv/{helper.c => cpu_helper.c} |  35 +-
 target/riscv/op_helper.c|  34 +-
 15 files changed, 599 insertions(+), 377 deletions(-)
 rename target/riscv/{helper.c => cpu_helper.c} (95%)


Re: [Qemu-devel] [PATCH v9 3/3] qmp hmp: Make system_wakeup check wake-up support and run state

2018-10-11 Thread Daniel Henrique Barboza




On 10/11/18 4:45 AM, Markus Armbruster wrote:

Daniel Henrique Barboza  writes:


The qmp/hmp command 'system_wakeup' is simply a direct call to
'qemu_system_wakeup_request' from vl.c. This function verifies if
runstate is SUSPENDED and if the wake up reason is valid before
proceeding. However, no error or warning is thrown if any of those
pre-requirements isn't met. There is no way for the caller to
differentiate between a successful wakeup or an error state caused
when trying to wake up a guest that wasn't suspended.

This means that system_wakeup is silently failing, which can be
considered a bug. Adding error handling isn't an API break in this
case - applications that didn't check the result will remain broken,
the ones that check it will have a chance to deal with it.

Adding to that, the commit before previous created a new QMP API called
query-current-machine, with a new flag called wakeup-suspend-support,
that indicates if the guest has the capability of waking up from suspended
state. Although such guest will never reach SUSPENDED state and erroring
it out in this scenario would suffice, it is more informative for the user
to differentiate between a failure because the guest isn't suspended versus
a failure because the guest does not have support for wake up at all.

All this considered, this patch changes qmp_system_wakeup to:

- check if the guest has the capability to wake-up from suspend. If
not, error out informing about the lack of support;

- make the runstate verification before proceeding to call
qemu_system_wakeup_request, firing up an error message if the user tries
to wake up a machine that isn't in SUSPENDED state.

After this patch, this is the output of system_wakeup in a guest that
does not have wake-up from suspend support (ppc64):

(qemu) system_wakeup
wake-up from suspend is not supported by this guest
(qemu)

And this is the output of system_wakeup in a x86 guest that has the
support but isn't suspended:

(qemu) system_wakeup
Unable to wake up: guest is not in suspended state
(qemu)

Reported-by: Balamuruhan S 
Signed-off-by: Daniel Henrique Barboza 
---
  hmp.c   |  5 -
  include/sysemu/sysemu.h |  1 +
  qapi/misc.json  |  5 -
  qmp.c   | 10 ++
  vl.c|  2 +-
  5 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/hmp.c b/hmp.c
index 4975fa56b0..e98c24782f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1203,7 +1203,10 @@ void hmp_cont(Monitor *mon, const QDict *qdict)
  
  void hmp_system_wakeup(Monitor *mon, const QDict *qdict)

  {
-qmp_system_wakeup(NULL);
+Error *err = NULL;
+
+qmp_system_wakeup();
+hmp_handle_error(mon, );
  }
  
  void hmp_nmi(Monitor *mon, const QDict *qdict)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 0446adacc6..8d91c5ad5b 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -74,6 +74,7 @@ void qemu_exit_preconfig_request(void);
  void qemu_system_reset_request(ShutdownCause reason);
  void qemu_system_suspend_request(void);
  void qemu_register_suspend_notifier(Notifier *notifier);
+bool qemu_wakeup_suspend_enabled(void);
  void qemu_system_wakeup_request(WakeupReason reason);
  void qemu_system_wakeup_enable(WakeupReason reason, bool enabled);
  void qemu_register_wakeup_notifier(Notifier *notifier);
diff --git a/qapi/misc.json b/qapi/misc.json
index b616d385a4..2f5995f45f 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1230,7 +1230,10 @@
  ##
  # @system_wakeup:
  #
-# Wakeup guest from suspend.  Does nothing in case the guest isn't suspended.
+# If the guest has wake-up from suspend support enabled
+# (wakeup-suspend-support flag from query-current-machine), wakeup guest
+# from suspend if the guest is in SUSPENDED state. Returns an error
+# otherwise.

Perhaps a note that versions older than 3.1 neglected to report errors
would be helpful.



Ok!




  #
  # Since:  1.1
  #
diff --git a/qmp.c b/qmp.c
index e7c0a2fd60..44e619d1be 100644
--- a/qmp.c
+++ b/qmp.c
@@ -183,6 +183,16 @@ void qmp_cont(Error **errp)
  
  void qmp_system_wakeup(Error **errp)

  {
+if (!qemu_wakeup_suspend_enabled()) {
+error_setg(errp,
+   "wake-up from suspend is not supported by this guest");
+return;
+}

Is this a new check?

If not, where is the condition checked before this patch?


This is a new check that concerns only the QMP callers, thus I chose not to
bake it inside qemu_system_wakeup_request().





+if (!runstate_check(RUN_STATE_SUSPENDED)) {
+error_setg(errp,
+   "Unable to wake up: guest is not in suspended state");
+return;
+}

Duplicates the check in qemu_system_wakeup_request().  Should that
function take an Error ** argument instead?


Yes, it is saner than adding a duplicated check. Shouldn't hurt
other callers as well. I'll respin the series with this change.




  qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
  }
  
diff 

Re: [Qemu-devel] [PATCH] oslib-posix: Use MAP_STACK in qemu_alloc_stack() on OpenBSD

2018-10-11 Thread Kamil Rytarowski
On 11.10.2018 16:25, Brad Smith wrote:
> On 10/11/2018 5:41 AM, Kamil Rytarowski wrote:
> 
>> On 11.10.2018 11:36, Peter Maydell wrote:
>>> On 11 October 2018 at 00:55, Brad Smith  wrote:
 And from FreeBSD...

   MAP_STACK MAP_STACK implies MAP_ANON, and offset of 0.  The fd
 argument must be -1 and prot must include at least
 PROT_READ and PROT_WRITE.

 This option creates a memory region that grows to at
 most len bytes in size, starting from the stack top
 and growing down.  The stack top is the starting
 address returned by the call, plus len bytes.  The
 bottom of the stack at maximum growth is the starting
 address returned by the call.

 Stacks created with MAP_STACK automatically grow.
 Guards prevent inadvertent use of the regions into
 which those stacks can grow without requiring mapping
 the whole stack in advance.
>>> Hmm. That "automatically growing" part sounds like
>>> behaviour we definitely do not want for our use case.
>>> So we're going to need to make this OS-specific :-(
>>>
>> I propose to restrict MAP_STACK it to OpenBSD (with a comment in the
>> code). Once it will be needed by someone else will be able to enable it
>> for other OSes.
> 
> I was going to propose doing something like that but you had replied
> before I did.
> What sort of comment did you have in mind?
> 

Why do we want it only on OpenBSD and its either unneeded or meaning
something else on other OSes.

#ifdef __OpenBSD__
flags |= MAP_STACK;
#endif



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PULL 2/7] tests/migration: Enable the migration test on s390x, too

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Thomas Huth 

We can re-use the s390-ccw bios code to implement a small firmware
for a s390x guest which prints out the "A" and "B" characters and
modifies the memory, as required for the migration test.

[quintela: Converted the compile script to Makefile rules]
Signed-off-by: Juan Quintela 
Signed-off-by: Thomas Huth 
Message-Id: <1539078677-25396-1-git-send-email-th...@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Dr. David Alan Gilbert 
  Fixed up Makefile since the aarch patch sneaked in first
---
 tests/Makefile.include   |   1 +
 tests/migration-test.c   |  24 +++
 tests/migration/Makefile |   2 +-
 tests/migration/migration-test.h |   4 +
 tests/migration/s390x/Makefile   |  24 +++
 tests/migration/s390x/a-b-bios.c |  36 +
 tests/migration/s390x/a-b-bios.h | 253 +++
 7 files changed, 343 insertions(+), 1 deletion(-)
 create mode 100644 tests/migration/s390x/Makefile
 create mode 100644 tests/migration/s390x/a-b-bios.c
 create mode 100644 tests/migration/s390x/a-b-bios.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 9324a8be6b..5eadfd52f9 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -416,6 +416,7 @@ check-qtest-s390x-$(CONFIG_POSIX) += 
tests/test-filter-redirector$(EXESUF)
 check-qtest-s390x-y += tests/drive_del-test$(EXESUF)
 check-qtest-s390x-y += tests/virtio-ccw-test$(EXESUF)
 check-qtest-s390x-y += tests/cpu-plug-test$(EXESUF)
+check-qtest-s390x-y += tests/migration-test$(EXESUF)
 
 check-qtest-generic-y += tests/machine-none-test$(EXESUF)
 check-qtest-generic-y += tests/qom-test$(EXESUF)
diff --git a/tests/migration-test.c b/tests/migration-test.c
index 5bdc0bd519..b7920255c5 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -96,6 +96,17 @@ static void init_bootfile(const char *bootpath, void 
*content)
 fclose(bootfile);
 }
 
+#include "tests/migration/s390x/a-b-bios.h"
+
+static void init_bootfile_s390x(const char *bootpath)
+{
+FILE *bootfile = fopen(bootpath, "wb");
+size_t len = sizeof(s390x_elf);
+
+g_assert_cmpint(fwrite(s390x_elf, len, 1, bootfile), ==, 1);
+fclose(bootfile);
+}
+
 /*
  * Wait for some output in the serial output file,
  * we get an 'A' followed by an endless string of 'B's
@@ -443,6 +454,19 @@ static int test_migrate_start(QTestState **from, 
QTestState **to,
   accel, tmpfs, bootpath, uri);
 start_address = X86_TEST_MEM_START;
 end_address = X86_TEST_MEM_END;
+} else if (g_str_equal(arch, "s390x")) {
+init_bootfile_s390x(bootpath);
+cmd_src = g_strdup_printf("-machine accel=%s -m 128M"
+  " -name source,debug-threads=on"
+  " -serial file:%s/src_serial -bios %s",
+  accel, tmpfs, bootpath);
+cmd_dst = g_strdup_printf("-machine accel=%s -m 128M"
+  " -name target,debug-threads=on"
+  " -serial file:%s/dest_serial -bios %s"
+  " -incoming %s",
+  accel, tmpfs, bootpath, uri);
+start_address = S390_TEST_MEM_START;
+end_address = S390_TEST_MEM_END;
 } else if (strcmp(arch, "ppc64") == 0) {
 cmd_src = g_strdup_printf("-machine accel=%s -m 256M -nodefaults"
   " -name source,debug-threads=on"
diff --git a/tests/migration/Makefile b/tests/migration/Makefile
index 91237a84d9..ff726ed7dd 100644
--- a/tests/migration/Makefile
+++ b/tests/migration/Makefile
@@ -5,7 +5,7 @@
 # See the COPYING file in the top-level directory.
 #
 
-TARGET_LIST = i386 aarch64
+TARGET_LIST = i386 aarch64 s390x
 
 SRC_PATH = ../..
 
diff --git a/tests/migration/migration-test.h b/tests/migration/migration-test.h
index 6939a134c2..03c252368a 100644
--- a/tests/migration/migration-test.h
+++ b/tests/migration/migration-test.h
@@ -14,6 +14,10 @@
 #define X86_TEST_MEM_START (1 * 1024 * 1024)
 #define X86_TEST_MEM_END   (100 * 1024 * 1024)
 
+/* S390 */
+#define S390_TEST_MEM_START (1 * 1024 * 1024)
+#define S390_TEST_MEM_END   (100 * 1024 * 1024)
+
 /* PPC */
 #define PPC_TEST_MEM_START (1 * 1024 * 1024)
 #define PPC_TEST_MEM_END   (100 * 1024 * 1024)
diff --git a/tests/migration/s390x/Makefile b/tests/migration/s390x/Makefile
new file mode 100644
index 00..6393c3e5b9
--- /dev/null
+++ b/tests/migration/s390x/Makefile
@@ -0,0 +1,24 @@
+# To specify cross compiler prefix, use CROSS_PREFIX=
+#   $ make CROSS_PREFIX=s390x-linux-gnu-
+
+.PHONY: all clean
+all: a-b-bios.h
+fwdir=../../../pc-bios/s390-ccw
+
+CFLAGS+=-ffreestanding -fno-delete-null-pointer-checks -fPIE -Os \
+   -msoft-float -march=z900 -fno-asynchronous-unwind-tables -Wl,-pie \
+   -Wl,--build-id=none -nostdlib
+
+a-b-bios.h: s390x.elf
+   echo "$$__note" > header.tmp
+ 

[Qemu-devel] [PULL 1/7] tests: Add migration test for aarch64

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Wei Huang 

This patch adds migration test support for aarch64. The test code, which
implements the same functionality as x86, is booted as a kernel in qemu.
Here are the design choices we make for aarch64:

 * We choose this -kernel approach because aarch64 QEMU doesn't provide a
   built-in fw like x86 does. So instead of relying on a boot loader, we
   use -kernel approach for aarch64.
 * The serial output is sent to PL011 directly.
 * The physical memory base for mach-virt machine is 0x4000. We change
   the start_address and end_address for aarch64.

In addition to providing the binary, this patch also includes the source
code and the build script in tests/migration/aarch64. So users can change
the source and/or re-compile the binary as they wish.

Reviewed-by: Juan Quintela 
Reviewed-by: Andrew Jones 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Wei Huang 
Message-Id: <1538669326-28135-1-git-send-email-...@redhat.com>
Signed-off-by: Dr. David Alan Gilbert 
---
 tests/Makefile.include   |  1 +
 tests/migration-test.c   | 27 --
 tests/migration/Makefile |  2 +-
 tests/migration/aarch64/Makefile | 18 +++
 tests/migration/aarch64/a-b-kernel.S | 75 
 tests/migration/aarch64/a-b-kernel.h | 18 +++
 tests/migration/migration-test.h |  9 
 7 files changed, 145 insertions(+), 5 deletions(-)
 create mode 100644 tests/migration/aarch64/Makefile
 create mode 100644 tests/migration/aarch64/a-b-kernel.S
 create mode 100644 tests/migration/aarch64/a-b-kernel.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 8264af64a8..9324a8be6b 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -402,6 +402,7 @@ check-qtest-arm-y += tests/hexloader-test$(EXESUF)
 check-qtest-aarch64-y = tests/numa-test$(EXESUF)
 check-qtest-aarch64-$(CONFIG_SDHCI) += tests/sdhci-test$(EXESUF)
 check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
+check-qtest-aarch64-y += tests/migration-test$(EXESUF)
 
 check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
 
diff --git a/tests/migration-test.c b/tests/migration-test.c
index 20f38f1930..5bdc0bd519 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -86,12 +86,13 @@ static const char *tmpfs;
  * repeatedly. It outputs a 'B' at a fixed rate while it's still running.
  */
 #include "tests/migration/i386/a-b-bootblock.h"
+#include "tests/migration/aarch64/a-b-kernel.h"
 
-static void init_bootfile_x86(const char *bootpath)
+static void init_bootfile(const char *bootpath, void *content)
 {
 FILE *bootfile = fopen(bootpath, "wb");
 
-g_assert_cmpint(fwrite(x86_bootsect, 512, 1, bootfile), ==, 1);
+g_assert_cmpint(fwrite(content, 512, 1, bootfile), ==, 1);
 fclose(bootfile);
 }
 
@@ -428,7 +429,7 @@ static int test_migrate_start(QTestState **from, QTestState 
**to,
 got_stop = false;
 
 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
-init_bootfile_x86(bootpath);
+init_bootfile(bootpath, x86_bootsect);
 cmd_src = g_strdup_printf("-machine accel=%s -m 150M"
   " -name source,debug-threads=on"
   " -serial file:%s/src_serial"
@@ -459,6 +460,24 @@ static int test_migrate_start(QTestState **from, 
QTestState **to,
 
 start_address = PPC_TEST_MEM_START;
 end_address = PPC_TEST_MEM_END;
+} else if (strcmp(arch, "aarch64") == 0) {
+init_bootfile(bootpath, aarch64_kernel);
+cmd_src = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
+  "-name vmsource,debug-threads=on -cpu max "
+  "-m 150M -serial file:%s/src_serial "
+  "-kernel %s ",
+  accel, tmpfs, bootpath);
+cmd_dst = g_strdup_printf("-machine virt,accel=%s,gic-version=max "
+  "-name vmdest,debug-threads=on -cpu max "
+  "-m 150M -serial file:%s/dest_serial "
+  "-kernel %s "
+  "-incoming %s ",
+  accel, tmpfs, bootpath, uri);
+
+start_address = ARM_TEST_MEM_START;
+end_address = ARM_TEST_MEM_END;
+
+g_assert(sizeof(aarch64_kernel) <= ARM_TEST_MAX_KERNEL_SIZE);
 } else {
 g_assert_not_reached();
 }
@@ -545,7 +564,7 @@ static void test_deprecated(void)
 {
 QTestState *from;
 
-from = qtest_start("");
+from = qtest_start("-machine none");
 
 deprecated_set_downtime(from, 0.12345);
 deprecated_set_speed(from, 12345);
diff --git a/tests/migration/Makefile b/tests/migration/Makefile
index dc3b551976..91237a84d9 100644
--- a/tests/migration/Makefile
+++ b/tests/migration/Makefile
@@ -5,7 +5,7 @@
 # See the COPYING file in the top-level 

[Qemu-devel] [PULL 3/7] migration: Stop postcopy fault thread before notifying

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Ilya Maximets 

POSTCOPY_NOTIFY_INBOUND_END handlers will remove userfault fds
from the postcopy_remote_fds array which could be still in
use by the fault thread. Let's stop the thread before
notification to avoid possible accessing wrong memory.

Fixes: 46343570c06e ("vhost+postcopy: Wire up POSTCOPY_END notify")
Cc: qemu-sta...@nongnu.org
Signed-off-by: Ilya Maximets 
Message-Id: <20181008160536.6332-2-i.maxim...@samsung.com>
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Maxime Coquelin 
Signed-off-by: Dr. David Alan Gilbert 
---
 migration/postcopy-ram.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 853d8b32ca..e5c02a32c5 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -533,6 +533,12 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState 
*mis)
 if (mis->have_fault_thread) {
 Error *local_err = NULL;
 
+/* Let the fault thread quit */
+atomic_set(>fault_thread_quit, 1);
+postcopy_fault_thread_notify(mis);
+trace_postcopy_ram_incoming_cleanup_join();
+qemu_thread_join(>fault_thread);
+
 if (postcopy_notify(POSTCOPY_NOTIFY_INBOUND_END, _err)) {
 error_report_err(local_err);
 return -1;
@@ -541,11 +547,6 @@ int postcopy_ram_incoming_cleanup(MigrationIncomingState 
*mis)
 if (qemu_ram_foreach_migratable_block(cleanup_range, mis)) {
 return -1;
 }
-/* Let the fault thread quit */
-atomic_set(>fault_thread_quit, 1);
-postcopy_fault_thread_notify(mis);
-trace_postcopy_ram_incoming_cleanup_join();
-qemu_thread_join(>fault_thread);
 
 trace_postcopy_ram_incoming_cleanup_closeuf();
 close(mis->userfault_fd);
-- 
2.19.0




[Qemu-devel] [PULL 7/7] migration-test: Only generate a single target architecture

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Juan Quintela 

Several changes:
- We only allow generate header "inside" the tree.  Why?  Because we
  need to connit the result, so it makes no sense to generate them on
  the build dir.
- We only generate a single target each time.  Getting all the
  cross-compilers correctly is an impossible task.  So know you do:
 make -C tests/migration $target (native)
 make CROSS_PREFIX=foo- -C tests/migratiion $target (cross)
  And you are done.

- If we are building out of tree, we have no data about if we are
  cross-compile or whatever.  So instead of guess what is happening,
  just do what I pointed on previous point.

Signed-off-by: Juan Quintela 
Message-Id: <20180913132313.11370-1-quint...@redhat.com>
Signed-off-by: Dr. David Alan Gilbert 
---
 tests/migration/Makefile | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/tests/migration/Makefile b/tests/migration/Makefile
index ff726ed7dd..13e99b1692 100644
--- a/tests/migration/Makefile
+++ b/tests/migration/Makefile
@@ -9,6 +9,19 @@ TARGET_LIST = i386 aarch64 s390x
 
 SRC_PATH = ../..
 
+.PHONY: help $(TARGET_LIST)
+help:
+   @echo "Create migration guest includes.  We generate a binary."
+   @echo "And then convert that binary to an include file that can be"
+   @echo "run in a guest."
+   @echo "Possible operations are:"
+   @echo
+   @echo " $(MAKE) cleanRemove all intermediate files"
+   @echo " $(MAKE) target   Generate for that target"
+   @echo " $(MAKE) CROSS_PREFIX=... target"
+   @echo "  Cross-compile than target"
+   @echo " Possible targets are: $(TARGET_LIST)"
+
 override define __note
 /* This file is automatically generated from the assembly file in
  * tests/migration/$@. Edit that file and then run "make all"
@@ -18,16 +31,8 @@ override define __note
 endef
 export __note
 
-find-arch-cross-cc = $(lastword $(shell grep -h "CROSS_CC_GUEST=" $(wildcard 
$(SRC_PATH)/$(patsubst i386,*86*,$(1))-softmmu/config-target.mak) /dev/null))
-parse-cross-prefix = $(subst gcc,,$(patsubst cc,gcc,$(patsubst 
CROSS_CC_GUEST="%",%,$(call find-arch-cross-cc,$(1)
-gen-cross-prefix = $(patsubst %-,CROSS_PREFIX=%-,$(call 
parse-cross-prefix,$(1)))
-
-.PHONY: all $(TARGET_LIST)
-
-all: $(TARGET_LIST)
-
 $(TARGET_LIST):
-   $(MAKE) -C $@ $(call gen-cross-prefix,$@)
+   $(MAKE) CROSS_PREFIX=$(CROSS_PREFIX) -C $@
 
 clean:
for target in $(TARGET_LIST); do \
-- 
2.19.0




[Qemu-devel] [PULL 6/7] qmp, hmp: make subsystem/system-vendor identities optional

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: "Denis V. Lunev" 

According to PCI specification, subsystem id and subsystem vendor id
are present only in type 0 and type 2 headers (at different offsets),
but not in type 1 headers.

Thus we should make this data optional in struct PciDeviceId and skip
reporting them via HMP if the information is not available.

Additional (wrong information) about PCI bridges (Type1 devices) has been
added in 5383a705 and fortunately not released. This patch fixes that
problem. The problem was spotted by Markus.

Signed-off-by: Denis V. Lunev 
CC: "Dr. David Alan Gilbert" 
CC: Eric Blake 
CC: Markus Armbruster 
Message-Id: <20181002135538.12113-1-...@openvz.org>
Reported-by: Markus Armbruster 
Reviewed-by: Eric Blake 
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Markus Armbruster 
Signed-off-by: Dr. David Alan Gilbert 
---
 hmp.c  |  6 --
 hw/pci/pci.c   | 13 ++---
 qapi/misc.json |  4 ++--
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/hmp.c b/hmp.c
index 61ef120423..7828f93a39 100644
--- a/hmp.c
+++ b/hmp.c
@@ -837,8 +837,10 @@ static void hmp_info_pci_device(Monitor *mon, const 
PciDeviceInfo *dev)
 
 monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
dev->id->vendor, dev->id->device);
-monitor_printf(mon, "  PCI subsystem %04" PRIx64 ":%04" PRIx64 "\n",
-   dev->id->subsystem_vendor, dev->id->subsystem);
+if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) {
+monitor_printf(mon, "  PCI subsystem %04" PRIx64 ":%04" PRIx64 
"\n",
+   dev->id->subsystem_vendor, dev->id->subsystem);
+}
 
 if (dev->has_irq) {
 monitor_printf(mon, "  IRQ %" PRId64 ".\n", dev->irq);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 51d0dec466..b937f0dc0a 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1737,9 +1737,6 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice 
*dev, PCIBus *bus,
 info->id = g_new0(PciDeviceId, 1);
 info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
 info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
-info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
-info->id->subsystem_vendor =
-pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
 info->regions = qmp_query_pci_regions(dev);
 info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
 
@@ -1752,6 +1749,16 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice 
*dev, PCIBus *bus,
 if (type == PCI_HEADER_TYPE_BRIDGE) {
 info->has_pci_bridge = true;
 info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
+} else if (type == PCI_HEADER_TYPE_NORMAL) {
+info->id->has_subsystem = info->id->has_subsystem_vendor = true;
+info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
+info->id->subsystem_vendor =
+pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
+} else if (type == PCI_HEADER_TYPE_CARDBUS) {
+info->id->has_subsystem = info->id->has_subsystem_vendor = true;
+info->id->subsystem = pci_get_word(dev->config + PCI_CB_SUBSYSTEM_ID);
+info->id->subsystem_vendor =
+pci_get_word(dev->config + PCI_CB_SUBSYSTEM_VENDOR_ID);
 }
 
 return info;
diff --git a/qapi/misc.json b/qapi/misc.json
index f98de3a58c..3a68af9ca3 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -839,8 +839,8 @@
 # Since: 2.4
 ##
 { 'struct': 'PciDeviceId',
-  'data': {'device': 'int', 'vendor': 'int', 'subsystem': 'int',
-'subsystem-vendor': 'int'} }
+  'data': {'device': 'int', 'vendor': 'int', '*subsystem': 'int',
+'*subsystem-vendor': 'int'} }
 
 ##
 # @PciDeviceInfo:
-- 
2.19.0




[Qemu-devel] [PULL 5/7] vhost-user: Don't ask for reply on postcopy mem table set

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Ilya Maximets 

According to documentation, NEED_REPLY_MASK should not be set
for VHOST_USER_SET_MEM_TABLE request in postcopy mode.
This restriction was mistakenly applied to 'reply_supported'
variable, which is local and used only for non-postcopy case.

CC: Dr. David Alan Gilbert 
Fixes: 9bb38019942c ("vhost+postcopy: Send address back to qemu")
Signed-off-by: Ilya Maximets 
Message-Id: <20181002140947.4107-1-i.maxim...@samsung.com>
Reviewed-by: Maxime Coquelin 
Signed-off-by: Dr. David Alan Gilbert 
---
 hw/virtio/vhost-user.c | 13 +
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index ed47d645d9..e09bed0e4a 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -374,8 +374,6 @@ static int vhost_user_set_mem_table_postcopy(struct 
vhost_dev *dev,
 int fds[VHOST_MEMORY_MAX_NREGIONS];
 int i, fd;
 size_t fd_num = 0;
-bool reply_supported = virtio_has_feature(dev->protocol_features,
-  VHOST_USER_PROTOCOL_F_REPLY_ACK);
 VhostUserMsg msg_reply;
 int region_i, msg_i;
 
@@ -384,10 +382,6 @@ static int vhost_user_set_mem_table_postcopy(struct 
vhost_dev *dev,
 .hdr.flags = VHOST_USER_VERSION,
 };
 
-if (reply_supported) {
-msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
-}
-
 if (u->region_rb_len < dev->mem->nregions) {
 u->region_rb = g_renew(RAMBlock*, u->region_rb, dev->mem->nregions);
 u->region_rb_offset = g_renew(ram_addr_t, u->region_rb_offset,
@@ -503,10 +497,6 @@ static int vhost_user_set_mem_table_postcopy(struct 
vhost_dev *dev,
 return -1;
 }
 
-if (reply_supported) {
-return process_message_reply(dev, );
-}
-
 return 0;
 }
 
@@ -519,8 +509,7 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
 size_t fd_num = 0;
 bool do_postcopy = u->postcopy_listen && u->postcopy_fd.handler;
 bool reply_supported = virtio_has_feature(dev->protocol_features,
-  VHOST_USER_PROTOCOL_F_REPLY_ACK) &&
-  !do_postcopy;
+  VHOST_USER_PROTOCOL_F_REPLY_ACK);
 
 if (do_postcopy) {
 /* Postcopy has enough differences that it's best done in it's own
-- 
2.19.0




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

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

The following changes since commit 75e50c80e051423a6f55a34ee4a1eec842444a5b:

  Merge remote-tracking branch 'remotes/armbru/tags/pull-misc-2018-10-10' into 
staging (2018-10-11 10:43:37 +0100)

are available in the Git repository at:

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

for you to fetch changes up to 36bd9e3c8b049cb9124e04ed8bf8f9451d63de03:

  migration-test: Only generate a single target architecture (2018-10-11 
19:58:26 +0100)


Migration pull 2018-10-11

With one bonus HMP/PCI fix from Denis.


Denis V. Lunev (1):
  qmp, hmp: make subsystem/system-vendor identities optional

Ilya Maximets (3):
  migration: Stop postcopy fault thread before notifying
  vhost-user: Fix userfaultfd leak
  vhost-user: Don't ask for reply on postcopy mem table set

Juan Quintela (1):
  migration-test: Only generate a single target architecture

Thomas Huth (1):
  tests/migration: Enable the migration test on s390x, too

Wei Huang (1):
  tests: Add migration test for aarch64

 hmp.c|   6 +-
 hw/pci/pci.c |  13 +-
 hw/virtio/vhost-user.c   |  20 ++-
 migration/postcopy-ram.c |  11 +-
 qapi/misc.json   |   4 +-
 tests/Makefile.include   |   2 +
 tests/migration-test.c   |  51 ++-
 tests/migration/Makefile |  25 ++--
 tests/migration/aarch64/Makefile |  18 +++
 tests/migration/aarch64/a-b-kernel.S |  75 +++
 tests/migration/aarch64/a-b-kernel.h |  18 +++
 tests/migration/migration-test.h |  13 ++
 tests/migration/s390x/Makefile   |  24 
 tests/migration/s390x/a-b-bios.c |  36 +
 tests/migration/s390x/a-b-bios.h | 253 +++
 15 files changed, 531 insertions(+), 38 deletions(-)
 create mode 100644 tests/migration/aarch64/Makefile
 create mode 100644 tests/migration/aarch64/a-b-kernel.S
 create mode 100644 tests/migration/aarch64/a-b-kernel.h
 create mode 100644 tests/migration/s390x/Makefile
 create mode 100644 tests/migration/s390x/a-b-bios.c
 create mode 100644 tests/migration/s390x/a-b-bios.h



[Qemu-devel] [PULL 4/7] vhost-user: Fix userfaultfd leak

2018-10-11 Thread Dr. David Alan Gilbert (git)
From: Ilya Maximets 

'fd' received from the vhost side is never freed.
Also, everything (including 'postcopy_listen' state) should be
cleaned up on vhost cleanup.

Fixes: 46343570c06e ("vhost+postcopy: Wire up POSTCOPY_END notify")
Fixes: f82c11165ffa ("vhost+postcopy: Register shared ufd with postcopy")
Cc: qemu-sta...@nongnu.org
Signed-off-by: Ilya Maximets 
Message-Id: <20181008160536.6332-3-i.maxim...@samsung.com>
Reviewed-by: Dr. David Alan Gilbert 
Reviewed-by: Maxime Coquelin 
Signed-off-by: Dr. David Alan Gilbert 
---
 hw/virtio/vhost-user.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b041343632..ed47d645d9 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1291,6 +1291,7 @@ static int vhost_user_postcopy_end(struct vhost_dev *dev, 
Error **errp)
 return ret;
 }
 postcopy_unregister_shared_ufd(>postcopy_fd);
+close(u->postcopy_fd.fd);
 u->postcopy_fd.handler = NULL;
 
 trace_vhost_user_postcopy_end_exit();
@@ -1430,6 +1431,12 @@ static int vhost_user_backend_cleanup(struct vhost_dev 
*dev)
 postcopy_remove_notifier(>postcopy_notifier);
 u->postcopy_notifier.notify = NULL;
 }
+u->postcopy_listen = false;
+if (u->postcopy_fd.handler) {
+postcopy_unregister_shared_ufd(>postcopy_fd);
+close(u->postcopy_fd.fd);
+u->postcopy_fd.handler = NULL;
+}
 if (u->slave_fd >= 0) {
 qemu_set_fd_handler(u->slave_fd, NULL, NULL, NULL);
 close(u->slave_fd);
-- 
2.19.0




Re: [Qemu-devel] [PATCH] migration-test: Only generate a single target architecture

2018-10-11 Thread Dr. David Alan Gilbert
* Juan Quintela (quint...@redhat.com) wrote:
> Several changes:
> - We only allow generate header "inside" the tree.  Why?  Because we
>   need to connit the result, so it makes no sense to generate them on
>   the build dir.
> - We only generate a single target each time.  Getting all the
>   cross-compilers correctly is an impossible task.  So know you do:
>  make -C tests/migration $target (native)
>  make CROSS_PREFIX=foo- -C tests/migratiion $target (cross)
>   And you are done.
> 
> - If we are building out of tree, we have no data about if we are
>   cross-compile or whatever.  So instead of guess what is happening,
>   just do what I pointed on previous point.
> 
> Signed-off-by: Juan Quintela 


Reviewed-by: Dr. David Alan Gilbert 

and queued.


> ---
>  tests/migration/Makefile | 23 ++-
>  1 file changed, 14 insertions(+), 9 deletions(-)
> 
> diff --git a/tests/migration/Makefile b/tests/migration/Makefile
> index ff726ed7dd..13e99b1692 100644
> --- a/tests/migration/Makefile
> +++ b/tests/migration/Makefile
> @@ -9,6 +9,19 @@ TARGET_LIST = i386 aarch64 s390x
>  
>  SRC_PATH = ../..
>  
> +.PHONY: help $(TARGET_LIST)
> +help:
> + @echo "Create migration guest includes.  We generate a binary."
> + @echo "And then convert that binary to an include file that can be"
> + @echo "run in a guest."
> + @echo "Possible operations are:"
> + @echo
> + @echo " $(MAKE) cleanRemove all intermediate files"
> + @echo " $(MAKE) target   Generate for that target"
> + @echo " $(MAKE) CROSS_PREFIX=... target"
> + @echo "  Cross-compile than target"
> + @echo " Possible targets are: $(TARGET_LIST)"
> +
>  override define __note
>  /* This file is automatically generated from the assembly file in
>   * tests/migration/$@. Edit that file and then run "make all"
> @@ -18,16 +31,8 @@ override define __note
>  endef
>  export __note
>  
> -find-arch-cross-cc = $(lastword $(shell grep -h "CROSS_CC_GUEST=" $(wildcard 
> $(SRC_PATH)/$(patsubst i386,*86*,$(1))-softmmu/config-target.mak) /dev/null))
> -parse-cross-prefix = $(subst gcc,,$(patsubst cc,gcc,$(patsubst 
> CROSS_CC_GUEST="%",%,$(call find-arch-cross-cc,$(1)
> -gen-cross-prefix = $(patsubst %-,CROSS_PREFIX=%-,$(call 
> parse-cross-prefix,$(1)))
> -
> -.PHONY: all $(TARGET_LIST)
> -
> -all: $(TARGET_LIST)
> -
>  $(TARGET_LIST):
> - $(MAKE) -C $@ $(call gen-cross-prefix,$@)
> + $(MAKE) CROSS_PREFIX=$(CROSS_PREFIX) -C $@
>  
>  clean:
>   for target in $(TARGET_LIST); do \
> -- 
> 2.17.1
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH 1/1] qmp, hmp: make subsystem/system-vendor identities optional

2018-10-11 Thread Dr. David Alan Gilbert
* Markus Armbruster (arm...@redhat.com) wrote:
> "Denis V. Lunev"  writes:
> 
> > According to PCI specification subsystem id and subsystem vendor id are
> > optinal and could be abscent in Type1 header and can be found on
> > different offsets within Type0 and Type2 headers.
> 
> Well, they *are* absent in Type1 headers.  Perhaps:
> 
>   According to PCI specification, subsystem id and subsystem vendor id
>   are present only in type 0 and type 2 headers (at different offsets),
>   but not in type 1 headers.

Queued with that text.

> > Thus we should make this data optional in struct PciDeviceId and skip
> > reporting them via HMP if the information is not available.
> >
> > Additional (wrong information) about PCI bridges (Type1 devices) has been
> > added in 5383a705 and fortunately not released. This patch fixes that
> > problem. The problem was spotted by Markus.
> 
> A machine-readable way to phrase the last sentence is
> Reported-by: Markus Armbruster 
> 
> > Signed-off-by: Denis V. Lunev 
> > CC: "Dr. David Alan Gilbert" 
> > CC: Eric Blake 
> > CC: Markus Armbruster 
> > ---
> >  hmp.c  |  6 --
> >  hw/pci/pci.c   | 13 ++---
> >  qapi/misc.json |  4 ++--
> >  3 files changed, 16 insertions(+), 7 deletions(-)
> >
> > diff --git a/hmp.c b/hmp.c
> > index 3a9f797677..55633d29a3 100644
> > --- a/hmp.c
> > +++ b/hmp.c
> > @@ -824,8 +824,10 @@ static void hmp_info_pci_device(Monitor *mon, const 
> > PciDeviceInfo *dev)
> >  
> >  monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
> > dev->id->vendor, dev->id->device);
> > -monitor_printf(mon, "  PCI subsystem %04" PRIx64 ":%04" PRIx64 
> > "\n",
> > -   dev->id->subsystem_vendor, dev->id->subsystem);
> > +if (dev->id->has_subsystem_vendor && dev->id->has_subsystem) {
> > +monitor_printf(mon, "  PCI subsystem %04" PRIx64 ":%04" PRIx64 
> > "\n",
> > +   dev->id->subsystem_vendor, dev->id->subsystem);
> > +}
> >  
> >  if (dev->has_irq) {
> >  monitor_printf(mon, "  IRQ %" PRId64 ".\n", dev->irq);
> > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > index 51d0dec466..b937f0dc0a 100644
> > --- a/hw/pci/pci.c
> > +++ b/hw/pci/pci.c
> > @@ -1737,9 +1737,6 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice 
> > *dev, PCIBus *bus,
> >  info->id = g_new0(PciDeviceId, 1);
> >  info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
> >  info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
> > -info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
> > -info->id->subsystem_vendor =
> > -pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
> >  info->regions = qmp_query_pci_regions(dev);
> >  info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
> >  
> > @@ -1752,6 +1749,16 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice 
> > *dev, PCIBus *bus,
> >  if (type == PCI_HEADER_TYPE_BRIDGE) {
> >  info->has_pci_bridge = true;
> >  info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
> > +} else if (type == PCI_HEADER_TYPE_NORMAL) {
> > +info->id->has_subsystem = info->id->has_subsystem_vendor = true;
> > +info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
> > +info->id->subsystem_vendor =
> > +pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
> > +} else if (type == PCI_HEADER_TYPE_CARDBUS) {
> > +info->id->has_subsystem = info->id->has_subsystem_vendor = true;
> > +info->id->subsystem = pci_get_word(dev->config + 
> > PCI_CB_SUBSYSTEM_ID);
> > +info->id->subsystem_vendor =
> > +pci_get_word(dev->config + PCI_CB_SUBSYSTEM_VENDOR_ID);
> >  }
> >  
> >  return info;
> > diff --git a/qapi/misc.json b/qapi/misc.json
> > index ada9af5add..95a6ed022d 100644
> > --- a/qapi/misc.json
> > +++ b/qapi/misc.json
> > @@ -839,8 +839,8 @@
> >  # Since: 2.4
> >  ##
> >  { 'struct': 'PciDeviceId',
> > -  'data': {'device': 'int', 'vendor': 'int', 'subsystem': 'int',
> > -'subsystem-vendor': 'int'} }
> > +  'data': {'device': 'int', 'vendor': 'int', '*subsystem': 'int',
> > +'*subsystem-vendor': 'int'} }
> 
> 'uint16' would match PCI, but I since we didn't for @device and @vendor,
> we probably shouldn't for @subsystem and @subsystem-vendor.
> 
> >  
> >  ##
> >  # @PciDeviceInfo:
> 
> With Eric's spelling corrections or my rephrasing of the commit message:
> Reviewed-by: Markus Armbruster 
> 
> David, would you like to pick this up?
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH 28/31] fsdev: Clean up error reporting in qemu_fsdev_add()

2018-10-11 Thread Markus Armbruster
Eric Blake  writes:

> On 10/8/18 12:31 PM, Markus Armbruster wrote:
>> Calling error_report() from within a a function that takes an Error **
>
> s/a a/a/

Fixing, thanks!

>> argument is suspicious.  qemu_fsdev_add() does that, and its caller
>> fsdev_init_func() then fails without setting an error.  Its caller
>> main(), via qemu_opts_foreach(), is fine with it, but clean it up
>> anyway.
>>



Re: [Qemu-devel] [PATCH v2 00/11] net: convert SysBus init method to a realize method

2018-10-11 Thread Eduardo Habkost
On Wed, Oct 10, 2018 at 03:30:25PM +0200, Philippe Mathieu-Daudé wrote:
> Cc'ing Eduardo since it might make sens to have this series go via his
> machine-next tree, rather than Jason's net tree.

Queued on machine-next, thanks!

> 
> On 01/10/2018 08:37, Cédric Le Goater wrote:
> > Hello,
> > 
> > Here is my take to the SysBus init to realize method conversion. I
> > picked the /net directory and did them all. Also added a couple of
> > reset methods in separate patches.
> > 
> > make check tested
> > 
> > Thanks,
> > 
> > C.
> > 
> > Changes since v1:
> > 
> >  - dropped changes in lan9118_init() and smc91c111_init()
> >  - fix alignment in milkymist_minimac2_realize()
> >  - improved etraxfs reset method
> >  
> > 
> > Cédric Le Goater (11):
> >   net: etraxfs_eth: convert SysBus init method to a realize method
> >   net: etraxfs_eth: add a reset method
> >   net: lan9118: convert SysBus init method to a realize method
> >   net: lance: convert SysBus init method to a realize method
> >   net: milkymist_minimac2: convert SysBus init method to a realize
> > method
> >   net: mipsnet: convert SysBus init method to a realize method
> >   net: opencores_eth: convert SysBus init method to a realize method
> >   net: smc91c111: convert SysBus init method to a realize method
> >   net: stellaris_enet: convert SysBus init method to a realize method
> >   net: stellaris_enet: add a reset method
> >   net: xgmac: convert SysBus init method to a realize method
> > 
> >  hw/net/etraxfs_eth.c| 44 ++---
> >  hw/net/lan9118.c|  9 +++-
> >  hw/net/lance.c  |  8 +++
> >  hw/net/milkymist-minimac2.c |  9 +++-
> >  hw/net/mipsnet.c|  9 +++-
> >  hw/net/opencores_eth.c  |  8 +++
> >  hw/net/smc91c111.c  |  8 +++
> >  hw/net/stellaris_enet.c | 15 ++---
> >  hw/net/xgmac.c  |  9 +++-
> >  9 files changed, 59 insertions(+), 60 deletions(-)
> > 
> 

-- 
Eduardo



Re: [Qemu-devel] [PATCH 24/31] vl: Clean up error reporting in vnc_init_func()

2018-10-11 Thread Markus Armbruster
Markus Armbruster  writes:

> Calling error_report() in a function that takes an Error ** argument
> is suspicious.  vnc_init_func() does that, and then fails without
> setting an error.  Its caller main(), via qemu_opts_foreach(), is fine
> with it, but clean it up anyway.
>
> Cc: Gerd Hoffmann 
> Signed-off-by: Markus Armbruster 
> ---
>  ui/vnc.c | 5 +++--
>  vl.c | 2 +-
>  2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/ui/vnc.c b/ui/vnc.c
> index cf221c83cc..df6c84b802 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -4082,8 +4082,9 @@ int vnc_init_func(void *opaque, QemuOpts *opts, Error 
> **errp)
>  vnc_display_init(id);

My patch is incomplete, there's fprintf(stderr, ...); exit(1); hiding
behind vnc_display_init().  See my review of "[PATCH RFC v5 2/7]
ui/vnc.c: polish vnc_init_func"
https://lists.nongnu.org/archive/html/qemu-devel/2018-10/msg02238.html
Message-ID: <87h8hs4oe3@dusky.pond.sub.org>


>  vnc_display_open(id, _err);
>  if (local_err != NULL) {
> -error_reportf_err(local_err, "Failed to start VNC server: ");
> -exit(1);
> +error_propagate(errp, local_err);
> +error_prepend(errp, "Failed to start VNC server: ");
> +return -1;
>  }
>  return 0;
>  }
> diff --git a/vl.c b/vl.c
> index 86eee4c798..5c159ca45c 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -4479,7 +4479,7 @@ int main(int argc, char **argv, char **envp)
>  /* init remote displays */
>  #ifdef CONFIG_VNC
>  qemu_opts_foreach(qemu_find_opts("vnc"),
> -  vnc_init_func, NULL, NULL);
> +  vnc_init_func, NULL, _fatal);
>  #endif
>  
>  if (using_spice) {



  1   2   3   4   >