[Qemu-devel] [PATCH v5] target-arm: Make the counter tick relative to cntfrq

2019-09-11 Thread Andrew Jeffery
Allow machines to configure CNTFRQ via a property if the ARM core
supports the generic timer. This is necessary on e.g. the ASPEED AST2600
SoC where the generic timer clock is run at 800MHz or above. The default
value for CNTFRQ remains at 62.50MHz (based on GTIMER_SCALE).

CNTFRQ is a read-as-written co-processor register; the property sets the
register's initial value which is used during realize() to configure the
QEMUTimers that back the generic timers. Beyond that the firmware can to
do whatever it sees fit with the CNTFRQ register though changes to the
value will not be reflected in the timers' rate.

I've tested this using an out-of-tree AST2600 SoC model (Cortex-A7) with
the SDK u-boot that sets CNTFRQ as appropriate, and by starting/running
machines with assorted ARM CPUs (palmetto-bmc with the ARM926EJ-S,
romulus-bmc with the ARM1176 and raspi2 with the Cortex-A53).

Signed-off-by: Andrew Jeffery 
---
v5: Remove unrelated submodule updates that snuck into v4

v4: https://patchwork.ozlabs.org/patch/1161340/
Fix configuration for cores without a generic timer

v3: https://patchwork.ozlabs.org/patch/1160634/
Peter - I think this addresses most of your feedback. I still reach into
the QEMUTimer to fetch out scale when adjusting the nexttick
calculation, but we no longer need to update the scale member and force
a recalculation of the period.

v2: https://patchwork.ozlabs.org/patch/1144389/
Signed-off-by: Andrew Jeffery 
---
 target/arm/cpu.c| 43 +++
 target/arm/cpu.h|  3 +++
 target/arm/helper.c | 30 ++
 3 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2399c144718d..8b63a27761bb 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -40,6 +40,8 @@
 #include "disas/capstone.h"
 #include "fpu/softfloat.h"
 
+#include 
+
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -976,6 +978,10 @@ static void arm_cpu_initfn(Object *obj)
 }
 }
 
+static Property arm_cpu_gt_cntfrq_property =
+DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq,
+   (1000 * 1000 * 1000) / GTIMER_SCALE);
+
 static Property arm_cpu_reset_cbar_property =
 DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
 
@@ -1172,6 +1178,11 @@ void arm_cpu_post_init(Object *obj)
 
 qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
  &error_abort);
+
+if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
+qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property,
+ &error_abort);
+}
 }
 
 static void arm_cpu_finalizefn(Object *obj)
@@ -1238,14 +1249,30 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
-cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-   arm_gt_ptimer_cb, cpu);
-cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-   arm_gt_vtimer_cb, cpu);
-cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-  arm_gt_htimer_cb, cpu);
-cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-  arm_gt_stimer_cb, cpu);
+
+{
+uint64_t scale;
+
+if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
+if (!cpu->gt_cntfrq) {
+error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
+   cpu->gt_cntfrq);
+return;
+}
+scale = MAX(1, NANOSECONDS_PER_SECOND / cpu->gt_cntfrq);
+} else {
+scale = GTIMER_SCALE;
+}
+
+cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+   arm_gt_ptimer_cb, cpu);
+cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+   arm_gt_vtimer_cb, cpu);
+cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+  arm_gt_htimer_cb, cpu);
+cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+  arm_gt_stimer_cb, cpu);
+}
 #endif
 
 cpu_exec_realizefn(cs, &local_err);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 297ad5e47ad8..8bd576f834ba 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -915,6 +915,9 @@ struct ARMCPU {
 
 /* Used to set the maximum vector length the cpu will support.  */
 uint32_t sve_max_vq;
+
+/* Used to configure the generic timer input clock */
+uint64_t gt_cntfrq;
 };
 
 void arm_cpu_post_init(Object *obj);
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 507026c9154b..09975

Re: [Qemu-devel] [PULL 15/36] memory: fix race between TCG and accesses to dirty bitmap

2019-09-11 Thread Pavel Dovgalyuk
Ping.


Pavel Dovgalyuk

> -Original Message-
> From: dovgaluk [mailto:dovga...@ispras.ru]
> Sent: Monday, August 26, 2019 3:19 PM
> To: Paolo Bonzini; pavel.dovga...@ispras.ru
> Cc: qemu-devel@nongnu.org; Qemu-devel
> Subject: Re: [Qemu-devel] [PULL 15/36] memory: fix race between TCG and 
> accesses to dirty
> bitmap
> 
> This patch breaks the execution recording.
> While vCPU tries to lock replay mutex in main while loop,
> vga causes dirty memory sync and do_run_on_cpu call.
> This call waits for vCPU to process the work queue.
> 
> Pavel Dovgalyuk
> 
> Paolo Bonzini писал 2019-08-20 09:59:
> > There is a race between TCG and accesses to the dirty log:
> >
> >   vCPU thread  reader thread
> >   ---  ---
> >   TLB check -> slow path
> > notdirty_mem_write
> >   write to RAM
> >   set dirty flag
> >clear dirty flag
> >   TLB check -> fast path
> >read memory
> > write to RAM
> >
> > Fortunately, in order to fix it, no change is required to the
> > vCPU thread.  However, the reader thread must delay the read after
> > the vCPU thread has finished the write.  This can be approximated
> > conservatively by run_on_cpu, which waits for the end of the current
> > translation block.
> >
> > A similar technique is used by KVM, which has to do a synchronous TLB
> > flush after doing a test-and-clear of the dirty-page flags.
> >
> > Reported-by: Dr. David Alan Gilbert 
> > Signed-off-by: Paolo Bonzini 
> > ---
> >  exec.c| 31 +++
> >  include/exec/memory.h | 12 
> >  memory.c  | 10 +-
> >  migration/ram.c   |  1 +
> >  4 files changed, 53 insertions(+), 1 deletion(-)
> >
> > diff --git a/exec.c b/exec.c
> > index 3e78de3..ae68f72 100644
> > --- a/exec.c
> > +++ b/exec.c
> > @@ -198,6 +198,7 @@ typedef struct subpage_t {
> >
> >  static void io_mem_init(void);
> >  static void memory_map_init(void);
> > +static void tcg_log_global_after_sync(MemoryListener *listener);
> >  static void tcg_commit(MemoryListener *listener);
> >
> >  static MemoryRegion io_mem_watch;
> > @@ -906,6 +907,7 @@ void cpu_address_space_init(CPUState *cpu, int
> > asidx,
> >  newas->cpu = cpu;
> >  newas->as = as;
> >  if (tcg_enabled()) {
> > +newas->tcg_as_listener.log_global_after_sync =
> > tcg_log_global_after_sync;
> >  newas->tcg_as_listener.commit = tcg_commit;
> >  memory_listener_register(&newas->tcg_as_listener, as);
> >  }
> > @@ -3143,6 +3145,35 @@ void
> > address_space_dispatch_free(AddressSpaceDispatch *d)
> >  g_free(d);
> >  }
> >
> > +static void do_nothing(CPUState *cpu, run_on_cpu_data d)
> > +{
> > +}
> > +
> > +static void tcg_log_global_after_sync(MemoryListener *listener)
> > +{while (1) {
>  qemu_mutex_unlock_iothread();
>  replay_mutex_lock();
>  qemu_mutex_lock_i
> > +CPUAddressSpace *cpuas;
> > +
> > +/* Wait for the CPU to end the current TB.  This avoids the
> > following
> > + * incorrect race:
> > + *
> > + *  vCPU migration
> > + *  --   -
> > + *  TLB check -> slow path
> > + *notdirty_mem_write
> > + *  write to RAM
> > + *  mark dirty
> > + *   clear dirty flag
> > + *  TLB check -> fast path
> > + *   read memory
> > + *write to RAM
> > + *
> > + * by pushing the migration thread's memory read after the vCPU
> > thread has
> > + * written the memory.
> > + */
> > +cpuas = container_of(listener, CPUAddressSpace, tcg_as_listener);
> > +run_on_cpu(cpuas->cpu, do_nothing, RUN_ON_CPU_NULL);
> > +}
> > +
> >  static void tcg_commit(MemoryListener *listener)
> >  {
> >  CPUAddressSpace *cpuas;
> > diff --git a/include/exec/memory.h b/include/exec/memory.h
> > index bb0961d..b6bcf31 100644
> > --- a/include/exec/memory.h
> > +++ b/include/exec/memory.h
> > @@ -419,6 +419,7 @@ struct MemoryListener {
> >  void (*log_clear)(MemoryListener *listener, MemoryRegionSection
> > *section);
> >  void (*log_global_start)(MemoryListener *listener);
> >  void (*log_global_stop)(MemoryListener *listener);
> > +void (*log_global_after_sync)(MemoryListener *listener);
> >  void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection
> > *section,
> >  bool match_data, uint64_t data, EventNotifier
> > *e);
> >  void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection
> > *section,
> > @@ -1682,6 +1683,17 @@ MemoryRegionSection
> > memory_region_find(MemoryRegion *mr,
> >  void memory_global_dirty_log_sync(void);
> >
> >  /**
> > + * memory_global_dirty_log_sync: synchronize 

[Qemu-devel] TCG plugins and the GPL (was: [PATCH v4 00/54] plugins for TCG)

2019-09-11 Thread Markus Armbruster
Alex Bennée  writes:

> Markus Armbruster  writes:
[...]
>> Please advise why TCG plugins don't undermine the GPL.  Any proposal to
>> add a plugin interface needs to do that.
>
> I'm not sure what we can say about this apart from "ask your lawyer".

I'm not asking for a legal argument, I'm asking for a pragmatic one.

> I'm certainly not proposing we add any sort of language about what
> should and shouldn't be allowed to use the plugin interface. I find it
> hard to see how anyone could argue code written to interface with the
> plugin API couldn't be considered a derived work.

What makes that so?  Is writing a plugin without linking with QEMU code
impractical?

> There are two use cases I have in mind:
>
> The first is FLOSS developers writing interesting tools that can take
> advantage of QEMU's control of the system to do experiments that are
> tricky with other setups (Valgrind is limited to same-arch, Dynamo/Pin
> are user-space only). I want these experiments to be easy to do without
> having to keep hacking and re-hacking QEMU's core code. I would hope
> QEMU developers would up-stream theirs into the QEMU source tree but I
> can imagine academics will have open source code that will only ever sit
> in their paper's repository.

GPL'ed code that's not for upstream is 100% legitimate.

> The other is users who currently maintain hacked up internal copies of
> QEMU as a test bed for whatever piece of silicon they are brewing behind
> closed doors. This code would never be distributed (hence never be a GPL
> issue)

Correct.  We can't force anybody to distribute, and that's only proper.

>and is generally kept private because it's IP sensitive
> (e.g: experimenting with different cache models). If we can provide an
> interface that allows them to keep their experiments private and
> separate from changes to the core code then maybe apart from making
> their lives a bit easier we will see some non-IP sensitive contributions
> come back to the upstream. I live in hope ;-)

I'm concerned about a third case: imlementing stuff as a plugin so you
can distribute it with a GPL-incompatible license.  Particularly
pernicious when that stuff could be useful upstream.

Are there any technical difficulties that could make distributing a
plugins in binary form impractical?



Re: [Qemu-devel] [PATCH] nbd/server: attach client channel to the export's AioContext

2019-09-11 Thread Sergio Lopez

Eric Blake  writes:

> On 9/11/19 12:21 PM, Eric Blake wrote:
>> On 9/11/19 11:15 AM, Sergio Lopez wrote:
>>> On creation, the export's AioContext is set to the same one as the
>>> BlockBackend, while the AioContext in the client QIOChannel is left
>>> untouched.
>>>
>>> As a result, when using data-plane, nbd_client_receive_next_request()
>>> schedules coroutines in the IOThread AioContext, while the client's
>>> QIOChannel is serviced from the main_loop, potentially triggering the
>>> assertion at qio_channel_restart_[read|write].
>>>
>>> To fix this, as soon we have the export corresponding to the client,
>>> we call qio_channel_attach_aio_context() to attach the QIOChannel
>>> context to the export's AioContext. This matches with the logic in
>>> blk_aio_attached().
>>>
>>> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1748253
>>> Signed-off-by: Sergio Lopez 
>>> ---
>>>  nbd/server.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>> 
>> I'd like a second opinion from Kevin, but the description makes sense to
>> me.  I'm happy to queue this through my NBD tree.
>> 
>> Reviewed-by: Eric Blake 
>
> I tried to test this patch, but even with it applied, I still got an
> aio-context crasher by attempting an nbd-server-start, nbd-server-add,
> nbd-server-stop (intentionally skipping the nbd-server-remove step) on a
> domain using iothreads, with a backtrace of:
>
> #0  0x7ff09d070e35 in raise () from target:/lib64/libc.so.6
> #1  0x7ff09d05b895 in abort () from target:/lib64/libc.so.6
> #2  0x55dd03b9ab86 in error_exit (err=1, msg=0x55dd03d59fb0
> <__func__.15769> "qemu_mutex_unlock_impl")
> at util/qemu-thread-posix.c:36
> #3  0x55dd03b9adcf in qemu_mutex_unlock_impl (mutex=0x55dd062d5090,
> file=0x55dd03d59041 "util/async.c",
> line=523) at util/qemu-thread-posix.c:96
> #4  0x55dd03b93433 in aio_context_release (ctx=0x55dd062d5030) at
> util/async.c:523
> #5  0x55dd03ac421b in bdrv_do_drained_begin (bs=0x55dd0673a2d0,
> recursive=false, parent=0x0,
> ignore_bds_parents=false, poll=true) at block/io.c:428
> #6  0x55dd03ac4299 in bdrv_drained_begin (bs=0x55dd0673a2d0) at
> block/io.c:434
> #7  0x55dd03aafb54 in blk_drain (blk=0x55dd06a3ec40) at
> block/block-backend.c:1605
> #8  0x55dd03aae054 in blk_remove_bs (blk=0x55dd06a3ec40) at
> block/block-backend.c:800
> #9  0x55dd03aad54a in blk_delete (blk=0x55dd06a3ec40) at
> block/block-backend.c:420
> #10 0x55dd03aad7d6 in blk_unref (blk=0x55dd06a3ec40) at
> block/block-backend.c:475
> #11 0x55dd03aecb68 in nbd_export_put (exp=0x55dd0726f920) at
> nbd/server.c:1666
> #12 0x55dd03aec8fe in nbd_export_close (exp=0x55dd0726f920) at
> nbd/server.c:1616
> #13 0x55dd03aecbf1 in nbd_export_close_all () at nbd/server.c:1689
> #14 0x55dd03748845 in qmp_nbd_server_stop (errp=0x7ffcdf3cb4e8) at
> blockdev-nbd.c:233
> ...
>
> Does that sound familiar to what you were seeing?  Does it mean we
> missed another spot where the context is set incorrectly?

It looks like it was trying to release the AioContext while it was still
held by some other thread. Is this stacktrace from the main thread or an
iothread? What was the other one doing?

> I'm happy to work with you on IRC for more real-time debugging of this
> (I'm woefully behind on understanding how aio contexts are supposed to
> work).

I must be missing some step, because I can't reproduce this one
here. I've tried both with an idle NDB server and one with a client
generating I/O. Is it reproducible 100% of them time?

Sergio.


signature.asc
Description: PGP signature


Re: [Qemu-devel] [PATCH v11 00/11] Build ACPI Heterogeneous Memory Attribute Table (HMAT)

2019-09-11 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20190912053638.4858-1-tao3...@intel.com/



Hi,

This series failed the docker-quick@centos7 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

=== TEST SCRIPT BEGIN ===
#!/bin/bash
make docker-image-centos7 V=1 NETWORK=1
time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1
=== TEST SCRIPT END ===

libudev   no
default devices   yes

warning: Python 2 support is deprecated
warning: Python 3 will be required for building future versions of QEMU

NOTE: cross-compilers enabled:  'cc'
  GEN x86_64-softmmu/config-devices.mak.tmp
---
Looking for expected file 'tests/data/acpi/pc/SRAT.acpihmat'
Looking for expected file 'tests/data/acpi/pc/SRAT'
**
ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: 
assertion failed: (exp_sdt.aml_file)
ERROR - Bail out! 
ERROR:/tmp/qemu-test/src/tests/bios-tables-test.c:327:load_expected_aml: 
assertion failed: (exp_sdt.aml_file)
make: *** [check-qtest-x86_64] Error 1
make: *** Waiting for unfinished jobs
  TESTiotest-qcow2: 036


The full log is available at
http://patchew.org/logs/20190912053638.4858-1-tao3...@intel.com/testing.docker-quick@centos7/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

[Qemu-devel] [PATCH v24 07/22] target/rx: RX disassembler

2019-09-11 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 
Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-5-ys...@users.sourceforge.jp>
Signed-off-by: Richard Henderson 
---
 include/disas/dis-asm.h |5 +
 target/rx/disas.c   | 1480 +++
 2 files changed, 1485 insertions(+)
 create mode 100644 target/rx/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index e9c7dd8eb4..a900bd0a27 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -226,6 +226,10 @@ enum bfd_architecture
 #define bfd_mach_nios2r22
   bfd_arch_lm32,   /* Lattice Mico32 */
 #define bfd_mach_lm32 1
+  bfd_arch_rx,   /* Renesas RX */
+#define bfd_mach_rx0x75
+#define bfd_mach_rx_v2 0x76
+#define bfd_mach_rx_v3 0x77
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -433,6 +437,7 @@ int print_insn_little_nios2 (bfd_vma, 
disassemble_info*);
 int print_insn_xtensa   (bfd_vma, disassemble_info*);
 int print_insn_riscv32  (bfd_vma, disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
+int print_insn_rx(bfd_vma, disassemble_info *);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/target/rx/disas.c b/target/rx/disas.c
new file mode 100644
index 00..8cada4825d
--- /dev/null
+++ b/target/rx/disas.c
@@ -0,0 +1,1480 @@
+/*
+ * Renesas RX Disassembler
+ *
+ * Copyright (c) 2019 Yoshinori Sato 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+
+typedef struct DisasContext {
+disassemble_info *dis;
+uint32_t addr;
+uint32_t pc;
+} DisasContext;
+
+
+static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
+   int i, int n)
+{
+bfd_byte buf;
+while (++i <= n) {
+ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
+insn |= buf << (32 - i * 8);
+}
+return insn;
+}
+
+static int32_t li(DisasContext *ctx, int sz)
+{
+int32_t addr;
+bfd_byte buf[4];
+addr = ctx->addr;
+
+switch (sz) {
+case 1:
+ctx->addr += 1;
+ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+return (int8_t)buf[0];
+case 2:
+ctx->addr += 2;
+ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+return ldsw_le_p(buf);
+case 3:
+ctx->addr += 3;
+ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
+return (int8_t)buf[2] << 16 | lduw_le_p(buf);
+case 0:
+ctx->addr += 4;
+ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
+return ldl_le_p(buf);
+default:
+g_assert_not_reached();
+}
+}
+
+static int bdsp_s(DisasContext *ctx, int d)
+{
+/*
+ * 0 -> 8
+ * 1 -> 9
+ * 2 -> 10
+ * 3 -> 3
+ * :
+ * 7 -> 7
+ */
+if (d < 3) {
+d += 8;
+}
+return d;
+}
+
+/* Include the auto-generated decoder.  */
+#include "decode.inc.c"
+
+#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+
+#define RX_MEMORY_BYTE 0
+#define RX_MEMORY_WORD 1
+#define RX_MEMORY_LONG 2
+
+#define RX_IM_BYTE 0
+#define RX_IM_WORD 1
+#define RX_IM_LONG 2
+#define RX_IM_UWORD 3
+
+static const char size[] = {'b', 'w', 'l'};
+static const char cond[][4] = {
+"eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
+"ge", "lt", "gt", "le", "o", "no", "ra", "f"
+};
+static const char psw[] = {
+'c', 'z', 's', 'o', 0, 0, 0, 0,
+'i', 'u', 0, 0, 0, 0, 0, 0,
+};
+
+static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+{
+bfd_byte buf[2];
+switch (ld) {
+case 0:
+return 0;
+case 1:
+ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
+ctx->addr += 1;
+return ((uint8_t)buf[0]) << size;
+case 2:
+ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
+ctx->addr += 2;
+return lduw_le_p(buf) << size;
+}
+g_assert_not_reached();
+}
+
+static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+{
+int dsp;
+static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
+if (ld < 3) {
+switch (mi) {
+case 4:
+/* dsp[rs].ub */
+dsp = rx_index_addr(ld, RX_MEMORY

Re: [Qemu-devel] [PATCH v4] target-arm: Make the counter tick relative to cntfrq

2019-09-11 Thread Cédric Le Goater
On 12/09/2019 05:25, Andrew Jeffery wrote:
> Allow machines to configure CNTFRQ via a property if the ARM core
> supports the generic timer. This is necessary on e.g. the ASPEED AST2600
> SoC where the generic timer clock is run at 800MHz or above. The default
> value for CNTFRQ remains at 62.50MHz (based on GTIMER_SCALE).
> 
> CNTFRQ is a read-as-written co-processor register; the property sets the
> register's initial value which is used during realize() to configure the
> QEMUTimers that back the generic timers. Beyond that the firmware can to
> do whatever it sees fit with the CNTFRQ register though changes to the
> value will not be reflected in the timers' rate.
> 
> I've tested this using an out-of-tree AST2600 SoC model (Cortex-A7) with
> the SDK u-boot that sets CNTFRQ as appropriate, and by starting/running
> machines with assorted ARM CPUs (palmetto-bmc with the ARM926EJ-S,
> romulus-bmc with the ARM1176 and raspi2 with the Cortex-A53).
> 
> Signed-off-by: Andrew Jeffery 
> ---
> v4: Fix configuration for cores without a generic timer
> 
> v3: https://patchwork.ozlabs.org/patch/1160634/
> Peter - I think this addresses most of your feedback. I still reach into
> the QEMUTimer to fetch out scale when adjusting the nexttick
> calculation, but we no longer need to update the scale member and force
> a recalculation of the period.
> 
> v2: https://patchwork.ozlabs.org/patch/1144389/
> ---
>  roms/SLOF   |  2 +-
>  roms/skiboot|  2 +-
>  target/arm/cpu.c| 43 +++
>  target/arm/cpu.h|  3 +++
>  target/arm/helper.c | 30 ++
>  5 files changed, 66 insertions(+), 14 deletions(-)
> 
> diff --git a/roms/SLOF b/roms/SLOF
> index 7bfe584e3219..ea221600a116 16
> --- a/roms/SLOF
> +++ b/roms/SLOF
> @@ -1 +1 @@
> -Subproject commit 7bfe584e321946771692711ff83ad2b5850daca7
> +Subproject commit ea221600a116883137ef90b2b7ab7d2472bc4f10
> diff --git a/roms/skiboot b/roms/skiboot
> index 261ca8e779e5..3a6fdede6ce1 16
> --- a/roms/skiboot
> +++ b/roms/skiboot
> @@ -1 +1 @@
> -Subproject commit 261ca8e779e5138869a45f174caa49be6a274501
> +Subproject commit 3a6fdede6ce117facec0108afe716cf5d0472c3f


The changes above seem not related.

C. 


> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 2399c144718d..8b63a27761bb 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -40,6 +40,8 @@
>  #include "disas/capstone.h"
>  #include "fpu/softfloat.h"
>  
> +#include 
> +
>  static void arm_cpu_set_pc(CPUState *cs, vaddr value)
>  {
>  ARMCPU *cpu = ARM_CPU(cs);
> @@ -976,6 +978,10 @@ static void arm_cpu_initfn(Object *obj)
>  }
>  }
>  
> +static Property arm_cpu_gt_cntfrq_property =
> +DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq,
> +   (1000 * 1000 * 1000) / GTIMER_SCALE);
> +
>  static Property arm_cpu_reset_cbar_property =
>  DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
>  
> @@ -1172,6 +1178,11 @@ void arm_cpu_post_init(Object *obj)
>  
>  qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
>   &error_abort);
> +
> +if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
> +qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property,
> + &error_abort);
> +}
>  }
>  
>  static void arm_cpu_finalizefn(Object *obj)
> @@ -1238,14 +1249,30 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
> **errp)
>  }
>  }
>  
> -cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
> -   arm_gt_ptimer_cb, cpu);
> -cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
> -   arm_gt_vtimer_cb, cpu);
> -cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
> -  arm_gt_htimer_cb, cpu);
> -cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
> -  arm_gt_stimer_cb, cpu);
> +
> +{
> +uint64_t scale;
> +
> +if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
> +if (!cpu->gt_cntfrq) {
> +error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
> +   cpu->gt_cntfrq);
> +return;
> +}
> +scale = MAX(1, NANOSECONDS_PER_SECOND / cpu->gt_cntfrq);
> +} else {
> +scale = GTIMER_SCALE;
> +}
> +
> +cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
> +   arm_gt_ptimer_cb, cpu);
> +cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
> +   arm_gt_vtimer_cb, cpu);
> +cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
> +  

[Qemu-devel] [PATCH v24 17/22] hw/rx: RX Target hardware definition

2019-09-11 Thread Yoshinori Sato
rx62n - RX62N cpu.
rx-virt - RX QEMU virtual target.

v23 changes.
Add missing includes.

v21 changes.
rx_load_image move to rx-virt.c

Signed-off-by: Yoshinori Sato 

Message-Id: <20190616142836.10614-17-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-9-ys...@users.sourceforge.jp>
Signed-off-by: Richard Henderson 
[PMD: Use TYPE_RX62N_CPU, use #define for RX62N_NR_TMR/CMT/SCI,
 renamed CPU -> MCU, device -> microcontroller]
Signed-off-by: Philippe Mathieu-Daudé 
---
v19: Fixed typo (Peter Maydell)
Signed-off-by: Yoshinori Sato 
---
 include/hw/rx/rx.h|   7 ++
 include/hw/rx/rx62n.h |  91 
 hw/rx/rx-virt.c   | 127 ++
 hw/rx/rx62n.c | 239 ++
 hw/rx/Kconfig |  14 +++
 hw/rx/Makefile.objs   |   2 +
 6 files changed, 480 insertions(+)
 create mode 100644 include/hw/rx/rx.h
 create mode 100644 include/hw/rx/rx62n.h
 create mode 100644 hw/rx/rx-virt.c
 create mode 100644 hw/rx/rx62n.c
 create mode 100644 hw/rx/Kconfig
 create mode 100644 hw/rx/Makefile.objs

diff --git a/include/hw/rx/rx.h b/include/hw/rx/rx.h
new file mode 100644
index 00..ff5924b81f
--- /dev/null
+++ b/include/hw/rx/rx.h
@@ -0,0 +1,7 @@
+#ifndef QEMU_RX_H
+#define QEMU_RX_H
+/* Definitions for RX board emulation.  */
+
+#include "target/rx/cpu-qom.h"
+
+#endif
diff --git a/include/hw/rx/rx62n.h b/include/hw/rx/rx62n.h
new file mode 100644
index 00..97ea8ddb8e
--- /dev/null
+++ b/include/hw/rx/rx62n.h
@@ -0,0 +1,91 @@
+/*
+ * RX62N MCU Object
+ *
+ * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
+ * (Rev.1.40 R01UH0033EJ0140)
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef HW_RX_RX62N_H
+#define HW_RX_RX62N_H
+
+#include "hw/sysbus.h"
+#include "hw/intc/rx_icu.h"
+#include "hw/timer/renesas_tmr.h"
+#include "hw/timer/renesas_cmt.h"
+#include "hw/char/renesas_sci.h"
+#include "target/rx/cpu.h"
+#include "qemu/units.h"
+
+#define TYPE_RX62N "rx62n"
+#define RX62N(obj) OBJECT_CHECK(RX62NState, (obj), TYPE_RX62N)
+
+#define RX62N_NR_TMR2
+#define RX62N_NR_CMT2
+#define RX62N_NR_SCI6
+
+typedef struct RX62NState {
+SysBusDevice parent_obj;
+
+RXCPU cpu;
+RXICUState icu;
+RTMRState tmr[RX62N_NR_TMR];
+RCMTState cmt[RX62N_NR_CMT];
+RSCIState sci[RX62N_NR_SCI];
+
+MemoryRegion *sysmem;
+bool kernel;
+
+MemoryRegion iram;
+MemoryRegion iomem1;
+MemoryRegion d_flash;
+MemoryRegion iomem2;
+MemoryRegion iomem3;
+MemoryRegion c_flash;
+qemu_irq irq[NR_IRQS];
+} RX62NState;
+
+/*
+ * RX62N Peripheral Address
+ * See users manual section 5
+ */
+#define RX62N_ICUBASE 0x00087000
+#define RX62N_TMRBASE 0x00088200
+#define RX62N_CMTBASE 0x00088000
+#define RX62N_SCIBASE 0x00088240
+
+/*
+ * RX62N Peripheral IRQ
+ * See users manual section 11
+ */
+#define RX62N_TMR_IRQBASE 174
+#define RX62N_CMT_IRQBASE 28
+#define RX62N_SCI_IRQBASE 214
+
+/*
+ * RX62N Internal Memory
+ * It is the value of R5F562N8.
+ * Please change the size for R5F562N7.
+ */
+#define RX62N_IRAM_BASE 0x
+#define RX62N_IRAM_SIZE (96 * KiB)
+#define RX62N_DFLASH_BASE 0x0010
+#define RX62N_DFLASH_SIZE (32 * KiB)
+#define RX62N_CFLASH_BASE 0xfff8
+#define RX62N_CFLASH_SIZE (512 * KiB)
+
+#define RX62N_PCLK (48 * 1000 * 1000)
+#endif
diff --git a/hw/rx/rx-virt.c b/hw/rx/rx-virt.c
new file mode 100644
index 00..4cfe2e3123
--- /dev/null
+++ b/hw/rx/rx-virt.c
@@ -0,0 +1,127 @@
+/*
+ * RX QEMU virtual platform
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#i

[Qemu-devel] [PATCH v24 15/22] hw/timer: RX62N internal timer modules

2019-09-11 Thread Yoshinori Sato
renesas_tmr: 8bit timer modules.
renesas_cmt: 16bit compare match timer modules.
This part use many renesas's CPU.
Hardware manual.
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf

Signed-off-by: Yoshinori Sato 
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-7-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/timer/renesas_cmt.h |  38 +++
 include/hw/timer/renesas_tmr.h |  53 
 hw/timer/renesas_cmt.c | 278 
 hw/timer/renesas_tmr.c | 458 +
 hw/timer/Kconfig   |   6 +
 hw/timer/Makefile.objs |   3 +
 6 files changed, 836 insertions(+)
 create mode 100644 include/hw/timer/renesas_cmt.h
 create mode 100644 include/hw/timer/renesas_tmr.h
 create mode 100644 hw/timer/renesas_cmt.c
 create mode 100644 hw/timer/renesas_tmr.c

diff --git a/include/hw/timer/renesas_cmt.h b/include/hw/timer/renesas_cmt.h
new file mode 100644
index 00..acd25c6e0b
--- /dev/null
+++ b/include/hw/timer/renesas_cmt.h
@@ -0,0 +1,38 @@
+/*
+ * Renesas Compare-match timer Object
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This code is licensed under the GPL version 2 or later.
+ *
+ */
+
+#ifndef HW_RENESAS_CMT_H
+#define HW_RENESAS_CMT_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_RENESAS_CMT "renesas-cmt"
+#define RCMT(obj) OBJECT_CHECK(RCMTState, (obj), TYPE_RENESAS_CMT)
+
+enum {
+CMT_CH = 2,
+CMT_NR_IRQ = 1 * CMT_CH,
+};
+
+typedef struct RCMTState {
+SysBusDevice parent_obj;
+
+uint64_t input_freq;
+MemoryRegion memory;
+
+uint16_t cmstr;
+uint16_t cmcr[CMT_CH];
+uint16_t cmcnt[CMT_CH];
+uint16_t cmcor[CMT_CH];
+int64_t tick[CMT_CH];
+qemu_irq cmi[CMT_CH];
+QEMUTimer *timer[CMT_CH];
+} RCMTState;
+
+#endif
diff --git a/include/hw/timer/renesas_tmr.h b/include/hw/timer/renesas_tmr.h
new file mode 100644
index 00..5787004c74
--- /dev/null
+++ b/include/hw/timer/renesas_tmr.h
@@ -0,0 +1,53 @@
+/*
+ * Renesas 8bit timer Object
+ *
+ * Copyright (c) 2018 Yoshinori Sato
+ *
+ * This code is licensed under the GPL version 2 or later.
+ *
+ */
+
+#ifndef HW_RENESAS_TMR_H
+#define HW_RENESAS_TMR_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_RENESAS_TMR "renesas-tmr"
+#define RTMR(obj) OBJECT_CHECK(RTMRState, (obj), TYPE_RENESAS_TMR)
+
+enum timer_event {
+cmia = 0,
+cmib = 1,
+ovi = 2,
+none = 3,
+TMR_NR_EVENTS = 4
+};
+
+enum {
+TMR_CH = 2,
+TMR_NR_IRQ = 3 * TMR_CH,
+};
+
+typedef struct RTMRState {
+SysBusDevice parent_obj;
+
+uint64_t input_freq;
+MemoryRegion memory;
+
+uint8_t tcnt[TMR_CH];
+uint8_t tcora[TMR_CH];
+uint8_t tcorb[TMR_CH];
+uint8_t tcr[TMR_CH];
+uint8_t tccr[TMR_CH];
+uint8_t tcor[TMR_CH];
+uint8_t tcsr[TMR_CH];
+int64_t tick;
+int64_t div_round[TMR_CH];
+enum timer_event next[TMR_CH];
+qemu_irq cmia[TMR_CH];
+qemu_irq cmib[TMR_CH];
+qemu_irq ovi[TMR_CH];
+QEMUTimer *timer[TMR_CH];
+} RTMRState;
+
+#endif
diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c
new file mode 100644
index 00..5d57c447b8
--- /dev/null
+++ b/hw/timer/renesas_cmt.c
@@ -0,0 +1,278 @@
+/*
+ * Renesas 16bit Compare-match timer
+ *
+ * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
+ * (Rev.1.40 R01UH0033EJ0140)
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "qemu/timer.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/qdev-properties.h"
+#include "hw/timer/renesas_cmt.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+
+/*
+ *  +0 CMSTR - common control
+ *  +2 CMCR  - ch0
+ *  +4 CMCNT - ch0
+ *  +6 CMCOR - ch0
+ *  +8 CMCR  - ch1
+ * +10 CMCNT - ch1
+ * +12 CMCOR - ch1
+ * If we think that the address of CH 0 has an offset of +2,
+ * we can treat it with the same address as CH 1, so define it like that.
+ */
+REG16(CMSTR, 0)
+  FIELD(CMSTR, STR0, 0, 1)
+  FIELD(CMSTR, STR1, 1, 1)
+  FIELD(CMSTR, STR,  0, 2)
+/* This addeess is channel offset */
+REG16(CMCR, 0)
+  FIELD(CMCR, CKS, 0, 2)
+  FIELD(CMCR, CMIE, 6, 

[Qemu-devel] [PATCH v24 16/22] hw/char: RX62N serial communication interface (SCI)

2019-09-11 Thread Yoshinori Sato
This module supported only non FIFO type.
Hardware manual.
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf

Signed-off-by: Yoshinori Sato 
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-8-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/char/renesas_sci.h |  45 +
 hw/char/renesas_sci.c | 343 ++
 hw/char/Kconfig   |   3 +
 hw/char/Makefile.objs |   1 +
 4 files changed, 392 insertions(+)
 create mode 100644 include/hw/char/renesas_sci.h
 create mode 100644 hw/char/renesas_sci.c

diff --git a/include/hw/char/renesas_sci.h b/include/hw/char/renesas_sci.h
new file mode 100644
index 00..50d1336944
--- /dev/null
+++ b/include/hw/char/renesas_sci.h
@@ -0,0 +1,45 @@
+/*
+ * Renesas Serial Communication Interface
+ *
+ * Copyright (c) 2018 Yoshinori Sato
+ *
+ * This code is licensed under the GPL version 2 or later.
+ *
+ */
+
+#include "chardev/char-fe.h"
+#include "qemu/timer.h"
+#include "hw/sysbus.h"
+
+#define TYPE_RENESAS_SCI "renesas-sci"
+#define RSCI(obj) OBJECT_CHECK(RSCIState, (obj), TYPE_RENESAS_SCI)
+
+enum {
+ERI = 0,
+RXI = 1,
+TXI = 2,
+TEI = 3,
+SCI_NR_IRQ = 4,
+};
+
+typedef struct {
+SysBusDevice parent_obj;
+MemoryRegion memory;
+
+uint8_t smr;
+uint8_t brr;
+uint8_t scr;
+uint8_t tdr;
+uint8_t ssr;
+uint8_t rdr;
+uint8_t scmr;
+uint8_t semr;
+
+uint8_t read_ssr;
+int64_t trtime;
+int64_t rx_next;
+QEMUTimer *timer;
+CharBackend chr;
+uint64_t input_freq;
+qemu_irq irq[SCI_NR_IRQ];
+} RSCIState;
diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c
new file mode 100644
index 00..df63c5292e
--- /dev/null
+++ b/hw/char/renesas_sci.c
@@ -0,0 +1,343 @@
+/*
+ * Renesas Serial Communication Interface
+ *
+ * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
+ * (Rev.1.40 R01UH0033EJ0140)
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/qdev-properties.h"
+#include "hw/char/renesas_sci.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+
+/* SCI register map */
+REG8(SMR, 0)
+  FIELD(SMR, CKS,  0, 2)
+  FIELD(SMR, MP,   2, 1)
+  FIELD(SMR, STOP, 3, 1)
+  FIELD(SMR, PM,   4, 1)
+  FIELD(SMR, PE,   5, 1)
+  FIELD(SMR, CHR,  6, 1)
+  FIELD(SMR, CM,   7, 1)
+REG8(BRR, 1)
+REG8(SCR, 2)
+  FIELD(SCR, CKE, 0, 2)
+  FIELD(SCR, TEIE, 2, 1)
+  FIELD(SCR, MPIE, 3, 1)
+  FIELD(SCR, RE,   4, 1)
+  FIELD(SCR, TE,   5, 1)
+  FIELD(SCR, RIE,  6, 1)
+  FIELD(SCR, TIE,  7, 1)
+REG8(TDR, 3)
+REG8(SSR, 4)
+  FIELD(SSR, MPBT, 0, 1)
+  FIELD(SSR, MPB,  1, 1)
+  FIELD(SSR, TEND, 2, 1)
+  FIELD(SSR, ERR, 3, 3)
+FIELD(SSR, PER,  3, 1)
+FIELD(SSR, FER,  4, 1)
+FIELD(SSR, ORER, 5, 1)
+  FIELD(SSR, RDRF, 6, 1)
+  FIELD(SSR, TDRE, 7, 1)
+REG8(RDR, 5)
+REG8(SCMR, 6)
+  FIELD(SCMR, SMIF, 0, 1)
+  FIELD(SCMR, SINV, 2, 1)
+  FIELD(SCMR, SDIR, 3, 1)
+  FIELD(SCMR, BCP2, 7, 1)
+REG8(SEMR, 7)
+  FIELD(SEMR, ACS0, 0, 1)
+  FIELD(SEMR, ABCS, 4, 1)
+
+static int can_receive(void *opaque)
+{
+RSCIState *sci = RSCI(opaque);
+if (sci->rx_next > qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) {
+return 0;
+} else {
+return FIELD_EX8(sci->scr, SCR, RE);
+}
+}
+
+static void receive(void *opaque, const uint8_t *buf, int size)
+{
+RSCIState *sci = RSCI(opaque);
+sci->rx_next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + sci->trtime;
+if (FIELD_EX8(sci->ssr, SSR, RDRF) || size > 1) {
+sci->ssr = FIELD_DP8(sci->ssr, SSR, ORER, 1);
+if (FIELD_EX8(sci->scr, SCR, RIE)) {
+qemu_set_irq(sci->irq[ERI], 1);
+}
+} else {
+sci->rdr = buf[0];
+sci->ssr = FIELD_DP8(sci->ssr, SSR, RDRF, 1);
+if (FIELD_EX8(sci->scr, SCR, RIE)) {
+qemu_irq_pulse(sci->irq[RXI]);
+}
+}
+}
+
+static void send_byte(RSCIState *sci)
+{
+if (qemu_chr_fe_backend_connected(&sci->chr)) {
+qemu_chr_fe_write_all(&sci->chr, &sci->tdr, 1);
+}
+timer_mod(sci->timer,
+ 

Re: [Qemu-devel] [PATCH v4] target-arm: Make the counter tick relative to cntfrq

2019-09-11 Thread Andrew Jeffery



On Thu, 12 Sep 2019, at 15:52, Cédric Le Goater wrote:
> On 12/09/2019 05:25, Andrew Jeffery wrote:
> > Allow machines to configure CNTFRQ via a property if the ARM core
> > supports the generic timer. This is necessary on e.g. the ASPEED AST2600
> > SoC where the generic timer clock is run at 800MHz or above. The default
> > value for CNTFRQ remains at 62.50MHz (based on GTIMER_SCALE).
> > 
> > CNTFRQ is a read-as-written co-processor register; the property sets the
> > register's initial value which is used during realize() to configure the
> > QEMUTimers that back the generic timers. Beyond that the firmware can to
> > do whatever it sees fit with the CNTFRQ register though changes to the
> > value will not be reflected in the timers' rate.
> > 
> > I've tested this using an out-of-tree AST2600 SoC model (Cortex-A7) with
> > the SDK u-boot that sets CNTFRQ as appropriate, and by starting/running
> > machines with assorted ARM CPUs (palmetto-bmc with the ARM926EJ-S,
> > romulus-bmc with the ARM1176 and raspi2 with the Cortex-A53).
> > 
> > Signed-off-by: Andrew Jeffery 
> > ---
> > v4: Fix configuration for cores without a generic timer
> > 
> > v3: https://patchwork.ozlabs.org/patch/1160634/
> > Peter - I think this addresses most of your feedback. I still reach into
> > the QEMUTimer to fetch out scale when adjusting the nexttick
> > calculation, but we no longer need to update the scale member and force
> > a recalculation of the period.
> > 
> > v2: https://patchwork.ozlabs.org/patch/1144389/
> > ---
> >  roms/SLOF   |  2 +-
> >  roms/skiboot|  2 +-
> >  target/arm/cpu.c| 43 +++
> >  target/arm/cpu.h|  3 +++
> >  target/arm/helper.c | 30 ++
> >  5 files changed, 66 insertions(+), 14 deletions(-)
> > 
> > diff --git a/roms/SLOF b/roms/SLOF
> > index 7bfe584e3219..ea221600a116 16
> > --- a/roms/SLOF
> > +++ b/roms/SLOF
> > @@ -1 +1 @@
> > -Subproject commit 7bfe584e321946771692711ff83ad2b5850daca7
> > +Subproject commit ea221600a116883137ef90b2b7ab7d2472bc4f10
> > diff --git a/roms/skiboot b/roms/skiboot
> > index 261ca8e779e5..3a6fdede6ce1 16
> > --- a/roms/skiboot
> > +++ b/roms/skiboot
> > @@ -1 +1 @@
> > -Subproject commit 261ca8e779e5138869a45f174caa49be6a274501
> > +Subproject commit 3a6fdede6ce117facec0108afe716cf5d0472c3f
> 
> 
> The changes above seem not related.

How did they get in there? :eyeroll:

Thanks. v5 I guess.

Andrew



[Qemu-devel] [PATCH v24 14/22] hw/intc: RX62N interrupt controller (ICUa)

2019-09-11 Thread Yoshinori Sato
This implementation supported only ICUa.
Hardware manual.
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01uh0033ej0140_rx62n.pdf

Signed-off-by: Yoshinori Sato 
Reviewed-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-6-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/hw/intc/rx_icu.h |  56 ++
 hw/intc/rx_icu.c | 379 +++
 hw/intc/Kconfig  |   3 +
 hw/intc/Makefile.objs|   1 +
 4 files changed, 439 insertions(+)
 create mode 100644 include/hw/intc/rx_icu.h
 create mode 100644 hw/intc/rx_icu.c

diff --git a/include/hw/intc/rx_icu.h b/include/hw/intc/rx_icu.h
new file mode 100644
index 00..acfcf06aef
--- /dev/null
+++ b/include/hw/intc/rx_icu.h
@@ -0,0 +1,56 @@
+#ifndef RX_ICU_H
+#define RX_ICU_H
+
+#include "qemu-common.h"
+#include "hw/irq.h"
+
+enum TRG_MODE {
+TRG_LEVEL = 0,
+TRG_NEDGE = 1,  /* Falling */
+TRG_PEDGE = 2,  /* Raising */
+TRG_BEDGE = 3,  /* Both */
+};
+
+struct IRQSource {
+enum TRG_MODE sense;
+int level;
+};
+
+enum {
+/* Software interrupt request */
+SWI = 27,
+NR_IRQS = 256,
+};
+
+struct RXICUState {
+SysBusDevice parent_obj;
+
+MemoryRegion memory;
+struct IRQSource src[NR_IRQS];
+char *icutype;
+uint32_t nr_irqs;
+uint32_t *map;
+uint32_t nr_sense;
+uint32_t *init_sense;
+
+uint8_t ir[NR_IRQS];
+uint8_t dtcer[NR_IRQS];
+uint8_t ier[NR_IRQS / 8];
+uint8_t ipr[142];
+uint8_t dmasr[4];
+uint16_t fir;
+uint8_t nmisr;
+uint8_t nmier;
+uint8_t nmiclr;
+uint8_t nmicr;
+int req_irq;
+qemu_irq _irq;
+qemu_irq _fir;
+qemu_irq _swi;
+};
+typedef struct RXICUState RXICUState;
+
+#define TYPE_RXICU "rx-icu"
+#define RXICU(obj) OBJECT_CHECK(RXICUState, (obj), TYPE_RXICU)
+
+#endif /* RX_ICU_H */
diff --git a/hw/intc/rx_icu.c b/hw/intc/rx_icu.c
new file mode 100644
index 00..ac4dcbfe37
--- /dev/null
+++ b/hw/intc/rx_icu.c
@@ -0,0 +1,379 @@
+/*
+ * RX Interrupt Control Unit
+ *
+ * Warning: Only ICUa is supported.
+ *
+ * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
+ * (Rev.1.40 R01UH0033EJ0140)
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "hw/sysbus.h"
+#include "hw/registerfields.h"
+#include "hw/qdev-properties.h"
+#include "hw/intc/rx_icu.h"
+#include "migration/vmstate.h"
+#include "qemu/error-report.h"
+
+REG8(IR, 0)
+  FIELD(IR, IR,  0, 1)
+REG8(DTCER, 0x100)
+  FIELD(DTCER, DTCE,  0, 1)
+REG8(IER, 0x200)
+REG8(SWINTR, 0x2e0)
+  FIELD(SWINTR, SWINT, 0, 1)
+REG16(FIR, 0x2f0)
+  FIELD(FIR, FVCT, 0, 8)
+  FIELD(FIR, FIEN, 15, 1)
+REG8(IPR, 0x300)
+  FIELD(IPR, IPR, 0, 4)
+REG8(DMRSR, 0x400)
+REG8(IRQCR, 0x500)
+  FIELD(IRQCR, IRQMD, 2, 2)
+REG8(NMISR, 0x580)
+  FIELD(NMISR, NMIST, 0, 1)
+  FIELD(NMISR, LVDST, 1, 1)
+  FIELD(NMISR, OSTST, 2, 1)
+REG8(NMIER, 0x581)
+  FIELD(NMIER, NMIEN, 0, 1)
+  FIELD(NMIER, LVDEN, 1, 1)
+  FIELD(NMIER, OSTEN, 2, 1)
+REG8(NMICLR, 0x582)
+  FIELD(NMICLR, NMICLR, 0, 1)
+  FIELD(NMICLR, OSTCLR, 2, 1)
+REG8(NMICR, 0x583)
+  FIELD(NMICR, NMIMD, 3, 1)
+
+#define request(icu, n) (icu->ipr[icu->map[n]] << 8 | n)
+
+static void set_irq(RXICUState *icu, int n_IRQ, int req)
+{
+if ((icu->fir & R_FIR_FIEN_MASK) &&
+(icu->fir & R_FIR_FVCT_MASK) == n_IRQ) {
+qemu_set_irq(icu->_fir, req);
+} else {
+qemu_set_irq(icu->_irq, req);
+}
+}
+
+static void rxicu_request(RXICUState *icu, int n_IRQ)
+{
+int enable;
+
+enable = icu->ier[n_IRQ / 8] & (1 << (n_IRQ & 7));
+if (n_IRQ > 0 && enable != 0 && atomic_read(&icu->req_irq) < 0) {
+atomic_set(&icu->req_irq, n_IRQ);
+set_irq(icu, n_IRQ, request(icu, n_IRQ));
+}
+}
+
+static void rxicu_set_irq(void *opaque, int n_IRQ, int level)
+{
+RXICUState *icu = opaque;
+struct IRQSource *src;
+int issue;
+
+if (n_IRQ >= NR_IRQS) {
+error_report("%s: IRQ %d out of range", __func__, n_IRQ);
+return;
+}
+
+src = &icu->src[n_IRQ];
+
+level = (level != 0);
+switch (src->sense) {
+case TRG_LEVEL:
+/* level-sen

[Qemu-devel] [PATCH v24 20/22] Add rx-softmmu

2019-09-11 Thread Yoshinori Sato
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-17-ys...@users.sourceforge.jp>
Signed-off-by: Richard Henderson 
pick ed65c02993 target/rx: Add RX to SysEmuTarget
pick 01372568ae tests: Add rx to machine-none-test.c
[PMD: Squashed patches from Richard Henderson modifying
  qapi/common.json and tests/machine-none-test.c]
Signed-off-by: Philippe Mathieu-Daudé 
---
 configure  | 8 
 default-configs/rx-softmmu.mak | 3 +++
 include/exec/poison.h  | 1 +
 include/sysemu/arch_init.h | 1 +
 arch_init.c| 2 ++
 tests/machine-none-test.c  | 1 +
 hw/Kconfig | 1 +
 7 files changed, 17 insertions(+)
 create mode 100644 default-configs/rx-softmmu.mak

diff --git a/configure b/configure
index 95134c0180..30ffde1788 100755
--- a/configure
+++ b/configure
@@ -7607,6 +7607,11 @@ case "$target_name" in
 gdb_xml_files="riscv-64bit-cpu.xml riscv-64bit-fpu.xml riscv-64bit-csr.xml"
 target_compiler=$cross_cc_riscv64
   ;;
+  rx)
+TARGET_ARCH=rx
+bflt="yes"
+target_compiler=$cross_cc_rx
+  ;;
   sh4|sh4eb)
 TARGET_ARCH=sh4
 bflt="yes"
@@ -7830,6 +7835,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   riscv*)
 disas_config "RISCV"
   ;;
+  rx)
+disas_config "RX"
+  ;;
   s390*)
 disas_config "S390"
   ;;
diff --git a/default-configs/rx-softmmu.mak b/default-configs/rx-softmmu.mak
new file mode 100644
index 00..a3eecefb11
--- /dev/null
+++ b/default-configs/rx-softmmu.mak
@@ -0,0 +1,3 @@
+# Default configuration for rx-softmmu
+
+CONFIG_RX_VIRT=y
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 955eb863ab..7b9ac361dc 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -26,6 +26,7 @@
 #pragma GCC poison TARGET_PPC
 #pragma GCC poison TARGET_PPC64
 #pragma GCC poison TARGET_ABI32
+#pragma GCC poison TARGET_RX
 #pragma GCC poison TARGET_S390X
 #pragma GCC poison TARGET_SH4
 #pragma GCC poison TARGET_SPARC
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index 62c6fe4cf1..6c011acc52 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -24,6 +24,7 @@ enum {
 QEMU_ARCH_NIOS2 = (1 << 17),
 QEMU_ARCH_HPPA = (1 << 18),
 QEMU_ARCH_RISCV = (1 << 19),
+QEMU_ARCH_RX = (1 << 20),
 };
 
 extern const uint32_t arch_type;
diff --git a/arch_init.c b/arch_init.c
index 0a1531124c..7a37fb2c34 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -73,6 +73,8 @@ int graphic_depth = 32;
 #define QEMU_ARCH QEMU_ARCH_PPC
 #elif defined(TARGET_RISCV)
 #define QEMU_ARCH QEMU_ARCH_RISCV
+#elif defined(TARGET_RX)
+#define QEMU_ARCH QEMU_ARCH_RX
 #elif defined(TARGET_S390X)
 #define QEMU_ARCH QEMU_ARCH_S390X
 #elif defined(TARGET_SH4)
diff --git a/tests/machine-none-test.c b/tests/machine-none-test.c
index 5953d31755..8bb54a6360 100644
--- a/tests/machine-none-test.c
+++ b/tests/machine-none-test.c
@@ -56,6 +56,7 @@ static struct arch2cpu cpus_map[] = {
 { "hppa", "hppa" },
 { "riscv64", "rv64gcsu-v1.10.0" },
 { "riscv32", "rv32gcsu-v1.9.1" },
+{ "rx", "rx62n" },
 };
 
 static const char *get_cpu_model_by_arch(const char *arch)
diff --git a/hw/Kconfig b/hw/Kconfig
index b45db3c813..77bbc59cc7 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -54,6 +54,7 @@ source nios2/Kconfig
 source openrisc/Kconfig
 source ppc/Kconfig
 source riscv/Kconfig
+source rx/Kconfig
 source s390x/Kconfig
 source sh4/Kconfig
 source sparc/Kconfig
-- 
2.20.1




[Qemu-devel] [PATCH v24 21/22] BootLinuxConsoleTest: Test the RX-Virt machine

2019-09-11 Thread Yoshinori Sato
From: Philippe Mathieu-Daudé 

Add two tests for the rx-virt machine, based on the recommended test
setup from Yoshinori Sato:
https://lists.gnu.org/archive/html/qemu-devel/2019-05/msg03586.html

- U-Boot prompt
- Linux kernel with Sash shell

These are very quick tests:

  $ avocado run -t arch:rx tests/acceptance/boot_linux_console.py
  JOB ID : 84a6ef01c0b87975ecbfcb31a920afd735753ace
  JOB LOG: 
/home/phil/avocado/job-results/job-2019-05-24T05.02-84a6ef0/job.log
   (1/2) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_rx_uboot: 
PASS (0.11 s)
   (2/2) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_rx_linux: 
PASS (0.45 s)
  RESULTS: PASS 2 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | 
CANCEL 0

Tests can also be run with:

  $ avocado --show=console run -t arch:rx tests/acceptance/boot_linux_console.py
  console: U-Boot 2016.05-rc3-23705-ga1ef3c71cb-dirty (Feb 05 2019 - 21:56:06 
+0900)
  console: Linux version 4.19.0+ (yo-satoh@yo-satoh-debian) (gcc version 9.0.0 
20181105 (experimental) (GCC)) #137 Wed Feb 20 23:20:02 JST 2019
  console: Built 1 zonelists, mobility grouping on.  Total pages: 8128
  ...
  console: SuperH (H)SCI(F) driver initialized
  console: 88240.serial: ttySC0 at MMIO 0x88240 (irq = 215, base_baud = 0) is a 
sci
  console: console [ttySC0] enabled
  console: 88248.serial: ttySC1 at MMIO 0x88248 (irq = 219, base_baud = 0) is a 
sci

Signed-off-by: Philippe Mathieu-Daudé 
---
Based-on: 20190517045136.3509-1-richard.hender...@linaro.org
"RX architecture support"
Signed-off-by: Yoshinori Sato 
---
 tests/acceptance/boot_linux_console.py | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/tests/acceptance/boot_linux_console.py 
b/tests/acceptance/boot_linux_console.py
index 2504ef0150..8309687778 100644
--- a/tests/acceptance/boot_linux_console.py
+++ b/tests/acceptance/boot_linux_console.py
@@ -373,3 +373,49 @@ class BootLinuxConsole(Test):
 self.vm.launch()
 console_pattern = 'Kernel command line: %s' % kernel_command_line
 self.wait_for_console_pattern(console_pattern)
+
+def test_rx_uboot(self):
+"""
+:avocado: tags=arch:rx
+:avocado: tags=machine:rx-virt
+:avocado: tags=endian:little
+"""
+uboot_url = ('https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz')
+uboot_hash = '9b78dbd43b40b2526848c0b1ce9de02c24f4dcdb'
+uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)
+uboot_path = archive.uncompress(uboot_path, self.workdir)
+
+self.vm.set_machine('rx-virt')
+self.vm.set_console()
+self.vm.add_args('-bios', uboot_path,
+ '-no-reboot')
+self.vm.launch()
+uboot_version = 'U-Boot 2016.05-rc3-23705-ga1ef3c71cb-dirty'
+self.wait_for_console_pattern(uboot_version)
+gcc_version = 'rx-unknown-linux-gcc (GCC) 9.0.0 20181105 
(experimental)'
+# FIXME limit baudrate on chardev, else we type too fast
+#self.exec_command_and_wait_for_pattern('version', gcc_version)
+
+def test_rx_linux(self):
+"""
+:avocado: tags=arch:rx
+:avocado: tags=machine:rx-virt
+:avocado: tags=endian:little
+"""
+dtb_url = ('https://acc.dl.osdn.jp/users/23/23887/rx-qemu.dtb')
+dtb_hash = '7b4e4e2c71905da44e86ce47adee2210b026ac18'
+dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash)
+kernel_url = ('http://acc.dl.osdn.jp/users/23/23845/zImage')
+kernel_hash = '39a81067f8d72faad90866ddfefa19165d68fc99'
+kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
+
+self.vm.set_machine('rx-virt')
+self.vm.set_console()
+kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'earlycon'
+self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-no-reboot')
+self.vm.launch()
+self.wait_for_console_pattern('Sash command shell (version 1.1.1)')
+self.exec_command_and_wait_for_pattern('printenv',
+   'TERM=linux')
-- 
2.20.1




[Qemu-devel] [PATCH v24 09/22] target/rx: Replace operand with prt_ldmi in disassembler

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

This has consistency with prt_ri().  It loads all data before
beginning output.  It uses exactly one call to prt() to emit
the full instruction.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-20-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 77 +--
 1 file changed, 27 insertions(+), 50 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 64342537ee..515b365528 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -135,18 +135,18 @@ static void rx_index_addr(DisasContext *ctx, char out[8], 
int ld, int mi)
 sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
 }
 
-static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+static void prt_ldmi(DisasContext *ctx, const char *insn,
+ int ld, int mi, int rs, int rd)
 {
 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
 char dsp[8];
 
 if (ld < 3) {
 rx_index_addr(ctx, dsp, ld, mi);
-prt("%s[r%d]%s", dsp, rs, sizes[mi]);
+prt("%s\t%s[r%d]%s, r%d", insn, dsp, rs, sizes[mi], rd);
 } else {
-prt("r%d", rs);
+prt("%s\tr%d, r%d", insn, rs, rd);
 }
-prt(", r%d", rd);
 }
 
 static void prt_ir(DisasContext *ctx, const char *insn, int imm, int rd)
@@ -416,8 +416,7 @@ static bool trans_AND_ir(DisasContext *ctx, arg_AND_ir *a)
 /* and rs,rd */
 static bool trans_AND_mr(DisasContext *ctx, arg_AND_mr *a)
 {
-prt("and\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "and", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -440,8 +439,7 @@ static bool trans_OR_ir(DisasContext *ctx, arg_OR_ir *a)
 /* or rs,rd */
 static bool trans_OR_mr(DisasContext *ctx, arg_OR_mr *a)
 {
-prt("or\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "or", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -463,8 +461,7 @@ static bool trans_XOR_ir(DisasContext *ctx, arg_XOR_ir *a)
 /* xor rs,rd */
 static bool trans_XOR_mr(DisasContext *ctx, arg_XOR_mr *a)
 {
-prt("xor\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "xor", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -479,8 +476,7 @@ static bool trans_TST_ir(DisasContext *ctx, arg_TST_ir *a)
 /* tst rs, rd */
 static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
 {
-prt("tst\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "tst", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -548,8 +544,7 @@ static bool trans_ADD_irr(DisasContext *ctx, arg_ADD_irr *a)
 /* add dsp[rs], rd */
 static bool trans_ADD_mr(DisasContext *ctx, arg_ADD_mr *a)
 {
-prt("add\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "add", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -573,8 +568,7 @@ static bool trans_CMP_ir(DisasContext *ctx, arg_CMP_ir *a)
 /* cmp dsp[rs], rs2 */
 static bool trans_CMP_mr(DisasContext *ctx, arg_CMP_mr *a)
 {
-prt("cmp\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "cmp", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -589,8 +583,7 @@ static bool trans_SUB_ir(DisasContext *ctx, arg_SUB_ir *a)
 /* sub dsp[rs], rd */
 static bool trans_SUB_mr(DisasContext *ctx, arg_SUB_mr *a)
 {
-prt("sub\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "sub", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -611,8 +604,7 @@ static bool trans_SBB_rr(DisasContext *ctx, arg_SBB_rr *a)
 /* sbb dsp[rs], rd */
 static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
 {
-prt("sbb\t");
-operand(ctx, a->ld, RX_IM_LONG, a->rs, a->rd);
+prt_ldmi(ctx, "sbb", a->ld, RX_IM_LONG, a->rs, a->rd);
 return true;
 }
 
@@ -640,8 +632,7 @@ static bool trans_MAX_ir(DisasContext *ctx, arg_MAX_ir *a)
 /* max dsp[rs], rd */
 static bool trans_MAX_mr(DisasContext *ctx, arg_MAX_mr *a)
 {
-prt("max\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "max", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -656,8 +647,7 @@ static bool trans_MIN_ir(DisasContext *ctx, arg_MIN_ir *a)
 /* min dsp[rs], rd */
 static bool trans_MIN_mr(DisasContext *ctx, arg_MIN_mr *a)
 {
-prt("max\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "min", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -673,8 +663,7 @@ static bool trans_MUL_ir(DisasContext *ctx, arg_MUL_ir *a)
 /* mul dsp[rs], rd */
 static bool trans_MUL_mr(DisasContext *ctx, arg_MUL_mr *a)
 {
-prt("mul\t");
-operand(ctx, a->ld, a->mi, a->rs, a->rd);
+prt_ldmi(ctx, "mul", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
@@ -696,8 +685,7 @@ static bool trans_EMUL_ir(DisasContext *ctx, arg_EMUL_ir *a)
 /* emul dsp[rs], rd */
 static bool trans_EMUL_mr(DisasContext *ctx

[Qemu-devel] [PATCH v24 08/22] target/rx: Disassemble rx_index_addr into a string

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

We were eliding all zero indexes.  It is only ld==0 that does
not have an index in the instruction.  This also allows us to
avoid breaking the final print into multiple pieces.

Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-19-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 154 +-
 1 file changed, 55 insertions(+), 99 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 8cada4825d..64342537ee 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -107,49 +107,42 @@ static const char psw[] = {
 'i', 'u', 0, 0, 0, 0, 0, 0,
 };
 
-static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
 {
-bfd_byte buf[2];
+uint32_t addr = ctx->addr;
+uint8_t buf[2];
+uint16_t dsp;
+
 switch (ld) {
 case 0:
-return 0;
+/* No index; return empty string.  */
+out[0] = '\0';
+return;
 case 1:
-ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
 ctx->addr += 1;
-return ((uint8_t)buf[0]) << size;
+ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+dsp = buf[0];
+break;
 case 2:
-ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
 ctx->addr += 2;
-return lduw_le_p(buf) << size;
+ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+dsp = lduw_le_p(buf);
+break;
+default:
+g_assert_not_reached();
 }
-g_assert_not_reached();
+
+sprintf(out, "%u", dsp << (mi < 3 ? mi : 4 - mi));
 }
 
 static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
 {
-int dsp;
 static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
+char dsp[8];
+
 if (ld < 3) {
-switch (mi) {
-case 4:
-/* dsp[rs].ub */
-dsp = rx_index_addr(ld, RX_MEMORY_BYTE, ctx);
-break;
-case 3:
-/* dsp[rs].uw */
-dsp = rx_index_addr(ld, RX_MEMORY_WORD, ctx);
-break;
-default:
-/* dsp[rs].b */
-/* dsp[rs].w */
-/* dsp[rs].l */
-dsp = rx_index_addr(ld, mi, ctx);
-break;
-}
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]%s", rs, sizes[mi]);
+rx_index_addr(ctx, dsp, ld, mi);
+prt("%s[r%d]%s", dsp, rs, sizes[mi]);
 } else {
 prt("r%d", rs);
 }
@@ -235,7 +228,7 @@ static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
 /* mov.[bwl] rs,rd */
 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 {
-int dsp;
+char dspd[8], dsps[8];
 
 prt("mov.%c\t", size[a->sz]);
 if (a->lds == 3 && a->ldd == 3) {
@@ -244,29 +237,15 @@ static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 return true;
 }
 if (a->lds == 3) {
-prt("r%d, ", a->rd);
-dsp = rx_index_addr(a->ldd, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rs);
+rx_index_addr(ctx, dspd, a->ldd, a->sz);
+prt("r%d, %s[r%d]", a->rs, dspd, a->rd);
 } else if (a->ldd == 3) {
-dsp = rx_index_addr(a->lds, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d], r%d", a->rs, a->rd);
+rx_index_addr(ctx, dsps, a->lds, a->sz);
+prt("%s[r%d], r%d", dsps, a->rs, a->rd);
 } else {
-dsp = rx_index_addr(a->lds, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d], ", a->rs);
-dsp = rx_index_addr(a->ldd, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rd);
+rx_index_addr(ctx, dsps, a->lds, a->sz);
+rx_index_addr(ctx, dspd, a->ldd, a->sz);
+prt("%s[r%d], %s[r%d]", dsps, a->rs, dspd, a->rd);
 }
 return true;
 }
@@ -357,12 +336,10 @@ static bool trans_PUSH_r(DisasContext *ctx, arg_PUSH_r *a)
 /* push dsp[rs] */
 static bool trans_PUSH_m(DisasContext *ctx, arg_PUSH_m *a)
 {
-prt("push\t");
-int dsp = rx_index_addr(a->ld, a->sz, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]", a->rs);
+char dsp[8];
+
+rx_index_addr(ctx, dsp, a->ld, a->sz);
+prt("push\t%s[r%d]", dsp, a->rs);
 return true;
 }
 
@@ -389,17 +366,13 @@ static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr 
*a)
 /* xchg dsp[rs].,rd */
 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
 {
-int dsp;
 static const char msize[][4] = {
 "b", "w", "l", "ub", "uw",
 };
+char dsp[8];
 
-prt("xchg\t");
-dsp = rx_index_addr(a->ld, a->mi, ctx);
-if (dsp > 0) {
-prt("%d", dsp);
-}
-prt("[r%d]

[Qemu-devel] [PATCH v24 06/22] target/rx: CPU definition

2019-09-11 Thread Yoshinori Sato
v21 changes
Add cpu-param.h
Remove CPU_COMMON
rx_load_image move to rx-virt.

Signed-off-by: Yoshinori Sato 

Message-Id: <20190616142836.10614-4-ys...@users.sourceforge.jp>
Reviewed-by: Richard Henderson 
Message-Id: <20190607091116.49044-4-ys...@users.sourceforge.jp>
Signed-off-by: Richard Henderson 
[PMD: Use newer QOM style, split cpu-qom.h, restrict access to
 extable array, use rx_cpu_tlb_fill() extracted from patch of
 Yoshinori Sato 'Convert to CPUClass::tlb_fill']
Signed-off-by: Philippe Mathieu-Daudé 

cpu.c: remove rx_load_image

Signed-off-by: Yoshinori Sato 
---
 target/rx/cpu-param.h   |  31 ++
 target/rx/cpu-qom.h |  42 
 target/rx/cpu.h | 181 +
 target/rx/cpu.c | 217 
 target/rx/gdbstub.c | 112 +
 target/rx/Makefile.objs |   1 -
 6 files changed, 583 insertions(+), 1 deletion(-)
 create mode 100644 target/rx/cpu-param.h
 create mode 100644 target/rx/cpu-qom.h
 create mode 100644 target/rx/cpu.h
 create mode 100644 target/rx/cpu.c
 create mode 100644 target/rx/gdbstub.c

diff --git a/target/rx/cpu-param.h b/target/rx/cpu-param.h
new file mode 100644
index 00..5da87fbebe
--- /dev/null
+++ b/target/rx/cpu-param.h
@@ -0,0 +1,31 @@
+/*
+ *  RX cpu parameters
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RX_CPU_PARAM_H
+#define RX_CPU_PARAM_H
+
+#define TARGET_LONG_BITS 32
+#define TARGET_PAGE_BITS 12
+
+#define TARGET_PHYS_ADDR_SPACE_BITS 32
+#define TARGET_VIRT_ADDR_SPACE_BITS 32
+
+#define NB_MMU_MODES 1
+#define MMU_MODE0_SUFFIX _all
+
+#endif
diff --git a/target/rx/cpu-qom.h b/target/rx/cpu-qom.h
new file mode 100644
index 00..8328900f3f
--- /dev/null
+++ b/target/rx/cpu-qom.h
@@ -0,0 +1,42 @@
+#ifndef QEMU_RX_CPU_QOM_H
+#define QEMU_RX_CPU_QOM_H
+
+#include "hw/core/cpu.h"
+/*
+ * RX CPU
+ *
+ * Copyright (c) 2019 Yoshinori Sato
+ * SPDX-License-Identifier: LGPL-2.0+
+ */
+
+#define TYPE_RX_CPU "rx-cpu"
+
+#define TYPE_RX62N_CPU RX_CPU_TYPE_NAME("rx62n")
+
+#define RXCPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(RXCPUClass, (klass), TYPE_RX_CPU)
+#define RXCPU(obj) \
+OBJECT_CHECK(RXCPU, (obj), TYPE_RX_CPU)
+#define RXCPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(RXCPUClass, (obj), TYPE_RX_CPU)
+
+/*
+ * RXCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A RX CPU model.
+ */
+typedef struct RXCPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+
+} RXCPUClass;
+
+#define CPUArchState struct CPURXState
+
+#endif
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
new file mode 100644
index 00..2d1eb7665c
--- /dev/null
+++ b/target/rx/cpu.h
@@ -0,0 +1,181 @@
+/*
+ *  RX emulation definition
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#ifndef RX_CPU_H
+#define RX_CPU_H
+
+#include "qemu/bitops.h"
+#include "qemu-common.h"
+#include "hw/registerfields.h"
+#include "cpu-qom.h"
+
+#include "exec/cpu-defs.h"
+
+/* PSW define */
+REG32(PSW, 0)
+FIELD(PSW, C, 0, 1)
+FIELD(PSW, Z, 1, 1)
+FIELD(PSW, S, 2, 1)
+FIELD(PSW, O, 3, 1)
+FIELD(PSW, I, 16, 1)
+FIELD(PSW, U, 17, 1)
+FIELD(PSW, PM, 20, 1)
+FIELD(PSW, IPL, 24, 4)
+
+/* FPSW define */
+REG32(FPSW, 0)
+FIELD(FPSW, RM, 0, 2)
+FIELD(FPSW, CV, 2, 1)
+FIELD(FPSW, CO, 3, 1)
+FIELD(FPSW, CZ, 4, 1)
+FIELD(FPSW, CU, 5, 1)
+FIELD(FPSW, CX, 6, 1)
+FIELD(FPSW, CE, 7, 1)
+FIELD(FPSW, CAUSE, 2, 6)
+FIELD(FPSW, DN, 8, 1)
+FIELD(FPSW, EV, 10, 1)
+FIELD(FPSW, EO, 11, 1)
+FIELD(FPSW, EZ, 12, 1)
+FIELD(FPSW, EU, 13, 1)
+FIELD(FPSW, EX, 14, 1)
+FIELD(FPSW, ENABLE, 10, 5)
+FIELD(FPSW, FV, 26, 1)
+FIELD(FPSW, FO, 27,

[Qemu-devel] [PATCH v24 03/22] hw/registerfields.h: Add 8bit and 16bit register macros

2019-09-11 Thread Yoshinori Sato
From: Philippe Mathieu-Daudé 

Some RX peripheral using 8bit and 16bit registers.
Added 8bit and 16bit APIs.

Signed-off-by: Yoshinori Sato 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-11-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Reviewed-by: Alistair Francis 
Signed-off-by: Richard Henderson 
---
 include/hw/registerfields.h | 32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
index 2659a58737..a0bb0654d6 100644
--- a/include/hw/registerfields.h
+++ b/include/hw/registerfields.h
@@ -22,6 +22,14 @@
 enum { A_ ## reg = (addr) };  \
 enum { R_ ## reg = (addr) / 4 };
 
+#define REG8(reg, addr)  \
+enum { A_ ## reg = (addr) };  \
+enum { R_ ## reg = (addr) };
+
+#define REG16(reg, addr)  \
+enum { A_ ## reg = (addr) };  \
+enum { R_ ## reg = (addr) / 2 };
+
 /* Define SHIFT, LENGTH and MASK constants for a field within a register */
 
 /* This macro will define R_FOO_BAR_MASK, R_FOO_BAR_SHIFT and R_FOO_BAR_LENGTH
@@ -34,6 +42,12 @@
 MAKE_64BIT_MASK(shift, length)};
 
 /* Extract a field from a register */
+#define FIELD_EX8(storage, reg, field)\
+extract8((storage), R_ ## reg ## _ ## field ## _SHIFT,\
+  R_ ## reg ## _ ## field ## _LENGTH)
+#define FIELD_EX16(storage, reg, field)   \
+extract16((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH)
 #define FIELD_EX32(storage, reg, field)   \
 extract32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
   R_ ## reg ## _ ## field ## _LENGTH)
@@ -49,6 +63,22 @@
  * Assigning values larger then the target field will result in
  * compilation warnings.
  */
+#define FIELD_DP8(storage, reg, field, val) ({\
+struct {  \
+unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
+} v = { .v = val };   \
+uint8_t d;\
+d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH, v.v);   \
+d; })
+#define FIELD_DP16(storage, reg, field, val) ({   \
+struct {  \
+unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
+} v = { .v = val };   \
+uint16_t d;   \
+d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
+  R_ ## reg ## _ ## field ## _LENGTH, v.v);   \
+d; })
 #define FIELD_DP32(storage, reg, field, val) ({   \
 struct {  \
 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
@@ -57,7 +87,7 @@
 d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT,   \
   R_ ## reg ## _ ## field ## _LENGTH, v.v);   \
 d; })
-#define FIELD_DP64(storage, reg, field, val) ({   \
+#define FIELD_DP64(storage, reg, field, val) ({ \
 struct {  \
 unsigned int v:R_ ## reg ## _ ## field ## _LENGTH;\
 } v = { .v = val };   \
-- 
2.20.1




[Qemu-devel] [PATCH v24 04/22] target/rx: TCG translation

2019-09-11 Thread Yoshinori Sato
This part only supported RXv1 instructions.
Instruction manual.
https://www.renesas.com/us/en/doc/products/mpumcu/doc/rx_family/r01us0032ej0120_rxsm.pdf

Signed-off-by: Yoshinori Sato 
Reviewed-by: Richard Henderson 
Tested-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-2-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/translate.c   | 2432 +++
 target/rx/Makefile.objs |   12 +
 target/rx/insns.decode  |  621 ++
 3 files changed, 3065 insertions(+)
 create mode 100644 target/rx/translate.c
 create mode 100644 target/rx/Makefile.objs
 create mode 100644 target/rx/insns.decode

diff --git a/target/rx/translate.c b/target/rx/translate.c
new file mode 100644
index 00..21a67db570
--- /dev/null
+++ b/target/rx/translate.c
@@ -0,0 +1,2432 @@
+/*
+ *  RX translation
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "qemu/qemu-print.h"
+#include "cpu.h"
+#include "exec/exec-all.h"
+#include "tcg-op.h"
+#include "exec/cpu_ldst.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+#include "exec/translator.h"
+#include "trace-tcg.h"
+#include "exec/log.h"
+
+typedef struct DisasContext {
+DisasContextBase base;
+CPURXState *env;
+uint32_t pc;
+} DisasContext;
+
+typedef struct DisasCompare {
+TCGv value;
+TCGv temp;
+TCGCond cond;
+} DisasCompare;
+
+const char rx_crname[][6] = {
+"psw", "pc", "usp", "fpsw", "", "", "", "",
+"bpsw", "bpc", "isp", "fintv", "intb", "", "", "",
+};
+
+/* Target-specific values for dc->base.is_jmp.  */
+#define DISAS_JUMPDISAS_TARGET_0
+#define DISAS_UPDATE  DISAS_TARGET_1
+#define DISAS_EXITDISAS_TARGET_2
+
+/* global register indexes */
+static TCGv cpu_regs[16];
+static TCGv cpu_psw_o, cpu_psw_s, cpu_psw_z, cpu_psw_c;
+static TCGv cpu_psw_i, cpu_psw_pm, cpu_psw_u, cpu_psw_ipl;
+static TCGv cpu_usp, cpu_fpsw, cpu_bpsw, cpu_bpc, cpu_isp;
+static TCGv cpu_fintv, cpu_intb, cpu_pc;
+static TCGv_i64 cpu_acc;
+
+#define cpu_sp cpu_regs[0]
+
+#include "exec/gen-icount.h"
+
+/* decoder helper */
+static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
+   int i, int n)
+{
+while (++i <= n) {
+uint8_t b = cpu_ldub_code(ctx->env, ctx->base.pc_next++);
+insn |= b << (32 - i * 8);
+}
+return insn;
+}
+
+static uint32_t li(DisasContext *ctx, int sz)
+{
+int32_t tmp, addr;
+CPURXState *env = ctx->env;
+addr = ctx->base.pc_next;
+
+tcg_debug_assert(sz < 4);
+switch (sz) {
+case 1:
+ctx->base.pc_next += 1;
+return cpu_ldsb_code(env, addr);
+case 2:
+ctx->base.pc_next += 2;
+return cpu_ldsw_code(env, addr);
+case 3:
+ctx->base.pc_next += 3;
+tmp = cpu_ldsb_code(env, addr + 2) << 16;
+tmp |= cpu_lduw_code(env, addr) & 0x;
+return tmp;
+case 0:
+ctx->base.pc_next += 4;
+return cpu_ldl_code(env, addr);
+}
+return 0;
+}
+
+static int bdsp_s(DisasContext *ctx, int d)
+{
+/*
+ * 0 -> 8
+ * 1 -> 9
+ * 2 -> 10
+ * 3 -> 3
+ * :
+ * 7 -> 7
+ */
+if (d < 3) {
+d += 8;
+}
+return d;
+}
+
+/* Include the auto-generated decoder. */
+#include "decode.inc.c"
+
+void rx_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+{
+RXCPU *cpu = RXCPU(cs);
+CPURXState *env = &cpu->env;
+int i;
+uint32_t psw;
+
+psw = rx_cpu_pack_psw(env);
+qemu_fprintf(f, "pc=0x%08x psw=0x%08x\n",
+ env->pc, psw);
+for (i = 0; i < 16; i += 4) {
+qemu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n",
+ i, env->regs[i], i + 1, env->regs[i + 1],
+ i + 2, env->regs[i + 2], i + 3, env->regs[i + 3]);
+}
+}
+
+static bool use_goto_tb(DisasContext *dc, target_ulong dest)
+{
+if (unlikely(dc->base.singlestep_enabled)) {
+return false;
+} else {
+return true;
+}
+}
+
+static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
+{
+if (use_goto_tb(dc, dest)) {
+tcg_gen_goto_tb(n);
+tcg_gen_movi_i32(cpu_pc, dest);
+tcg_gen_exit_tb(dc->base.tb, n);
+} else {
+tcg_gen_movi_i32(cpu_pc, dest);
+   

[Qemu-devel] [PATCH v24 05/22] target/rx: TCG helper

2019-09-11 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 

Message-Id: <20190616142836.10614-3-ys...@users.sourceforge.jp>
Reviewed-by: Richard Henderson 
Message-Id: <20190607091116.49044-3-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
[PMD: Removed tlb_fill, extracted from patch of Yoshinori Sato
 'Convert to CPUClass::tlb_fill']
Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
---
 target/rx/helper.h|  31 +++
 target/rx/helper.c| 149 +
 target/rx/op_helper.c | 470 ++
 3 files changed, 650 insertions(+)
 create mode 100644 target/rx/helper.h
 create mode 100644 target/rx/helper.c
 create mode 100644 target/rx/op_helper.c

diff --git a/target/rx/helper.h b/target/rx/helper.h
new file mode 100644
index 00..f0b7ebbbf7
--- /dev/null
+++ b/target/rx/helper.h
@@ -0,0 +1,31 @@
+DEF_HELPER_1(raise_illegal_instruction, noreturn, env)
+DEF_HELPER_1(raise_access_fault, noreturn, env)
+DEF_HELPER_1(raise_privilege_violation, noreturn, env)
+DEF_HELPER_1(wait, noreturn, env)
+DEF_HELPER_1(debug, noreturn, env)
+DEF_HELPER_2(rxint, noreturn, env, i32)
+DEF_HELPER_1(rxbrk, noreturn, env)
+DEF_HELPER_FLAGS_3(fadd, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fsub, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fmul, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdiv, TCG_CALL_NO_WG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fcmp, TCG_CALL_NO_WG, void, env, f32, f32)
+DEF_HELPER_FLAGS_2(ftoi, TCG_CALL_NO_WG, i32, env, f32)
+DEF_HELPER_FLAGS_2(round, TCG_CALL_NO_WG, i32, env, f32)
+DEF_HELPER_FLAGS_2(itof, TCG_CALL_NO_WG, f32, env, i32)
+DEF_HELPER_2(set_fpsw, void, env, i32)
+DEF_HELPER_FLAGS_2(racw, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_psw_rte, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_psw, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_1(pack_psw, i32, env)
+DEF_HELPER_FLAGS_3(div, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_3(divu, TCG_CALL_NO_WG, i32, env, i32, i32)
+DEF_HELPER_FLAGS_1(scmpu, TCG_CALL_NO_WG, void, env)
+DEF_HELPER_1(smovu, void, env)
+DEF_HELPER_1(smovf, void, env)
+DEF_HELPER_1(smovb, void, env)
+DEF_HELPER_2(sstr, void, env, i32)
+DEF_HELPER_FLAGS_2(swhile, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(suntil, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(rmpa, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_1(satr, void, env)
diff --git a/target/rx/helper.c b/target/rx/helper.c
new file mode 100644
index 00..a34a40af83
--- /dev/null
+++ b/target/rx/helper.c
@@ -0,0 +1,149 @@
+/*
+ *  RX emulation
+ *
+ *  Copyright (c) 2019 Yoshinori Sato
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+#include "exec/log.h"
+#include "exec/cpu_ldst.h"
+#include "sysemu/sysemu.h"
+#include "hw/irq.h"
+
+void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
+{
+if (env->psw_pm == 0) {
+env->psw_ipl = FIELD_EX32(psw, PSW, IPL);
+if (rte) {
+/* PSW.PM can write RTE and RTFI */
+env->psw_pm = FIELD_EX32(psw, PSW, PM);
+}
+env->psw_u = FIELD_EX32(psw, PSW, U);
+env->psw_i = FIELD_EX32(psw, PSW, I);
+}
+env->psw_o = FIELD_EX32(psw, PSW, O) << 31;
+env->psw_s = FIELD_EX32(psw, PSW, S) << 31;
+env->psw_z = 1 - FIELD_EX32(psw, PSW, Z);
+env->psw_c = FIELD_EX32(psw, PSW, C);
+}
+
+#define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
+void rx_cpu_do_interrupt(CPUState *cs)
+{
+RXCPU *cpu = RXCPU(cs);
+CPURXState *env = &cpu->env;
+int do_irq = cs->interrupt_request & INT_FLAGS;
+uint32_t save_psw;
+
+env->in_sleep = 0;
+
+if (env->psw_u) {
+env->usp = env->regs[0];
+} else {
+env->isp = env->regs[0];
+}
+save_psw = rx_cpu_pack_psw(env);
+env->psw_pm = env->psw_i = env->psw_u = 0;
+
+if (do_irq) {
+if (do_irq & CPU_INTERRUPT_FIR) {
+env->bpc = env->pc;
+env->bpsw = save_psw;
+env->pc = env->fintv;
+env->psw_ipl = 15;
+cs->interrupt_request &= ~CPU_INTERRUPT_FIR;
+qemu_set_irq(env->ack, env->ack_irq);
+qemu_log_mask(CPU_LOG_INT, "fast interrupt raised\n");
+} else if (do_irq & CPU_INTERRUPT_HARD) {
+env->isp -= 4;
+cpu_

[Qemu-devel] [PATCH v24 00/22] Add RX archtecture support

2019-09-11 Thread Yoshinori Sato
Hello.
This patch series is added Renesas RX target emulation.

Changes for v23.
Follow master changes.

Changes for v22.
Added some include.

Changes for v21.
rebase latest master.
Remove unneeded hmp_info_tlb.

Chanegs for v20.
Reorderd patches.
Squashed v19 changes.

Changes for v19.
Follow tcg changes.
Cleanup cpu.c.
simplify rx_cpu_class_by_name and rx_load_image move to rx-virt.

My git repository is bellow.
git://git.pf.osdn.net/gitroot/y/ys/ysato/qemu.git tags/rx-20190912

Testing binaries bellow.
u-boot
Download - https://osdn.net/users/ysato/pf/qemu/dl/u-boot.bin.gz

starting
$ gzip -d u-boot.bin.gz
$ qemu-system-rx -bios u-boot.bin

linux and pico-root (only sash)
Download - https://osdn.net/users/ysato/pf/qemu/dl/zImage (kernel)
   https://osdn.net/users/ysato/pf/qemu/dl/rx-qemu.dtb (DeviceTree)

starting
$ qemu-system-rx -kernel zImage -dtb rx-qemu.dtb -append "earlycon"

Philippe Mathieu-Daudé (3):
  hw/registerfields.h: Add 8bit and 16bit register macros
  hw/rx: Restrict the RX62N microcontroller to the RX62N CPU core
  BootLinuxConsoleTest: Test the RX-Virt machine

Richard Henderson (7):
  target/rx: Disassemble rx_index_addr into a string
  target/rx: Replace operand with prt_ldmi in disassembler
  target/rx: Use prt_ldmi for XCHG_mr disassembly
  target/rx: Emit all disassembly in one prt()
  target/rx: Collect all bytes during disassembly
  target/rx: Dump bytes for each insn during disassembly
  hw/rx: Honor -accel qtest

Yoshinori Sato (12):
  MAINTAINERS: Add RX
  qemu/bitops.h: Add extract8 and extract16
  target/rx: TCG translation
  target/rx: TCG helper
  target/rx: CPU definition
  target/rx: RX disassembler
  hw/intc: RX62N interrupt controller (ICUa)
  hw/timer: RX62N internal timer modules
  hw/char: RX62N serial communication interface (SCI)
  hw/rx: RX Target hardware definition
  Add rx-softmmu
  qapi/machine.json: Add RX cpu.

 configure  |8 +
 default-configs/rx-softmmu.mak |3 +
 qapi/machine.json  |2 +-
 include/disas/dis-asm.h|5 +
 include/exec/poison.h  |1 +
 include/hw/char/renesas_sci.h  |   45 +
 include/hw/intc/rx_icu.h   |   56 +
 include/hw/registerfields.h|   32 +-
 include/hw/rx/rx.h |7 +
 include/hw/rx/rx62n.h  |   91 +
 include/hw/timer/renesas_cmt.h |   38 +
 include/hw/timer/renesas_tmr.h |   53 +
 include/qemu/bitops.h  |   38 +
 include/sysemu/arch_init.h |1 +
 target/rx/cpu-param.h  |   31 +
 target/rx/cpu-qom.h|   42 +
 target/rx/cpu.h|  181 ++
 target/rx/helper.h |   31 +
 arch_init.c|2 +
 hw/char/renesas_sci.c  |  343 
 hw/intc/rx_icu.c   |  379 
 hw/rx/rx-virt.c|  135 ++
 hw/rx/rx62n.c  |  247 +++
 hw/timer/renesas_cmt.c |  278 +++
 hw/timer/renesas_tmr.c |  458 +
 target/rx/cpu.c|  217 +++
 target/rx/disas.c  | 1446 ++
 target/rx/gdbstub.c|  112 ++
 target/rx/helper.c |  149 ++
 target/rx/op_helper.c  |  470 +
 target/rx/translate.c  | 2432 
 tests/machine-none-test.c  |1 +
 MAINTAINERS|   19 +
 hw/Kconfig |1 +
 hw/char/Kconfig|3 +
 hw/char/Makefile.objs  |1 +
 hw/intc/Kconfig|3 +
 hw/intc/Makefile.objs  |1 +
 hw/rx/Kconfig  |   14 +
 hw/rx/Makefile.objs|2 +
 hw/timer/Kconfig   |6 +
 hw/timer/Makefile.objs |3 +
 target/rx/Makefile.objs|   11 +
 target/rx/insns.decode |  621 ++
 tests/acceptance/boot_linux_console.py |   46 +
 45 files changed, 8063 insertions(+), 2 deletions(-)
 create mode 100644 default-configs/rx-softmmu.mak
 create mode 100644 include/hw/char/renesas_sci.h
 create mode 100644 include/hw/intc/rx_icu.h
 create mode 100644 include/hw/rx/rx.h
 create mode 100644 include/hw/rx/rx62n.h
 create mode 100644 include/hw/timer/renesas_cmt.h
 create mode 100644 include/hw/timer/renesas_tmr.h
 create mode 100644 target/rx/cpu-param.h
 create mode 100644 target/rx/cpu-qom.h
 create mode 100644 target/rx/cpu.h
 create mode 100644 target/rx/helper.h
 create mode 100644 hw/char/renesas_sci.c
 create mode 100644 hw/intc/rx_icu.c
 create mode 100644 hw/rx/rx-virt.c
 create mode 100644 hw/rx/rx62n.c
 create mode 100644 hw/timer/renesas_cmt.c
 create mode 100644 hw/timer/renesas_tmr.c
 create mode 100644 target/rx/cpu.c
 create mode 

[Qemu-devel] [PATCH v24 19/22] hw/rx: Restrict the RX62N microcontroller to the RX62N CPU core

2019-09-11 Thread Yoshinori Sato
From: Philippe Mathieu-Daudé 

While the VIRT machine can use different microcontrollers,
the RX62N microcontroller is tied to the RX62N CPU core.

Signed-off-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
---
 hw/rx/rx-virt.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/hw/rx/rx-virt.c b/hw/rx/rx-virt.c
index 4cfe2e3123..9676a5e7bf 100644
--- a/hw/rx/rx-virt.c
+++ b/hw/rx/rx-virt.c
@@ -17,6 +17,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/error-report.h"
 #include "qapi/error.h"
 #include "qemu-common.h"
 #include "cpu.h"
@@ -56,6 +57,7 @@ static void rx_load_image(RXCPU *cpu, const char *filename,
 
 static void rxvirt_init(MachineState *machine)
 {
+MachineClass *mc = MACHINE_GET_CLASS(machine);
 RX62NState *s = g_new(RX62NState, 1);
 MemoryRegion *sysmem = get_system_memory();
 MemoryRegion *sdram = g_new(MemoryRegion, 1);
@@ -64,6 +66,12 @@ static void rxvirt_init(MachineState *machine)
 void *dtb = NULL;
 int dtb_size;
 
+if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
+error_report("This board can only be used with CPU %s",
+ mc->default_cpu_type);
+exit(1);
+}
+
 /* Allocate memory space */
 memory_region_init_ram(sdram, NULL, "sdram", 16 * MiB,
&error_fatal);
-- 
2.20.1




[Qemu-devel] [PATCH v24 22/22] qapi/machine.json: Add RX cpu.

2019-09-11 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 
---
 qapi/machine.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qapi/machine.json b/qapi/machine.json
index ca26779f1a..70398c521f 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -28,7 +28,7 @@
   'data' : [ 'aarch64', 'alpha', 'arm', 'cris', 'hppa', 'i386', 'lm32',
  'm68k', 'microblaze', 'microblazeel', 'mips', 'mips64',
  'mips64el', 'mipsel', 'moxie', 'nios2', 'or1k', 'ppc',
- 'ppc64', 'riscv32', 'riscv64', 's390x', 'sh4',
+ 'ppc64', 'riscv32', 'riscv64', 'rx', 's390x', 'sh4',
  'sh4eb', 'sparc', 'sparc64', 'tricore', 'unicore32',
  'x86_64', 'xtensa', 'xtensaeb' ] }
 
-- 
2.20.1




[Qemu-devel] [PATCH v24 10/22] target/rx: Use prt_ldmi for XCHG_mr disassembly

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

Note that the ld == 3 case handled by prt_ldmi is decoded as
XCHG_rr and cannot appear here.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-21-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 515b365528..db10385fd0 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -366,13 +366,7 @@ static bool trans_XCHG_rr(DisasContext *ctx, arg_XCHG_rr 
*a)
 /* xchg dsp[rs].,rd */
 static bool trans_XCHG_mr(DisasContext *ctx, arg_XCHG_mr *a)
 {
-static const char msize[][4] = {
-"b", "w", "l", "ub", "uw",
-};
-char dsp[8];
-
-rx_index_addr(ctx, dsp, a->ld, a->mi);
-prt("xchg\t%s[r%d].%s, r%d", dsp, a->rs, msize[a->mi], a->rd);
+prt_ldmi(ctx, "xchg", a->ld, a->mi, a->rs, a->rd);
 return true;
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH v24 11/22] target/rx: Emit all disassembly in one prt()

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

Many of the multi-part prints have been eliminated by previous
patches.  Eliminate the rest of them.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-22-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 75 ---
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index db10385fd0..ebc1a44249 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -228,24 +228,21 @@ static bool trans_MOV_ra(DisasContext *ctx, arg_MOV_ra *a)
 /* mov.[bwl] rs,rd */
 static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 {
-char dspd[8], dsps[8];
+char dspd[8], dsps[8], szc = size[a->sz];
 
-prt("mov.%c\t", size[a->sz]);
 if (a->lds == 3 && a->ldd == 3) {
 /* mov.[bwl] rs,rd */
-prt("r%d, r%d", a->rs, a->rd);
-return true;
-}
-if (a->lds == 3) {
+prt("mov.%c\tr%d, r%d", szc, a->rs, a->rd);
+} else if (a->lds == 3) {
 rx_index_addr(ctx, dspd, a->ldd, a->sz);
-prt("r%d, %s[r%d]", a->rs, dspd, a->rd);
+prt("mov.%c\tr%d, %s[r%d]", szc, a->rs, dspd, a->rd);
 } else if (a->ldd == 3) {
 rx_index_addr(ctx, dsps, a->lds, a->sz);
-prt("%s[r%d], r%d", dsps, a->rs, a->rd);
+prt("mov.%c\t%s[r%d], r%d", szc, dsps, a->rs, a->rd);
 } else {
 rx_index_addr(ctx, dsps, a->lds, a->sz);
 rx_index_addr(ctx, dspd, a->ldd, a->sz);
-prt("%s[r%d], %s[r%d]", dsps, a->rs, dspd, a->rd);
+prt("mov.%c\t%s[r%d], %s[r%d]", szc, dsps, a->rs, dspd, a->rd);
 }
 return true;
 }
@@ -254,8 +251,11 @@ static bool trans_MOV_mm(DisasContext *ctx, arg_MOV_mm *a)
 /* mov.[bwl] rs,[-rd] */
 static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
 {
-prt("mov.%c\tr%d, ", size[a->sz], a->rs);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
+if (a->ad) {
+prt("mov.%c\tr%d, [-r%d]", size[a->sz], a->rs, a->rd);
+} else {
+prt("mov.%c\tr%d, [r%d+]", size[a->sz], a->rs, a->rd);
+}
 return true;
 }
 
@@ -263,9 +263,11 @@ static bool trans_MOV_rp(DisasContext *ctx, arg_MOV_rp *a)
 /* mov.[bwl] [-rd],rs */
 static bool trans_MOV_pr(DisasContext *ctx, arg_MOV_pr *a)
 {
-prt("mov.%c\t", size[a->sz]);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
-prt(", r%d", a->rs);
+if (a->ad) {
+prt("mov.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
+} else {
+prt("mov.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
+}
 return true;
 }
 
@@ -299,9 +301,11 @@ static bool trans_MOVU_ar(DisasContext *ctx, arg_MOVU_ar 
*a)
 /* movu.[bw] [-rs],rd */
 static bool trans_MOVU_pr(DisasContext *ctx, arg_MOVU_pr *a)
 {
-prt("movu.%c\t", size[a->sz]);
-prt((a->ad == 0) ? "[r%d+]" : "[-r%d]", a->rd);
-prt(", r%d", a->rs);
+if (a->ad) {
+prt("movu.%c\t[-r%d], r%d", size[a->sz], a->rd, a->rs);
+} else {
+prt("movu.%c\t[r%d+], r%d", size[a->sz], a->rd, a->rs);
+}
 return true;
 }
 
@@ -478,11 +482,11 @@ static bool trans_TST_mr(DisasContext *ctx, arg_TST_mr *a)
 /* not rs, rd */
 static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
 {
-prt("not\t");
 if (a->rs != a->rd) {
-prt("r%d, ", a->rs);
+prt("not\tr%d, r%d", a->rs, a->rd);
+} else {
+prt("not\tr%d", a->rs);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -490,11 +494,11 @@ static bool trans_NOT_rr(DisasContext *ctx, arg_NOT_rr *a)
 /* neg rs, rd */
 static bool trans_NEG_rr(DisasContext *ctx, arg_NEG_rr *a)
 {
-prt("neg\t");
 if (a->rs != a->rd) {
-prt("r%d, ", a->rs);
+prt("neg\tr%d, r%d", a->rs, a->rd);
+} else {
+prt("neg\tr%d", a->rs);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -606,11 +610,10 @@ static bool trans_SBB_mr(DisasContext *ctx, arg_SBB_mr *a)
 /* abs rs, rd */
 static bool trans_ABS_rr(DisasContext *ctx, arg_ABS_rr *a)
 {
-prt("abs\t");
-if (a->rs == a->rd) {
-prt("r%d", a->rd);
+if (a->rs != a->rd) {
+prt("abs\tr%d, r%d", a->rs, a->rd);
 } else {
-prt("r%d, r%d", a->rs, a->rd);
+prt("abs\tr%d", a->rs);
 }
 return true;
 }
@@ -733,11 +736,11 @@ static bool trans_DIVU_mr(DisasContext *ctx, arg_DIVU_mr 
*a)
 /* shll #imm:5, rs, rd */
 static bool trans_SHLL_irr(DisasContext *ctx, arg_SHLL_irr *a)
 {
-prt("shll\t#%d, ", a->imm);
 if (a->rs2 != a->rd) {
-prt("r%d, ", a->rs2);
+prt("shll\t#%d, r%d, r%d", a->imm, a->rs2, a->rd);
+} else {
+prt("shll\t#%d, r%d", a->imm, a->rd);
 }
-prt("r%d", a->rd);
 return true;
 }
 
@@ -752,11 +755,11 @@ static bool trans_SHLL_rr(DisasContext *ctx, arg_SHLL_rr 
*a)
 /* shar #imm:5, rs, rd */
 static bool trans_SHAR_irr(DisasContext *ctx, arg_SHAR_irr

[Qemu-devel] [PATCH v24 12/22] target/rx: Collect all bytes during disassembly

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

Collected, to be used in the next patch.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-23-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 62 ---
 1 file changed, 42 insertions(+), 20 deletions(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index ebc1a44249..5a32a87534 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -25,43 +25,59 @@ typedef struct DisasContext {
 disassemble_info *dis;
 uint32_t addr;
 uint32_t pc;
+uint8_t len;
+uint8_t bytes[8];
 } DisasContext;
 
 
 static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
-   int i, int n)
+  int i, int n)
 {
-bfd_byte buf;
+uint32_t addr = ctx->addr;
+
+g_assert(ctx->len == i);
+g_assert(n <= ARRAY_SIZE(ctx->bytes));
+
 while (++i <= n) {
-ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
-insn |= buf << (32 - i * 8);
+ctx->dis->read_memory_func(addr++, &ctx->bytes[i - 1], 1, ctx->dis);
+insn |= ctx->bytes[i - 1] << (32 - i * 8);
 }
+ctx->addr = addr;
+ctx->len = n;
+
 return insn;
 }
 
 static int32_t li(DisasContext *ctx, int sz)
 {
-int32_t addr;
-bfd_byte buf[4];
-addr = ctx->addr;
+uint32_t addr = ctx->addr;
+uintptr_t len = ctx->len;
 
 switch (sz) {
 case 1:
+g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 1;
-ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
-return (int8_t)buf[0];
+ctx->len += 1;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
+return (int8_t)ctx->bytes[len];
 case 2:
+g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 2;
-ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
-return ldsw_le_p(buf);
+ctx->len += 2;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
+return ldsw_le_p(ctx->bytes + len);
 case 3:
+g_assert(len + 3 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 3;
-ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
-return (int8_t)buf[2] << 16 | lduw_le_p(buf);
+ctx->len += 3;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 3, ctx->dis);
+return (int8_t)ctx->bytes[len + 2] << 16 | lduw_le_p(ctx->bytes + len);
 case 0:
+g_assert(len + 4 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 4;
-ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
-return ldl_le_p(buf);
+ctx->len += 4;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 4, ctx->dis);
+return ldl_le_p(ctx->bytes + len);
 default:
 g_assert_not_reached();
 }
@@ -110,7 +126,7 @@ static const char psw[] = {
 static void rx_index_addr(DisasContext *ctx, char out[8], int ld, int mi)
 {
 uint32_t addr = ctx->addr;
-uint8_t buf[2];
+uintptr_t len = ctx->len;
 uint16_t dsp;
 
 switch (ld) {
@@ -119,14 +135,18 @@ static void rx_index_addr(DisasContext *ctx, char out[8], 
int ld, int mi)
 out[0] = '\0';
 return;
 case 1:
+g_assert(len + 1 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 1;
-ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
-dsp = buf[0];
+ctx->len += 1;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 1, ctx->dis);
+dsp = ctx->bytes[len];
 break;
 case 2:
+g_assert(len + 2 <= ARRAY_SIZE(ctx->bytes));
 ctx->addr += 2;
-ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
-dsp = lduw_le_p(buf);
+ctx->len += 2;
+ctx->dis->read_memory_func(addr, ctx->bytes + len, 2, ctx->dis);
+dsp = lduw_le_p(ctx->bytes + len);
 break;
 default:
 g_assert_not_reached();
@@ -1392,8 +1412,10 @@ int print_insn_rx(bfd_vma addr, disassemble_info *dis)
 DisasContext ctx;
 uint32_t insn;
 int i;
+
 ctx.dis = dis;
 ctx.pc = ctx.addr = addr;
+ctx.len = 0;
 
 insn = decode_load(&ctx);
 if (!decode(&ctx, insn)) {
-- 
2.20.1




[Qemu-devel] [PATCH v24 02/22] qemu/bitops.h: Add extract8 and extract16

2019-09-11 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-10-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 include/qemu/bitops.h | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 3f0926cf40..764f9d1ea0 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -300,6 +300,44 @@ static inline uint32_t extract32(uint32_t value, int 
start, int length)
 return (value >> start) & (~0U >> (32 - length));
 }
 
+/**
+ * extract8:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 8 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it. The bit field must
+ * lie entirely within the 8 bit word. It is valid to request that
+ * all 8 bits are returned (ie @length 8 and @start 0).
+ *
+ * Returns: the value of the bit field extracted from the input value.
+ */
+static inline uint8_t extract8(uint8_t value, int start, int length)
+{
+assert(start >= 0 && length > 0 && length <= 8 - start);
+return extract32(value, start, length);
+}
+
+/**
+ * extract16:
+ * @value: the value to extract the bit field from
+ * @start: the lowest bit in the bit field (numbered from 0)
+ * @length: the length of the bit field
+ *
+ * Extract from the 16 bit input @value the bit field specified by the
+ * @start and @length parameters, and return it. The bit field must
+ * lie entirely within the 16 bit word. It is valid to request that
+ * all 16 bits are returned (ie @length 16 and @start 0).
+ *
+ * Returns: the value of the bit field extracted from the input value.
+ */
+static inline uint16_t extract16(uint16_t value, int start, int length)
+{
+assert(start >= 0 && length > 0 && length <= 16 - start);
+return extract32(value, start, length);
+}
+
 /**
  * extract64:
  * @value: the value to extract the bit field from
-- 
2.20.1




[Qemu-devel] [PATCH v24 18/22] hw/rx: Honor -accel qtest

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

Issue an error if no kernel, no bios, and not qtest'ing.
Fixes make check-qtest-rx: test/qom-test.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-16-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
We could squash this with the previous patch
---
 hw/rx/rx62n.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c
index ac47f2a397..a0986fd15e 100644
--- a/hw/rx/rx62n.c
+++ b/hw/rx/rx62n.c
@@ -21,12 +21,14 @@
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qemu/error-report.h"
 #include "hw/hw.h"
 #include "hw/rx/rx62n.h"
 #include "hw/loader.h"
 #include "hw/sysbus.h"
 #include "hw/qdev-properties.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "cpu.h"
 
 /*
@@ -191,8 +193,14 @@ static void rx62n_realize(DeviceState *dev, Error **errp)
 memory_region_init_rom(&s->c_flash, NULL, "codeflash",
RX62N_CFLASH_SIZE, errp);
 memory_region_add_subregion(s->sysmem, RX62N_CFLASH_BASE, &s->c_flash);
+
 if (!s->kernel) {
-rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0);
+if (bios_name) {
+rom_add_file_fixed(bios_name, RX62N_CFLASH_BASE, 0);
+}  else if (!qtest_enabled()) {
+error_report("No bios or kernel specified");
+exit(1);
+}
 }
 
 /* Initialize CPU */
-- 
2.20.1




[Qemu-devel] [PATCH v24 13/22] target/rx: Dump bytes for each insn during disassembly

2019-09-11 Thread Yoshinori Sato
From: Richard Henderson 

There are so many different forms of each RX instruction
that it will be very useful to be able to look at the bytes
to see on which path a bug may lie.

Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Yoshinori Sato 
Signed-off-by: Yoshinori Sato 
Message-Id: <20190607091116.49044-24-ys...@users.sourceforge.jp>
Tested-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 target/rx/disas.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target/rx/disas.c b/target/rx/disas.c
index 5a32a87534..d73b53db44 100644
--- a/target/rx/disas.c
+++ b/target/rx/disas.c
@@ -102,7 +102,21 @@ static int bdsp_s(DisasContext *ctx, int d)
 /* Include the auto-generated decoder.  */
 #include "decode.inc.c"
 
-#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+static void dump_bytes(DisasContext *ctx)
+{
+int i, len = ctx->len;
+
+for (i = 0; i < len; ++i) {
+ctx->dis->fprintf_func(ctx->dis->stream, "%02x ", ctx->bytes[i]);
+}
+ctx->dis->fprintf_func(ctx->dis->stream, "%*c", (8 - i) * 3, '\t');
+}
+
+#define prt(...) \
+do {\
+dump_bytes(ctx);\
+ctx->dis->fprintf_func(ctx->dis->stream, __VA_ARGS__);  \
+} while (0)
 
 #define RX_MEMORY_BYTE 0
 #define RX_MEMORY_WORD 1
-- 
2.20.1




[Qemu-devel] [PATCH v24 01/22] MAINTAINERS: Add RX

2019-09-11 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20190607091116.49044-18-ys...@users.sourceforge.jp>
Signed-off-by: Richard Henderson 
---
 MAINTAINERS | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 50eaf005f4..bfc99986cc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -271,6 +271,13 @@ F: include/hw/riscv/
 F: linux-user/host/riscv32/
 F: linux-user/host/riscv64/
 
+RENESAS RX CPUs
+M: Yoshinori Sato 
+S: Maintained
+F: target/rx/
+F: hw/rx/
+F: include/hw/rx/
+
 S390 TCG CPUs
 M: Richard Henderson 
 M: David Hildenbrand 
@@ -1118,6 +1125,18 @@ F: pc-bios/canyonlands.dt[sb]
 F: pc-bios/u-boot-sam460ex-20100605.bin
 F: roms/u-boot-sam460ex
 
+RX Machines
+---
+rx-virt
+M: Yoshinori Sato 
+S: Maintained
+F: hw/rx/rxqemu.c
+F: hw/intc/rx_icu.c
+F: hw/timer/renesas_*.c
+F: hw/char/renesas_sci.c
+F: include/hw/timer/renesas_*.h
+F: include/hw/char/renesas_sci.h
+
 SH4 Machines
 
 R2D
-- 
2.20.1




[Qemu-devel] [PATCH v11 10/11] hmat acpi: Build Memory Side Cache Information Structure(s)

2019-09-11 Thread Tao Xu
From: Liu Jingqi 

This structure describes memory side cache information for memory
proximity domains if the memory side cache is present and the
physical device forms the memory side cache.
The software could use this information to effectively place
the data in memory to maximize the performance of the system
memory that use the memory side cache.

Reviewed-by: Daniel Black 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v11:
- Move numa option patches forward.
---
 hw/acpi/hmat.c | 64 +-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
index 2d76dd0cd1..17a6afec99 100644
--- a/hw/acpi/hmat.c
+++ b/hw/acpi/hmat.c
@@ -160,13 +160,62 @@ static void build_hmat_lb(GArray *table_data, 
HMAT_LB_Info *hmat_lb,
 }
 }
 
+/* ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure: Table 5-147 */
+static void build_hmat_cache(GArray *table_data, HMAT_Cache_Info *hmat_cache)
+{
+/*
+ * Cache Attributes: Bits [3:0] – Total Cache Levels
+ * for this Memory Proximity Domain
+ */
+uint32_t cache_attr = hmat_cache->total_levels & 0xF;
+
+/* Bits [7:4] : Cache Level described in this structure */
+cache_attr |= (hmat_cache->level & 0xF) << 4;
+
+/* Bits [11:8] - Cache Associativity */
+cache_attr |= (hmat_cache->associativity & 0xF) << 8;
+
+/* Bits [15:12] - Write Policy */
+cache_attr |= (hmat_cache->write_policy & 0xF) << 12;
+
+/* Bits [31:16] - Cache Line size in bytes */
+cache_attr |= (hmat_cache->line_size & 0x) << 16;
+
+cache_attr = cpu_to_le32(cache_attr);
+
+/* Type */
+build_append_int_noprefix(table_data, 2, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Length */
+build_append_int_noprefix(table_data, 32, 4);
+/* Proximity Domain for the Memory */
+build_append_int_noprefix(table_data, hmat_cache->mem_proximity, 4);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);
+/* Memory Side Cache Size */
+build_append_int_noprefix(table_data, hmat_cache->size, 8);
+/* Cache Attributes */
+build_append_int_noprefix(table_data, cache_attr, 4);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/*
+ * Number of SMBIOS handles (n)
+ * Linux kernel uses Memory Side Cache Information Structure
+ * without SMBIOS entries for now, so set Number of SMBIOS handles
+ * as 0.
+ */
+build_append_int_noprefix(table_data, 0, 2);
+}
+
 /* Build HMAT sub table structures */
 static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
 {
 uint16_t flags;
 uint32_t *initiator_list;
-int i, j, hrchy, type;
+int i, j, hrchy, type, level;
 HMAT_LB_Info *numa_hmat_lb;
+HMAT_Cache_Info *numa_hmat_cache;
 
 for (i = 0; i < nstat->num_nodes; i++) {
 flags = 0;
@@ -202,6 +251,19 @@ static void hmat_build_table_structs(GArray *table_data, 
NumaState *nstat)
 }
 }
 }
+
+/*
+ * ACPI 6.3: 5.2.27.5 Memory Side Cache Information Structure:
+ * Table 5-147
+ */
+for (i = 0; i < nstat->num_nodes; i++) {
+for (level = 0; level <= MAX_HMAT_CACHE_LEVEL; level++) {
+numa_hmat_cache = nstat->hmat_cache[i][level];
+if (numa_hmat_cache) {
+build_hmat_cache(table_data, numa_hmat_cache);
+}
+}
+}
 g_free(initiator_list);
 }
 
-- 
2.20.1




[Qemu-devel] [PATCH v11 06/11] numa: Extend CLI to provide memory latency and bandwidth information

2019-09-11 Thread Tao Xu
From: Liu Jingqi 

Add -numa hmat-lb option to provide System Locality Latency and
Bandwidth Information. These memory attributes help to build
System Locality Latency and Bandwidth Information Structure(s)
in ACPI Heterogeneous Memory Attribute Table (HMAT).

Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v11:
- Move numa option patches forward.
- Add num_initiator in Numa_state to record the number of
  initiators.
- Simplify struct HMAT_LB_Info, use uint64_t array to store data.
- Drop hmat_get_base().

Changes in v10:
- use new builtin type 'time' as qapi input.
---
 hw/core/numa.c| 114 ++
 include/sysemu/numa.h |  44 
 qapi/machine.json |  95 ++-
 qemu-options.hx   |  49 +-
 4 files changed, 299 insertions(+), 3 deletions(-)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index bdce7d4217..82322734e3 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -186,6 +186,100 @@ void parse_numa_distance(MachineState *ms, 
NumaDistOptions *dist, Error **errp)
 ms->numa_state->have_numa_distance = true;
 }
 
+void parse_numa_hmat_lb(NumaState *nstat, NumaHmatLBOptions *node,
+Error **errp)
+{
+int i;
+int init = node->initiator;
+int targ = node->target;
+int nb_nodes = nstat->num_nodes;
+NodeInfo *numa_info = nstat->nodes;
+HMAT_LB_Info *hmat_lb = nstat->hmat_lb[node->hierarchy][node->data_type];
+
+/* Error checking */
+if (init >= nb_nodes) {
+error_setg(errp, "Invalid initiator=%d, it should be less than %d.",
+   init, nb_nodes);
+return;
+}
+if (targ >= nb_nodes) {
+error_setg(errp, "Invalid target=%d, it should be less than %d.",
+   targ, nb_nodes);
+return;
+}
+if (!numa_info[init].has_cpu) {
+error_setg(errp, "Invalid initiator=%d, it isn't an "
+   "initiator proximity domain.", init);
+return;
+}
+if (!numa_info[targ].present) {
+error_setg(errp, "Invalid target=%d, it hasn't a valid NUMA node.",
+   targ);
+return;
+}
+
+/* HMAT latency and bandwidth data initialization */
+if (nstat->num_initiator == 0) {
+for (i = 0; i < nstat->num_nodes; i++) {
+if (numa_info[i].has_cpu) {
+nstat->num_initiator++;
+}
+}
+}
+
+if (!hmat_lb) {
+int size = nstat->num_initiator * nb_nodes * sizeof(uint64_t);
+hmat_lb = g_malloc0(sizeof(*hmat_lb));
+nstat->hmat_lb[node->hierarchy][node->data_type] = hmat_lb;
+hmat_lb->latency = g_malloc0(size);
+hmat_lb->bandwidth = g_malloc0(size);
+}
+hmat_lb->hierarchy = node->hierarchy;
+hmat_lb->data_type = node->data_type;
+
+/* Input latency data */
+if (node->data_type <= HMATLB_DATA_TYPE_WRITE_LATENCY) {
+if (!node->has_latency) {
+error_setg(errp, "Missing 'latency' option.");
+return;
+}
+if (node->has_bandwidth) {
+error_setg(errp, "Invalid option 'bandwidth' since "
+   "the data type is latency.");
+return;
+}
+if (hmat_lb->latency[init * nb_nodes + targ]) {
+error_setg(errp, "Duplicate configuration of the latency for "
+"initiator=%d and target=%d.", init, targ);
+return;
+}
+
+hmat_lb->latency[init * nb_nodes + targ] = node->latency;
+}
+
+/* Input bandwidth data */
+if (node->data_type >= HMATLB_DATA_TYPE_ACCESS_BANDWIDTH) {
+if (!node->has_bandwidth) {
+error_setg(errp, "Missing 'bandwidth' option.");
+return;
+}
+if (node->has_latency) {
+error_setg(errp, "Invalid option 'latency' since "
+   "the data type is bandwidth.");
+return;
+}
+if (hmat_lb->bandwidth[init * nb_nodes + targ]) {
+error_setg(errp, "Duplicate configuration of the bandwidth for "
+"initiator=%d and target=%d.", init, targ);
+return;
+}
+
+/* Convert Byte to Megabyte */
+hmat_lb->bandwidth[init * nb_nodes + targ] =
+node->bandwidth / 1024 / 1024;
+}
+}
+
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
 {
 Error *err = NULL;
@@ -224,6 +318,19 @@ void set_numa_options(MachineState *ms, NumaOptions 
*object, Error **errp)
 machine_set_cpu_numa_node(ms, qapi_NumaCpuOptions_base(&object->u.cpu),
   &err);
 break;
+case NUMA_OPTIONS_TYPE_HMAT_LB:
+if (!ms->numa_state->hmat_enabled) {
+error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
+   "(HMAT) is disabled, use -machine hmat=on before "
+   

[Qemu-devel] [PATCH v11 07/11] numa: Extend CLI to provide memory side cache information

2019-09-11 Thread Tao Xu
From: Liu Jingqi 

Add -numa hmat-cache option to provide Memory Side Cache Information.
These memory attributes help to build Memory Side Cache Information
Structure(s) in ACPI Heterogeneous Memory Attribute Table (HMAT).

Reviewed-by: Daniel Black 
Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v11:
- Move numa option patches forward.
---
 hw/core/numa.c| 74 +++
 include/sysemu/numa.h | 31 +
 qapi/machine.json | 81 +--
 qemu-options.hx   | 16 +++--
 4 files changed, 198 insertions(+), 4 deletions(-)

diff --git a/hw/core/numa.c b/hw/core/numa.c
index 82322734e3..6b8ed8b8c8 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -280,6 +280,67 @@ void parse_numa_hmat_lb(NumaState *nstat, 
NumaHmatLBOptions *node,
 }
 }
 
+void parse_numa_hmat_cache(MachineState *ms, NumaHmatCacheOptions *node,
+   Error **errp)
+{
+int nb_numa_nodes = ms->numa_state->num_nodes;
+HMAT_Cache_Info *hmat_cache = NULL;
+
+if (node->node_id >= nb_numa_nodes) {
+error_setg(errp, "Invalid node-id=%" PRIu32
+   ", it should be less than %d.",
+   node->node_id, nb_numa_nodes);
+return;
+}
+
+if (node->total > MAX_HMAT_CACHE_LEVEL) {
+error_setg(errp, "Invalid total=%" PRIu8
+   ", it should be less than or equal to %d.",
+   node->total, MAX_HMAT_CACHE_LEVEL);
+return;
+}
+if (node->level > node->total) {
+error_setg(errp, "Invalid level=%" PRIu8
+   ", it should be less than or equal to"
+   " total=%" PRIu8 ".",
+   node->level, node->total);
+return;
+}
+if (ms->numa_state->hmat_cache[node->node_id][node->level]) {
+error_setg(errp, "Duplicate configuration of the side cache for "
+   "node-id=%" PRIu32 " and level=%" PRIu8 ".",
+   node->node_id, node->level);
+return;
+}
+
+if ((node->level > 1) &&
+ms->numa_state->hmat_cache[node->node_id][node->level - 1] &&
+(node->size >=
+ms->numa_state->hmat_cache[node->node_id][node->level - 1]->size)) 
{
+error_setg(errp, "Invalid size=0x%" PRIx64
+   ", the size of level=%" PRIu8
+   " should be less than the size(0x%" PRIx64
+   ") of level=%" PRIu8 ".",
+   node->size, node->level,
+   ms->numa_state->hmat_cache[node->node_id]
+ [node->level - 1]->size,
+   node->level - 1);
+return;
+}
+
+hmat_cache = g_malloc0(sizeof(*hmat_cache));
+
+hmat_cache->mem_proximity = node->node_id;
+hmat_cache->size = node->size;
+hmat_cache->total_levels = node->total;
+hmat_cache->level = node->level;
+hmat_cache->associativity = node->assoc;
+hmat_cache->write_policy = node->policy;
+hmat_cache->line_size = node->line;
+
+ms->numa_state->hmat_cache[node->node_id][node->level] = hmat_cache;
+}
+
 void set_numa_options(MachineState *ms, NumaOptions *object, Error **errp)
 {
 Error *err = NULL;
@@ -331,6 +392,19 @@ void set_numa_options(MachineState *ms, NumaOptions 
*object, Error **errp)
 goto end;
 }
 break;
+case NUMA_OPTIONS_TYPE_HMAT_CACHE:
+if (!ms->numa_state->hmat_enabled) {
+error_setg(errp, "ACPI Heterogeneous Memory Attribute Table "
+   "(HMAT) is disabled, use -machine hmat=on before "
+   "set initiator of NUMA");
+return;
+}
+
+parse_numa_hmat_cache(ms, &object->u.hmat_cache, &err);
+if (err) {
+goto end;
+}
+break;
 default:
 abort();
 }
diff --git a/include/sysemu/numa.h b/include/sysemu/numa.h
index 876beaee22..39312eefd4 100644
--- a/include/sysemu/numa.h
+++ b/include/sysemu/numa.h
@@ -35,6 +35,8 @@ enum {
 #define HMAT_LB_LEVELS(HMAT_LB_MEM_CACHE_3RD_LEVEL + 1)
 #define HMAT_LB_TYPES (HMAT_LB_DATA_WRITE_BANDWIDTH + 1)
 
+#define MAX_HMAT_CACHE_LEVEL3
+
 struct NodeInfo {
 uint64_t node_mem;
 struct HostMemoryBackend *node_memdev;
@@ -65,6 +67,30 @@ struct HMAT_LB_Info {
 };
 typedef struct HMAT_LB_Info HMAT_LB_Info;
 
+struct HMAT_Cache_Info {
+/* The memory proximity domain to which the memory belongs. */
+uint32_tmem_proximity;
+
+/* Size of memory side cache in bytes. */
+uint64_tsize;
+
+/* Total cache levels for this memory proximity domain. */
+uint8_t total_levels;
+
+/* Cache level described in this structure. */
+uint8_t level;
+
+/* Cache Associativity: None/Direct Mapped/Comple Cache Indexing */
+uint8_t associativity;
+
+/* Write Policy: None/Write Back(WB)/Write Through(WT) */
+uin

[Qemu-devel] [PATCH v11 11/11] tests/bios-tables-test: add test cases for ACPI HMAT

2019-09-11 Thread Tao Xu
ACPI table HMAT has been introduced, QEMU now builds HMAT tables for
Heterogeneous Memory with boot option '-numa node'.

Add test cases on PC and Q35 machines with 2 numa nodes.
Because HMAT is generated when system enable numa, the
following tables need to be added for this test:
  tests/acpi-test-data/pc/*.acpihmat
  tests/acpi-test-data/pc/HMAT.*
  tests/acpi-test-data/q35/*.acpihmat
  tests/acpi-test-data/q35/HMAT.*

Reviewed-by: Daniel Black 
Reviewed-by: Jingqi Liu 
Suggested-by: Igor Mammedov 
Signed-off-by: Tao Xu 
---

No changes in V11.

Changes in v10:
- Update test case, add "-machine hmat=on"
---
 tests/bios-tables-test.c | 44 
 1 file changed, 44 insertions(+)

diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index 9b3d8b0d1b..976788b6fa 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -870,6 +870,48 @@ static void test_acpi_piix4_tcg_dimm_pxm(void)
 test_acpi_tcg_dimm_pxm(MACHINE_PC);
 }
 
+static void test_acpi_tcg_acpi_hmat(const char *machine)
+{
+test_data data;
+
+memset(&data, 0, sizeof(data));
+data.machine = machine;
+data.variant = ".acpihmat";
+test_acpi_one(" -machine hmat=on"
+  " -smp 2,sockets=2"
+  " -m 128M,slots=2,maxmem=1G"
+  " -object memory-backend-ram,size=64M,id=m0"
+  " -object memory-backend-ram,size=64M,id=m1"
+  " -numa node,nodeid=0,memdev=m0"
+  " -numa node,nodeid=1,memdev=m1,initiator=0"
+  " -numa cpu,node-id=0,socket-id=0"
+  " -numa cpu,node-id=0,socket-id=1"
+  " -numa hmat-lb,initiator=0,target=0,hierarchy=memory,"
+  "data-type=access-latency,latency=5ns"
+  " -numa hmat-lb,initiator=0,target=0,hierarchy=memory,"
+  "data-type=access-bandwidth,bandwidth=500M"
+  " -numa hmat-lb,initiator=0,target=1,hierarchy=memory,"
+  "data-type=access-latency,latency=10ns"
+  " -numa hmat-lb,initiator=0,target=1,hierarchy=memory,"
+  "data-type=access-bandwidth,bandwidth=100M"
+  " -numa hmat-cache,node-id=0,size=0x2,total=1,level=1"
+  ",assoc=direct,policy=write-back,line=8"
+  " -numa hmat-cache,node-id=1,size=0x2,total=1,level=1"
+  ",assoc=direct,policy=write-back,line=8",
+  &data);
+free_test_data(&data);
+}
+
+static void test_acpi_q35_tcg_acpi_hmat(void)
+{
+test_acpi_tcg_acpi_hmat(MACHINE_Q35);
+}
+
+static void test_acpi_piix4_tcg_acpi_hmat(void)
+{
+test_acpi_tcg_acpi_hmat(MACHINE_PC);
+}
+
 static void test_acpi_virt_tcg(void)
 {
 test_data data = {
@@ -914,6 +956,8 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem);
 qtest_add_func("acpi/piix4/dimmpxm", test_acpi_piix4_tcg_dimm_pxm);
 qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
+qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
+qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
 } else if (strcmp(arch, "aarch64") == 0) {
 qtest_add_func("acpi/virt", test_acpi_virt_tcg);
 }
-- 
2.20.1




[Qemu-devel] [PATCH v11 04/11] tests: Add test for QAPI builtin type time

2019-09-11 Thread Tao Xu
Add tests for time input such as zero, around limit of precision,
signed upper limit, actual upper limit, beyond limits, time suffixes,
and etc.

Signed-off-by: Tao Xu 
---

No changes in v11.

New patch in v10.
---
 tests/test-keyval.c| 125 +
 tests/test-qobject-input-visitor.c |  29 +++
 2 files changed, 154 insertions(+)

diff --git a/tests/test-keyval.c b/tests/test-keyval.c
index 09b0ae3c68..b36914f0fc 100644
--- a/tests/test-keyval.c
+++ b/tests/test-keyval.c
@@ -490,6 +490,130 @@ static void test_keyval_visit_size(void)
 visit_free(v);
 }
 
+static void test_keyval_visit_time(void)
+{
+Error *err = NULL;
+Visitor *v;
+QDict *qdict;
+uint64_t time;
+
+/* Lower limit zero */
+qdict = keyval_parse("time1=0", NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &error_abort);
+g_assert_cmpuint(time, ==, 0);
+visit_check_struct(v, &error_abort);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Around limit of precision: 2^53-1, 2^53, 2^53+1 */
+qdict = keyval_parse("time1=9007199254740991,"
+ "time2=9007199254740992,"
+ "time3=9007199254740993",
+ NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &error_abort);
+g_assert_cmphex(time, ==, 0x1f);
+visit_type_time(v, "time2", &time, &error_abort);
+g_assert_cmphex(time, ==, 0x20);
+visit_type_time(v, "time3", &time, &error_abort);
+g_assert_cmphex(time, ==, 0x20);
+visit_check_struct(v, &error_abort);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Close to signed upper limit 0x7c00 (53 msbs set) */
+qdict = keyval_parse("time1=9223372036854774784," /* 7c00 */
+ "time2=9223372036854775295", /* 7dff */
+ NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &error_abort);
+g_assert_cmphex(time, ==, 0x7c00);
+visit_type_time(v, "time2", &time, &error_abort);
+g_assert_cmphex(time, ==, 0x7c00);
+visit_check_struct(v, &error_abort);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Close to actual upper limit 0xf800 (53 msbs set) */
+qdict = keyval_parse("time1=18446744073709549568," /* f800 */
+ "time2=18446744073709550591", /* fbff */
+ NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &error_abort);
+g_assert_cmphex(time, ==, 0xf800);
+visit_type_time(v, "time2", &time, &error_abort);
+g_assert_cmphex(time, ==, 0xf800);
+visit_check_struct(v, &error_abort);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Beyond limits */
+qdict = keyval_parse("time1=-1,"
+ "time2=18446744073709550592", /* fc00 */
+ NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &err);
+error_free_or_abort(&err);
+visit_type_time(v, "time2", &time, &err);
+error_free_or_abort(&err);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Suffixes */
+qdict = keyval_parse("time1=2ps,time2=3.4ns,time3=5us,"
+ "time4=0.6ms,time5=700s",
+ NULL, &error_abort);
+v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
+qobject_unref(qdict);
+visit_start_struct(v, NULL, NULL, 0, &error_abort);
+visit_type_time(v, "time1", &time, &error_abort);
+g_assert_cmpuint(time, ==, 2);
+visit_type_time(v, "time2", &time, &error_abort);
+g_assert_cmpuint(time, ==, 3400);
+visit_type_time(v, "time3", &time, &error_abort);
+g_assert_cmphex(time, ==, 5 * 1000 * 1000);
+visit_type_time(v, "time4", &time, &error_abort);
+g_assert_cmphex(time, ==, 600 * 1000 * 1000);
+visit_type_time(v, "time5", &time, &error_abort);
+g_assert_cmphex(time, ==, 700 * 1ULL);
+visit_check_struct(v, &error_abort);
+visit_end_struct(v, NULL);
+visit_free(v);
+
+/* Beyond limit with suffix */
+qdict = keyval_parse("time1=18446745s", NULL, &error_abort);
+

[Qemu-devel] [PATCH v11 05/11] numa: Extend CLI to provide initiator information for numa nodes

2019-09-11 Thread Tao Xu
In ACPI 6.3 chapter 5.2.27 Heterogeneous Memory Attribute Table (HMAT),
The initiator represents processor which access to memory. And in 5.2.27.3
Memory Proximity Domain Attributes Structure, the attached initiator is
defined as where the memory controller responsible for a memory proximity
domain. With attached initiator information, the topology of heterogeneous
memory can be described.

Extend CLI of "-numa node" option to indicate the initiator numa node-id.
In the linux kernel, the codes in drivers/acpi/hmat/hmat.c parse and report
the platform's HMAT tables.

Suggested-by: Dan Williams 
Signed-off-by: Tao Xu 
---

No changes in v11.

Changes in v10:
- Add machine oprion properties "-machine hmat=on|off" for
enabling or disabling HMAT in QEMU.
- Add more description for initiator option.
- Report error then HMAT is enalbe and initiator option is
missing. Not allow invaild initiator now. (Igor)
---
 hw/core/machine.c | 72 +++
 hw/core/numa.c| 11 +++
 include/sysemu/numa.h |  6 
 qapi/machine.json | 10 +-
 qemu-options.hx   | 35 ++---
 5 files changed, 128 insertions(+), 6 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1689ad3bf8..b42f574282 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -518,6 +518,20 @@ static void machine_set_nvdimm(Object *obj, bool value, 
Error **errp)
 ms->nvdimms_state->is_enabled = value;
 }
 
+static bool machine_get_hmat(Object *obj, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+return ms->numa_state->hmat_enabled;
+}
+
+static void machine_set_hmat(Object *obj, bool value, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+ms->numa_state->hmat_enabled = value;
+}
+
 static char *machine_get_nvdimm_persistence(Object *obj, Error **errp)
 {
 MachineState *ms = MACHINE(obj);
@@ -645,6 +659,7 @@ void machine_set_cpu_numa_node(MachineState *machine,
const CpuInstanceProperties *props, Error 
**errp)
 {
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+NodeInfo *numa_info = machine->numa_state->nodes;
 bool match = false;
 int i;
 
@@ -714,6 +729,16 @@ void machine_set_cpu_numa_node(MachineState *machine,
 match = true;
 slot->props.node_id = props->node_id;
 slot->props.has_node_id = props->has_node_id;
+
+if (numa_info[props->node_id].initiator_valid &&
+(props->node_id != numa_info[props->node_id].initiator)) {
+error_setg(errp, "The initiator of CPU NUMA node %" PRId64
+   " should be itself.", props->node_id);
+return;
+}
+numa_info[props->node_id].initiator_valid = true;
+numa_info[props->node_id].has_cpu = true;
+numa_info[props->node_id].initiator = props->node_id;
 }
 
 if (!match) {
@@ -960,6 +985,13 @@ static void machine_initfn(Object *obj)
 
 if (mc->numa_mem_supported) {
 ms->numa_state = g_new0(NumaState, 1);
+object_property_add_bool(obj, "hmat",
+ machine_get_hmat, machine_set_hmat,
+ &error_abort);
+object_property_set_description(obj, "hmat",
+"Set on/off to enable/disable "
+"ACPI Heterogeneous Memory Attribute "
+"Table (HMAT)", NULL);
 }
 
 /* Register notifier when init is done for sysbus sanity checks */
@@ -1048,6 +1080,41 @@ static char *cpu_slot_to_string(const CPUArchId *cpu)
 return g_string_free(s, false);
 }
 
+static void numa_validate_initiator(NumaState *nstat)
+{
+int i;
+NodeInfo *numa_info = nstat->nodes;
+
+for (i = 0; i < nstat->num_nodes; i++) {
+if (numa_info[i].initiator >= MAX_NODES) {
+error_report("The initiator id %" PRIu16 " expects an integer "
+ "between 0 and %d", numa_info[i].initiator,
+ MAX_NODES - 1);
+goto err;
+}
+
+if (!numa_info[numa_info[i].initiator].present) {
+error_report("NUMA node %" PRIu16 " is missing, use "
+ "'-numa node' option to declare it first.",
+ numa_info[i].initiator);
+goto err;
+}
+
+if (numa_info[numa_info[i].initiator].has_cpu) {
+numa_info[i].initiator_valid = true;
+} else {
+error_report("The initiator of NUMA node %d is invalid.", i);
+goto err;
+}
+}
+
+return;
+
+err:
+error_printf("\n");
+exit(1);
+}
+
 static void machine_numa_finish_cpu_init(MachineState *machine)
 {
 int i;
@@ -1088,6 +1155,11 @@ static void machine_numa_finish_cpu_init(MachineState 
*machine)
 machine_set_cpu_numa_node(machine, &props, &error_fatal);
 }

[Qemu-devel] [PATCH v11 09/11] hmat acpi: Build System Locality Latency and Bandwidth Information Structure(s)

2019-09-11 Thread Tao Xu
From: Liu Jingqi 

This structure describes the memory access latency and bandwidth
information from various memory access initiator proximity domains.
The latency and bandwidth numbers represented in this structure
correspond to rated latency and bandwidth for the platform.
The software could use this information as hint for optimization.

Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v11:
- Calculate base in build_hmat_lb().
---
 hw/acpi/hmat.c | 123 -
 hw/acpi/hmat.h |   2 +
 2 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
index 1368fce7ee..2d76dd0cd1 100644
--- a/hw/acpi/hmat.c
+++ b/hw/acpi/hmat.c
@@ -27,6 +27,7 @@
 #include "qemu/osdep.h"
 #include "sysemu/numa.h"
 #include "hw/acpi/hmat.h"
+#include "qemu/error-report.h"
 
 /*
  * ACPI 6.3:
@@ -67,11 +68,105 @@ static void build_hmat_mpda(GArray *table_data, uint16_t 
flags, int initiator,
 build_append_int_noprefix(table_data, 0, 8);
 }
 
+static bool entry_overflow(uint64_t *lb_data, uint64_t base, int len)
+{
+int i;
+
+for (i = 0; i < len; i++) {
+if (lb_data[i] / base >= UINT16_MAX) {
+return true;
+}
+}
+
+return false;
+}
+/*
+ * ACPI 6.3: 5.2.27.4 System Locality Latency and Bandwidth Information
+ * Structure: Table 5-146
+ */
+static void build_hmat_lb(GArray *table_data, HMAT_LB_Info *hmat_lb,
+  uint32_t num_initiator, uint32_t num_target,
+  uint32_t *initiator_list, int type)
+{
+uint8_t mask = 0x0f;
+uint32_t s = num_initiator;
+uint32_t t = num_target;
+uint64_t base = 1;
+uint64_t *lb_data;
+int i, unit;
+
+/* Type */
+build_append_int_noprefix(table_data, 1, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Length */
+build_append_int_noprefix(table_data, 32 + 4 * s + 4 * t + 2 * s * t, 4);
+/* Flags: Bits [3:0] Memory Hierarchy, Bits[7:4] Reserved */
+build_append_int_noprefix(table_data, hmat_lb->hierarchy & mask, 1);
+/* Data Type */
+build_append_int_noprefix(table_data, hmat_lb->data_type, 1);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Number of Initiator Proximity Domains (s) */
+build_append_int_noprefix(table_data, s, 4);
+/* Number of Target Proximity Domains (t) */
+build_append_int_noprefix(table_data, t, 4);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);
+
+if (HMAT_IS_LATENCY(type)) {
+unit = 1000;
+lb_data = hmat_lb->latency;
+} else {
+unit = 1024;
+lb_data = hmat_lb->bandwidth;
+}
+
+while (entry_overflow(lb_data, base, s * t)) {
+for (i = 0; i < s * t; i++) {
+if (!QEMU_IS_ALIGNED(lb_data[i], unit * base)) {
+error_report("Invalid latency/bandwidth input, all "
+"latencies/bandwidths should be specified in the same units.");
+exit(1);
+}
+}
+base *= unit;
+}
+
+/* Entry Base Unit */
+build_append_int_noprefix(table_data, base, 8);
+
+/* Initiator Proximity Domain List */
+for (i = 0; i < s; i++) {
+build_append_int_noprefix(table_data, initiator_list[i], 4);
+}
+
+/* Target Proximity Domain List */
+for (i = 0; i < t; i++) {
+build_append_int_noprefix(table_data, i, 4);
+}
+
+/* Latency or Bandwidth Entries */
+for (i = 0; i < s * t; i++) {
+uint16_t entry;
+
+if (HMAT_IS_LATENCY(type)) {
+entry = hmat_lb->latency[i] / base;
+} else {
+entry = hmat_lb->bandwidth[i] / base;
+}
+
+build_append_int_noprefix(table_data, entry, 2);
+}
+}
+
 /* Build HMAT sub table structures */
 static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
 {
 uint16_t flags;
-int i;
+uint32_t *initiator_list;
+int i, j, hrchy, type;
+HMAT_LB_Info *numa_hmat_lb;
 
 for (i = 0; i < nstat->num_nodes; i++) {
 flags = 0;
@@ -82,6 +177,32 @@ static void hmat_build_table_structs(GArray *table_data, 
NumaState *nstat)
 
 build_hmat_mpda(table_data, flags, nstat->nodes[i].initiator, i);
 }
+
+initiator_list = g_malloc0(nstat->num_initiator * sizeof(uint32_t));
+for (i = 0, j = 0; i < nstat->num_nodes; i++) {
+if (nstat->nodes[i].has_cpu) {
+initiator_list[j] = i;
+j++;
+}
+}
+
+/*
+ * ACPI 6.3: 5.2.27.4 System Locality Latency and Bandwidth Information
+ * Structure: Table 5-146
+ */
+for (hrchy = HMAT_LB_MEM_MEMORY;
+ hrchy <= HMAT_LB_MEM_CACHE_3RD_LEVEL; hrchy++) {
+for (type = HMAT_LB_DATA_ACCESS_LATENCY;
+ type <= HMAT_LB_DATA_WRITE_BANDWIDTH; type++) {
+numa_hmat_lb = nstat->hmat_lb[hrchy][type];
+
+if (numa_hmat_lb) {
+

[Qemu-devel] [PATCH v11 00/11] Build ACPI Heterogeneous Memory Attribute Table (HMAT)

2019-09-11 Thread Tao Xu
This series of patches will build Heterogeneous Memory Attribute Table (HMAT)
according to the command line. The ACPI HMAT describes the memory attributes,
such as memory side cache attributes and bandwidth and latency details,
related to the Memory Proximity Domain.
The software is expected to use HMAT information as hint for optimization.

In the linux kernel, the codes in drivers/acpi/hmat/hmat.c parse and report
the platform's HMAT tables.

The V10 patches link:
https://patchwork.kernel.org/cover/11125287/

Changelog:
v11:
- Move numa option patches forward.
- Add num_initiator in Numa_state to record the number of
initiators.
- Simplify struct HMAT_LB_Info, use uint64_t array to store data.
- Drop hmat_get_base().
- Calculate base in build_hmat_lb().
v10:
- Add qemu_strtotime_ps() to convert strings with time suffixes
to numbers, and add some tests for it.
- Add qapi buildin type time, and add some tests for it.
- Add machine oprion properties "-machine hmat=on|off" for
  enabling or disabling HMAT in QEMU.
v9:
- change the CLI input way, make it more user firendly (Daniel Black)
use latency=NUM[p|n|u]s and bandwidth=NUM[M|G|P](B/s) as input and drop
the base-lat and base-bw input.

Liu Jingqi (5):
  numa: Extend CLI to provide memory latency and bandwidth information
  numa: Extend CLI to provide memory side cache information
  hmat acpi: Build Memory Proximity Domain Attributes Structure(s)
  hmat acpi: Build System Locality Latency and Bandwidth Information
Structure(s)
  hmat acpi: Build Memory Side Cache Information Structure(s)

Tao Xu (6):
  util/cutils: Add qemu_strtotime_ps()
  tests/cutils: Add test for qemu_strtotime_ps()
  qapi: Add builtin type time
  tests: Add test for QAPI builtin type time
  numa: Extend CLI to provide initiator information for numa nodes
  tests/bios-tables-test: add test cases for ACPI HMAT

 hw/acpi/Kconfig|   5 +
 hw/acpi/Makefile.objs  |   1 +
 hw/acpi/hmat.c | 284 +
 hw/acpi/hmat.h |  47 +
 hw/core/machine.c  |  72 
 hw/core/numa.c | 199 
 hw/i386/acpi-build.c   |   5 +
 include/qapi/visitor-impl.h|   4 +
 include/qapi/visitor.h |   9 +
 include/qemu/cutils.h  |   1 +
 include/sysemu/numa.h  |  81 
 qapi/machine.json  | 182 +-
 qapi/opts-visitor.c|  22 +++
 qapi/qapi-visit-core.c |  12 ++
 qapi/qobject-input-visitor.c   |  18 ++
 qapi/trace-events  |   1 +
 qemu-options.hx|  96 +-
 scripts/qapi/common.py |   2 +
 tests/bios-tables-test.c   |  44 +
 tests/test-cutils.c| 199 
 tests/test-keyval.c| 125 +
 tests/test-qobject-input-visitor.c |  29 +++
 util/cutils.c  |  82 +
 23 files changed, 1511 insertions(+), 9 deletions(-)
 create mode 100644 hw/acpi/hmat.c
 create mode 100644 hw/acpi/hmat.h

-- 
2.20.1




[Qemu-devel] [PATCH v11 08/11] hmat acpi: Build Memory Proximity Domain Attributes Structure(s)

2019-09-11 Thread Tao Xu
From: Liu Jingqi 

HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
(HMAT). The specification references below link:
http://www.uefi.org/sites/default/files/resources/ACPI_6_3_final_Jan30.pdf

It describes the memory attributes, such as memory side cache
attributes and bandwidth and latency details, related to the
Memory Proximity Domain. The software is
expected to use this information as hint for optimization.

This structure describes Memory Proximity Domain Attributes by memory
subsystem and its associativity with processor proximity domain as well as
hint for memory usage.

In the linux kernel, the codes in drivers/acpi/hmat/hmat.c parse and report
the platform's HMAT tables.

Reviewed-by: Daniel Black 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Liu Jingqi 
Signed-off-by: Tao Xu 
---

Changes in v11:
- Move numa option patches forward.
---
 hw/acpi/Kconfig   |   5 +++
 hw/acpi/Makefile.objs |   1 +
 hw/acpi/hmat.c| 101 ++
 hw/acpi/hmat.h|  45 +++
 hw/i386/acpi-build.c  |   5 +++
 5 files changed, 157 insertions(+)
 create mode 100644 hw/acpi/hmat.c
 create mode 100644 hw/acpi/hmat.h

diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 7c59cf900b..039bb99efa 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -7,6 +7,7 @@ config ACPI_X86
 select ACPI_NVDIMM
 select ACPI_CPU_HOTPLUG
 select ACPI_MEMORY_HOTPLUG
+select ACPI_HMAT
 
 config ACPI_X86_ICH
 bool
@@ -31,3 +32,7 @@ config ACPI_VMGENID
 bool
 default y
 depends on PC
+
+config ACPI_HMAT
+bool
+depends on ACPI
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 9bb2101e3b..c05019b059 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -6,6 +6,7 @@ common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
 common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
 common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
+common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
 common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
 
 common-obj-y += acpi_interface.o
diff --git a/hw/acpi/hmat.c b/hw/acpi/hmat.c
new file mode 100644
index 00..1368fce7ee
--- /dev/null
+++ b/hw/acpi/hmat.c
@@ -0,0 +1,101 @@
+/*
+ * HMAT ACPI Implementation
+ *
+ * Copyright(C) 2019 Intel Corporation.
+ *
+ * Author:
+ *  Liu jingqi 
+ *  Tao Xu 
+ *
+ * HMAT is defined in ACPI 6.3: 5.2.27 Heterogeneous Memory Attribute Table
+ * (HMAT)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/numa.h"
+#include "hw/acpi/hmat.h"
+
+/*
+ * ACPI 6.3:
+ * 5.2.27.3 Memory Proximity Domain Attributes Structure: Table 5-145
+ */
+static void build_hmat_mpda(GArray *table_data, uint16_t flags, int initiator,
+   int mem_node)
+{
+
+/* Memory Proximity Domain Attributes Structure */
+/* Type */
+build_append_int_noprefix(table_data, 0, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Length */
+build_append_int_noprefix(table_data, 40, 4);
+/* Flags */
+build_append_int_noprefix(table_data, flags, 2);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 2);
+/* Proximity Domain for the Attached Initiator */
+build_append_int_noprefix(table_data, initiator, 4);
+/* Proximity Domain for the Memory */
+build_append_int_noprefix(table_data, mem_node, 4);
+/* Reserved */
+build_append_int_noprefix(table_data, 0, 4);
+/*
+ * Reserved:
+ * Previously defined as the Start Address of the System Physical
+ * Address Range. Deprecated since ACPI Spec 6.3.
+ */
+build_append_int_noprefix(table_data, 0, 8);
+/*
+ * Reserved:
+ * Previously defined as the Range Length of the region in bytes.
+ * Deprecated since ACPI Spec 6.3.
+ */
+build_append_int_noprefix(table_data, 0, 8);
+}
+
+/* Build HMAT sub table structures */
+static void hmat_build_table_structs(GArray *table_data, NumaState *nstat)
+{
+uint16_t flags;
+int i;
+
+for (i = 0; i < nstat->num_nodes; i++) {
+flags = 0;
+
+if (nstat->nodes[i].initiator_valid) {
+flags |= HMAT_PROX_INIT_VALID;
+}
+
+build_hmat_mpda(table_data, flags, nstat->nodes[i].initiator, 

[Qemu-devel] [PATCH v11 01/11] util/cutils: Add qemu_strtotime_ps()

2019-09-11 Thread Tao Xu
To convert strings with time suffixes to numbers, support time unit are
"ps" for picosecond, "ns" for nanosecond, "us" for microsecond, "ms"
for millisecond or "s" for second.

Signed-off-by: Tao Xu 
---

No changes in v11.

New patch in v10.
---
 include/qemu/cutils.h |  1 +
 util/cutils.c | 82 +++
 2 files changed, 83 insertions(+)

diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 12301340a4..0e70a807e1 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -180,5 +180,6 @@ int uleb128_decode_small(const uint8_t *in, uint32_t *n);
  * *str1 is <, == or > than *str2.
  */
 int qemu_pstrcmp0(const char **str1, const char **str2);
+int qemu_strtotime_ps(const char *nptr, const char **end, uint64_t *result);
 
 #endif
diff --git a/util/cutils.c b/util/cutils.c
index fd591cadf0..a50c15f46a 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -847,3 +847,85 @@ int qemu_pstrcmp0(const char **str1, const char **str2)
 {
 return g_strcmp0(*str1, *str2);
 }
+
+static int64_t timeunit_mul(const char *unitstr)
+{
+if (g_strcmp0(unitstr, "ps") == 0) {
+return 1;
+} else if (g_strcmp0(unitstr, "ns") == 0) {
+return 1000;
+} else if (g_strcmp0(unitstr, "us") == 0) {
+return 100;
+} else if (g_strcmp0(unitstr, "ms") == 0) {
+return 10LL;
+} else if (g_strcmp0(unitstr, "s") == 0) {
+return 1LL;
+} else {
+return -1;
+}
+}
+
+
+/*
+ * Convert string to time, support time unit are ps for picosecond,
+ * ns for nanosecond, us for microsecond, ms for millisecond or s for second.
+ * End pointer will be returned in *end, if not NULL. Return -ERANGE on
+ * overflow, and -EINVAL on other error.
+ */
+static int do_strtotime(const char *nptr, const char **end,
+  const char *default_unit, uint64_t *result)
+{
+int retval;
+const char *endptr;
+int mul_required = 0;
+int64_t mul;
+double val, integral, fraction;
+
+retval = qemu_strtod_finite(nptr, &endptr, &val);
+if (retval) {
+goto out;
+}
+fraction = modf(val, &integral);
+if (fraction != 0) {
+mul_required = 1;
+}
+
+mul = timeunit_mul(endptr);
+
+if (mul == 1LL) {
+endptr++;
+} else if (mul != -1) {
+endptr += 2;
+} else {
+mul = timeunit_mul(default_unit);
+assert(mul >= 0);
+}
+if (mul == 1 && mul_required) {
+retval = -EINVAL;
+goto out;
+}
+/*
+ * Values >= 0xfc00 overflow uint64_t after their trip
+ * through double (53 bits of precision).
+ */
+if ((val * (double)mul >= 0xfc00) || val < 0) {
+retval = -ERANGE;
+goto out;
+}
+*result = val * (double)mul;
+retval = 0;
+
+out:
+if (end) {
+*end = endptr;
+} else if (*endptr) {
+retval = -EINVAL;
+}
+
+return retval;
+}
+
+int qemu_strtotime_ps(const char *nptr, const char **end, uint64_t *result)
+{
+return do_strtotime(nptr, end, "ps", result);
+}
-- 
2.20.1




[Qemu-devel] [PATCH v11 03/11] qapi: Add builtin type time

2019-09-11 Thread Tao Xu
Add optional builtin type time, fallback is uint64. This type use
qemu_strtotime_ps() for pre-converting time suffix to numbers.

Signed-off-by: Tao Xu 
---

No changes in v11.

New patch in v10.
---
 include/qapi/visitor-impl.h  |  4 
 include/qapi/visitor.h   |  9 +
 qapi/opts-visitor.c  | 22 ++
 qapi/qapi-visit-core.c   | 12 
 qapi/qobject-input-visitor.c | 18 ++
 qapi/trace-events|  1 +
 scripts/qapi/common.py   |  2 ++
 7 files changed, 68 insertions(+)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 8ccb3b6c20..e0979563c7 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -88,6 +88,10 @@ struct Visitor
 void (*type_size)(Visitor *v, const char *name, uint64_t *obj,
   Error **errp);
 
+/* Optional; fallback is type_uint64() */
+void (*type_time)(Visitor *v, const char *name, uint64_t *obj,
+  Error **errp);
+
 /* Must be set */
 void (*type_bool)(Visitor *v, const char *name, bool *obj, Error **errp);
 
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 5b2ed3f202..4c3198b1c5 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -554,6 +554,15 @@ void visit_type_int64(Visitor *v, const char *name, 
int64_t *obj,
 void visit_type_size(Visitor *v, const char *name, uint64_t *obj,
  Error **errp);
 
+/*
+ * Visit a uint64_t value.
+ * Like visit_type_uint64(), except that some visitors may choose to
+ * recognize numbers with timeunit suffix, such as "ps", "ns", "us"
+ * "ms" and "s".
+ */
+void visit_type_time(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp);
+
 /*
  * Visit a boolean value.
  *
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 324b197495..d73b2e51a0 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -508,6 +508,27 @@ opts_type_size(Visitor *v, const char *name, uint64_t 
*obj, Error **errp)
 processed(ov, name);
 }
 
+static void
+opts_type_time(Visitor *v, const char *name, uint64_t *obj, Error **errp)
+{
+OptsVisitor *ov = to_ov(v);
+const QemuOpt *opt;
+int err;
+
+opt = lookup_scalar(ov, name, errp);
+if (!opt) {
+return;
+}
+
+err = qemu_strtotime_ps(opt->str ? opt->str : "", NULL, obj);
+if (err < 0) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
+   "a time value");
+return;
+}
+
+processed(ov, name);
+}
 
 static void
 opts_optional(Visitor *v, const char *name, bool *present)
@@ -555,6 +576,7 @@ opts_visitor_new(const QemuOpts *opts)
 ov->visitor.type_int64  = &opts_type_int64;
 ov->visitor.type_uint64 = &opts_type_uint64;
 ov->visitor.type_size   = &opts_type_size;
+ov->visitor.type_time   = &opts_type_time;
 ov->visitor.type_bool   = &opts_type_bool;
 ov->visitor.type_str= &opts_type_str;
 
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 5365561b07..ac8896455c 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -277,6 +277,18 @@ void visit_type_size(Visitor *v, const char *name, 
uint64_t *obj,
 }
 }
 
+void visit_type_time(Visitor *v, const char *name, uint64_t *obj,
+ Error **errp)
+{
+assert(obj);
+trace_visit_type_time(v, name, obj);
+if (v->type_time) {
+v->type_time(v, name, obj, errp);
+} else {
+v->type_uint64(v, name, obj, errp);
+}
+}
+
 void visit_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
 {
 assert(obj);
diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c
index 32236cbcb1..9b66941d8a 100644
--- a/qapi/qobject-input-visitor.c
+++ b/qapi/qobject-input-visitor.c
@@ -627,6 +627,23 @@ static void qobject_input_type_size_keyval(Visitor *v, 
const char *name,
 }
 }
 
+static void qobject_input_type_time_keyval(Visitor *v, const char *name,
+   uint64_t *obj, Error **errp)
+{
+QObjectInputVisitor *qiv = to_qiv(v);
+const char *str = qobject_input_get_keyval(qiv, name, errp);
+
+if (!str) {
+return;
+}
+
+if (qemu_strtotime_ps(str, NULL, obj) < 0) {
+/* TODO report -ERANGE more nicely */
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+   full_name(qiv, name), "time");
+}
+}
+
 static void qobject_input_optional(Visitor *v, const char *name, bool *present)
 {
 QObjectInputVisitor *qiv = to_qiv(v);
@@ -708,6 +725,7 @@ Visitor *qobject_input_visitor_new_keyval(QObject *obj)
 v->visitor.type_any = qobject_input_type_any;
 v->visitor.type_null = qobject_input_type_null;
 v->visitor.type_size = qobject_input_type_size_keyval;
+v->visitor.type_time = qobject_input_type_time_keyval;
 v->keyval = true;
 
 return &v->visitor;
diff --git a/qapi/trace-events b/qapi/trace-events

[Qemu-devel] [PATCH v11 02/11] tests/cutils: Add test for qemu_strtotime_ps()

2019-09-11 Thread Tao Xu
Test the input of basic, time suffixes, float, invaild, trailing and
overflow.

Signed-off-by: Tao Xu 
---

No changes in v11.

New patch in v10.
---
 tests/test-cutils.c | 199 
 1 file changed, 199 insertions(+)

diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 1aa8351520..19c967d3d5 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -2179,6 +2179,193 @@ static void test_qemu_strtosz_metric(void)
 g_assert(endptr == str + 6);
 }
 
+static void test_qemu_strtotime_ps_simple(void)
+{
+const char *str;
+const char *endptr;
+int err;
+uint64_t res = 0xbaadf00d;
+
+str = "0";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0);
+g_assert(endptr == str + 1);
+
+str = "56789";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 56789);
+g_assert(endptr == str + 5);
+
+err = qemu_strtotime_ps(str, NULL, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 56789);
+
+/* Note: precision is 53 bits since we're parsing with strtod() */
+
+str = "9007199254740991"; /* 2^53-1 */
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0x1f);
+g_assert(endptr == str + 16);
+
+str = "9007199254740992"; /* 2^53 */
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0x20);
+g_assert(endptr == str + 16);
+
+str = "9007199254740993"; /* 2^53+1 */
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0x20); /* rounded to 53 bits */
+g_assert(endptr == str + 16);
+
+str = "18446744073709549568"; /* 0xf800 (53 msbs set) */
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0xf800);
+g_assert(endptr == str + 20);
+
+str = "18446744073709550591"; /* 0xfbff */
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 0xf800); /* rounded to 53 bits */
+g_assert(endptr == str + 20);
+
+/* 0x7e00..0x7fff get rounded to
+ * 0x8000, thus -ERANGE; see test_qemu_strtosz_erange() */
+}
+
+static void test_qemu_strtotime_ps_units(void)
+{
+const char *ps = "1ps";
+const char *ns = "1ns";
+const char *us = "1us";
+const char *ms = "1ms";
+const char *s = "1s";
+int err;
+const char *endptr;
+uint64_t res = 0xbaadf00d;
+
+err = qemu_strtotime_ps(ps, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 1);
+g_assert(endptr == ps + 3);
+
+err = qemu_strtotime_ps(ns, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 1000);
+g_assert(endptr == ns + 3);
+
+err = qemu_strtotime_ps(us, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 100);
+g_assert(endptr == us + 3);
+
+err = qemu_strtotime_ps(ms, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 10LL);
+g_assert(endptr == ms + 3);
+
+err = qemu_strtotime_ps(s, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 1ULL);
+g_assert(endptr == s + 2);
+}
+
+static void test_qemu_strtotime_ps_float(void)
+{
+const char *str = "56.789ns";
+int err;
+const char *endptr;
+uint64_t res = 0xbaadf00d;
+
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, 0);
+g_assert_cmpint(res, ==, 56.789 * 1000);
+g_assert(endptr == str + 8);
+}
+
+static void test_qemu_strtotime_ps_invalid(void)
+{
+const char *str;
+const char *endptr;
+int err;
+uint64_t res = 0xbaadf00d;
+
+str = "";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+g_assert(endptr == str);
+
+str = " \t ";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+g_assert(endptr == str);
+
+str = "crap";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+g_assert(endptr == str);
+
+str = "inf";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+g_assert(endptr == str);
+
+str = "NaN";
+err = qemu_strtotime_ps(str, &endptr, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+g_assert(endptr == str);
+}
+
+static void test_qemu_strtotime_ps_trailing(void)
+{
+const char *str;
+int err;
+uint64_t res = 0xbaadf00d;
+
+str = "123xxx";
+
+err = qemu_strtotime_ps(str, NULL, &res);
+g_assert_cmpint(err, ==, -EINVAL);
+}
+
+static voi

[Qemu-devel] [Bug 1843151] Re: Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

2019-09-11 Thread James Harvey
Sorry, in comment #2 for the native graphics window command line, I
copied from the wrong trial.  The argument for QXL should have been
included, because that works with a native graphics window:

   (...bootindex=0) \
   -vga qxl

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

Title:
  Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

Status in QEMU:
  New

Bug description:
  Host is Arch Linux.  linux 5.2.13, qemu 4.1.0.  virt-viewer 8.0.

  Guest is Arch Linux Sept 2019 ISO.  linux 5.2.11.

  Have replicated this both on a system using amdgpu and one using
  integrated ASPEED graphics.

  Downgrading from 4.1.0 to 4.0.0 works as usual, see:
  https://www.youtube.com/watch?v=NyMdcYwOCvY

  Going back to 4.1.0 reproduces, see:
  https://www.youtube.com/watch?v=H3nGG2Mk6i0

  4.1.0 displays fine until KMS kicks in.

  Using 4.1.0 with virtio-vga doesn't cause this.

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



[Qemu-devel] [PATCH] ppc: Add support for 'mffscrn', 'mffscrni' instructions

2019-09-11 Thread Paul A. Clarke
From: "Paul A. Clarke" 

ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR)
instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl.
This patch adds support for 'mffscrn' and 'mffscrni' instructions.

'mffscrn' and 'mffscrni' are identical to 'mffsl', except they also set
the rounding mode in the FPSCR.

On CPUs without support for 'mffscrn'/'mffscrni' (below ISA 3.0), the
instructions will execute identically to 'mffs'.

Signed-off-by: Paul A. Clarke 
---
 target/ppc/internal.h  |  3 ++
 target/ppc/translate/fp-impl.inc.c | 66 ++
 target/ppc/translate/fp-ops.inc.c  |  2 ++
 3 files changed, 71 insertions(+)

diff --git a/target/ppc/internal.h b/target/ppc/internal.h
index d3d327e..15d655b 100644
--- a/target/ppc/internal.h
+++ b/target/ppc/internal.h
@@ -157,6 +157,9 @@ EXTRACT_HELPER(FPL, 25, 1);
 EXTRACT_HELPER(FPFLM, 17, 8);
 EXTRACT_HELPER(FPW, 16, 1);
 
+/* mffscrni */
+EXTRACT_HELPER(RM, 11, 2);
+
 /* addpcis */
 EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
 #if defined(TARGET_PPC64)
diff --git a/target/ppc/translate/fp-impl.inc.c 
b/target/ppc/translate/fp-impl.inc.c
index 7cd9d8d..70a4788 100644
--- a/target/ppc/translate/fp-impl.inc.c
+++ b/target/ppc/translate/fp-impl.inc.c
@@ -639,6 +639,72 @@ static void gen_mffsl(DisasContext *ctx)
 tcg_temp_free_i64(t0);
 }
 
+static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1)
+{
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i32 mask = tcg_const_i32(0x0001);
+
+gen_reset_fpstatus();
+tcg_gen_extu_tl_i64(t0, cpu_fpscr);
+set_fpr(rD(ctx->opcode), t0);
+
+/* Mask FPSCR value to clear RN.  */
+tcg_gen_andi_i64(t0, t0, ~FP_MODE);
+
+/* Merge RN into FPSCR value.  */
+tcg_gen_or_i64(t0, t0, t1);
+
+gen_helper_store_fpscr(cpu_env, t0, mask);
+
+tcg_temp_free_i32(mask);
+tcg_temp_free_i64(t0);
+}
+
+/* mffscrn */
+static void gen_mffscrn(DisasContext *ctx)
+{
+TCGv_i64 t1;
+
+if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+return gen_mffs(ctx);
+}
+
+if (unlikely(!ctx->fpu_enabled)) {
+gen_exception(ctx, POWERPC_EXCP_FPU);
+return;
+}
+
+t1 = tcg_temp_new_i64();
+get_fpr(t1, rB(ctx->opcode));
+/* Mask FRB to get just RN.  */
+tcg_gen_andi_i64(t1, t1, FP_MODE);
+
+gen_helper_mffscrn(ctx, t1);
+
+tcg_temp_free_i64(t1);
+}
+
+/* mffscrni */
+static void gen_mffscrni(DisasContext *ctx)
+{
+TCGv_i64 t1;
+
+if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) {
+return gen_mffs(ctx);
+}
+
+if (unlikely(!ctx->fpu_enabled)) {
+gen_exception(ctx, POWERPC_EXCP_FPU);
+return;
+}
+
+t1 = tcg_const_i64((uint64_t)RM(ctx->opcode));
+
+gen_helper_mffscrn(ctx, t1);
+
+tcg_temp_free_i64(t1);
+}
+
 /* mtfsb0 */
 static void gen_mtfsb0(DisasContext *ctx)
 {
diff --git a/target/ppc/translate/fp-ops.inc.c 
b/target/ppc/translate/fp-ops.inc.c
index 88ebc25..598cd53 100644
--- a/target/ppc/translate/fp-ops.inc.c
+++ b/target/ppc/translate/fp-ops.inc.c
@@ -107,6 +107,8 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
 GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x, PPC_FLOAT, PPC_NONE),
 GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x, PPC_FLOAT,
 PPC2_ISA300),
+GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x, PPC_FLOAT, 
PPC_NONE),
+GEN_HANDLER_E_2(mffscrni, 0x3F, 0x07, 0x12, 0x17, 0x, PPC_FLOAT, 
PPC_NONE),
 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
 GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x, PPC_FLOAT),
-- 
1.8.3.1




[Qemu-devel] [Bug 1843151] Re: Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

2019-09-11 Thread James Harvey
Finding a minimal case did shed some light on this.

Using QEMU's native graphics window, this works fine:

$ /usr/bin/qemu-system-x86_64 \
   -m 1G \
   -blockdev 
raw,node-name=install_iso,read-only=on,file.driver=file,file.filename=/mnt/losable/ISOs/archlinux-2019.09.01-x86_64.iso
 \
   -device ide-cd,drive=install_iso,bus=ide.0,bootindex=0

But, introducing spice reproduces the problem:

$ /usr/bin/qemu-system-x86_64 \
   -m 1G \
   -blockdev 
raw,node-name=install_iso,read-only=on,file.driver=file,file.filename=/mnt/losable/ISOs/archlinux-2019.09.01-x86_64.iso
 \
   -spice unix,addr=/tmp/spice.qxl.sock,disable-ticketing \
   -device ide-cd,drive=install_iso,bus=ide.0,bootindex=0 \
   -vga qxl

$ remote-viewer "spice+unix:///tmp/spice.qxl.sock"

I've been running remote-viewer (from virt-viewer package) since around
March 13, version 8.0 since then.  It's only when upgrading QEMU from
4.0.0 to 4.1.0 that introduces the problem.

Running remote-viewer this way also shows that it outputs these, right
when KMS changes resolution:

(remote-viewer:15090): GLib-GObject-WARNING **: 23:56:03.914: value "64"
of type 'gint' is invalid or out of range for property 'desktop-width'
of type 'gint'

(remote-viewer:15090): GLib-GObject-WARNING **: 23:56:03.915: value "64"
of type 'gint' is invalid or out of range for property 'desktop-height'
of type 'gint'

When downgrading to QEMU 4.0.0, remote-viewer STILL outputs these lines
regarding desktop-width and height, when KMS changes resolution.

In case it helps, below are spice-debug logs from remote-viewer.  I've
included the whole log, but also added a bunch of spacing and a header
showing the second worth of output correlating with the KMS resolution
change.

QEMU 4.0.0 without the bug: http://ix.io/1USn

QEMU 4.1.0 with the bug: http://ix.io/1USo

So, it's always possible the fix might need to be in remote-viewer, but
at minimum, the case it would need to handle properly wasn't being given
to it until QEMU 4.1.0.

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

Title:
  Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

Status in QEMU:
  New

Bug description:
  Host is Arch Linux.  linux 5.2.13, qemu 4.1.0.  virt-viewer 8.0.

  Guest is Arch Linux Sept 2019 ISO.  linux 5.2.11.

  Have replicated this both on a system using amdgpu and one using
  integrated ASPEED graphics.

  Downgrading from 4.1.0 to 4.0.0 works as usual, see:
  https://www.youtube.com/watch?v=NyMdcYwOCvY

  Going back to 4.1.0 reproduces, see:
  https://www.youtube.com/watch?v=H3nGG2Mk6i0

  4.1.0 displays fine until KMS kicks in.

  Using 4.1.0 with virtio-vga doesn't cause this.

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



[Qemu-devel] [Bug 1843151] Re: Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

2019-09-11 Thread James Harvey
Comparing the spice debug logs, where I see this with QEMU 4.0.0 without
the bug:

(remote-viewer:19270): GSpice-DEBUG: 00:05:21.201: channel-display.c:1979 
display-2:0: received new monitors config from guest: n: 1/4
(remote-viewer:19270): GSpice-DEBUG: 00:05:21.201: channel-display.c:1997 
display-2:0: monitor id: 0, surface id: 0, +0+0-1024x768

I see this with QEMU 4.1.0 with the bug:

(remote-viewer:19896): GSpice-DEBUG: 00:07:40.019: channel-display.c:1975 
display-2:0: received empty monitor config
(remote-viewer:19896): GSpice-DEBUG: 00:07:40.049: channel-cursor.c:542 
cursor-4:0: cursor_handle_reset, init_done: 1
(remote-viewer:19896): GSpice-DEBUG: 00:07:40.049: channel-display.c:1951 
display-2:0: 0: FIXME primary destroy, but is display really disabled?

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

Title:
  Regression: QEMU 4.1.0 qxl and KMS resoluiton only 4x10

Status in QEMU:
  New

Bug description:
  Host is Arch Linux.  linux 5.2.13, qemu 4.1.0.  virt-viewer 8.0.

  Guest is Arch Linux Sept 2019 ISO.  linux 5.2.11.

  Have replicated this both on a system using amdgpu and one using
  integrated ASPEED graphics.

  Downgrading from 4.1.0 to 4.0.0 works as usual, see:
  https://www.youtube.com/watch?v=NyMdcYwOCvY

  Going back to 4.1.0 reproduces, see:
  https://www.youtube.com/watch?v=H3nGG2Mk6i0

  4.1.0 displays fine until KMS kicks in.

  Using 4.1.0 with virtio-vga doesn't cause this.

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



[Qemu-devel] [PATCH v4] target-arm: Make the counter tick relative to cntfrq

2019-09-11 Thread Andrew Jeffery
Allow machines to configure CNTFRQ via a property if the ARM core
supports the generic timer. This is necessary on e.g. the ASPEED AST2600
SoC where the generic timer clock is run at 800MHz or above. The default
value for CNTFRQ remains at 62.50MHz (based on GTIMER_SCALE).

CNTFRQ is a read-as-written co-processor register; the property sets the
register's initial value which is used during realize() to configure the
QEMUTimers that back the generic timers. Beyond that the firmware can to
do whatever it sees fit with the CNTFRQ register though changes to the
value will not be reflected in the timers' rate.

I've tested this using an out-of-tree AST2600 SoC model (Cortex-A7) with
the SDK u-boot that sets CNTFRQ as appropriate, and by starting/running
machines with assorted ARM CPUs (palmetto-bmc with the ARM926EJ-S,
romulus-bmc with the ARM1176 and raspi2 with the Cortex-A53).

Signed-off-by: Andrew Jeffery 
---
v4: Fix configuration for cores without a generic timer

v3: https://patchwork.ozlabs.org/patch/1160634/
Peter - I think this addresses most of your feedback. I still reach into
the QEMUTimer to fetch out scale when adjusting the nexttick
calculation, but we no longer need to update the scale member and force
a recalculation of the period.

v2: https://patchwork.ozlabs.org/patch/1144389/
---
 roms/SLOF   |  2 +-
 roms/skiboot|  2 +-
 target/arm/cpu.c| 43 +++
 target/arm/cpu.h|  3 +++
 target/arm/helper.c | 30 ++
 5 files changed, 66 insertions(+), 14 deletions(-)

diff --git a/roms/SLOF b/roms/SLOF
index 7bfe584e3219..ea221600a116 16
--- a/roms/SLOF
+++ b/roms/SLOF
@@ -1 +1 @@
-Subproject commit 7bfe584e321946771692711ff83ad2b5850daca7
+Subproject commit ea221600a116883137ef90b2b7ab7d2472bc4f10
diff --git a/roms/skiboot b/roms/skiboot
index 261ca8e779e5..3a6fdede6ce1 16
--- a/roms/skiboot
+++ b/roms/skiboot
@@ -1 +1 @@
-Subproject commit 261ca8e779e5138869a45f174caa49be6a274501
+Subproject commit 3a6fdede6ce117facec0108afe716cf5d0472c3f
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2399c144718d..8b63a27761bb 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -40,6 +40,8 @@
 #include "disas/capstone.h"
 #include "fpu/softfloat.h"
 
+#include 
+
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
 ARMCPU *cpu = ARM_CPU(cs);
@@ -976,6 +978,10 @@ static void arm_cpu_initfn(Object *obj)
 }
 }
 
+static Property arm_cpu_gt_cntfrq_property =
+DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq,
+   (1000 * 1000 * 1000) / GTIMER_SCALE);
+
 static Property arm_cpu_reset_cbar_property =
 DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
 
@@ -1172,6 +1178,11 @@ void arm_cpu_post_init(Object *obj)
 
 qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
  &error_abort);
+
+if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
+qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property,
+ &error_abort);
+}
 }
 
 static void arm_cpu_finalizefn(Object *obj)
@@ -1238,14 +1249,30 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
-cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-   arm_gt_ptimer_cb, cpu);
-cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-   arm_gt_vtimer_cb, cpu);
-cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-  arm_gt_htimer_cb, cpu);
-cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
-  arm_gt_stimer_cb, cpu);
+
+{
+uint64_t scale;
+
+if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
+if (!cpu->gt_cntfrq) {
+error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
+   cpu->gt_cntfrq);
+return;
+}
+scale = MAX(1, NANOSECONDS_PER_SECOND / cpu->gt_cntfrq);
+} else {
+scale = GTIMER_SCALE;
+}
+
+cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+   arm_gt_ptimer_cb, cpu);
+cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+   arm_gt_vtimer_cb, cpu);
+cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+  arm_gt_htimer_cb, cpu);
+cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
+  arm_gt_stimer_cb, cpu);
+}
 #endif
 
 cpu_exec_realizefn(cs, &local_err);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 297ad5e47ad8

Re: [Qemu-devel] [PATCH 2/6] exec.c: remove an unnecessary assert on PHYS_MAP_NODE_NIL in phys_map_node_alloc()

2019-09-11 Thread Wei Yang
On Fri, Aug 23, 2019 at 09:07:50AM +0800, Wei Yang wrote:
>On Thu, Aug 22, 2019 at 12:24:32PM +0200, Paolo Bonzini wrote:
>>On 21/03/19 09:25, Wei Yang wrote:
>>> PHYS_MAP_NODE_NIL is assigned to PhysPageEntry.ptr in case this is not a
>>> leaf entry, while map->nodes_nb range in [0, nodes_nb_alloc).
>>> 
>>> Seems we are asserting on two different things, just remove it.
>>
>>The assertion checks that this "if" is not entered incorrectly:
>>
>>if (lp->skip && lp->ptr == PHYS_MAP_NODE_NIL) {
>>lp->ptr = phys_map_node_alloc(map, level == 0);
>>}
>>
>
>Hmm... I may not get your point.
>
>phys_map_node_alloc() will get an available PhysPageEntry and return its
>index, which will be assigned to its parent's ptr.
>
>The "if" checks on the parent's ptr, while the assertion asserts the index for
>the new child. I may miss something?
>

Hi, Paolo,

Do I miss something?


-- 
Wei Yang
Help you, Help me



[Qemu-devel] [PATCH] migration: fix one typo in comment of function migration_total_bytes()

2019-09-11 Thread Wei Yang
Signed-off-by: Wei Yang 
---
 migration/migration.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/migration/migration.c b/migration/migration.c
index fbdabd34d9..cae3e894ad 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3023,7 +3023,7 @@ static MigThrError migration_detect_error(MigrationState 
*s)
 }
 }
 
-/* How many bytes have we transferred since the beggining of the migration */
+/* How many bytes have we transferred since the beginning of the migration */
 static uint64_t migration_total_bytes(MigrationState *s)
 {
 return qemu_ftell(s->to_dst_file) + ram_counters.multifd_bytes;
-- 
2.17.1




Re: [Qemu-devel] [PATCH 5/7] spapr: Do not put empty properties for -kernel/-initrd/-append

2019-09-11 Thread Alexey Kardashevskiy



On 11/09/2019 18:46, Greg Kurz wrote:
> On Wed, 11 Sep 2019 14:04:50 +1000
> David Gibson  wrote:
> 
>> From: Alexey Kardashevskiy 
>>
>> We are going to use spapr_build_fdt() for the boot time FDT and as an
>> update for SLOF during handling of H_CAS. SLOF will apply all properties
>> from the QEMU's FDT which is usually ok unless there are properties
>> changed by grub or guest kernel. The properties are:
>> bootargs, linux,initrd-start, linux,initrd-end, linux,stdout-path,
>> linux,rtas-base, linux,rtas-entry. Resetting those during CAS will most
>> likely cause grub failure.
>>
> 
> s/Resetting/Clearing ? They still get reset to the initial setup if "-kernel"
> and "-initrd" were passed, but it is okay since neither grub, nor the guest
> kernel is supposed to change them in this case, correct ?

Correct.



>> This only creates such properties if we are booting with "-kernel" and
>> "-initrd" so they won't get included into the DT update blob and
> 
> so they won't get included {if we're not booting with "-kernel" ...}
> 
>> therefore the guest is more likely to boot successfully.
>>
> 
> Maybe rephrase like:
> 
> Don't create such properties if we're booting without "-kernel" and
> "-initrd" ...
> 
>> Signed-off-by: Alexey Kardashevskiy 
>> Signed-off-by: David Gibson 
>> ---
>>  hw/ppc/spapr.c | 15 ++-
>>  1 file changed, 10 insertions(+), 5 deletions(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index d072c2aa3d..d18744268f 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -1177,11 +1177,16 @@ static void spapr_dt_chosen(SpaprMachineState 
>> *spapr, void *fdt)
>>  
>>  _FDT(chosen = fdt_add_subnode(fdt, 0, "chosen"));
>>  
>> -_FDT(fdt_setprop_string(fdt, chosen, "bootargs", 
>> machine->kernel_cmdline));
>> -_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
>> -  spapr->initrd_base));
>> -_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
>> -  spapr->initrd_base + spapr->initrd_size));
>> +if (machine->kernel_cmdline && machine->kernel_cmdline[0]) {
> 
> machine->kernel_cmdline cannot be NULL.
> 
> From vl.c:
> 
> if (!kernel_cmdline) {
> kernel_cmdline = "";
> current_machine->kernel_cmdline = (char *)kernel_cmdline;
> }

I do not see the point in having an empty string instead of NULL really
and probably one day somebody else will think the same so I prepared :)

> 
> Also this doesn't check if we're booting with -kernel but rather
> that we're booting with -append ${some_not_empty_string}... what
> about checking spapr->kernel_size, pretty much like you do for
> the initrd ?


We are preserving here "bootargs" which either comes from grub or
"-append" so I do just this. Having -kernel usually (always?) means
there is no grub which we are fixing here but this is just a consequence
of a weird command line.



>> +_FDT(fdt_setprop_string(fdt, chosen, "bootargs",
>> +machine->kernel_cmdline));
>> +}
>> +if (spapr->initrd_size) {
>> +_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-start",
>> +  spapr->initrd_base));
>> +_FDT(fdt_setprop_cell(fdt, chosen, "linux,initrd-end",
>> +  spapr->initrd_base + spapr->initrd_size));
>> +}
>>  
>>  if (spapr->kernel_size) {
>>  uint64_t kprop[2] = { cpu_to_be64(KERNEL_LOAD_ADDR),
> 

-- 
Alexey



Re: [Qemu-devel] [PATCH] docker: add sanitizers back to clang build

2019-09-11 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20190912014442.5757-1-js...@redhat.com/



Hi,

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

Subject: [Qemu-devel] [PATCH] docker: add sanitizers back to clang build
Message-id: 20190912014442.5757-1-js...@redhat.com
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

From https://github.com/patchew-project/qemu
 * [new tag] patchew/20190912014442.5757-1-js...@redhat.com -> 
patchew/20190912014442.5757-1-js...@redhat.com
Switched to a new branch 'test'
96d44b9 docker: add sanitizers back to clang build

=== OUTPUT BEGIN ===
ERROR: Missing Signed-off-by: line(s)

total: 1 errors, 0 warnings, 12 lines checked

Commit 96d44b9f7f66 (docker: add sanitizers back to clang build) has style 
problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190912014442.5757-1-js...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH 6/7] spapr: Stop providing RTAS blob

2019-09-11 Thread Alexey Kardashevskiy



On 11/09/2019 19:16, Greg Kurz wrote:
> On Wed, 11 Sep 2019 14:04:51 +1000
> David Gibson  wrote:
> 
>> From: Alexey Kardashevskiy 
>>
>> SLOF implements one itself so let's remove it from QEMU. It is one less
>> image and simpler setup as the RTAS blob never stays in its initial place
>> anyway as the guest OS always decides where to put it.
>>
>> Signed-off-by: Alexey Kardashevskiy 
>> Signed-off-by: David Gibson 
>> ---
>>  MAINTAINERS |   2 --
>>  Makefile|   2 +-
>>  configure   |   6 +
>>  hw/ppc/spapr.c  |  32 ++---
>>  hw/ppc/spapr_rtas.c |  41 
>>  include/hw/ppc/spapr.h  |   2 --
>>  pc-bios/spapr-rtas.bin  | Bin 20 -> 0 bytes
>>  pc-bios/spapr-rtas/Makefile |  27 -
>>  pc-bios/spapr-rtas/spapr-rtas.S |  37 
>>  9 files changed, 4 insertions(+), 145 deletions(-)
>>  delete mode 100644 pc-bios/spapr-rtas.bin
>>  delete mode 100644 pc-bios/spapr-rtas/Makefile
>>  delete mode 100644 pc-bios/spapr-rtas/spapr-rtas.S
>>
> 
> Nice diffstat :)
> 
> But pwclient fails to apply it :(
> 
> [greg@bahia qemu-spapr]$ pwclient git-am 1160642
> Applying patch #1160642 using 'git am'
> Description: [6/7] spapr: Stop providing RTAS blob
> Applying: spapr: Stop providing RTAS blob
> error: cannot apply binary patch to 'pc-bios/spapr-rtas.bin' without full 
> index line


Some git feature/bug with removing binaries:

https://stackoverflow.com/questions/17152171/git-cannot-apply-binary-patch-without-full-index-line


David posted with this:
===
diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
deleted file mode 100644
index fc24c8ed8b..00
Binary files a/pc-bios/spapr-rtas.bin and /dev/null differ
===

And my patch has a bigger chunk:

git format-patch -1 --stdout 1a5efb9283c2
(there is no additional flag needed to my git 2.17.1):

===
diff --git a/pc-bios/spapr-rtas.bin b/pc-bios/spapr-rtas.bin
deleted file mode 100644
index
fc24c8ed8b92a3a441aed6e2bd013b2ccece9229..
GIT binary patch
literal 0
HcmV?d1

literal 20
bcmbi{{=neEz@X&Uz@PvCJTV0q
===

I do not know why are these different.

Thy this one:
https://patchwork.ozlabs.org/patch/1132443/



> error: pc-bios/spapr-rtas.bin: patch does not apply
> Patch failed at 0001 spapr: Stop providing RTAS blob
> hint: Use 'git am --show-current-patch' to see the failed patch
> When you have resolved this problem, run "git am --continue".
> If you prefer to skip this patch, run "git am --skip" instead.
> To restore the original branch and stop patching, run "git am --abort".
> 'git am' failed with exit status 128
> 
> and
> 
> [greg@bahia qemu-spapr]$ git am --show-current-patch | patch -p1 --merge 
> patching file MAINTAINERS
> patching file Makefile
> patching file configure
> patching file hw/ppc/spapr.c
> patching file hw/ppc/spapr_rtas.c
> patching file include/hw/ppc/spapr.h
> patching file pc-bios/spapr-rtas.bin
> Not deleting file pc-bios/spapr-rtas.bin as content differs from patch
> 
> Not sure what's happening here...
> 
> patching file pc-bios/spapr-rtas/Makefile
> patching file pc-bios/spapr-rtas/spapr-rtas.S
> 
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 50eaf005f4..9823f40213 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -1077,8 +1077,6 @@ F: hw/*/spapr*
>>  F: include/hw/*/spapr*
>>  F: hw/*/xics*
>>  F: include/hw/*/xics*
>> -F: pc-bios/spapr-rtas/*
>> -F: pc-bios/spapr-rtas.bin
>>  F: pc-bios/slof.bin
>>  F: docs/specs/ppc-spapr-hcalls.txt
>>  F: docs/specs/ppc-spapr-hotplug.txt
>> diff --git a/Makefile b/Makefile
>> index ae17a83067..4637f95371 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -764,7 +764,7 @@ qemu-nsis.bmp \
>>  bamboo.dtb canyonlands.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
>>  multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin \
>>  s390-ccw.img s390-netboot.img \
>> -spapr-rtas.bin slof.bin skiboot.lid \
>> +slof.bin skiboot.lid \
>>  palcode-clipper \
>>  u-boot.e500 u-boot-sam460-20100605.bin \
>>  qemu_vga.ndrv \
>> diff --git a/configure b/configure
>> index 95134c0180..b79d38592b 100755
>> --- a/configure
>> +++ b/configure
>> @@ -6211,9 +6211,6 @@ if { test "$cpu" = "i386" || test "$cpu" = "x86_64"; } 
>> && \
>>  fi
>>  done
>>  fi
>> -if test "$ARCH" = "ppc64" && test "$targetos" != "Darwin" ; then
>> -  roms="$roms spapr-rtas"
>> -fi
>>  
>>  # Only build s390-ccw bios if we're on s390x and the compiler has 
>> -march=z900
>>  if test "$cpu" = "s390x" ; then
>> @@ -7930,14 +7927,13 @@ fi
>>  DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
>> tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm"
>>  DIRS="$DIRS tests/fp tests/qgraph"
>>  DIRS="$DIRS docs docs/interop fsdev scsi"
>> -DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
>> +DIRS="$DIRS pc-bios/op

[Qemu-devel] [PATCH] docker: add sanitizers back to clang build

2019-09-11 Thread John Snow
Fedora23 is but a distant twinkle.
The sanitizer works again, and even if not,
we have --enable-sanitizers now.

---

The problem is that I do see some ASAN warnings:

  TESTcheck-qtest-aarch64: tests/device-introspect-test

Direct leak of 2272 byte(s) in 48 object(s) allocated from:
#0 0x55aea5598b4e in calloc 
(/tmp/qemu-test/build/aarch64-softmmu/qemu-system-aarch64+0x19a9b4e)
#1 0x7f783ff11ce0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x55ce0)

Direct leak of 864 byte(s) in 18 object(s) allocated from:
#0 0x55aea5598b4e in calloc 
(/tmp/qemu-test/build/aarch64-softmmu/qemu-system-aarch64+0x19a9b4e)
#1 0x7f783ff11ce0 in g_malloc0 (/lib64/libglib-2.0.so.0+0x55ce0)
#2 0x55aea712b379 in object_initialize_with_type 
/tmp/qemu-test/src/qom/object.c:467:5


I'd run it again, but it took eight years to get to that point,
it's late and I'm tired.

Signed-off-by: John Snow 
---
 tests/docker/test-clang | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/tests/docker/test-clang b/tests/docker/test-clang
index 324e341cea..db9e6970b7 100755
--- a/tests/docker/test-clang
+++ b/tests/docker/test-clang
@@ -17,11 +17,7 @@ requires clang
 
 cd "$BUILD_DIR"
 
-OPTS="--cxx=clang++ --cc=clang --host-cc=clang"
-# -fsanitize=undefined is broken on Fedora 23, skip it for now
-# See also: https://bugzilla.redhat.com/show_bug.cgi?id=1263834
-#OPTS="$OPTS --extra-cflags=-fsanitize=undefined \
-#--extra-cflags=-fno-sanitize=float-divide-by-zero"
+OPTS="--cxx=clang++ --cc=clang --host-cc=clang --enable-sanitizers"
 build_qemu $OPTS
 check_qemu
 install_qemu
-- 
2.21.0




[Qemu-devel] [GIT PULL for qemu-pseries] pseries: Update SLOF firmware image

2019-09-11 Thread Alexey Kardashevskiy
The following changes since commit 0d0b906ae20d763db0f07fc74aef2c355b8474c7:

  spapr: Render full FDT on ibm,client-architecture-support (2019-09-11 
16:22:29 +1000)

are available in the Git repository at:

  g...@github.com:aik/qemu.git tags/qemu-slof-20190911

for you to fetch changes up to 96159c298b655506ccf65863486b062a43645099:

  pseries: Update SLOF firmware image (2019-09-11 16:27:01 +1000)


Alexey Kardashevskiy (1):
  pseries: Update SLOF firmware image

 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 930656 -> 930640 bytes
 roms/SLOF|   2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)


*** Note: this is not for master, this is for pseries



[Qemu-devel] [PATCH v4 4/4] iotests: use python logging for iotests.log()

2019-09-11 Thread John Snow
We can turn logging on/off globally instead of per-function.

Remove use_log from run_job, and use python logging to turn on
diffable output when we run through a script entry point.

iotest 245 changes output order due to buffering reasons.

Signed-off-by: John Snow 
---
 tests/qemu-iotests/030|  4 +--
 tests/qemu-iotests/245|  1 +
 tests/qemu-iotests/245.out| 24 +-
 tests/qemu-iotests/iotests.py | 47 +--
 4 files changed, 43 insertions(+), 33 deletions(-)

diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index f3766f2a81..01aa96ed16 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -411,8 +411,8 @@ class TestParallelOps(iotests.QMPTestCase):
 result = self.vm.qmp('block-job-set-speed', device='drive0', speed=0)
 self.assert_qmp(result, 'return', {})
 
-self.vm.run_job(job='drive0', auto_dismiss=True, use_log=False)
-self.vm.run_job(job='node4', auto_dismiss=True, use_log=False)
+self.vm.run_job(job='drive0', auto_dismiss=True)
+self.vm.run_job(job='node4', auto_dismiss=True)
 self.assert_no_active_block_jobs()
 
 # Test a block-stream and a block-commit job in parallel
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245
index 41218d5f1d..eba2157cff 100644
--- a/tests/qemu-iotests/245
+++ b/tests/qemu-iotests/245
@@ -1000,5 +1000,6 @@ class TestBlockdevReopen(iotests.QMPTestCase):
 self.reopen(opts, {'backing': 'hd2'})
 
 if __name__ == '__main__':
+iotests.activate_logging()
 iotests.main(supported_fmts=["qcow2"],
  supported_protocols=["file"])
diff --git a/tests/qemu-iotests/245.out b/tests/qemu-iotests/245.out
index a19de5214d..15c3630e92 100644
--- a/tests/qemu-iotests/245.out
+++ b/tests/qemu-iotests/245.out
@@ -1,17 +1,17 @@
+{"execute": "job-finalize", "arguments": {"id": "commit0"}}
+{"return": {}}
+{"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
+{"execute": "job-finalize", "arguments": {"id": "stream0"}}
+{"return": {}}
+{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
+{"execute": "job-finalize", "arguments": {"id": "stream0"}}
+{"return": {}}
+{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
+{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
 ..
 --
 Ran 18 tests
 
 OK
-{"execute": "job-finalize", "arguments": {"id": "commit0"}}
-{"return": {}}
-{"data": {"id": "commit0", "type": "commit"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-{"data": {"device": "commit0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
-{"return": {}}
-{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
-{"execute": "job-finalize", "arguments": {"id": "stream0"}}
-{"return": {}}
-{"data": {"id": "stream0", "type": "stream"}, "event": "BLOCK_JOB_PENDING", 
"timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
-{"data": {"device": "stream0", "len": 3145728, "offset": 3145728, "speed": 0, 
"type": "stream"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": 
{"microseconds": "USECS", "seconds": "SECS"}}
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 92117a64bc..7e46fb2754 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -35,6 +35,13 @@ from collections import OrderedDict
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu import qtest
 
+# Use this logger for logging messages directly from the iotests module
+logger = logging.getLogger(__name__)
+logger.addHandler(logging.NullHandler())
+
+# Use this logger for messages that ought to be used for diff output.
+test_logger = logging.getL

[Qemu-devel] [PATCH v4 2/4] iotest 258: use script_main

2019-09-11 Thread John Snow
Since this one is nicely factored to use a single entry point,
use script_main to run the tests.

Signed-off-by: John Snow 
---
 tests/qemu-iotests/258 | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/tests/qemu-iotests/258 b/tests/qemu-iotests/258
index b84cf02254..1372522c7a 100755
--- a/tests/qemu-iotests/258
+++ b/tests/qemu-iotests/258
@@ -23,11 +23,6 @@ import iotests
 from iotests import log, qemu_img, qemu_io_silent, \
 filter_qmp_testfiles, filter_qmp_imgfmt
 
-# Need backing file and change-backing-file support
-iotests.verify_image_format(supported_fmts=['qcow2', 'qed'])
-iotests.verify_platform(['linux'])
-
-
 # Returns a node for blockdev-add
 def node(node_name, path, backing=None, fmt=None, throttle=None):
 if fmt is None:
@@ -160,4 +155,5 @@ def main():
 test_concurrent_finish(False)
 
 if __name__ == '__main__':
-main()
+# Need backing file and change-backing-file support
+iotests.script_main(main, supported_fmts=['qcow2', 'qed'])
-- 
2.21.0




Re: [Qemu-devel] issue related to boot aix 7.1 when I try to use qemu ppc64

2019-09-11 Thread da...@gibson.dropbear.id.au
On Wed, Sep 11, 2019 at 03:58:14PM +, Muolo Vincenzo (S.I.) wrote:
> Hi to all
> 
> I try to use ( into VM debian 10  running into VMWARE virtualization 
> environment ) qemu ppc64  version to simulate an AIX 7.1 TL04  OS
> 
> 
> root@vkvm-acmm:/AIX# qemu-system-ppc64  -version
> QEMU emulator version 3.1.0 (Debian 1:3.1+dfsg-8+deb10u2)
> Copyright (c) 2003-2018 Fabrice Bellard and the QEMU Project developers
> 
> 
> I run the following commands into my linux DEB but after few time i have to 
> following issue ( trap  interrupt kernel see to end .. ):
> 
> qemu-system-ppc64 -cpu POWER8 -machine pseries -m 4096 -serial stdio -drive 
> file=disk.img,if=none,id=drive-virtio-disk0 -device virtio-scsi-pci,id=scsi 
> -device scsi-hd,drive=drive-virtio-disk0 -cdrom aix.iso -prom-env 
> "boot-command=dev / 0 0 s\" ibm,aix-diagnostics\" property boot 
> cdrom:\ppc\chrp\bootfile.exe -s verbose" -net nic -net tap -display vnc=:1
> W: /etc/qemu-ifup: no bridge for guest interface found

Running AIX under qemu really isn't tested or supported as yet.  We're
just starting to look at this these days, but you'd want to get the
very latest upstream qemu (4.1) and even then there could well be
remaining problems.

> 
> 
> SLOF **
> QEMU Starting
> Build Date = Dec 28 2018 13:55:34
> FW Version = buildd@ release 20180702
> Press "s" to enter Open Firmware.
> 
> Populating /vdevice methods
> Populating /vdevice/vty@7100
> Populating /vdevice/nvram@7101
> Populating /vdevice/l-lan@7102
> Populating /vdevice/v-scsi@7103
>SCSI: Looking for devices
>   8200 CD-ROM   : "QEMU QEMU CD-ROM  2.5+"
> Populating /pci@8002000
>  00  (D) : 1234 qemu vga
>  00 0800 (D) : 1033 0194serial bus [ usb-xhci ]
>  00 1000 (D) : 1af4 1004virtio [ scsi ]
> Populating /pci@8002000/scsi@2
>SCSI: Looking for devices
>   100 DISK : "QEMU QEMU HARDDISK2.5+"
> Installing QEMU fb
> 
> 
> 
> Scanning USB
>   XHCI: Initializing
> USB Keyboard
> USB mouse
> No console specified using screen & keyboard
> 
>   Welcome to Open Firmware
> 
>   Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
>   This program and the accompanying materials are made available
>   under the terms of the BSD License available at
>   http://www.opensource.org/licenses/bsd-license.php
> 
> 
> Trying to load: -s verbose from: 
> /vdevice/v-scsi@7103/disk@8200:\ppc\chrp\bootfile.exe ...   
> Successfully loaded
> AIX
> StarLED{814}
> 
> AIX Version 7.1
> exec(/etc/init){1,0}
> 
> INIT: EXECUTING /sbin/rc.boot 1
> exec(/usr/bin/sh,-c,/sbin/rc.boot 1){1179684,1}
> exec(/sbin/rc.boot,/sbin/rc.boot,1){1179684,1}
> + PHASE=1
> + + bootinfo -p
> exec(/usr/sbin/bootinfo,-p){1245222,1179684}
> PLATFORM=chrp
> + [ ! -x /usr/lib/boot/bin/bootinfo_chrp ]
> + [ 1 -eq 1 ]
> + 1> /usr/lib/libc.a
> + init -c unlink /usr/lib/boot/bin/!(*_chrp)
> exec(/etc/init,-c,unlink /usr/lib/boot/bin/!(*_chrp)){1245224,1179684}
> + chramfs -t
> exec(/usr/sbin/chramfs,-t){1245226,1179684}
> + init -c unlink /usr/sbin/chramfs
> + 1> /dev/null
> exec(/etc/init,-c,unlink /usr/sbin/chramfs){1245228,1179684}
> + + bootinfo -t
> exec(/usr/sbin/bootinfo,-t){1245230,1179684}
> BOOTYPE=3
> + [ 0 -ne 0 ]
> + [ -z 3 ]
> + unset pdev_to_ldev undolt native_netboot_cfg
> + unset disknet_odm_init config_ATM
> + /usr/lib/methods/showled 0x510 DEV CFG 1 START
> exec(/usr/lib/methods/showled,0x510,DEV CFG 1 START){1245232,1179684}
> + cfgmgr -f -v
> exec(/usr/sbin/cfgmgr,-f,-v){1245234,1179684}
> cfgmgr is running in phase 1
> 
> Time: 0 LEDS: 0x538
> Invoking top level program -- "/etc/methods/defsys"
> exec(/bin/sh,-c,/etc/methods/defsys ){1310760,1245234}
> exec(/etc/methods/defsys){1310760,1245234}
> exec(/bin/sh,-c,/usr/lib/methods/define_rspc -n -c sys -s node -t 
> chrp){1376298,1310760}
> exec(/usr/lib/methods/define_rspc,-n,-c,sys,-s,node,-t,chrp){1376298,1310760}
> Time: 0 LEDS: 0x539
> Return code = 0
> * stdout *
> sys0
> 
> * stderr *
> MS 1376298 1310760 /usr/lib/methods/define_rspc -n -c sys -s node -t chrp
> M4 1376298 Defining device: uniquetype=sys/node/chrp parent= connection=
> M4 1376298 ..define_dvc()
> M4 1376298 ..generate_name()
> M4 1376298 Generated name: sys0
> M4 1376298 ..create_cudv()
> M4 1376298 Adding new CuDv
> M4 1376298 Defined device sys0
> 
> 
> Attempting to configure device 'sys0'
> Time: 0 LEDS: 0x811
> Invoking /usr/lib/methods/cfgsys_chrp -1 -l sys0
> exec(/bin/sh,-c,/usr/lib/methods/cfgsys_chrp -1 -l sys0){1310762,1245234}
> Number of running methods: 1
> exec(/usr/lib/methods/cfgsys_chrp,-1,-l,sys0){1310762,1245234}
> LED{A20}
> Illegal Trap Instruction Interrupt in Kernel
> 05911ACCtweqir0,0r0=0
> KDB(0)>
> 
> So how c

[Qemu-devel] [PATCH v4 1/4] iotests: add script_initialize

2019-09-11 Thread John Snow
Like script_main, but doesn't require a single point of entry.
Replace all existing initialization sections with this drop-in replacement.

This brings debug support to all existing script-style iotests.

Note: supported_oses=['linux'] was omitted, as it is a default argument.
Signed-off-by: John Snow 
---
 tests/qemu-iotests/149|  3 +-
 tests/qemu-iotests/194|  3 +-
 tests/qemu-iotests/202|  3 +-
 tests/qemu-iotests/203|  3 +-
 tests/qemu-iotests/206|  2 +-
 tests/qemu-iotests/207|  2 +-
 tests/qemu-iotests/208|  2 +-
 tests/qemu-iotests/209|  2 +-
 tests/qemu-iotests/210|  2 +-
 tests/qemu-iotests/211|  2 +-
 tests/qemu-iotests/212|  2 +-
 tests/qemu-iotests/213|  2 +-
 tests/qemu-iotests/216|  3 +-
 tests/qemu-iotests/218|  2 +-
 tests/qemu-iotests/219|  2 +-
 tests/qemu-iotests/222|  5 ++-
 tests/qemu-iotests/224|  3 +-
 tests/qemu-iotests/228|  3 +-
 tests/qemu-iotests/234|  3 +-
 tests/qemu-iotests/235|  4 +--
 tests/qemu-iotests/236|  2 +-
 tests/qemu-iotests/237|  2 +-
 tests/qemu-iotests/238|  2 ++
 tests/qemu-iotests/242|  2 +-
 tests/qemu-iotests/246|  2 +-
 tests/qemu-iotests/248|  2 +-
 tests/qemu-iotests/254|  2 +-
 tests/qemu-iotests/255|  2 +-
 tests/qemu-iotests/256|  2 +-
 tests/qemu-iotests/262|  3 +-
 tests/qemu-iotests/iotests.py | 61 +++
 31 files changed, 73 insertions(+), 62 deletions(-)

diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149
index 4f363f295f..9fa97966c5 100755
--- a/tests/qemu-iotests/149
+++ b/tests/qemu-iotests/149
@@ -383,8 +383,7 @@ def test_once(config, qemu_img=False):
 
 
 # Obviously we only work with the luks image format
-iotests.verify_image_format(supported_fmts=['luks'])
-iotests.verify_platform()
+iotests.script_initialize(supported_fmts=['luks'])
 
 # We need sudo in order to run cryptsetup to create
 # dm-crypt devices. This is safe to use on any
diff --git a/tests/qemu-iotests/194 b/tests/qemu-iotests/194
index d746ab1e21..c8aeb6d0e4 100755
--- a/tests/qemu-iotests/194
+++ b/tests/qemu-iotests/194
@@ -21,8 +21,7 @@
 
 import iotests
 
-iotests.verify_image_format(supported_fmts=['qcow2', 'qed', 'raw'])
-iotests.verify_platform(['linux'])
+iotests.script_initialize(supported_fmts=['qcow2', 'qed', 'raw'])
 
 with iotests.FilePath('source.img') as source_img_path, \
  iotests.FilePath('dest.img') as dest_img_path, \
diff --git a/tests/qemu-iotests/202 b/tests/qemu-iotests/202
index 581ca34d79..1271ac9459 100755
--- a/tests/qemu-iotests/202
+++ b/tests/qemu-iotests/202
@@ -24,8 +24,7 @@
 
 import iotests
 
-iotests.verify_image_format(supported_fmts=['qcow2'])
-iotests.verify_platform(['linux'])
+iotests.script_initialize(supported_fmts=['qcow2'])
 
 with iotests.FilePath('disk0.img') as disk0_img_path, \
  iotests.FilePath('disk1.img') as disk1_img_path, \
diff --git a/tests/qemu-iotests/203 b/tests/qemu-iotests/203
index 4874a1a0d8..c40fe231ea 100755
--- a/tests/qemu-iotests/203
+++ b/tests/qemu-iotests/203
@@ -24,8 +24,7 @@
 
 import iotests
 
-iotests.verify_image_format(supported_fmts=['qcow2'])
-iotests.verify_platform(['linux'])
+iotests.script_initialize(supported_fmts=['qcow2'])
 
 with iotests.FilePath('disk0.img') as disk0_img_path, \
  iotests.FilePath('disk1.img') as disk1_img_path, \
diff --git a/tests/qemu-iotests/206 b/tests/qemu-iotests/206
index 5bb738bf23..23ff2f624b 100755
--- a/tests/qemu-iotests/206
+++ b/tests/qemu-iotests/206
@@ -23,7 +23,7 @@
 import iotests
 from iotests import imgfmt
 
-iotests.verify_image_format(supported_fmts=['qcow2'])
+iotests.script_initialize(supported_fmts=['qcow2'])
 
 def blockdev_create(vm, options):
 result = vm.qmp_log('blockdev-create',
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
index ec8c1d06f0..ab9e3b6747 100755
--- a/tests/qemu-iotests/207
+++ b/tests/qemu-iotests/207
@@ -24,7 +24,7 @@ import iotests
 import subprocess
 import re
 
-iotests.verify_image_format(supported_fmts=['raw'])
+iotests.script_initialize(supported_fmts=['raw'])
 iotests.verify_protocol(supported=['ssh'])
 
 def filter_hash(qmsg):
diff --git a/tests/qemu-iotests/208 b/tests/qemu-iotests/208
index 1e202388dc..dfce6f9fe4 100755
--- a/tests/qemu-iotests/208
+++ b/tests/qemu-iotests/208
@@ -22,7 +22,7 @@
 
 import iotests
 
-iotests.verify_image_format(supported_fmts=['generic'])
+iotests.script_initialize(supported_fmts=['generic'])
 
 with iotests.FilePath('disk.img') as disk_img_path, \
  iotests.FilePath('disk-snapshot.img') as disk_snapshot_img_path, \
diff --git a/tests/qemu-iotests/209 b/tests/qemu-iotests/209
index 259e991ec6..a77f884166 100755
--- a/tests/qemu-iotests/209
+++ b/tests/qemu-iotests/209
@@ -22,7 +22,7 @@ import iotests
 from iotests import qemu_img_create, qemu_io, qemu_img_verbose, qemu_nbd,

[Qemu-devel] [PATCH v4 3/4] iotests: specify protocol support via initialization info

2019-09-11 Thread John Snow
Switch from verify_protocols to any one of:
iotests.main, iotests.script_main, iotests.script_initialize.

Signed-off-by: John Snow 
---
 tests/qemu-iotests/207 | 4 ++--
 tests/qemu-iotests/210 | 4 ++--
 tests/qemu-iotests/211 | 4 ++--
 tests/qemu-iotests/212 | 4 ++--
 tests/qemu-iotests/213 | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
index ab9e3b6747..35d98f2736 100755
--- a/tests/qemu-iotests/207
+++ b/tests/qemu-iotests/207
@@ -24,8 +24,8 @@ import iotests
 import subprocess
 import re
 
-iotests.script_initialize(supported_fmts=['raw'])
-iotests.verify_protocol(supported=['ssh'])
+iotests.script_initialize(supported_fmts=['raw'],
+  supported_protocols=['ssh'])
 
 def filter_hash(qmsg):
 def _filter(key, value):
diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210
index 5a7013cd34..d9fe780c07 100755
--- a/tests/qemu-iotests/210
+++ b/tests/qemu-iotests/210
@@ -23,8 +23,8 @@
 import iotests
 from iotests import imgfmt
 
-iotests.script_initialize(supported_fmts=['luks'])
-iotests.verify_protocol(supported=['file'])
+iotests.script_initialize(supported_fmts=['luks'],
+  supported_protocols=['file'])
 
 def blockdev_create(vm, options):
 result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211
index 4d6aac497f..155fac4e87 100755
--- a/tests/qemu-iotests/211
+++ b/tests/qemu-iotests/211
@@ -23,8 +23,8 @@
 import iotests
 from iotests import imgfmt
 
-iotests.script_initialize(supported_fmts=['vdi'])
-iotests.verify_protocol(supported=['file'])
+iotests.script_initialize(supported_fmts=['vdi'],
+  supported_protocols=['file'])
 
 def blockdev_create(vm, options):
 result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212
index ec35bceb11..67e5a1dbb5 100755
--- a/tests/qemu-iotests/212
+++ b/tests/qemu-iotests/212
@@ -23,8 +23,8 @@
 import iotests
 from iotests import imgfmt
 
-iotests.script_initialize(supported_fmts=['parallels'])
-iotests.verify_protocol(supported=['file'])
+iotests.script_initialize(supported_fmts=['parallels'],
+  supported_protocols=['file'])
 
 def blockdev_create(vm, options):
 result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213
index 3d2c024375..23f387ab63 100755
--- a/tests/qemu-iotests/213
+++ b/tests/qemu-iotests/213
@@ -23,8 +23,8 @@
 import iotests
 from iotests import imgfmt
 
-iotests.script_initialize(supported_fmts=['vhdx'])
-iotests.verify_protocol(supported=['file'])
+iotests.script_initialize(supported_fmts=['vhdx'],
+  supported_protocols=['file'])
 
 def blockdev_create(vm, options):
 result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
-- 
2.21.0




[Qemu-devel] [PATCH v4 0/4] iotests: use python logging

2019-09-11 Thread John Snow
This series uses python logging to enable output conditionally on
iotests.log(). We unify an initialization call (which also enables
debugging output for those tests with -d) and then make the switch
inside of iotests.

It will help alleviate the need to create logged/unlogged versions
of all the various helpers we have made.

V4:
 - Rebased on top of kwolf/block at the behest of mreitz

V3:
 - Rebased for 4.1+; now based on main branch.

V2:
 - Added all of the other python tests I missed to use script_initialize
 - Refactored the common setup as per Ehabkost's suggestion
 - Added protocol arguments to common initialization,
   but this isn't strictly required.

John Snow (4):
  iotests: add script_initialize
  iotest 258: use script_main
  iotests: specify protocol support via initialization info
  iotests: use python logging for iotests.log()

 tests/qemu-iotests/030|   4 +-
 tests/qemu-iotests/149|   3 +-
 tests/qemu-iotests/194|   3 +-
 tests/qemu-iotests/202|   3 +-
 tests/qemu-iotests/203|   3 +-
 tests/qemu-iotests/206|   2 +-
 tests/qemu-iotests/207|   4 +-
 tests/qemu-iotests/208|   2 +-
 tests/qemu-iotests/209|   2 +-
 tests/qemu-iotests/210|   4 +-
 tests/qemu-iotests/211|   4 +-
 tests/qemu-iotests/212|   4 +-
 tests/qemu-iotests/213|   4 +-
 tests/qemu-iotests/216|   3 +-
 tests/qemu-iotests/218|   2 +-
 tests/qemu-iotests/219|   2 +-
 tests/qemu-iotests/222|   5 +-
 tests/qemu-iotests/224|   3 +-
 tests/qemu-iotests/228|   3 +-
 tests/qemu-iotests/234|   3 +-
 tests/qemu-iotests/235|   4 +-
 tests/qemu-iotests/236|   2 +-
 tests/qemu-iotests/237|   2 +-
 tests/qemu-iotests/238|   2 +
 tests/qemu-iotests/242|   2 +-
 tests/qemu-iotests/245|   1 +
 tests/qemu-iotests/245.out|  24 
 tests/qemu-iotests/246|   2 +-
 tests/qemu-iotests/248|   2 +-
 tests/qemu-iotests/254|   2 +-
 tests/qemu-iotests/255|   2 +-
 tests/qemu-iotests/256|   2 +-
 tests/qemu-iotests/258|   8 +--
 tests/qemu-iotests/262|   3 +-
 tests/qemu-iotests/iotests.py | 108 +-
 35 files changed, 123 insertions(+), 106 deletions(-)

-- 
2.21.0




Re: [Qemu-devel] [PATCH v2 4/4] hw/ppc/pnv: fix checkpatch.pl coding style warnings

2019-09-11 Thread David Gibson
On Wed, Sep 11, 2019 at 07:59:25PM +0530, Balamuruhan S wrote:
> There were few trailing comments after `/*` instead in
> new line and line more than 80 character, these fixes are
> trivial and doesn't change any logic in code.
> 
> Signed-off-by: Balamuruhan S 

This makes sense independent of the rest, so I've applied it now.  The
rest of the patches I'll wait on a respin to address Cédric's comments.

> ---
>  hw/ppc/pnv.c | 49 -
>  1 file changed, 32 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index f249e72356..77a86c6a23 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -187,7 +187,8 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void 
> *fdt)
>  
>  _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));
>  _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));
> -_FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", 
> cpu->hash64_opts->slb_size)));
> +_FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size",
> +   cpu->hash64_opts->slb_size)));
>  _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));
>  _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));
>  
> @@ -200,19 +201,23 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, 
> void *fdt)
> segs, sizeof(segs;
>  }
>  
> -/* Advertise VMX/VSX (vector extensions) if available
> +/*
> + * Advertise VMX/VSX (vector extensions) if available
>   *   0 / no property == no vector extensions
>   *   1   == VMX / Altivec available
> - *   2   == VSX available */
> + *   2   == VSX available
> + */
>  if (env->insns_flags & PPC_ALTIVEC) {
>  uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;
>  
>  _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));
>  }
>  
> -/* Advertise DFP (Decimal Floating Point) if available
> +/*
> + * Advertise DFP (Decimal Floating Point) if available
>   *   0 / no property == no DFP
> - *   1   == DFP available */
> + *   1   == DFP available
> + */
>  if (env->insns_flags2 & PPC2_DFP) {
>  _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));
>  }
> @@ -424,7 +429,8 @@ static int pnv_dt_isa_device(DeviceState *dev, void 
> *opaque)
>  return 0;
>  }
>  
> -/* The default LPC bus of a multichip system is on chip 0. It's
> +/*
> + * The default LPC bus of a multichip system is on chip 0. It's
>   * recognized by the firmware (skiboot) using a "primary" property.
>   */
>  static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
> @@ -442,8 +448,10 @@ static void pnv_dt_isa(PnvMachineState *pnv, void *fdt)
>  assert(phandle > 0);
>  _FDT((fdt_setprop_cell(fdt, isa_offset, "phandle", phandle)));
>  
> -/* ISA devices are not necessarily parented to the ISA bus so we
> - * can not use object_child_foreach() */
> +/*
> + * ISA devices are not necessarily parented to the ISA bus so we
> + * can not use object_child_foreach()
> + */
>  qbus_walk_children(BUS(pnv->isa_bus), pnv_dt_isa_device, NULL, NULL, 
> NULL,
> &args);
>  }
> @@ -545,7 +553,8 @@ static void pnv_reset(MachineState *machine)
>  
>  qemu_devices_reset();
>  
> -/* OpenPOWER systems have a BMC, which can be defined on the
> +/*
> + * OpenPOWER systems have a BMC, which can be defined on the
>   * command line with:
>   *
>   *   -device ipmi-bmc-sim,id=bmc0
> @@ -705,7 +714,8 @@ static void pnv_init(MachineState *machine)
>  
>  pnv->chips[i] = PNV_CHIP(chip);
>  
> -/* TODO: put all the memory in one node on chip 0 until we find a
> +/*
> + * TODO: put all the memory in one node on chip 0 until we find a
>   * way to specify different ranges for each chip
>   */
>  if (i == 0) {
> @@ -732,8 +742,10 @@ static void pnv_init(MachineState *machine)
>  /* Create an RTC ISA device too */
>  mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
>  
> -/* OpenPOWER systems use a IPMI SEL Event message to notify the
> - * host to powerdown */
> +/*
> + * OpenPOWER systems use a IPMI SEL Event message to notify the
> + * host to powerdown
> + */
>  pnv->powerdown_notifier.notify = pnv_powerdown_notify;
>  qemu_register_powerdown_notifier(&pnv->powerdown_notifier);
>  }
> @@ -803,7 +815,8 @@ static void pnv_chip_power9_intc_create(PnvChip *chip, 
> PowerPCCPU *cpu,
>  pnv_cpu->intc = obj;
>  }
>  
> -/* Allowed core identifiers on a POWER8 Processor Chip :
> +/*
> + * Allowed core identifiers on a POWER8 Processor Chip :
>   *
>   * 
>   *  EX1  - Venice only
> @@ -928,8 +941,10 @@ static void pnv_chip_power8_realize(DeviceState *dev, 
> Error **errp)
>  (uint64_t) PNV_XSCOM_BASE(chip),
>   

Re: [Qemu-devel] [Qemu-block] [PATCH] qcow2: Stop overwriting compressed clusters one by one

2019-09-11 Thread John Snow



On 9/11/19 11:16 AM, Alberto Garcia wrote:
> handle_alloc() tries to find as many contiguous clusters that need
> copy-on-write as possible in order to allocate all of them at the same
> time.
> 
> However, compressed clusters are only overwritten one by one, so let's
> say that we have an image with 1024 consecutive compressed clusters:
> 
>qemu-img create -f qcow2 hd.qcow2 64M
>for f in `seq 0 64 65472`; do
>   qemu-io -c "write -c ${f}k 64k" hd.qcow2
>done
> 
> In this case trying to overwrite the whole image with one large write
> request results in 1024 separate allocations:
> 
>qemu-io -c "write 0 64M" hd.qcow2
> 
> This restriction comes from commit 095a9c58ce12afeeb90c2 from 2018.

You accidentally typed a reasonably modern date. It's from *2008*!

> Nowadays QEMU can overwrite multiple compressed clusters just fine,
> and in fact it already does: as long as the first cluster that
> handle_alloc() finds is not compressed, all other compressed clusters
> in the same batch will be overwritten in one go:
> 
>qemu-img create -f qcow2 hd.qcow2 64M
>qemu-io -c "write -z 0 64k" hd.qcow2
>for f in `seq 64 64 65472`; do
>   qemu-io -c "write -c ${f}k 64k" hd.qcow2
>done
> 
> Compared to the previous one, overwriting this image on my computer
> goes from 8.35s down to 230ms.
> 
> Signed-off-by: Alberto Garcia 
> ---
>  block/qcow2-cluster.c | 8 +---
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
> index f09cc992af..dcacd3c450 100644
> --- a/block/qcow2-cluster.c
> +++ b/block/qcow2-cluster.c
> @@ -1351,13 +1351,7 @@ static int handle_alloc(BlockDriverState *bs, uint64_t 
> guest_offset,
>  }
>  
>  entry = be64_to_cpu(l2_slice[l2_index]);
> -
> -/* For the moment, overwrite compressed clusters one by one */
> -if (entry & QCOW_OFLAG_COMPRESSED) {
> -nb_clusters = 1;
> -} else {
> -nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, 
> l2_index);
> -}
> +nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
>  
>  /* This function is only called when there were no non-COW clusters, so 
> if
>   * we can't find any unallocated or COW clusters either, something is
> 

Well, given that count_cow_clusters already works this way, this doesn't
break anything that wasn't broken before, at least.

Reviewed-by: John Snow 



Re: [Qemu-devel] Valgrind confused by queue macros

2019-09-11 Thread John Snow



On 9/10/19 9:27 AM, Mark Syms wrote:
> Hi,
> 
> While trying to track down an issue in using qemu 4.1 with some development 
> features we needed/wanted to run valgrind on it to find a memory error. 
> Unfortunately the form of the queue macros seems to really confuse valgrind 
> and cause it to report many " Use of uninitialised value " errors.
> 
> As an example, in qemu_aio_coroutine_enter - 
> 
> Use of uninitialised value of size 8
>at 0x69E7E5: qemu_aio_coroutine_enter (qemu-coroutine.c:109)
> 
> Conditional jump or move depends on uninitialised value(s)
>at 0x69E7FA: qemu_aio_coroutine_enter (qemu-coroutine.c:112)
> 
> Use of uninitialised value of size 8
>at 0x69E800: qemu_aio_coroutine_enter (qemu-coroutine.c:118)
> 
> Use of uninitialised value of size 8
>at 0x69E809: qemu_aio_coroutine_enter (qemu-coroutine.c:120)
> 
> Use of uninitialised value of size 8
>at 0x69E822: qemu_aio_coroutine_enter (qemu-coroutine.c:122)
> 
> Use of uninitialised value of size 8
>at 0x69E83A: qemu_aio_coroutine_enter (qemu-coroutine.c:134)
> 
> Use of uninitialised value of size 8
>at 0x69E845: qemu_aio_coroutine_enter (qemu-coroutine.c:139)
> 
> This seems to ultimately result from it thinking that pending is not 
> initialised by this line
> 
> QSIMPLEQ_HEAD(, Coroutine) pending = QSIMPLEQ_HEAD_INITIALIZER(pending);
> 
> As this issue in itself accounts for 7 errors every time that 
> qemu_aio_coroutine_enter is called (which is frequently) valgrind very soon 
> gives up and says the code is too broken to report errors on - unless that is 
> you disable the error-limit which is what we've done but then you still have 
> to identify the real errors in the middle of these ones.
> 
> Not sure what it is about the macros in the initialisation line that cause 
> valgrind to think it isn't initialised, whilst there is a small amount of 
> macro magic in there it looks like it does actually result in things being 
> correctly initialised.
> 
> This is using valgrind 3.13.0-13.el7 on a CentOS 7 system.
> 
> Any clues about how to resolve this? Or is it just a fact of life that 
> valgrind is never going to be happy with this code?
> 
> Thanks,
> 
> Mark.
> 

I haven't used valgrind on a "real" run of QEMU in some time, usually
using it for the test suite instead.

In this case, are you sure it's choking on the macro and not getting
confused about all of the stack swaps that QEMU is doing in the
coroutine module?

CCing some folks who have worked on valgrind support in the past, they
might have a more targeted idea.

--js



Re: [Qemu-devel] [PATCH v2 04/17] RISC-V: add vector extension configure instruction

2019-09-11 Thread Richard Henderson
> +void VECTOR_HELPER(vsetvl)(CPURISCVState *env, uint32_t rs1, uint32_t rs2,
> +uint32_t rd)
> +{
> +int sew, max_sew, vlmax, vl;
> +
> +if (rs2 == 0) {
> +vector_vtype_set_ill(env);
> +riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> +return;
> +}

I don't see that vsetvl, rs2 == r0 should raise SIGILL.
Is that requirement new, after the 0.7.1 specification?
If so, this should happen in the translator and not here.
You should *not* change cpu state (setting vill here) before raising SIGILL.

As far as I can see "vsetvl rd, rs1, r0" == "vsetvli rd, rs1, e8".

> +env->vfp.vtype = env->gpr[rs2];

You should pass the rs2 register by value, not by index.

> +sew = 1 << vector_get_width(env) / 8;
> +max_sew = sizeof(target_ulong);
> +
> +if (env->misa & RVD) {
> +max_sew = max_sew > 8 ? max_sew : 8;
> +} else if (env->misa & RVF) {
> +max_sew = max_sew > 4 ? max_sew : 4;
> +}
> +if (sew > max_sew) {
> +vector_vtype_set_ill(env);
> +return;
> +}
> +
> +vlmax = vector_get_vlmax(env);
> +if (rs1 == 0) {
> +vl = vlmax;
> +} else if (env->gpr[rs1] <= vlmax) {
> +vl = env->gpr[rs1];
> +} else if (env->gpr[rs1] < 2 * vlmax) {
> +vl = ceil(env->gpr[rs1] / 2);
> +} else {
> +vl = vlmax;
> +}

You should pass rs1 register by value, not by index.
The special case of rs1 == r0 can be handled by passing the value
(target_ulong)-1, which will match the final case above.

> +env->vfp.vl = vl;
> +env->gpr[rd] = vl;
> +env->vfp.vstart = 0;
> +return;
> +}

You should return vl and have it assigned to rd by the translator code, and not
assign it here.

> +void VECTOR_HELPER(vsetvli)(CPURISCVState *env, uint32_t rs1, uint32_t zimm,
> +uint32_t rd)

You should not require a separate helper function for this.

Passing the zimm constant as the value for rs2 above is the correct mapping
between the two instructions.


r~



Re: [Qemu-devel] [Qemu-block] [PATCH] block/create: Do not abort if a block driver is not available

2019-09-11 Thread John Snow



On 9/11/19 6:08 PM, Philippe Mathieu-Daudé wrote:
> The 'blockdev-create' QMP command was introduced as experimental
> feature in commit b0292b851b8, using the assert() debug call.
> It got promoted to 'stable' command in 3fb588a0f2c, but the
> assert call was not removed.
> 
> Some block drivers are optional, and bdrv_find_format() might
> return a NULL value, triggering the assertion.
> 
> Stable code is not expected to abort, so return an error instead.
> 
> This is easily reproducible when libnfs is not installed:
> 
>   ./configure
>   [...]
>   module supportno
>   Block whitelist (rw)
>   Block whitelist (ro)
>   libiscsi support  yes
>   libnfs supportno
>   [...]
> 
> Start QEMU:
> 
>   $ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait
> 
> Send the 'blockdev-create' with the 'nfs' driver:
> 
>   $ ( cat << 'EOF'
>   {'execute': 'qmp_capabilities'}
>   {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': 
> {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': 
> '::1', 'type': 'inet', 'id': 'x'}
>   EOF
>   ) | socat STDIO UNIX:/tmp/qemu.qmp
>   {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, 
> "package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}}
>   {"return": {}}
> 
> QEMU crashes:
> 
>   $ gdb qemu-system-x86_64 core
>   Program received signal SIGSEGV, Segmentation fault.
>   (gdb) bt
>   #0  0x7510957f in raise () at /lib64/libc.so.6
>   #1  0x750f3895 in abort () at /lib64/libc.so.6
>   #2  0x750f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
>   #3  0x75101a26 in .annobin_assert.c_end () at /lib64/libc.so.6
>   #4  0x55d7e1f1 in qmp_blockdev_create (job_id=0x56baee40 "x", 
> options=0x5710, errp=0x7fffc770) at block/create.c:69
>   #5  0x55c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, 
> ret=0x7fffc7f8, errp=0x7fffc7f0) at 
> qapi/qapi-commands-block-core.c:1314
>   #6  0x55deb0a0 in do_qmp_dispatch (cmds=0x5645de70 
> , request=0x7fffdc005c70, allow_oob=false, errp=0x7fffc898) 
> at qapi/qmp-dispatch.c:131
>   #7  0x55deb2a1 in qmp_dispatch (cmds=0x5645de70 , 
> request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174
> 
> With this patch applied, QEMU returns a QMP error:
> 
>   {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': 
> {'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': 
> '::1', 'type': 'inet', 'id': 'x'}
>   {"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' 
> not found or not supported"}}
> 
> Reported-by: Xu Tian 
> Signed-off-by: Philippe Mathieu-Daudé 

Reviewed-by: John Snow 



Re: [Qemu-devel] [PATCH v2 03/17] RISC-V: support vector extension csr

2019-09-11 Thread Richard Henderson
On 9/11/19 2:25 AM, liuzhiwei wrote:
> @@ -873,7 +925,12 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_FFLAGS] =  { fs,   read_fflags,  write_fflags  
> },
>  [CSR_FRM] = { fs,   read_frm, write_frm 
> },
>  [CSR_FCSR] ={ fs,   read_fcsr,write_fcsr
> },
> -
> +/* Vector CSRs */
> +[CSR_VSTART] =  { any,   read_vstart, write_vstart  
> },
> +[CSR_VXSAT] =   { any,   read_vxsat,  write_vxsat   
> },
> +[CSR_VXRM] ={ any,   read_vxrm,   write_vxrm
> },
> +[CSR_VL] =  { any,   read_vl
> },
> +[CSR_VTYPE] =   { any,   read_vtype 
> },

Is there really no MSTATUS bit to disable the vector unit,
as there is for the FPU?  That seems like a defect in the
specification if true...


r~



Re: [Qemu-devel] [PATCH v2 01/17] RISC-V: add vfp field in CPURISCVState

2019-09-11 Thread Richard Henderson
On 9/11/19 10:51 AM, Chih-Min Chao wrote:
> Could  the VLEN be configurable in cpu initialization but not fixed in
> compilation phase ?
> Take the integer element as example  and the difference should be the
> stride of vfp.vreg[x] isn't continuous

Do you really want an unbounded amount of vector register storage?

> uint8_t *mem = malloc(size)
> for (int idx = 0; idx < 32; ++idx) {
> vfp.vreg[idx].u64 = (void *)&mem[idx * elem];
> vfp.vreg[idx].u32 = (void *)&mem[idx * elem];
> vfp.vreg[idx].u16 = (void *)&mem[idx * elem];
>}

This isn't adjusting the stride of the elements.  And in any case this would
have to be re-adjusted for every vsetvl.


r~



Re: [Qemu-devel] [PATCH v2 01/17] RISC-V: add vfp field in CPURISCVState

2019-09-11 Thread Richard Henderson
On 9/11/19 2:25 AM, liuzhiwei wrote:
>  uint64_t fpr[32]; /* assume both F and D extensions */
> +
> +/* vector coprocessor state.  */
> +struct {
> +union VECTOR {
> +float64  f64[VUNIT(64)];
> +float32  f32[VUNIT(32)];
> +float16  f16[VUNIT(16)];
> +uint64_t u64[VUNIT(64)];
> +int64_t  s64[VUNIT(64)];
> +uint32_t u32[VUNIT(32)];
> +int32_t  s32[VUNIT(32)];
> +uint16_t u16[VUNIT(16)];
> +int16_t  s16[VUNIT(16)];
> +uint8_t  u8[VUNIT(8)];
> +int8_t   s8[VUNIT(8)];
> +} vreg[32];
> +target_ulong vxrm;
> +target_ulong vxsat;
> +target_ulong vl;
> +target_ulong vstart;
> +target_ulong vtype;
> +float_status fp_status;
> +} vfp;

Is there a good reason why you're putting all of these into a sub-structure?
And more, a sub-structure whose name, vfp, looks like it is copied from ARM?

Why are the vxrm, vxsat, vl, vstart, vtype fields sized target_ulong?  I would
think that most could be uint32_t.  Although I suppose frm is also target_ulong
and need not be...

Why are you adding a new fp_status field?  The new vector floating point
instructions set the exact same fflags exception bits as normal fp instructions.


r~



[Qemu-devel] [Bug 1843651] [NEW] m68k fpu bug

2019-09-11 Thread Pierre Muller
Public bug reported:

On gcc123 cfarm machine,
I was testing m68k executables generated by Free Pascal Compiler.

muller@gcc123:~/pas/check$ cat inf.pp
function get_double(x : double):double;
  begin
get_double:=x;
  end;


var
  y : double;
  py : pbyte;
  i : byte;
begin
  y:=1.0/0.0;
  py:=@y;
{$ifdef ENDIAN_LITTLE}
  write('little endian y=');
  for i:=7 downto 0 do
{$else not ENDIAN_LITTLE}
  write('big endian y=');
  for i:=0 to 7 do
{$endif}
write(hexstr(py[i],2));
  writeln;
  y:=get_double(y)+1;
{$ifdef ENDIAN_LITTLE}
  write('little endian y=');
  for i:=7 downto 0 do
{$else not ENDIAN_LITTLE}
  write('big endian y=');
  for i:=0 to 7 do
{$endif}
write(hexstr(py[i],2));
  writeln;
end.
muller@gcc123:~/pas/check$ ppc68k inf
Free Pascal Compiler version 3.3.1-r20:42973M [2019/09/11] for m68k
Copyright (c) 1993-2019 by Florian Klaempfl and others
Target OS: Linux for m68k
Compiling inf.pp
Assembling program
Linking inf
33 lines compiled, 0.1 sec
muller@gcc123:~/pas/check$ ./inf
big endian y=7FF0
big endian y=7FFF
muller@gcc123:~/pas/check$ qemu-m68k ./inf
big endian y=7FF0
big endian y=7FFF
muller@gcc123:~/pas/check$ ~/sys-root/bin/qemu-m68k ./inf
qemu-m68kqemu-m68k-fixed
muller@gcc123:~/pas/check$ ~/sys-root/bin/qemu-m68k-fixed ./inf
big endian y=7FF0
big endian y=7FF0

~/sys-root/bin/qemu-m68k  is 4.1.0 release,
~/sys-root/bin/qemu-m68k-fixed is the same source with a unique change:

gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h:214:#if defined(TARGET_M68K)
gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-215-#define 
floatx80_infinity_low  LIT64(0x)
gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-216-#else
gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-217-#define 
floatx80_infinity_low  LIT64(0x8000)
gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-218-#endif

the M68K branch value is set to the same value as the other branch.

The problem of the M68K specific floatx86_infinity_low values
is that is enters in conflict with
muller@gcc123:~/pas/check$ grep -nA6 invalid_enc  
/home/muller/gnu/qemu/qemu-4.1.0/include/fpu/softfloat.h
752:static inline bool floatx80_invalid_encoding(floatx80 a)
753-{
754-return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0;
755-}

And thus the m68k variant of floatx80 representing +Infinity is
considered as an invalid encoding, and thus converted into a NaN 
7FFF

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  m68k fpu bug

Status in QEMU:
  New

Bug description:
  On gcc123 cfarm machine,
  I was testing m68k executables generated by Free Pascal Compiler.

  muller@gcc123:~/pas/check$ cat inf.pp
  function get_double(x : double):double;
begin
  get_double:=x;
end;

  
  var
y : double;
py : pbyte;
i : byte;
  begin
y:=1.0/0.0;
py:=@y;
  {$ifdef ENDIAN_LITTLE}
write('little endian y=');
for i:=7 downto 0 do
  {$else not ENDIAN_LITTLE}
write('big endian y=');
for i:=0 to 7 do
  {$endif}
  write(hexstr(py[i],2));
writeln;
y:=get_double(y)+1;
  {$ifdef ENDIAN_LITTLE}
write('little endian y=');
for i:=7 downto 0 do
  {$else not ENDIAN_LITTLE}
write('big endian y=');
for i:=0 to 7 do
  {$endif}
  write(hexstr(py[i],2));
writeln;
  end.
  muller@gcc123:~/pas/check$ ppc68k inf
  Free Pascal Compiler version 3.3.1-r20:42973M [2019/09/11] for m68k
  Copyright (c) 1993-2019 by Florian Klaempfl and others
  Target OS: Linux for m68k
  Compiling inf.pp
  Assembling program
  Linking inf
  33 lines compiled, 0.1 sec
  muller@gcc123:~/pas/check$ ./inf
  big endian y=7FF0
  big endian y=7FFF
  muller@gcc123:~/pas/check$ qemu-m68k ./inf
  big endian y=7FF0
  big endian y=7FFF
  muller@gcc123:~/pas/check$ ~/sys-root/bin/qemu-m68k ./inf
  qemu-m68kqemu-m68k-fixed
  muller@gcc123:~/pas/check$ ~/sys-root/bin/qemu-m68k-fixed ./inf
  big endian y=7FF0
  big endian y=7FF0

  ~/sys-root/bin/qemu-m68k  is 4.1.0 release,
  ~/sys-root/bin/qemu-m68k-fixed is the same source with a unique change:

  gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h:214:#if defined(TARGET_M68K)
  gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-215-#define 
floatx80_infinity_low  LIT64(0x)
  gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-216-#else
  gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-217-#define 
floatx80_infinity_low  LIT64(0x8000)
  gnu/qemu/qemu-4.1.0/fpu/softfloat-specialize.h-218-#endif

  the M68K branch value is set to the same value as the other branch.

  The problem of the M68K specific floatx86_infinity_low values
  is that is enters in conflict with
  muller@gcc123:~/pas/check$ grep -nA6 inva

Re: [Qemu-devel] [PATCH] block/create: Do not abort if a block driver is not available

2019-09-11 Thread Eric Blake
On 9/11/19 5:08 PM, Philippe Mathieu-Daudé wrote:
> The 'blockdev-create' QMP command was introduced as experimental
> feature in commit b0292b851b8, using the assert() debug call.
> It got promoted to 'stable' command in 3fb588a0f2c, but the
> assert call was not removed.
> 
> Some block drivers are optional, and bdrv_find_format() might
> return a NULL value, triggering the assertion.
> 
> Stable code is not expected to abort, so return an error instead.
> 

> 
> Reported-by: Xu Tian 
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  block/create.c | 6 +-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/block/create.c b/block/create.c
> index 1bd00ed5f8..89812669df 100644
> --- a/block/create.c
> +++ b/block/create.c
> @@ -64,9 +64,13 @@ void qmp_blockdev_create(const char *job_id, 
> BlockdevCreateOptions *options,
>  const char *fmt = BlockdevDriver_str(options->driver);
>  BlockDriver *drv = bdrv_find_format(fmt);
>  
> +if (!drv) {
> +error_setg(errp, "Block driver '%s' not found or not supported", 
> fmt);
> +return;
> +}
> +
>  /* If the driver is in the schema, we know that it exists. But it may not
>   * be whitelisted. */
> -assert(drv);
>  if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
>  error_setg(errp, "Driver is not whitelisted");

Matches that we error for not being on the whitelist.

Reviewed-by: Eric Blake 

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2 27/28] s390x/tcg: MVO: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> Each operand can have a maximum length of 16. Make sure to prepare all
> reads/writes before writing.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 26 ++
>  1 file changed, 14 insertions(+), 12 deletions(-)

Reviewed-by: Richard Henderson 

r~



[Qemu-devel] [PATCH] block/create: Do not abort if a block driver is not available

2019-09-11 Thread Philippe Mathieu-Daudé
The 'blockdev-create' QMP command was introduced as experimental
feature in commit b0292b851b8, using the assert() debug call.
It got promoted to 'stable' command in 3fb588a0f2c, but the
assert call was not removed.

Some block drivers are optional, and bdrv_find_format() might
return a NULL value, triggering the assertion.

Stable code is not expected to abort, so return an error instead.

This is easily reproducible when libnfs is not installed:

  ./configure
  [...]
  module supportno
  Block whitelist (rw)
  Block whitelist (ro)
  libiscsi support  yes
  libnfs supportno
  [...]

Start QEMU:

  $ qemu-system-x86_64 -S -qmp unix:/tmp/qemu.qmp,server,nowait

Send the 'blockdev-create' with the 'nfs' driver:

  $ ( cat << 'EOF'
  {'execute': 'qmp_capabilities'}
  {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': 
{'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': 
'::1', 'type': 'inet', 'id': 'x'}
  EOF
  ) | socat STDIO UNIX:/tmp/qemu.qmp
  {"QMP": {"version": {"qemu": {"micro": 50, "minor": 1, "major": 4}, 
"package": "v4.1.0-733-g89ea03a7dc"}, "capabilities": ["oob"]}}
  {"return": {}}

QEMU crashes:

  $ gdb qemu-system-x86_64 core
  Program received signal SIGSEGV, Segmentation fault.
  (gdb) bt
  #0  0x7510957f in raise () at /lib64/libc.so.6
  #1  0x750f3895 in abort () at /lib64/libc.so.6
  #2  0x750f3769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
  #3  0x75101a26 in .annobin_assert.c_end () at /lib64/libc.so.6
  #4  0x55d7e1f1 in qmp_blockdev_create (job_id=0x56baee40 "x", 
options=0x5710, errp=0x7fffc770) at block/create.c:69
  #5  0x55c96b52 in qmp_marshal_blockdev_create (args=0x7fffdc003830, 
ret=0x7fffc7f8, errp=0x7fffc7f0) at qapi/qapi-commands-block-core.c:1314
  #6  0x55deb0a0 in do_qmp_dispatch (cmds=0x5645de70 
, request=0x7fffdc005c70, allow_oob=false, errp=0x7fffc898) 
at qapi/qmp-dispatch.c:131
  #7  0x55deb2a1 in qmp_dispatch (cmds=0x5645de70 , 
request=0x7fffdc005c70, allow_oob=false) at qapi/qmp-dispatch.c:174

With this patch applied, QEMU returns a QMP error:

  {'execute': 'blockdev-create', 'arguments': {'job-id': 'x', 'options': 
{'size': 0, 'driver': 'nfs', 'location': {'path': '/', 'server': {'host': 
'::1', 'type': 'inet', 'id': 'x'}
  {"id": "x", "error": {"class": "GenericError", "desc": "Block driver 'nfs' 
not found or not supported"}}

Reported-by: Xu Tian 
Signed-off-by: Philippe Mathieu-Daudé 
---
 block/create.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/create.c b/block/create.c
index 1bd00ed5f8..89812669df 100644
--- a/block/create.c
+++ b/block/create.c
@@ -64,9 +64,13 @@ void qmp_blockdev_create(const char *job_id, 
BlockdevCreateOptions *options,
 const char *fmt = BlockdevDriver_str(options->driver);
 BlockDriver *drv = bdrv_find_format(fmt);
 
+if (!drv) {
+error_setg(errp, "Block driver '%s' not found or not supported", fmt);
+return;
+}
+
 /* If the driver is in the schema, we know that it exists. But it may not
  * be whitelisted. */
-assert(drv);
 if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
 error_setg(errp, "Driver is not whitelisted");
 return;
-- 
2.20.1




Re: [Qemu-devel] [PATCH] nbd/server: attach client channel to the export's AioContext

2019-09-11 Thread Eric Blake
On 9/11/19 4:33 PM, Eric Blake wrote:

> I tried to test this patch, but even with it applied, I still got an
> aio-context crasher by attempting an nbd-server-start, nbd-server-add,
> nbd-server-stop (intentionally skipping the nbd-server-remove step) on a
> domain using iothreads, with a backtrace of:

The crash also reproduces with nbd-server-remove instead of
nbd-server-stop.  Both QMP commands eventually call into the
blk_remove_bs() that calls the fatal blk_drain().  So libvirt can't work
around the bug merely by adding an nbd-server-remove step.

> 
> #0  0x7ff09d070e35 in raise () from target:/lib64/libc.so.6
> #1  0x7ff09d05b895 in abort () from target:/lib64/libc.so.6
> #2  0x55dd03b9ab86 in error_exit (err=1, msg=0x55dd03d59fb0
> <__func__.15769> "qemu_mutex_unlock_impl")
> at util/qemu-thread-posix.c:36
> #3  0x55dd03b9adcf in qemu_mutex_unlock_impl (mutex=0x55dd062d5090,
> file=0x55dd03d59041 "util/async.c",
> line=523) at util/qemu-thread-posix.c:96
> #4  0x55dd03b93433 in aio_context_release (ctx=0x55dd062d5030) at
> util/async.c:523
> #5  0x55dd03ac421b in bdrv_do_drained_begin (bs=0x55dd0673a2d0,
> recursive=false, parent=0x0,
> ignore_bds_parents=false, poll=true) at block/io.c:428
> #6  0x55dd03ac4299 in bdrv_drained_begin (bs=0x55dd0673a2d0) at
> block/io.c:434
> #7  0x55dd03aafb54 in blk_drain (blk=0x55dd06a3ec40) at
> block/block-backend.c:1605
> #8  0x55dd03aae054 in blk_remove_bs (blk=0x55dd06a3ec40) at
> block/block-backend.c:800


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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2 16/28] s390x/tcg: Fault-safe memmove

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> +static void access_memmove_idx(CPUS390XState *env, vaddr dest, vaddr src,
> +   int size, int dest_idx, int src_idx,
> +   uintptr_t ra)
> +{
> +S390Access srca = access_prepare_idx(env, src, size, MMU_DATA_LOAD, 
> src_idx,
> + ra);
> +S390Access desta = access_prepare_idx(env, dest, size, MMU_DATA_STORE,
> +  dest_idx, ra);

I was just thinking that it might be worth passing in these Access structures.
 It seems that usually we wind up computing them in several locations.

Hoisting it up it would make MVC look like

midx = cpu_mmu_index(env);
srca = access_prepare_idx(env, src, size, LOAD, midx, ra);
dsta = access_prepare_idx(env, dst, size, STORE, midx, ra);

if (dst == src + 1) {
uint8_t x = access_get_byte(env, &srca, 0, ra);
access_memset(env, &dsta, x, size, ra);
} else if (!is_destructive_overlap(env, dst, src, size)) {
access_memmove(env, &dsta, &srca, size, ra);
} else {
// byte by byte loop, but still need srca, dsta.
}

which seems even More Correct, since the current access_memset path does not
check for read watchpoints or faults on all of [src, src+size-1].


r~



Re: [Qemu-devel] [PATCH v2 26/28] s390x/tcg: MVST: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> +/*
> + * Our access should not exceed single pages, as we must not report 
> access
> + * exceptions exceeding the actually copied range (which we don't know at
> + * this point). We might over-indicate watchpoints within the pages
> + * (if we ever care, we have to limit processing to a single byte).
> + */
> +srca = access_prepare(env, s, len, MMU_DATA_LOAD, ra);
> +desta = access_prepare(env, d, len, MMU_DATA_STORE, ra);
> +for (i = 0; i < len; i++) {
> +const uint8_t v = access_get_byte(env, &srca, i, ra);
> +
> +access_set_byte(env, &desta, i, v, ra);
>  if (v == c) {
> -set_address_zero(env, r1, d + len);
> +set_address_zero(env, r1, d + i);
>  return 1;
>  }

Worth using memchr + memmove w/ nondestructive overlap?

That said,
Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH 0/3] proper locking on bitmap add/remove paths

2019-09-11 Thread John Snow



On 9/11/19 10:09 AM, Vladimir Sementsov-Ogievskiy wrote:
> 10.09.2019 23:37, no-re...@patchew.org wrote:
>> Patchew URL: 
>> https://patchew.org/QEMU/20190910162724.79574-1-vsement...@virtuozzo.com/
>>
>>
>>
>> Hi,
>>
>> This series failed the docker-quick@centos7 build test. Please find the 
>> testing commands and
>> their output below. If you have Docker installed, you can probably reproduce 
>> it
>> locally.
>>
>> === TEST SCRIPT BEGIN ===
>> #!/bin/bash
>> make docker-image-centos7 V=1 NETWORK=1
>> time make docker-test-quick@centos7 SHOW_ENV=1 J=14 NETWORK=1

(Was patchew even using clang?)

>> === TEST SCRIPT END ===
>>
>> libudev   no
>> default devices   yes
>>
>> warning: Python 2 support is deprecated
>> warning: Python 3 will be required for building future versions of QEMU
>>
>> NOTE: cross-compilers enabled:  'cc'
>>GEN x86_64-softmmu/config-devices.mak.tmp
>> ---
>>CC  block/qed-cluster.o
>>CC  block/qed-check.o
>> /tmp/qemu-test/src/block/qcow2-bitmap.c: In function 
>> 'qcow2_co_remove_persistent_dirty_bitmap':
>> /tmp/qemu-test/src/block/qcow2-bitmap.c:502:8: error: 'bm' may be used 
>> uninitialized in this function [-Werror=maybe-uninitialized]
>>   if (bm == NULL) {
>>  ^
>> /tmp/qemu-test/src/block/qcow2-bitmap.c:1413:18: note: 'bm' was declared here
>>
>>
>> The full log is available at
>> http://patchew.org/logs/20190910162724.79574-1-vsement...@virtuozzo.com/testing.docker-quick@centos7/?type=message.
>> ---
>> Email generated automatically by Patchew [https://patchew.org/].
>> Please send your feedback to patchew-de...@redhat.com
>>
> 
> Who knows, how to clang Qemu?
> 
> I try with
> ./configure --target-list=x86_64-softmmu --enable-debug --disable-virtfs 
> --enable-werror --audio-drv-list=oss --extra-cflags=-Wall --enable-sanitizers 
> --cc=clang --cxx=clang++
> make -j9
> 

../../configure --target-list="x86_64-softmmu" --cc=clang --cxx=clang++
--host-cc=clang

works OK for me in fedora 30.

--target-list="x86_64-softmmu" --cc=clang --cxx=clang++ --host-cc=clang
--enable-werror --extra-cflags=-Wall

Seems OK too, and finally adding

--enable-sanitizers

also appears to work alright.


clang version 8.0.0 (Fedora 8.0.0-1.fc30)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin


Maybe something bad in your ccache or some intermediate state in your
build dir. I use separate build directories for gcc and clang just in case.

--js




Re: [Qemu-devel] [PATCH v2 25/28] s390x/tcg: MVZ: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> We can process a maximum of 256 bytes, crossing two pages.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 24/28] s390x/tcg: MVN: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> We can process a maximum of 256 bytes, crossing two pages.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 23/28] s390x/tcg: MVCIN: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> We can process a maximum of 256 bytes, crossing two pages. Calculate the
> accessed range upfront - src is accessed right-to-left.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 14 +++---
>  1 file changed, 11 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH] nbd/server: attach client channel to the export's AioContext

2019-09-11 Thread Eric Blake
On 9/11/19 12:21 PM, Eric Blake wrote:
> On 9/11/19 11:15 AM, Sergio Lopez wrote:
>> On creation, the export's AioContext is set to the same one as the
>> BlockBackend, while the AioContext in the client QIOChannel is left
>> untouched.
>>
>> As a result, when using data-plane, nbd_client_receive_next_request()
>> schedules coroutines in the IOThread AioContext, while the client's
>> QIOChannel is serviced from the main_loop, potentially triggering the
>> assertion at qio_channel_restart_[read|write].
>>
>> To fix this, as soon we have the export corresponding to the client,
>> we call qio_channel_attach_aio_context() to attach the QIOChannel
>> context to the export's AioContext. This matches with the logic in
>> blk_aio_attached().
>>
>> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1748253
>> Signed-off-by: Sergio Lopez 
>> ---
>>  nbd/server.c | 2 ++
>>  1 file changed, 2 insertions(+)
> 
> I'd like a second opinion from Kevin, but the description makes sense to
> me.  I'm happy to queue this through my NBD tree.
> 
> Reviewed-by: Eric Blake 

I tried to test this patch, but even with it applied, I still got an
aio-context crasher by attempting an nbd-server-start, nbd-server-add,
nbd-server-stop (intentionally skipping the nbd-server-remove step) on a
domain using iothreads, with a backtrace of:

#0  0x7ff09d070e35 in raise () from target:/lib64/libc.so.6
#1  0x7ff09d05b895 in abort () from target:/lib64/libc.so.6
#2  0x55dd03b9ab86 in error_exit (err=1, msg=0x55dd03d59fb0
<__func__.15769> "qemu_mutex_unlock_impl")
at util/qemu-thread-posix.c:36
#3  0x55dd03b9adcf in qemu_mutex_unlock_impl (mutex=0x55dd062d5090,
file=0x55dd03d59041 "util/async.c",
line=523) at util/qemu-thread-posix.c:96
#4  0x55dd03b93433 in aio_context_release (ctx=0x55dd062d5030) at
util/async.c:523
#5  0x55dd03ac421b in bdrv_do_drained_begin (bs=0x55dd0673a2d0,
recursive=false, parent=0x0,
ignore_bds_parents=false, poll=true) at block/io.c:428
#6  0x55dd03ac4299 in bdrv_drained_begin (bs=0x55dd0673a2d0) at
block/io.c:434
#7  0x55dd03aafb54 in blk_drain (blk=0x55dd06a3ec40) at
block/block-backend.c:1605
#8  0x55dd03aae054 in blk_remove_bs (blk=0x55dd06a3ec40) at
block/block-backend.c:800
#9  0x55dd03aad54a in blk_delete (blk=0x55dd06a3ec40) at
block/block-backend.c:420
#10 0x55dd03aad7d6 in blk_unref (blk=0x55dd06a3ec40) at
block/block-backend.c:475
#11 0x55dd03aecb68 in nbd_export_put (exp=0x55dd0726f920) at
nbd/server.c:1666
#12 0x55dd03aec8fe in nbd_export_close (exp=0x55dd0726f920) at
nbd/server.c:1616
#13 0x55dd03aecbf1 in nbd_export_close_all () at nbd/server.c:1689
#14 0x55dd03748845 in qmp_nbd_server_stop (errp=0x7ffcdf3cb4e8) at
blockdev-nbd.c:233
...

Does that sound familiar to what you were seeing?  Does it mean we
missed another spot where the context is set incorrectly?

I'm happy to work with you on IRC for more real-time debugging of this
(I'm woefully behind on understanding how aio contexts are supposed to
work).

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2 22/28] s390x/tcg: NC: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> We can process a maximum of 256 bytes, crossing two pages.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 21/28] s390x/tcg: XC: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> We can process a maximum of 256 bytes, crossing two pages. While at it,
> increment the length once.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 20/28] s390x/tcg: OC: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> +srca2 = access_prepare(env, dest, l, MMU_DATA_LOAD, ra);
> +desta = access_prepare(env, dest, l, MMU_DATA_STORE, ra);

We should find a way to perform this in one step.
RWM isn't uncommon...

That said,
Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 19/28] s390x/tcg: MVCLU: Fault-safe handling

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> The last remaining bit is padding with two bytes.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 18/28] s390x/tcg: MVC: Fault-safe handling on destructive overlaps

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> +static S390Access access_prepare(CPUS390XState *env, vaddr vaddr, int size,
> + MMUAccessType access_type, uintptr_t ra)
> +{
> +int mmu_idx = cpu_mmu_index(env, false);
> +
> +return access_prepare_idx(env, vaddr, size, access_type, mmu_idx, ra);
> +}
> +
>  static void access_memset_idx(CPUS390XState *env, vaddr vaddr, uint8_t byte,
>int size, int mmu_idx, uintptr_t ra)
>  {
> @@ -420,9 +428,13 @@ static uint32_t do_helper_mvc(CPUS390XState *env, 
> uint32_t l, uint64_t dest,
>  } else if (!is_destructive_overlap(env, dest, src, l)) {
>  access_memmove(env, dest, src, l, ra);
>  } else {
> +S390Access srca = access_prepare(env, src, l, MMU_DATA_LOAD, ra);
> +S390Access desta = access_prepare(env, dest, l, MMU_DATA_STORE, ra);

I was just thinking it might be better to drop the non-idx functions:
access_prepare, access_memset, access_memmove.  What this is leading to is
computation of cpu_mmu_index multiple times, as here.

It could just as easily be hoisted to the top of do_helper_mvc and used in all
of the sub-cases.

That said, the code here is correct so
Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 17/28] s390x/tcg: MVCS/MVCP: Use access_memmove_idx()

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> As we are moving between address spaces, we can use access_memmove_idx()
> without checking for destructive overlaps (especially of real storage
> locations):
> "Each storage operand is processed left to right. The
> storage-operand-consistency rules are the same as
> for MOVE (MVC), except that when the operands
> overlap in real storage, the use of the common real-
> storage locations is not necessarily recognized."
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 20 ++--
>  1 file changed, 6 insertions(+), 14 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH v2 16/28] s390x/tcg: Fault-safe memmove

2019-09-11 Thread Richard Henderson
On 9/6/19 3:57 AM, David Hildenbrand wrote:
> Replace fast_memmove() variants by access_memmove() variants, that
> first try to probe access to all affected pages (maximum is two pages).
> 
> In MVCOS, simply always call access_memmove_as() and drop the TODO
> about LAP. LAP is already handled in the MMU.
> 
> Get rid of adj_len_to_page(), which is now unused.
> 
> Signed-off-by: David Hildenbrand 
> ---
>  target/s390x/mem_helper.c | 204 +-
>  1 file changed, 115 insertions(+), 89 deletions(-)

Reviewed-by: Richard Henderson 

r~



Re: [Qemu-devel] [PATCH 0/3] Automatic RCU read unlock

2019-09-11 Thread no-reply
Patchew URL: 
https://patchew.org/QEMU/20190911164202.31136-1-dgilb...@redhat.com/



Hi,

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

Subject: [Qemu-devel] [PATCH 0/3] Automatic RCU read unlock
Message-id: 20190911164202.31136-1-dgilb...@redhat.com
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
bf33be9 migration: Use automatic rcu_read unlock in rdma.c
c64f2f4 migration: Use automatic rcu_read unlock in ram.c
af6a608 rcu: Add automatically released rcu_read_lock variant

=== OUTPUT BEGIN ===
1/3 Checking commit af6a608b908d (rcu: Add automatically released rcu_read_lock 
variant)
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#33: FILE: include/qemu/rcu.h:165:
+#define RCU_READ_LOCK_AUTO g_auto(rcu_read_auto_t) \
+_rcu_read_auto = 'x'; \
+rcu_read_lock();

total: 1 errors, 0 warnings, 18 lines checked

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

2/3 Checking commit c64f2f4c923f (migration: Use automatic rcu_read unlock in 
ram.c)
3/3 Checking commit bf33be959c2b (migration: Use automatic rcu_read unlock in 
rdma.c)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190911164202.31136-1-dgilb...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [https://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

Re: [Qemu-devel] [PATCH v6 4/8] linux-user/syscall: Introduce target_sockaddr_nl

2019-09-11 Thread Philippe Mathieu-Daudé
On Mon, Sep 9, 2019 at 4:23 PM Laurent Vivier  wrote:
> Le 08/09/2019 à 08:15, Philippe Mathieu-Daudé a écrit :
> > Signed-off-by: Philippe Mathieu-Daudé 
> > Tested-By: Guido Günther 
> > ---
> >  linux-user/syscall.c  | 6 --
> >  linux-user/syscall_defs.h | 7 +++
> >  2 files changed, 11 insertions(+), 2 deletions(-)
> >
> > diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> > index 8b41a03901..5128312db5 100644
> > --- a/linux-user/syscall.c
> > +++ b/linux-user/syscall.c
> > @@ -1494,8 +1494,10 @@ static inline abi_long 
> > host_to_target_sockaddr(abi_ulong target_addr,
> >  sizeof(target_saddr->sa_family)) {
> >  target_saddr->sa_family = tswap16(addr->sa_family);
> >  }
> > -if (addr->sa_family == AF_NETLINK && len >= sizeof(struct 
> > sockaddr_nl)) {
> > -struct sockaddr_nl *target_nl = (struct sockaddr_nl *)target_saddr;
> > +if (addr->sa_family == AF_NETLINK &&
> > +len >= sizeof(struct target_sockaddr_nl)) {
> > +struct target_sockaddr_nl *target_nl =
> > +   (struct target_sockaddr_nl *)target_saddr;
> >  target_nl->nl_pid = tswap32(target_nl->nl_pid);
> >  target_nl->nl_groups = tswap32(target_nl->nl_groups);
> >  } else if (addr->sa_family == AF_PACKET) {
> > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
> > index 0662270300..fcedd0d0fb 100644
> > --- a/linux-user/syscall_defs.h
> > +++ b/linux-user/syscall_defs.h
> > @@ -153,6 +153,13 @@ struct target_sockaddr_un {
> >  uint8_t sun_path[108];
> >  };
> >
> > +struct target_sockaddr_nl {
> > +uint16_t nl_family; /* AF_NETLINK */
> > +uint16_t __pad;
> > +uint32_t nl_pid;
> > +uint32_t nl_groups;
> > +};
>
> You should use abi_ushort and abi_uint to keep alignments good (for
> instance m68k aligns on 16bit whereas others on 32bit).

Are you sure? The other target_sockaddr don't use that...
Is this because netlink is a host-only structure? (while other are
serialized over some interface).

Thanks,

Phil.



[Qemu-devel] [Bug 1805256] Re: qemu-img hangs on rcu_call_ready_event logic in Aarch64 when converting images

2019-09-11 Thread Rafael David Tinoco
** Also affects: qemu (Ubuntu Ff-series)
   Importance: Undecided
   Status: New

** Also affects: qemu (Ubuntu Bionic)
   Importance: Undecided
   Status: New

** Also affects: qemu (Ubuntu Eoan)
   Importance: Medium
 Assignee: Rafael David Tinoco (rafaeldtinoco)
   Status: In Progress

** Also affects: qemu (Ubuntu Disco)
   Importance: Undecided
   Status: New

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

Title:
  qemu-img hangs on rcu_call_ready_event logic in Aarch64 when
  converting images

Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  In Progress
Status in qemu source package in Bionic:
  New
Status in qemu source package in Disco:
  New
Status in qemu source package in Eoan:
  In Progress
Status in qemu source package in FF-Series:
  New

Bug description:
  Command:

  qemu-img convert -f qcow2 -O qcow2 ./disk01.qcow2 ./output.qcow2

  Hangs indefinitely approximately 30% of the runs.

  

  Workaround:

  qemu-img convert -m 1 -f qcow2 -O qcow2 ./disk01.qcow2 ./output.qcow2

  Run "qemu-img convert" with "a single coroutine" to avoid this issue.

  

  (gdb) thread 1
  ...
  (gdb) bt
  #0 0xbf1ad81c in __GI_ppoll
  #1 0xaabcf73c in ppoll
  #2 qemu_poll_ns
  #3 0xaabd0764 in os_host_main_loop_wait
  #4 main_loop_wait
  ...

  (gdb) thread 2
  ...
  (gdb) bt
  #0 syscall ()
  #1 0xaabd41cc in qemu_futex_wait
  #2 qemu_event_wait (ev=ev@entry=0xaac86ce8 )
  #3 0xaabed05c in call_rcu_thread
  #4 0xaabd34c8 in qemu_thread_start
  #5 0xbf25c880 in start_thread
  #6 0xbf1b6b9c in thread_start ()

  (gdb) thread 3
  ...
  (gdb) bt
  #0 0xbf11aa20 in __GI___sigtimedwait
  #1 0xbf2671b4 in __sigwait
  #2 0xaabd1ddc in sigwait_compat
  #3 0xaabd34c8 in qemu_thread_start
  #4 0xbf25c880 in start_thread
  #5 0xbf1b6b9c in thread_start

  

  (gdb) run
  Starting program: /usr/bin/qemu-img convert -f qcow2 -O qcow2
  ./disk01.ext4.qcow2 ./output.qcow2

  [New Thread 0xbec5ad90 (LWP 72839)]
  [New Thread 0xbe459d90 (LWP 72840)]
  [New Thread 0xbdb57d90 (LWP 72841)]
  [New Thread 0xacac9d90 (LWP 72859)]
  [New Thread 0xa7ffed90 (LWP 72860)]
  [New Thread 0xa77fdd90 (LWP 72861)]
  [New Thread 0xa6ffcd90 (LWP 72862)]
  [New Thread 0xa67fbd90 (LWP 72863)]
  [New Thread 0xa5ffad90 (LWP 72864)]

  [Thread 0xa5ffad90 (LWP 72864) exited]
  [Thread 0xa6ffcd90 (LWP 72862) exited]
  [Thread 0xa77fdd90 (LWP 72861) exited]
  [Thread 0xbdb57d90 (LWP 72841) exited]
  [Thread 0xa67fbd90 (LWP 72863) exited]
  [Thread 0xacac9d90 (LWP 72859) exited]
  [Thread 0xa7ffed90 (LWP 72860) exited]

  
  """

  All the tasks left are blocked in a system call, so no task left to call
  qemu_futex_wake() to unblock thread #2 (in futex()), which would unblock
  thread #1 (doing poll() in a pipe with thread #2).

  Those 7 threads exit before disk conversion is complete (sometimes in
  the beginning, sometimes at the end).

  

  [ Original Description ]

  On the HiSilicon D06 system - a 96 core NUMA arm64 box - qemu-img
  frequently hangs (~50% of the time) with this command:

  qemu-img convert -f qcow2 -O qcow2 /tmp/cloudimg /tmp/cloudimg2

  Where "cloudimg" is a standard qcow2 Ubuntu cloud image. This
  qcow2->qcow2 conversion happens to be something uvtool does every time
  it fetches images.

  Once hung, attaching gdb gives the following backtrace:

  (gdb) bt
  #0  0xae4f8154 in __GI_ppoll (fds=0xe8a67dc0, 
nfds=187650274213760,
  timeout=, timeout@entry=0x0, sigmask=0xc123b950)
  at ../sysdeps/unix/sysv/linux/ppoll.c:39
  #1  0xbbefaf00 in ppoll (__ss=0x0, __timeout=0x0, __nfds=,
  __fds=) at /usr/include/aarch64-linux-gnu/bits/poll2.h:77
  #2  qemu_poll_ns (fds=, nfds=,
  timeout=timeout@entry=-1) at util/qemu-timer.c:322
  #3  0xbbefbf80 in os_host_main_loop_wait (timeout=-1)
  at util/main-loop.c:233
  #4  main_loop_wait (nonblocking=) at util/main-loop.c:497
  #5  0xbbe2aa30 in convert_do_copy (s=0xc123bb58) at 
qemu-img.c:1980
  #6  img_convert (argc=, argv=) at 
qemu-img.c:2456
  #7  0xbbe2333c in main (argc=7, argv=) at 
qemu-img.c:4975

  Reproduced w/ latest QEMU git (@ 53744e0a182)

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



Re: [Qemu-devel] [RFC v2 1/2] docs: vhost-user: add in-band kick/call messages

2019-09-11 Thread Johannes Berg
On Wed, 2019-09-11 at 20:15 +0100, Dr. David Alan Gilbert wrote:

> > Extend the protocol slightly, so that a message can be used for kick
> > and call instead, if VHOST_USER_PROTOCOL_F_IN_BAND_NOTIFICATIONS is
> > negotiated. This in itself doesn't guarantee synchronisation, but both
> > sides can also negotiate VHOST_USER_PROTOCOL_F_REPLY_ACK and thus get
> > a reply to this message by setting the need_reply flag, and ensure
> > synchronisation this way.
> 
> I'm confused; if you've already got REPLY_ACK, why do we need anything
> else?  We already require the reply on set_mem_table as part of
> postcopy.

Hmm? How's this related to set_mem_table?

For simulation purposes, I need the kick and call (and error perhaps
though it's not really used by anyone now it seems) to be synchronous
messages instead of asynchronous event FD pushes.

But I think enough words have been expended on explaining it already, if
I may kindly ask you to read the discussions with Stefan and Michael
here:

https://lore.kernel.org/qemu-devel/20190902121233.13382-1-johan...@sipsolutions.net/

Thanks,
johannes




Re: [Qemu-devel] [RFC v2 1/2] docs: vhost-user: add in-band kick/call messages

2019-09-11 Thread Dr. David Alan Gilbert
* Johannes Berg (johan...@sipsolutions.net) wrote:
> From: Johannes Berg 
> 
> For good reason, vhost-user is currently built asynchronously, that
> way better performance can be obtained. However, for certain use
> cases such as simulation, this is problematic.
> 
> Consider an event-based simulation in which both the device and CPU
> have scheduled according to a simulation "calendar". Now, consider
> the CPU sending I/O to the device, over a vring in the vhost-user
> protocol. In this case, the CPU must wait for the vring interrupt
> to have been processed by the device, so that the device is able to
> put an entry onto the simulation calendar to obtain time to handle
> the interrupt. Note that this doesn't mean the I/O is actually done
> at this time, it just means that the handling of it is scheduled
> before the CPU can continue running.
> 
> This cannot be done with the asynchronous eventfd based vring kick
> and call design.
> 
> Extend the protocol slightly, so that a message can be used for kick
> and call instead, if VHOST_USER_PROTOCOL_F_IN_BAND_NOTIFICATIONS is
> negotiated. This in itself doesn't guarantee synchronisation, but both
> sides can also negotiate VHOST_USER_PROTOCOL_F_REPLY_ACK and thus get
> a reply to this message by setting the need_reply flag, and ensure
> synchronisation this way.

I'm confused; if you've already got REPLY_ACK, why do we need anything
else?  We already require the reply on set_mem_table as part of
postcopy.

Dave

> To really use it in both directions, VHOST_USER_PROTOCOL_F_SLAVE_REQ
> is also needed.
> 
> Since it is used for simulation purposes and too many messages on
> the socket can lock up the virtual machine, document that this should
> only be used together with the mentioned features.
> 
> Signed-off-by: Johannes Berg 
> ---
>  docs/interop/vhost-user.rst | 113 ++--
>  1 file changed, 96 insertions(+), 17 deletions(-)
> 
> diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
> index 7827b710aa0a..c4396eabf9e9 100644
> --- a/docs/interop/vhost-user.rst
> +++ b/docs/interop/vhost-user.rst
> @@ -2,6 +2,7 @@
>  Vhost-user Protocol
>  ===
>  :Copyright: 2014 Virtual Open Systems Sarl.
> +:Copyright: 2019 Intel Corporation
>  :Licence: This work is licensed under the terms of the GNU GPL,
>version 2 or later. See the COPYING file in the top-level
>directory.
> @@ -279,6 +280,9 @@ If *master* is unable to send the full message or 
> receives a wrong
>  reply it will close the connection. An optional reconnection mechanism
>  can be implemented.
>  
> +If *slave* detects some error such as incompatible features, it may also
> +close the connection. This should only happen in exceptional circumstances.
> +
>  Any protocol extensions are gated by protocol feature bits, which
>  allows full backwards compatibility on both master and slave.  As
>  older slaves don't support negotiating protocol features, a feature
> @@ -315,7 +319,8 @@ it until ring is started, or after it has been stopped.
>  
>  Client must start ring upon receiving a kick (that is, detecting that
>  file descriptor is readable) on the descriptor specified by
> -``VHOST_USER_SET_VRING_KICK``, and stop ring upon receiving
> +``VHOST_USER_SET_VRING_KICK`` (or receiving the in-band message
> +``VHOST_USER_VRING_KICK`` if negotiated) and stop ring upon receiving
>  ``VHOST_USER_GET_VRING_BASE``.
>  
>  While processing the rings (whether they are enabled or not), client
> @@ -767,24 +772,48 @@ When reconnecting:
>  #. Resubmit inflight ``DescStatePacked`` entries in order of their
> counter value
>  
> +In-band notifications
> +-
> +
> +In some limited situations (e.g. for simulation) it is desirable to
> +have the kick, call and error (if used) signals done via in-band
> +messages instead of asynchronous eventfd notifications. This can be
> +done by negotiating the ``VHOST_USER_PROTOCOL_F_IN_BAND_NOTIFICATIONS``
> +protocol feature.
> +
> +Note that due to the fact that too many messages on the sockets can
> +cause the sending application(s) to block, it is not advised to use
> +this feature unless absolutely necessary. It is also considered an
> +error to negotiate this feature without also negotiating
> +``VHOST_USER_PROTOCOL_F_SLAVE_REQ`` and ``VHOST_USER_PROTOCOL_F_REPLY_ACK``,
> +the former is necessary for getting a message channel from the slave
> +to the master, while the latter needs to be used with the in-band
> +notification messages to block until they are processed, both to avoid
> +blocking later and for proper processing (at least in the simulation
> +use case.) As it has no other way of signalling this error, the slave
> +should close the connection as a response to a
> +``VHOST_USER_SET_PROTOCOL_FEATURES`` message that sets the in-band
> +notifications feature flag without the other two.
> +
>  Protocol features
>  -
>  
>  .. code:: c
>  
> -  #define

Re: [Qemu-devel] qemu_futex_wait() lockups in ARM64: 2 possible issues

2019-09-11 Thread Rafael David Tinoco
> Zhengui's theory that notify_me doesn't work properly on ARM is more
> promising, but he couldn't provide a clear explanation of why he thought
> notify_me is involved.  In particular, I would have expected notify_me to
> be wrong if the qemu_poll_ns call came from aio_ctx_dispatch, for example:
> 
> 
> glib_pollfds_fill
>   g_main_context_prepare
> aio_ctx_prepare
>   atomic_or(&ctx->notify_me, 1)
> qemu_poll_ns
> glib_pollfds_poll
>   g_main_context_check
> aio_ctx_check
>   atomic_and(&ctx->notify_me, ~1)
>   g_main_context_dispatch
> aio_ctx_dispatch
>   /* do something for event */
> qemu_poll_ns 
> 

Paolo,

I tried confining execution in a single NUMA domain (cpu & mem) and
still faced the issue, then, I added a mutex "ctx->notify_me_lcktest"
into context to protect "ctx->notify_me", like showed bellow, and it
seems to have either fixed or mitigated it.

I was able to cause the hung once every 3 or 4 runs. I have already ran
qemu-img convert more than 30 times now and couldn't reproduce it again.

Next step is to play with the barriers and check why existing ones
aren't enough for ordering access to ctx->notify_me ... or should I
try/do something else in your opinion ?

This arch/machine (Huawei D06):

$ lscpu
Architecture:aarch64
Byte Order:  Little Endian
CPU(s):  96
On-line CPU(s) list: 0-95
Thread(s) per core:  1
Core(s) per socket:  48
Socket(s):   2
NUMA node(s):4
Vendor ID:   0x48
Model:   0
Stepping:0x0
CPU max MHz: 2000.
CPU min MHz: 200.
BogoMIPS:200.00
L1d cache:   64K
L1i cache:   64K
L2 cache:512K
L3 cache:32768K
NUMA node0 CPU(s):   0-23
NUMA node1 CPU(s):   24-47
NUMA node2 CPU(s):   48-71
NUMA node3 CPU(s):   72-95
Flags:   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics
cpuid asimdrdm dcpop



diff --git a/include/block/aio.h b/include/block/aio.h
index 0ca25dfec6..0724086d91 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -84,6 +84,7 @@ struct AioContext {
  * dispatch phase, hence a simple counter is enough for them.
  */
 uint32_t notify_me;
+QemuMutex notify_me_lcktest;

 /* A lock to protect between QEMUBH and AioHandler adders and deleter,
  * and to ensure that no callbacks are removed while we're walking and
diff --git a/util/aio-posix.c b/util/aio-posix.c
index 51c41ed3c9..031d6e2997 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -529,7 +529,9 @@ static bool run_poll_handlers(AioContext *ctx,
int64_t max_ns, int64_t *timeout)
 bool progress;
 int64_t start_time, elapsed_time;

+qemu_mutex_lock(&ctx->notify_me_lcktest);
 assert(ctx->notify_me);
+qemu_mutex_unlock(&ctx->notify_me_lcktest);
 assert(qemu_lockcnt_count(&ctx->list_lock) > 0);

 trace_run_poll_handlers_begin(ctx, max_ns, *timeout);
@@ -601,8 +603,10 @@ bool aio_poll(AioContext *ctx, bool blocking)
  * so disable the optimization now.
  */
 if (blocking) {
+qemu_mutex_lock(&ctx->notify_me_lcktest);
 assert(in_aio_context_home_thread(ctx));
 atomic_add(&ctx->notify_me, 2);
+qemu_mutex_unlock(&ctx->notify_me_lcktest);
 }

 qemu_lockcnt_inc(&ctx->list_lock);
@@ -647,8 +651,10 @@ bool aio_poll(AioContext *ctx, bool blocking)
 }

 if (blocking) {
+qemu_mutex_lock(&ctx->notify_me_lcktest);
 atomic_sub(&ctx->notify_me, 2);
 aio_notify_accept(ctx);
+qemu_mutex_unlock(&ctx->notify_me_lcktest);
 }

 /* Adjust polling time */
diff --git a/util/async.c b/util/async.c
index c10642a385..140e1e86f5 100644
--- a/util/async.c
+++ b/util/async.c
@@ -221,7 +221,9 @@ aio_ctx_prepare(GSource *source, gint*timeout)
 {
 AioContext *ctx = (AioContext *) source;

+qemu_mutex_lock(&ctx->notify_me_lcktest);
 atomic_or(&ctx->notify_me, 1);
+qemu_mutex_unlock(&ctx->notify_me_lcktest);

 /* We assume there is no timeout already supplied */
 *timeout = qemu_timeout_ns_to_ms(aio_compute_timeout(ctx));
@@ -239,8 +241,10 @@ aio_ctx_check(GSource *source)
 AioContext *ctx = (AioContext *) source;
 QEMUBH *bh;

+qemu_mutex_lock(&ctx->notify_me_lcktest);
 atomic_and(&ctx->notify_me, ~1);
 aio_notify_accept(ctx);
+qemu_mutex_unlock(&ctx->notify_me_lcktest);

 for (bh = ctx->first_bh; bh; bh = bh->next) {
 if (bh->scheduled) {
@@ -346,11 +350,13 @@ void aio_notify(AioContext *ctx)
 /* Write e.g. bh->scheduled before reading ctx->notify_me.  Pairs
  * with atomic_or in aio_ctx_prepare or atomic_add in aio_poll.
  */
-smp_mb();
+//smp_mb();
+qemu_mutex_lock(&ctx->notify_me_lcktest);
 if (ctx->notify_me) {
 event_notifier_set(&ctx->notifier);
 atomic_mb_set(&ctx->notified, true);
 }
+qemu_mutex_unlock(&ctx->notify_me_l

[Qemu-devel] [PATCH v2 4/5] rcu: Use automatic rc_read unlock in core memory/exec code

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Only in the cases where nothing else interesting happens
after the unlock.

Signed-off-by: Dr. David Alan Gilbert 
---
 exec.c  | 46 +
 include/exec/ram_addr.h |  8 ++-
 memory.c| 15 +-
 3 files changed, 21 insertions(+), 48 deletions(-)

diff --git a/exec.c b/exec.c
index 235d6bc883..ac3d933e1a 100644
--- a/exec.c
+++ b/exec.c
@@ -1034,16 +1034,14 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr 
addr, MemTxAttrs attrs)
 return;
 }
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 mr = address_space_translate(as, addr, &addr, &l, false, attrs);
 if (!(memory_region_is_ram(mr)
   || memory_region_is_romd(mr))) {
-rcu_read_unlock();
 return;
 }
 ram_addr = memory_region_get_ram_addr(mr) + addr;
 tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
-rcu_read_unlock();
 }
 
 static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
@@ -1329,14 +1327,13 @@ static void tlb_reset_dirty_range_all(ram_addr_t start, 
ram_addr_t length)
 end = TARGET_PAGE_ALIGN(start + length);
 start &= TARGET_PAGE_MASK;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 block = qemu_get_ram_block(start);
 assert(block == qemu_get_ram_block(end - 1));
 start1 = (uintptr_t)ramblock_ptr(block, start - block->offset);
 CPU_FOREACH(cpu) {
 tlb_reset_dirty(cpu, start1, length);
 }
-rcu_read_unlock();
 }
 
 /* Note: start and end must be within the same ram block.  */
@@ -1661,7 +1658,7 @@ void ram_block_dump(Monitor *mon)
 RAMBlock *block;
 char *psize;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 monitor_printf(mon, "%24s %8s  %18s %18s %18s\n",
"Block Name", "PSize", "Offset", "Used", "Total");
 RAMBLOCK_FOREACH(block) {
@@ -1673,7 +1670,6 @@ void ram_block_dump(Monitor *mon)
(uint64_t)block->max_length);
 g_free(psize);
 }
-rcu_read_unlock();
 }
 
 #ifdef __linux__
@@ -1995,11 +1991,10 @@ static unsigned long last_ram_page(void)
 RAMBlock *block;
 ram_addr_t last = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 RAMBLOCK_FOREACH(block) {
 last = MAX(last, block->offset + block->max_length);
 }
-rcu_read_unlock();
 return last >> TARGET_PAGE_BITS;
 }
 
@@ -2086,7 +2081,7 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char 
*name, DeviceState *dev)
 }
 pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 RAMBLOCK_FOREACH(block) {
 if (block != new_block &&
 !strcmp(block->idstr, new_block->idstr)) {
@@ -2095,7 +2090,6 @@ void qemu_ram_set_idstr(RAMBlock *new_block, const char 
*name, DeviceState *dev)
 abort();
 }
 }
-rcu_read_unlock();
 }
 
 /* Called with iothread lock held.  */
@@ -2637,17 +2631,16 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool 
round_offset,
 
 if (xen_enabled()) {
 ram_addr_t ram_addr;
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 ram_addr = xen_ram_addr_from_mapcache(ptr);
 block = qemu_get_ram_block(ram_addr);
 if (block) {
 *offset = ram_addr - block->offset;
 }
-rcu_read_unlock();
 return block;
 }
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 block = atomic_rcu_read(&ram_list.mru_block);
 if (block && block->host && host - block->host < block->max_length) {
 goto found;
@@ -2663,7 +2656,6 @@ RAMBlock *qemu_ram_block_from_host(void *ptr, bool 
round_offset,
 }
 }
 
-rcu_read_unlock();
 return NULL;
 
 found:
@@ -2671,7 +2663,6 @@ found:
 if (round_offset) {
 *offset &= TARGET_PAGE_MASK;
 }
-rcu_read_unlock();
 return block;
 }
 
@@ -3380,10 +3371,9 @@ MemTxResult address_space_read_full(AddressSpace *as, 
hwaddr addr,
 FlatView *fv;
 
 if (len > 0) {
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 fv = address_space_to_flatview(as);
 result = flatview_read(fv, addr, attrs, buf, len);
-rcu_read_unlock();
 }
 
 return result;
@@ -3397,10 +3387,9 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr 
addr,
 FlatView *fv;
 
 if (len > 0) {
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 fv = address_space_to_flatview(as);
 result = flatview_write(fv, addr, attrs, buf, len);
-rcu_read_unlock();
 }
 
 return result;
@@ -3440,7 +3429,7 @@ static inline MemTxResult 
address_space_write_rom_internal(AddressSpace *as,
 hwaddr addr1;
 MemoryRegion *mr;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 while (len > 0) {
 l = len;
 mr = address_space_translate(as, addr, &addr1, &l, true, attrs);
@@ -3465,7 +3454,6 @@ static inline MemTxResult 
address_space_write_rom_i

[Qemu-devel] [PATCH v2 2/5] migration: Use automatic rcu_read unlock in ram.c

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Use the automatic read unlocker in migration/ram.c;
only for the cases where the unlock is at the end of the function.

Signed-off-by: Dr. David Alan Gilbert 
---
 migration/ram.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/migration/ram.c b/migration/ram.c
index b2bd618a89..1bb82acfe0 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -181,14 +181,14 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void 
*opaque)
 RAMBlock *block;
 int ret = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
+
 RAMBLOCK_FOREACH_NOT_IGNORED(block) {
 ret = func(block, opaque);
 if (ret) {
 break;
 }
 }
-rcu_read_unlock();
 return ret;
 }
 
@@ -2398,13 +2398,12 @@ static void migration_page_queue_free(RAMState *rs)
 /* This queue generally should be empty - but in the case of a failed
  * migration might have some droppings in.
  */
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 QSIMPLEQ_FOREACH_SAFE(mspr, &rs->src_page_requests, next_req, next_mspr) {
 memory_region_unref(mspr->rb->mr);
 QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);
 g_free(mspr);
 }
-rcu_read_unlock();
 }
 
 /**
@@ -2425,7 +2424,8 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
 RAMState *rs = ram_state;
 
 ram_counters.postcopy_requests++;
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
+
 if (!rbname) {
 /* Reuse last RAMBlock */
 ramblock = rs->last_req_rb;
@@ -2467,12 +2467,10 @@ int ram_save_queue_pages(const char *rbname, ram_addr_t 
start, ram_addr_t len)
 QSIMPLEQ_INSERT_TAIL(&rs->src_page_requests, new_entry, next_req);
 migration_make_urgent_request();
 qemu_mutex_unlock(&rs->src_page_req_mutex);
-rcu_read_unlock();
 
 return 0;
 
 err:
-rcu_read_unlock();
 return -1;
 }
 
@@ -2712,7 +2710,8 @@ static uint64_t ram_bytes_total_common(bool count_ignored)
 RAMBlock *block;
 uint64_t total = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
+
 if (count_ignored) {
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
 total += block->used_length;
@@ -2722,7 +2721,6 @@ static uint64_t ram_bytes_total_common(bool count_ignored)
 total += block->used_length;
 }
 }
-rcu_read_unlock();
 return total;
 }
 
@@ -3086,7 +3084,7 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
 RAMBlock *block;
 int ret;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 
 /* This should be our last sync, the src is now paused */
 migration_bitmap_sync(rs);
@@ -3107,13 +3105,11 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
  * point.
  */
 error_report("migration ram resized during precopy phase");
-rcu_read_unlock();
 return -EINVAL;
 }
 /* Deal with TPS != HPS and huge pages */
 ret = postcopy_chunk_hostpages(ms, block);
 if (ret) {
-rcu_read_unlock();
 return ret;
 }
 
@@ -3128,7 +3124,6 @@ int ram_postcopy_send_discard_bitmap(MigrationState *ms)
 trace_ram_postcopy_send_discard_bitmap();
 
 ret = postcopy_each_ram_send_discard(ms);
-rcu_read_unlock();
 
 return ret;
 }
@@ -3149,7 +3144,7 @@ int ram_discard_range(const char *rbname, uint64_t start, 
size_t length)
 
 trace_ram_discard_range(rbname, start, length);
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 RAMBlock *rb = qemu_ram_block_by_name(rbname);
 
 if (!rb) {
@@ -3169,8 +3164,6 @@ int ram_discard_range(const char *rbname, uint64_t start, 
size_t length)
 ret = ram_block_discard_range(rb, start, length);
 
 err:
-rcu_read_unlock();
-
 return ret;
 }
 
-- 
2.21.0




[Qemu-devel] [PATCH v2 0/5] Automatic RCU read unlock

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 


This patch uses glib's g_auto mechanism to automatically free
rcu_read_lock's at the end of the block.  Given that humans
have a habit of forgetting an error path somewhere it's
best to leave it to the compiler.

(Note I've found the actual cause of my deadlock actually
isn't a misisng unlock; it's a lock ordering thing)

v2
  Rework auto mechanism based on Dan and Eduardo's comments
  Add some more uses in memory/exec
  Add a missing unlock in a function I've not used the macro in

Dr. David Alan Gilbert (5):
  rcu: Add automatically released rcu_read_lock variant
  migration: Use automatic rcu_read unlock in ram.c
  migration: Use automatic rcu_read unlock in rdma.c
  rcu: Use automatic rc_read unlock in core memory/exec code
  migration: Missing rcu_read_unlock

 exec.c  | 46 ++---
 include/exec/ram_addr.h |  8 ++
 include/qemu/rcu.h  | 18 +
 memory.c| 15 ---
 migration/ram.c | 26 ---
 migration/rdma.c| 57 -
 6 files changed, 60 insertions(+), 110 deletions(-)

-- 
2.21.0




[Qemu-devel] [PATCH v2 1/5] rcu: Add automatically released rcu_read_lock variant

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

RCU_READ_LOCK_AUTO takes the rcu_read_lock and then uses glib's
g_auto infrastructure (and thus whatever the compiler's hooks are) to
release it on all exits of the block.

Signed-off-by: Dr. David Alan Gilbert 
---
 include/qemu/rcu.h | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 22876d1428..8768a7b60a 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -154,6 +154,24 @@ extern void call_rcu1(struct rcu_head *head, RCUCBFunc 
*func);
   }),\
   (RCUCBFunc *)g_free);
 
+typedef void RCUReadAuto;
+static inline RCUReadAuto *rcu_read_auto_lock(void)
+{
+rcu_read_lock();
+/* Anything non-NULL causes the cleanup function to be called */
+return (void *)0x1;
+}
+
+static inline void rcu_read_auto_unlock(RCUReadAuto *r)
+{
+rcu_read_unlock();
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock)
+
+#define RCU_READ_LOCK_AUTO \
+g_autoptr(RCUReadAuto) _rcu_read_auto = rcu_read_auto_lock()
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.21.0




[Qemu-devel] [PATCH v2 3/5] migration: Use automatic rcu_read unlock in rdma.c

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Use the automatic read unlocker in migration/rdma.c.

Signed-off-by: Dr. David Alan Gilbert 
---
 migration/rdma.c | 57 ++--
 1 file changed, 11 insertions(+), 46 deletions(-)

diff --git a/migration/rdma.c b/migration/rdma.c
index 78e6b72bac..32c9aba7b3 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -88,7 +88,6 @@ static uint32_t known_capabilities = RDMA_CAPABILITY_PIN_ALL;
 " to abort!"); \
 rdma->error_reported = 1; \
 } \
-rcu_read_unlock(); \
 return rdma->error_state; \
 } \
 } while (0)
@@ -2678,11 +2677,10 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 size_t i;
 size_t len = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 rdma = atomic_rcu_read(&rioc->rdmaout);
 
 if (!rdma) {
-rcu_read_unlock();
 return -EIO;
 }
 
@@ -2695,7 +2693,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 ret = qemu_rdma_write_flush(f, rdma);
 if (ret < 0) {
 rdma->error_state = ret;
-rcu_read_unlock();
 return ret;
 }
 
@@ -2715,7 +2712,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 
 if (ret < 0) {
 rdma->error_state = ret;
-rcu_read_unlock();
 return ret;
 }
 
@@ -2724,7 +2720,6 @@ static ssize_t qio_channel_rdma_writev(QIOChannel *ioc,
 }
 }
 
-rcu_read_unlock();
 return done;
 }
 
@@ -2764,11 +2759,10 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
 ssize_t i;
 size_t done = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 rdma = atomic_rcu_read(&rioc->rdmain);
 
 if (!rdma) {
-rcu_read_unlock();
 return -EIO;
 }
 
@@ -2805,7 +2799,6 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
 
 if (ret < 0) {
 rdma->error_state = ret;
-rcu_read_unlock();
 return ret;
 }
 
@@ -2819,14 +2812,12 @@ static ssize_t qio_channel_rdma_readv(QIOChannel *ioc,
 /* Still didn't get enough, so lets just return */
 if (want) {
 if (done == 0) {
-rcu_read_unlock();
 return QIO_CHANNEL_ERR_BLOCK;
 } else {
 break;
 }
 }
 }
-rcu_read_unlock();
 return done;
 }
 
@@ -2882,7 +2873,7 @@ qio_channel_rdma_source_prepare(GSource *source,
 GIOCondition cond = 0;
 *timeout = -1;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 if (rsource->condition == G_IO_IN) {
 rdma = atomic_rcu_read(&rsource->rioc->rdmain);
 } else {
@@ -2891,7 +2882,6 @@ qio_channel_rdma_source_prepare(GSource *source,
 
 if (!rdma) {
 error_report("RDMAContext is NULL when prepare Gsource");
-rcu_read_unlock();
 return FALSE;
 }
 
@@ -2900,7 +2890,6 @@ qio_channel_rdma_source_prepare(GSource *source,
 }
 cond |= G_IO_OUT;
 
-rcu_read_unlock();
 return cond & rsource->condition;
 }
 
@@ -2911,7 +2900,7 @@ qio_channel_rdma_source_check(GSource *source)
 RDMAContext *rdma;
 GIOCondition cond = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 if (rsource->condition == G_IO_IN) {
 rdma = atomic_rcu_read(&rsource->rioc->rdmain);
 } else {
@@ -2920,7 +2909,6 @@ qio_channel_rdma_source_check(GSource *source)
 
 if (!rdma) {
 error_report("RDMAContext is NULL when check Gsource");
-rcu_read_unlock();
 return FALSE;
 }
 
@@ -2929,7 +2917,6 @@ qio_channel_rdma_source_check(GSource *source)
 }
 cond |= G_IO_OUT;
 
-rcu_read_unlock();
 return cond & rsource->condition;
 }
 
@@ -2943,7 +2930,7 @@ qio_channel_rdma_source_dispatch(GSource *source,
 RDMAContext *rdma;
 GIOCondition cond = 0;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 if (rsource->condition == G_IO_IN) {
 rdma = atomic_rcu_read(&rsource->rioc->rdmain);
 } else {
@@ -2952,7 +2939,6 @@ qio_channel_rdma_source_dispatch(GSource *source,
 
 if (!rdma) {
 error_report("RDMAContext is NULL when dispatch Gsource");
-rcu_read_unlock();
 return FALSE;
 }
 
@@ -2961,7 +2947,6 @@ qio_channel_rdma_source_dispatch(GSource *source,
 }
 cond |= G_IO_OUT;
 
-rcu_read_unlock();
 return (*func)(QIO_CHANNEL(rsource->rioc),
(cond & rsource->condition),
user_data);
@@ -3058,7 +3043,7 @@ qio_channel_rdma_shutdown(QIOChannel *ioc,
 QIOChannelRDMA *rioc = QIO_CHANNEL_RDMA(ioc);
 RDMAContext *rdmain, *rdmaout;
 
-rcu_read_lock();
+RCU_READ_LOCK_AUTO;
 
 rdmain = atomic_rcu_read(&rioc->rdmain);
 rdmaout = atomic_rcu_read(&rioc->rdmain);
@@ -3085,7 +3070,6 @@ qio_channel_rdma_shutdown(QIOChannel *ioc,
 break;
 }
 
-rcu_read_unlock();
 retur

[Qemu-devel] [PATCH v2 5/5] migration: Missing rcu_read_unlock

2019-09-11 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Error path missing an unlock.

Signed-off-by: Dr. David Alan Gilbert 
---
 migration/ram.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/migration/ram.c b/migration/ram.c
index 1bb82acfe0..977172ea7e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3445,6 +3445,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
 RAMBLOCK_FOREACH_MIGRATABLE(block) {
 if (!block->idstr[0]) {
 error_report("%s: RAMBlock with empty name", __func__);
+rcu_read_unlock();
 return -1;
 }
 qemu_put_byte(f, strlen(block->idstr));
-- 
2.21.0




Re: [Qemu-devel] [PATCH V2 2/2] migration/qemu-file: fix potential buf waste for extra buf_index adjustment

2019-09-11 Thread Dr. David Alan Gilbert
* Wei Yang (richard.weiy...@gmail.com) wrote:
> From: Wei Yang 
> 
> In add_to_iovec(), qemu_fflush() will be called if iovec is full. If
> this happens, buf_index is reset. Currently, this is not checked and
> buf_index would always been adjust with buf size.
> 
> This is not harmful, but will waste some space in file buffer.
> 
> This patch make add_to_iovec() return 1 when it has flushed the file.
> Then the caller could check the return value to see whether it is
> necessary to adjust the buf_index any more.
> 
> Signed-off-by: Wei Yang 
> Reviewed-by: Dr. David Alan Gilbert 
> 
> ---
> v2:
>* wrap these common steps into add_buf_to_iovec()
> ---
>  migration/qemu-file.c | 43 ++-
>  1 file changed, 26 insertions(+), 17 deletions(-)
> 
> diff --git a/migration/qemu-file.c b/migration/qemu-file.c
> index 47f16d0e54..417eeba64b 100644
> --- a/migration/qemu-file.c
> +++ b/migration/qemu-file.c
> @@ -382,8 +382,16 @@ int qemu_fclose(QEMUFile *f)
>  return ret;
>  }
>  
> -static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size,
> - bool may_free)
> +/*
> + * Add buf to iovec. Do flush if iovec is full.
> + *
> + * Return values:
> + * 1 iovec is full and flushed
> + * 0 iovec is not flushed
> + *
> + */
> +static int add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size,
> +bool may_free)
>  {
>  /* check for adjacent buffer and coalesce them */
>  if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
> @@ -401,6 +409,19 @@ static void add_to_iovec(QEMUFile *f, const uint8_t 
> *buf, size_t size,
>  
>  if (f->iovcnt >= MAX_IOV_SIZE) {
>  qemu_fflush(f);
> +return 1;
> +}
> +
> +return 0;
> +}
> +
> +static void add_buf_to_iovec(QEMUFile *f, size_t len)
> +{
> +if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) {
> +f->buf_index += len;
> +if (f->buf_index == IO_BUF_SIZE) {
> +qemu_fflush(f);
> +}

Yep, that's better.

Dave

>  }
>  }
>  
> @@ -430,11 +451,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, 
> size_t size)
>  }
>  memcpy(f->buf + f->buf_index, buf, l);
>  f->bytes_xfer += l;
> -add_to_iovec(f, f->buf + f->buf_index, l, false);
> -f->buf_index += l;
> -if (f->buf_index == IO_BUF_SIZE) {
> -qemu_fflush(f);
> -}
> +add_buf_to_iovec(f, l);
>  if (qemu_file_get_error(f)) {
>  break;
>  }
> @@ -451,11 +468,7 @@ void qemu_put_byte(QEMUFile *f, int v)
>  
>  f->buf[f->buf_index] = v;
>  f->bytes_xfer++;
> -add_to_iovec(f, f->buf + f->buf_index, 1, false);
> -f->buf_index++;
> -if (f->buf_index == IO_BUF_SIZE) {
> -qemu_fflush(f);
> -}
> +add_buf_to_iovec(f, 1);
>  }
>  
>  void qemu_file_skip(QEMUFile *f, int size)
> @@ -761,11 +774,7 @@ ssize_t qemu_put_compression_data(QEMUFile *f, z_stream 
> *stream,
>  }
>  
>  qemu_put_be32(f, blen);
> -add_to_iovec(f, f->buf + f->buf_index, blen, false);
> -f->buf_index += blen;
> -if (f->buf_index == IO_BUF_SIZE) {
> -qemu_fflush(f);
> -}
> +add_buf_to_iovec(f, blen);
>  return blen + sizeof(int32_t);
>  }
>  
> -- 
> 2.15.1
> 
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



  1   2   3   4   >