Re: [RFC 00/10] add the rest of riscv bitmapip-0.93 instructions

2021-09-23 Thread eric tang
Ok, thanks. ^ ^!

Alistair Francis  于2021年9月24日周五 下午12:39写道:

> On Sat, Sep 18, 2021 at 6:20 PM Eric Tang 
> wrote:
> >
> > These patches fixed some issues about srow/sroiw/clzw instructions and
> > add the rest of riscv bitmapip-0.93 instructions except fsri/fsriw &
> > bext/bdep & bextw/bdepw for opcode coding or name conflict problems. The
> > problems had been fixed in riscv bitmapip-1.0 version.
> >
> > I have tested these bitmapip instructions, passed by compare the results
> > that produced by qemu and spike.
> >
> > Please review and give your opinion kindly :)
>
> Hey Eric,
>
> Thanks for the patches!
>
> Unfortunately there is already a series "target/riscv: Update QEmu for
> Zb[abcs] 1.0.0"
> (https://www.mail-archive.com/qemu-devel@nongnu.org/msg839086.html)
> that adds support for the v1.0.0 bit manip extension. That has been
> reviewed and queued to be merged.
>
> If you have fixes or features that apply on top of that please send
> them though :)
>
> Alistair
>
> >
> > Eric Tang (10):
> >   target/riscv: rvb: fixed an error about srow/sroiw instructions
> >   target/riscv: rvb: add carry-less multiply instructions
> >   target/riscv: rvb: add cmix/cmov instructions
> >   target/riscv: rvb: add generalized shuffle instructions
> >   target/riscv: rvb: add crossbar permutation instructions
> >   target/riscv: rvb: add bfp/bfpw instructions
> >   target/riscv: rvb: add CRC instructions
> >   target/riscv: rvb: add bit-matrix instructions
> >   target/riscv: rvb: fixed an issue about clzw instruction
> >   target/riscv: rvb: add funnel shfit instructions
> >
> >  target/riscv/bitmanip_helper.c  | 351 
> >  target/riscv/helper.h   |  28 ++
> >  target/riscv/insn32.decode  |  36 +++
> >  target/riscv/insn_trans/trans_rvb.c.inc | 215 ++-
> >  target/riscv/translate.c|  14 +
> >  5 files changed, 641 insertions(+), 3 deletions(-)
> >
> > --
> > 2.17.1
> >
> >
>


Re: [PATCH] block: introduce max_hw_iov for use in scsi-generic

2021-09-23 Thread Paolo Bonzini
Yes, the question is whether it still exists...

Paolo

El jue., 23 sept. 2021 16:48, Christian Borntraeger 
escribió:

>
>
> Am 23.09.21 um 15:04 schrieb Paolo Bonzini:
> > Linux limits the size of iovecs to 1024 (UIO_MAXIOV in the kernel
> > sources, IOV_MAX in POSIX).  Because of this, on some host adapters
> > requests with many iovecs are rejected with -EINVAL by the
> > io_submit() or readv()/writev() system calls.
> >
> > In fact, the same limit applies to SG_IO as well.  To fix both the
> > EINVAL and the possible performance issues from using fewer iovecs
> > than allowed by Linux (some HBAs have max_segments as low as 128),
> > introduce a separate entry in BlockLimits to hold the max_segments
> > value from sysfs.  This new limit is used only for SG_IO and clamped
> > to bs->bl.max_iov anyway, just like max_hw_transfer is clamped to
> > bs->bl.max_transfer.
> >
> > Reported-by: Halil Pasic 
> > Cc: Hanna Reitz 
> > Cc: Kevin Wolf 
> > Cc: qemu-bl...@nongnu.org
> > Fixes: 18473467d5 ("file-posix: try BLKSECTGET on block devices too, do
> not round to power of 2", 2021-06-25)
>
> This sneaked in shortly before the 6.1 release (between rc0 and rc1 I
> think).
> Shouldnt that go to stable in cass this still exist?
>
>
> > Signed-off-by: Paolo Bonzini 
> > ---
> >   block/block-backend.c  | 6 ++
> >   block/file-posix.c | 2 +-
> >   block/io.c | 1 +
> >   hw/scsi/scsi-generic.c | 2 +-
> >   include/block/block_int.h  | 7 +++
> >   include/sysemu/block-backend.h | 1 +
> >   6 files changed, 17 insertions(+), 2 deletions(-)
> >
> > diff --git a/block/block-backend.c b/block/block-backend.c
> > index 6140d133e2..ba2b5ebb10 100644
> > --- a/block/block-backend.c
> > +++ b/block/block-backend.c
> > @@ -1986,6 +1986,12 @@ uint32_t blk_get_max_transfer(BlockBackend *blk)
> >   return ROUND_DOWN(max, blk_get_request_alignment(blk));
> >   }
> >
> > +int blk_get_max_hw_iov(BlockBackend *blk)
> > +{
> > +return MIN_NON_ZERO(blk->root->bs->bl.max_hw_iov,
> > +blk->root->bs->bl.max_iov);
> > +}
> > +
> >   int blk_get_max_iov(BlockBackend *blk)
> >   {
> >   return blk->root->bs->bl.max_iov;
> > diff --git a/block/file-posix.c b/block/file-posix.c
> > index cb9bffe047..1567edb3d5 100644
> > --- a/block/file-posix.c
> > +++ b/block/file-posix.c
> > @@ -1273,7 +1273,7 @@ static void raw_refresh_limits(BlockDriverState
> *bs, Error **errp)
> >
> >   ret = hdev_get_max_segments(s->fd, );
> >   if (ret > 0) {
> > -bs->bl.max_iov = ret;
> > +bs->bl.max_hw_iov = ret;
> >   }
> >   }
> >   }
> > diff --git a/block/io.c b/block/io.c
> > index a19942718b..f38e7f81d8 100644
> > --- a/block/io.c
> > +++ b/block/io.c
> > @@ -136,6 +136,7 @@ static void bdrv_merge_limits(BlockLimits *dst,
> const BlockLimits *src)
> >   dst->min_mem_alignment = MAX(dst->min_mem_alignment,
> >src->min_mem_alignment);
> >   dst->max_iov = MIN_NON_ZERO(dst->max_iov, src->max_iov);
> > +dst->max_hw_iov = MIN_NON_ZERO(dst->max_hw_iov, src->max_hw_iov);
> >   }
> >
> >   typedef struct BdrvRefreshLimitsState {
> > diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
> > index 665baf900e..0306ccc7b1 100644
> > --- a/hw/scsi/scsi-generic.c
> > +++ b/hw/scsi/scsi-generic.c
> > @@ -180,7 +180,7 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq
> *r, SCSIDevice *s, int len)
> >   page = r->req.cmd.buf[2];
> >   if (page == 0xb0) {
> >   uint64_t max_transfer =
> blk_get_max_hw_transfer(s->conf.blk);
> > -uint32_t max_iov = blk_get_max_iov(s->conf.blk);
> > +uint32_t max_iov = blk_get_max_hw_iov(s->conf.blk);
> >
> >   assert(max_transfer);
> >   max_transfer = MIN_NON_ZERO(max_transfer, max_iov *
> qemu_real_host_page_size)
> > diff --git a/include/block/block_int.h b/include/block/block_int.h
> > index f1a54db0f8..c31cbd034a 100644
> > --- a/include/block/block_int.h
> > +++ b/include/block/block_int.h
> > @@ -702,6 +702,13 @@ typedef struct BlockLimits {
> >*/
> >   uint64_t max_hw_transfer;
> >
> > +/* Maximal number of scatter/gather elements allowed by the
> hardware.
> > + * Applies whenever transfers to the device bypass the kernel I/O
> > + * scheduler, for example with SG_IO.  If larger than max_iov
> > + * or if zero, blk_get_max_hw_iov will fall back to max_iov.
> > + */
> > +int max_hw_iov;
> > +
> >   /* memory alignment, in bytes so that no bounce buffer is needed */
> >   size_t min_mem_alignment;
> >
> > diff --git a/include/sysemu/block-backend.h
> b/include/sysemu/block-backend.h
> > index 29d4fdbf63..82bae55161 100644
> > --- a/include/sysemu/block-backend.h
> > +++ b/include/sysemu/block-backend.h
> > @@ -211,6 +211,7 @@ uint32_t blk_get_request_alignment(BlockBackend
> *blk);
> >   uint32_t 

Re: [RFC 00/10] add the rest of riscv bitmapip-0.93 instructions

2021-09-23 Thread Alistair Francis
On Sat, Sep 18, 2021 at 6:20 PM Eric Tang  wrote:
>
> These patches fixed some issues about srow/sroiw/clzw instructions and
> add the rest of riscv bitmapip-0.93 instructions except fsri/fsriw &
> bext/bdep & bextw/bdepw for opcode coding or name conflict problems. The
> problems had been fixed in riscv bitmapip-1.0 version.
>
> I have tested these bitmapip instructions, passed by compare the results
> that produced by qemu and spike.
>
> Please review and give your opinion kindly :)

Hey Eric,

Thanks for the patches!

Unfortunately there is already a series "target/riscv: Update QEmu for
Zb[abcs] 1.0.0"
(https://www.mail-archive.com/qemu-devel@nongnu.org/msg839086.html)
that adds support for the v1.0.0 bit manip extension. That has been
reviewed and queued to be merged.

If you have fixes or features that apply on top of that please send
them though :)

Alistair

>
> Eric Tang (10):
>   target/riscv: rvb: fixed an error about srow/sroiw instructions
>   target/riscv: rvb: add carry-less multiply instructions
>   target/riscv: rvb: add cmix/cmov instructions
>   target/riscv: rvb: add generalized shuffle instructions
>   target/riscv: rvb: add crossbar permutation instructions
>   target/riscv: rvb: add bfp/bfpw instructions
>   target/riscv: rvb: add CRC instructions
>   target/riscv: rvb: add bit-matrix instructions
>   target/riscv: rvb: fixed an issue about clzw instruction
>   target/riscv: rvb: add funnel shfit instructions
>
>  target/riscv/bitmanip_helper.c  | 351 
>  target/riscv/helper.h   |  28 ++
>  target/riscv/insn32.decode  |  36 +++
>  target/riscv/insn_trans/trans_rvb.c.inc | 215 ++-
>  target/riscv/translate.c|  14 +
>  5 files changed, 641 insertions(+), 3 deletions(-)
>
> --
> 2.17.1
>
>



Re: [PATCH v11 00/16] target/riscv: Update QEmu for Zb[abcs] 1.0.0

2021-09-23 Thread Alistair Francis
On Fri, Sep 24, 2021 at 7:32 AM Philipp Tomsich
 wrote:
>
> Alistair,
>
> Is there something that is holding this series up?
> I believe we should avoid having an outdated draft version of the
> bitmanip proposal in 6.2.

Thanks for the ping.

Applied to riscv-to-apply.next

Alistair

>
> Thanks,
> Philipp.
>
>
> On Sat, 11 Sept 2021 at 16:00, Philipp Tomsich  
> wrote:
> >
> >
> > The Zb[abcs] extensions have complete public review and are nearing
> > ratifications. These individual extensions are one part of what was
> > previously though of as the "BitManip" (B) extension, leaving the
> > final details of future Zb* extensions open as they will undergo
> > further public discourse.
> >
> > This series updates the earlier support for the B extension by
> >  - removing those instructions that are not included in Zb[abcs]
> >  - splitting this into 4 separate extensions that can be independently
> >enabled: Zba (addressing), Zbb (basic bit-manip), Zbc (carryless
> >multiplication), Zbs (single-bit operations)
> >  - update the to the 1.0.0 version (e.g. w-forms of rev8 and Zbs
> >instructions are not included in Zb[abcs])
> >
> > For the latest version of the public review speicifcaiton
> > (incorporating some editorial fixes and corrections from the review
> > period), refer to:
> >   
> > https://github.com/riscv/riscv-bitmanip/releases/download/1.0.0/bitmanip-1.0.0-31-g2af7256.pdf
> >
> >
> > Changes in v11:
> > - Swaps out the EXT_ZERO to EXT_NONE, as no extension is to be performed.
> > - Fix typos in commit message.
> >
> > Changes in v10:
> > - New patch
> > - New patch, fixing regressions discovered with x264_r.
> > - New patch, fixing correctnes for clzw called on a register with undefined
> >   (as in: not properly sign-extended) upper bits.
> > - Retested with CF3 and SPEC2017 (size=test, size=ref); addressing new
> >   regressions (due to bugs in gen_clzw) from testing with SPEC2017 using
> >   different optimization levels
> > - Split off gen_add_uw() fix into a separate patch, as requested.
> >
> > Changes in v9:
> > - Retested with CF3 and SPEC2017 (size=test only).
> > - Rebased to 8880cc4362.
> > - Update gen_add_uw() to use a temporary instead of messing with
> >   arg1 (fixes a regression after rebase on CF3 and SPEC2017).
> > - Rebased to 8880cc4362.
> > - Picked up Alistair's Reviewed-by, after patman had failed to catch
> >   it for v8.
> > - Rebased to 8880cc4362.
> > - Fixes a whitespace-at-the-end-of-line warning for the rev8 comment
> >   in insn32.decode
> > - Rebased to 8880cc4362.
> >
> > Changes in v8:
> > - Optimize orc.b further by reordering the shift/and, updating the
> >   comment to reflect that we put the truth-value into the LSB, and
> >   putting the (now only) constant in a temporary
> > - Fold the final bitwise-not into the second and, using and andc.
> >
> > Changes in v7:
> > - Free TCG temporary in gen_orc_b().
> >
> > Changes in v6:
> > - Move gen_clmulh to trans_rvb.c.inc, as per Richard H's request.
> > - Fixed orc.b (now passes SPEC w/ optimized string functions) by
> >   adding the missing final negation.
> >
> > Changes in v5:
> > - Introduce gen_clmulh (as suggested by Richard H) and use to simplify
> >   trans_clmulh().
> >
> > Changes in v4:
> > - Drop rewrite of slli.uw (to match formal specification), as it would
> >   remove an optimization.
> > - Change orc.b to implementation suggested by Richard Henderson
> > - reorder trans_rev8* functions to be sequential
> > - rename rev8 to rev8_32 in decoder
> > - Renamed RV32 variant to zext_h_32.
> > - Reordered trans_zext_h_{32,64} to be next to each other.
> >
> > Changes in v3:
> > - Split off removal of 'x-b' property and 'ext_b' field into a separate
> >   patch to ensure bisectability.
> > - The changes to the Zba instructions (i.e. the REQUIRE_ZBA macro
> >   and its use for qualifying the Zba instructions) are moved into
> >   a separate commit.
> > - Remove the W-form instructions from Zbs in a separate commit.
> > - Remove shift-one instructions in a separate commit.
> > - The changes to the Zbs instructions (i.e. the REQUIRE_ZBS macro) and
> >   its use for qualifying the Zba instructions) are moved into a
> >   separate commit.
> > - This adds the Zbc instructions as a spearate commit.
> > - Uses a helper for clmul/clmulr instead of inlining the calculation of
> >   the result (addressing a comment from Richard Henderson).
> > - The changes to the Zbb instructions (i.e. use the REQUIRE_ZBB macro)
> >   are now in a separate commit.
> > - Moved orc.b and gorc/gorci changes into separate commit.
> > - Using the simpler orc.b implementation suggested by Richard Henderson
> > - Moved the REQUIRE_32BIT macro into a separate commit.
> > - rev8-addition & grevi*-removal moved to a separate commit
> > - Moved zext.h-addition & pack*-removal to a separate commit.
> > - Removing RVB moved into a separate commit at the tail-end of the series.
> >
> > Changes in v2:
> > - Fix missing ';' from 

Re: [PATCH v2] spapr/xive: Fix kvm_xive_source_reset trace event

2021-09-23 Thread David Gibson
On Wed, Sep 22, 2021 at 09:02:05AM +0200, Cédric Le Goater wrote:
> The trace event was placed in the wrong routine. Move it under
> kvmppc_xive_source_reset_one().
> 
> Fixes: 4e960974d4ee ("xive: Add trace events")
> Signed-off-by: Cédric Le Goater 

Applied to ppc-for-6.2, thanks.

> ---
>  hw/intc/spapr_xive_kvm.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/intc/spapr_xive_kvm.c b/hw/intc/spapr_xive_kvm.c
> index beb904d5bdee..bf43ffb54018 100644
> --- a/hw/intc/spapr_xive_kvm.c
> +++ b/hw/intc/spapr_xive_kvm.c
> @@ -236,6 +236,8 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int 
> srcno, Error **errp)
>  SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
>  uint64_t state = 0;
>  
> +trace_kvm_xive_source_reset(srcno);
> +
>  assert(xive->fd != -1);
>  
>  if (xive_source_irq_is_lsi(xsrc, srcno)) {
> @@ -328,8 +330,6 @@ uint64_t kvmppc_xive_esb_rw(XiveSource *xsrc, int srcno, 
> uint32_t offset,
>  return xive_esb_rw(xsrc, srcno, offset, data, 1);
>  }
>  
> -trace_kvm_xive_source_reset(srcno);
> -
>  /*
>   * Special Load EOI handling for LSI sources. Q bit is never set
>   * and the interrupt should be re-triggered if the level is still

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


signature.asc
Description: PGP signature


Re: [PATCH v7 0/7] DEVICE_UNPLUG_GUEST_ERROR QAPI event

2021-09-23 Thread David Gibson
On Wed, Sep 22, 2021 at 02:03:33PM +0200, Markus Armbruster wrote:
> Markus Armbruster  writes:
> 
> > Not yet merged.  David, would you like to do the pull request?
> 
> Oops, there's v8.  Take that one of course.

I have it in ppc-for-6.2, probably looking at a PR next week.

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


signature.asc
Description: PGP signature


[PATCH v1 8/9] hw/mos6522: Synchronize timer interrupt and timer counter

2021-09-23 Thread Finn Thain
We rely on a QEMUTimer callback to set the interrupt flag, and this races
with counter register accesses, such that the guest might see the counter
reloaded but might not see the interrupt flagged.

According to the datasheet, a real 6522 device counts down to , then
raises the relevant IRQ. After the  count, the counter reloads from
the latch (for timer 1) or continues to decrement thru FFFE (for timer 2).

Therefore, the guest operating system may read zero from T1CH and infer
that the counter has not yet wrapped (given another full count hasn't
yet elapsed.)

Similarly, the guest may find the timer interrupt flag to be set and
infer that the counter is non-zero (given another full count hasn't yet
elapsed).

Synchronize the timer counter and interrupt flag such that the guest will
observe the intended sequence of states. Document the known deviations
from a real 6522 device.

Eliminate the duplication of logic in get_counter() and
get_next_irq_time() by calling the former before the latter.

Call get_counter() prior to clearing interrupt flags so that the flags
remain synchronized with the timer counter.

Call get_counter() prior to changing the latch so that the old latch value
may be used to reload the counter. Every reload must use the value of the
latch as it was at the moment of the reload (not some later value).

Remove excess calls to qemu_clock_get_ns() to help avoid the possiblity
of inconsistency between timer interrupt flags and counters.

Signed-off-by: Finn Thain 
---
Changed since RFC:
 - Improved code commentary and commit log text.
 - Removed qemu_clock_get_ns() call from set_counter() for simplicity.
 - Moved the changes to the QEMUTimer callbacks from the previous patch
   into this one because they relate more to syncronization than to
   register accesses.
---
 hw/misc/mos6522.c | 171 +-
 hw/misc/trace-events  |   2 +-
 include/hw/misc/mos6522.h |   7 ++
 3 files changed, 103 insertions(+), 77 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 385ea81b62..8957c5e65c 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -52,33 +52,72 @@ static void mos6522_update_irq(MOS6522State *s)
 }
 }
 
+static void mos6522_timer_raise_irq(MOS6522State *s, MOS6522Timer *ti)
+{
+if (ti->state == irq) {
+return;
+}
+ti->state = irq;
+if (ti->index == 0) {
+s->ifr |= T1_INT;
+} else {
+s->ifr |= T2_INT;
+}
+mos6522_update_irq(s);
+}
+
 static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti, int64_t now)
 {
 int64_t d;
 unsigned int counter;
-
+bool reload;
+
+/*
+ * Timer 1 counts down from the latch value to -1 (period of latch + 2),
+ * then raises its interrupt and reloads.
+ * Timer 2 counts down from the latch value to -1, then raises its
+ * interrupt and continues to -2 and so on without any further interrupts.
+ *
+ * TODO
+ * This implementation deviates from hardware behaviour because it omits
+ * the phase two clock. On a real 6522, the counter is decremented on a
+ * falling edge and the interrupt is asserted on a rising edge. Register
+ * accesses are synchronous with this clock. That means successive
+ * accesses to T1CL or T2CL can't yield the same value because
+ * they can't happen in the same clock cycle.
+ */
 d = muldiv64(now - ti->load_time, ti->frequency, NANOSECONDS_PER_SECOND);
 
-if (ti->index == 0) {
-/* the timer goes down from latch to -1 (period of latch + 2) */
-if (d <= (ti->counter_value + 1)) {
-counter = ti->counter_value - d;
-} else {
-int64_t d_post_reload = d - (ti->counter_value + 2);
-/* XXX this calculation assumes that ti->latch has not changed */
-counter = ti->latch - (d_post_reload % (ti->latch + 2));
-}
-} else {
-counter = ti->counter_value - d;
+reload = (d >= ti->counter_value + 2);
+
+if (ti->index == 0 && reload) {
+int64_t more_reloads;
+
+d -= ti->counter_value + 2;
+more_reloads = d / (ti->latch + 2);
+d -= more_reloads * (ti->latch + 2);
+ti->load_time += muldiv64(ti->counter_value + 2 +
+  more_reloads * (ti->latch + 2),
+  NANOSECONDS_PER_SECOND, ti->frequency);
+ti->counter_value = ti->latch;
+}
+
+counter = ti->counter_value - d;
+
+if (reload) {
+mos6522_timer_raise_irq(s, ti);
 }
+
 return counter & 0x;
 }
 
-static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
+static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val,
+int64_t now)
 {
 trace_mos6522_set_counter(1 + ti->index, val);
-ti->load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+ti->load_time = now;
 ti->counter_value = val;
+ti->state 

[PATCH v1 9/9] hw/mos6522: Implement oneshot mode

2021-09-23 Thread Finn Thain
Timer 1 has two modes: continuous interrupt and oneshot.

Signed-off-by: Finn Thain 
---
Changed since RFC:
 - Moved to end of series. This patch is quite a bit shorter here.
---
 hw/misc/mos6522.c | 6 --
 include/hw/misc/mos6522.h | 2 ++
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 8957c5e65c..bbed0b84c0 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -148,7 +148,8 @@ static void mos6522_timer1_update(MOS6522State *s, 
MOS6522Timer *ti,
 }
 get_counter(s, ti, now);
 ti->next_irq_time = get_next_irq_time(s, ti, now);
-if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
+if ((s->ier & T1_INT) == 0 ||
+((s->acr & T1MODE) == T1MODE_ONESHOT && ti->state >= irq)) {
 timer_del(ti->timer);
 } else {
 timer_mod(ti->timer, ti->next_irq_time);
@@ -163,7 +164,7 @@ static void mos6522_timer2_update(MOS6522State *s, 
MOS6522Timer *ti,
 }
 get_counter(s, ti, now);
 ti->next_irq_time = get_next_irq_time(s, ti, now);
-if ((s->ier & T2_INT) == 0) {
+if ((s->ier & T2_INT) == 0 || (s->acr & T2MODE) || ti->state >= irq) {
 timer_del(ti->timer);
 } else {
 timer_mod(ti->timer, ti->next_irq_time);
@@ -345,6 +346,7 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, 
unsigned size)
 case VIA_REG_ACR:
 s->acr = val;
 mos6522_timer1_update(s, >timers[0], now);
+mos6522_timer2_update(s, >timers[1], now);
 break;
 case VIA_REG_PCR:
 s->pcr = val;
diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h
index a2df5fa942..4dbba6b273 100644
--- a/include/hw/misc/mos6522.h
+++ b/include/hw/misc/mos6522.h
@@ -50,8 +50,10 @@
 #define T1_INT 0x40/* Timer 1 interrupt */
 
 /* Bits in ACR */
+#define T2MODE 0x20/* Timer 2 mode */
 #define T1MODE 0xc0/* Timer 1 mode */
 #define T1MODE_CONT0x40/*  continuous interrupts */
+#define T1MODE_ONESHOT 0x00/*  timed interrupt */
 
 /* VIA registers */
 #define VIA_REG_B   0x00
-- 
2.26.3




[PATCH v1 6/9] hw/mos6522: Call mos6522_update_irq() when appropriate

2021-09-23 Thread Finn Thain
It necessary to call mos6522_update_irq() when the interrupt flags
change and unnecessary when they haven't.

Signed-off-by: Finn Thain 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/mos6522.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 6bd60f2118..bfe1719b18 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -203,10 +203,12 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned 
size)
 if (now >= s->timers[0].next_irq_time) {
 mos6522_timer1_update(s, >timers[0], now);
 s->ifr |= T1_INT;
+mos6522_update_irq(s);
 }
 if (now >= s->timers[1].next_irq_time) {
 mos6522_timer2_update(s, >timers[1], now);
 s->ifr |= T2_INT;
+mos6522_update_irq(s);
 }
 switch (addr) {
 case VIA_REG_B:
@@ -231,7 +233,6 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned 
size)
 break;
 case VIA_REG_T1CH:
 val = get_counter(s, >timers[0]) >> 8;
-mos6522_update_irq(s);
 break;
 case VIA_REG_T1LL:
 val = s->timers[0].latch & 0xff;
-- 
2.26.3




[PATCH v1 7/9] hw/mos6522: Avoid using discrepant QEMU clock values

2021-09-23 Thread Finn Thain
mos6522_read() and mos6522_write() may call various functions to determine
timer irq state, timer counter value and QEMUTimer deadline. All called
functions must use the same value for the present time.

Signed-off-by: Finn Thain 
Reviewed-by: Philippe Mathieu-Daudé 
---
Changed since RFC
 - Moved the changes to QEMUTimer callbacks to the next patch.
 - Fix whitespace.
---
 hw/misc/mos6522.c | 47 +++
 1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index bfe1719b18..385ea81b62 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -39,9 +39,9 @@
 /* XXX: implement all timer modes */
 
 static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
-  int64_t current_time);
+  int64_t now);
 static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
-  int64_t current_time);
+  int64_t now);
 
 static void mos6522_update_irq(MOS6522State *s)
 {
@@ -52,13 +52,12 @@ static void mos6522_update_irq(MOS6522State *s)
 }
 }
 
-static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti)
+static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti, int64_t now)
 {
 int64_t d;
 unsigned int counter;
 
-d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
- ti->frequency, NANOSECONDS_PER_SECOND);
+d = muldiv64(now - ti->load_time, ti->frequency, NANOSECONDS_PER_SECOND);
 
 if (ti->index == 0) {
 /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -88,7 +87,7 @@ static void set_counter(MOS6522State *s, MOS6522Timer *ti, 
unsigned int val)
 }
 
 static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
- int64_t current_time)
+ int64_t now)
 {
 int64_t d, next_time;
 unsigned int counter;
@@ -98,8 +97,7 @@ static int64_t get_next_irq_time(MOS6522State *s, 
MOS6522Timer *ti,
 }
 
 /* current counter value */
-d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
- ti->frequency, NANOSECONDS_PER_SECOND);
+d = muldiv64(now - ti->load_time, ti->frequency, NANOSECONDS_PER_SECOND);
 
 /* the timer goes down from latch to -1 (period of latch + 2) */
 if (d <= (ti->counter_value + 1)) {
@@ -122,20 +120,19 @@ static int64_t get_next_irq_time(MOS6522State *s, 
MOS6522Timer *ti,
 trace_mos6522_get_next_irq_time(ti->latch, d, next_time - d);
 next_time = muldiv64(next_time, NANOSECONDS_PER_SECOND, ti->frequency) +
  ti->load_time;
-
-if (next_time <= current_time) {
-next_time = current_time + 1;
-}
 return next_time;
 }
 
 static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
- int64_t current_time)
+  int64_t now)
 {
 if (!ti->timer) {
 return;
 }
-ti->next_irq_time = get_next_irq_time(s, ti, current_time);
+ti->next_irq_time = get_next_irq_time(s, ti, now);
+if (ti->next_irq_time <= now) {
+ti->next_irq_time = now + 1;
+}
 if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
 timer_del(ti->timer);
 } else {
@@ -144,12 +141,15 @@ static void mos6522_timer1_update(MOS6522State *s, 
MOS6522Timer *ti,
 }
 
 static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
- int64_t current_time)
+  int64_t now)
 {
 if (!ti->timer) {
 return;
 }
-ti->next_irq_time = get_next_irq_time(s, ti, current_time);
+ti->next_irq_time = get_next_irq_time(s, ti, now);
+if (ti->next_irq_time <= now) {
+ti->next_irq_time = now + 1;
+}
 if ((s->ier & T2_INT) == 0) {
 timer_del(ti->timer);
 } else {
@@ -227,12 +227,12 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned 
size)
 val = s->dira;
 break;
 case VIA_REG_T1CL:
-val = get_counter(s, >timers[0]) & 0xff;
+val = get_counter(s, >timers[0], now) & 0xff;
 s->ifr &= ~T1_INT;
 mos6522_update_irq(s);
 break;
 case VIA_REG_T1CH:
-val = get_counter(s, >timers[0]) >> 8;
+val = get_counter(s, >timers[0], now) >> 8;
 break;
 case VIA_REG_T1LL:
 val = s->timers[0].latch & 0xff;
@@ -241,12 +241,12 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned 
size)
 val = (s->timers[0].latch >> 8) & 0xff;
 break;
 case VIA_REG_T2CL:
-val = get_counter(s, >timers[1]) & 0xff;
+val = get_counter(s, >timers[1], now) & 0xff;
 s->ifr &= ~T2_INT;
 mos6522_update_irq(s);
 break;
 case VIA_REG_T2CH:
-val = get_counter(s, >timers[1]) >> 8;
+val = 

[PATCH v1 0/9] hw/mos6522: VIA timer emulation fixes and improvements

2021-09-23 Thread Finn Thain
This is a patch series for QEMU that I started last year. The aim was to 
try to get a monotonic clocksource for Linux/m68k guests. That hasn't 
been achieved yet (for q800 machines). I'm submitting the patch series 
because,

 - it improves 6522 emulation fidelity, although slightly slower, and

 - it allows Linux/m68k to make use of the additional timer that the 
   hardware indeed offers, but which QEMU omits, and which may be of 
   benefit to Linux guests [1], and

 - I see that Mark has been working on timer emulation issues in his 
   github repo [2] and it seems likely that MacOS, NetBSD or A/UX guests 
   will also require better 6522 emulation.

To make collaboration easier these patches can also be fetched from 
github [3].

On a real Quadra, accesses to the SY6522 chips are slow because they are 
synchronous with the 783360 Hz "phase 2" clock. In QEMU, they are slow 
because of the division operation in the timer count calculation. This 
patch series improves the fidelity of the emulated chip, but the price 
is more division ops.

The emulated 6522 still deviates from the behaviour of the real thing, 
however. For example, two consecutive accesses to a real 6522 timer 
counter can never yield the same value. This is not true of the emulated 
6522 in QEMU 6, wherein two consecutive accesses to a timer count 
register have been observed to yield the same value.

Two problems presently affecting a Linux guest are clock drift and 
monotonicity failure in the 'via' clocksource. That is, the clocksource 
counter can jump backwards. This can be observed by patching Linux like 
so,

diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -606,6 +606,8 @@ void __init via_init_clock(void)
clocksource_register_hz(_clk, VIA_CLOCK_FREQ);
 }
 
+static u32 prev_ticks;
+
 static u64 mac_read_clk(struct clocksource *cs)
 {
unsigned long flags;
@@ -631,6 +633,8 @@ static u64 mac_read_clk(struct clocksource *cs)
count = count_high << 8;
ticks = VIA_TIMER_CYCLES - count;
ticks += clk_offset + clk_total;
+   if (ticks < prev_ticks) pr_warn("%s: %u < %u\n", __func__, ticks, 
prev_ticks);
+   prev_ticks = ticks;
local_irq_restore(flags);
 
return ticks;


Or just enable CONFIG_DEBUG_TIMEKEEPING:

[ 1872.72] INFO: timekeeping: Cycle offset (4294966426) is larger than the 
'via1' clock's 50% safety margin (2147483647)
[ 1872.72] timekeeping: Your kernel is still fine, but is feeling a bit 
nervous 
[ 1907.51] INFO: timekeeping: Cycle offset (4294962989) is larger than the 
'via1' clock's 50% safety margin (2147483647) 
[ 1907.51] timekeeping: Your kernel is still fine, but is feeling a bit 
nervous 
[ 1907.90] INFO: timekeeping: Cycle offset (4294963248) is larger than the 
'via1' clock's 50% safety margin (2147483647) 
[ 1907.90] timekeeping: Your kernel is still fine, but is feeling a bit 
nervous


This problem can be partly blamed on a 6522 design limitation, which is 
that the timer counter has no overflow register. Hence, if a timer 
counter wraps around and the kernel is late to handle the subsequent 
interrupt, the kernel can't account for any missed ticks.

On a real Quadra, the kernel mitigates this limitation by minimizing 
interrupt latency. But on QEMU, interrupt latency is unbounded. This 
can't be mitigated by the guest kernel and leads to clock drift.

This latency can be observed by patching QEMU like so:

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -379,6 +379,12 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned size)
 s->pcr = val;
 break;
 case VIA_REG_IFR:
+if (val & T1_INT) {
+static int64_t last_t1_int_cleared;
+int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+if (now - last_t1_int_cleared > 2000) printf("\t%s: t1 int 
clear is late\n", __func__);
+last_t1_int_cleared = now;
+}
 /* reset bits */
 s->ifr &= ~val;
 mos6522_update_irq(s);


This logic asserts that, given that Linux/m68k sets CONFIG_HZ to 100, 
the emulator will theoretically see each timer 1 interrupt cleared 
within 20 ms of the previous one. But that deadline is often missed on 
my QEMU host [4].

On real Mac hardware you could observe the same scenario if a high 
priority interrupt were to sufficiently delay the timer interrupt 
handler. (This is the reason why the VIA1 interrupt priority gets 
increased from level 1 to level 6 when running on Quadras.)

Anyway, for now, the clocksource monotonicity problem in Linux/mac68k 
guests is still unresolved. Nonetheless, I think this patch series does 
improve the situation.

[1] I've also been working on some improvements to Linux/m68k based on 
Arnd Bergman's clockevent RFC patch, 

[PATCH v1 4/9] hw/mos6522: Rename timer callback functions

2021-09-23 Thread Finn Thain
This improves readability.

Signed-off-by: Finn Thain 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/mos6522.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 1d4a56077e..c0d6bee4cc 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -154,7 +154,7 @@ static void mos6522_timer2_update(MOS6522State *s, 
MOS6522Timer *ti,
 }
 }
 
-static void mos6522_timer1(void *opaque)
+static void mos6522_timer1_expired(void *opaque)
 {
 MOS6522State *s = opaque;
 MOS6522Timer *ti = >timers[0];
@@ -164,7 +164,7 @@ static void mos6522_timer1(void *opaque)
 mos6522_update_irq(s);
 }
 
-static void mos6522_timer2(void *opaque)
+static void mos6522_timer2_expired(void *opaque)
 {
 MOS6522State *s = opaque;
 MOS6522Timer *ti = >timers[1];
@@ -445,8 +445,10 @@ static void mos6522_init(Object *obj)
 s->timers[i].index = i;
 }
 
-s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, mos6522_timer1, s);
-s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, mos6522_timer2, s);
+s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  mos6522_timer1_expired, s);
+s->timers[1].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+  mos6522_timer2_expired, s);
 }
 
 static void mos6522_finalize(Object *obj)
-- 
2.26.3




[PATCH v1 2/9] hw/mos6522: Remove get_counter_value() methods and functions

2021-09-23 Thread Finn Thain
This code appears to be unnecessary.

Signed-off-by: Finn Thain 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/mos6522.c | 22 ++
 1 file changed, 2 insertions(+), 20 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index a478c1ca43..ff246b5437 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -52,23 +52,13 @@ static void mos6522_update_irq(MOS6522State *s)
 }
 }
 
-static uint64_t get_counter_value(MOS6522State *s, MOS6522Timer *ti)
-{
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-if (ti->index == 0) {
-return mdc->get_timer1_counter_value(s, ti);
-} else {
-return mdc->get_timer2_counter_value(s, ti);
-}
-}
-
 static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti)
 {
 int64_t d;
 unsigned int counter;
 
-d = get_counter_value(s, ti);
+d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
+ ti->frequency, NANOSECONDS_PER_SECOND);
 
 if (ti->index == 0) {
 /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -191,12 +181,6 @@ static void mos6522_set_sr_int(MOS6522State *s)
 mos6522_update_irq(s);
 }
 
-static uint64_t mos6522_get_counter_value(MOS6522State *s, MOS6522Timer *ti)
-{
-return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ti->load_time,
-ti->frequency, NANOSECONDS_PER_SECOND);
-}
-
 static void mos6522_portA_write(MOS6522State *s)
 {
 qemu_log_mask(LOG_UNIMP, "portA_write unimplemented\n");
@@ -498,8 +482,6 @@ static void mos6522_class_init(ObjectClass *oc, void *data)
 mdc->portB_write = mos6522_portB_write;
 mdc->portA_write = mos6522_portA_write;
 mdc->update_irq = mos6522_update_irq;
-mdc->get_timer1_counter_value = mos6522_get_counter_value;
-mdc->get_timer2_counter_value = mos6522_get_counter_value;
 }
 
 static const TypeInfo mos6522_type_info = {
-- 
2.26.3




[PATCH v1 5/9] hw/mos6522: Fix initial timer counter reload

2021-09-23 Thread Finn Thain
The first reload of timer 1 is early by half of a clock cycle as it gets
measured from a falling edge. By contrast, the succeeding reloads are
measured from rising edge to rising edge.

Neglecting that complication, the behaviour of the counter should be the
same from one reload to the next. The sequence is always:

N, N-1, N-2, ... 2, 1, 0, -1, N, N-1, N-2, ...

But at the first reload, the present driver does this instead:

N, N-1, N-2, ... 2, 1, 0, -1, N-1, N-2, ...

Fix this deviation for both timer 1 and timer 2, and allow for the fact
that on a real 6522 the timer 2 counter is not reloaded when it wraps.

Signed-off-by: Finn Thain 
---
 hw/misc/mos6522.c | 19 +++
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index c0d6bee4cc..6bd60f2118 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -63,15 +63,16 @@ static unsigned int get_counter(MOS6522State *s, 
MOS6522Timer *ti)
 if (ti->index == 0) {
 /* the timer goes down from latch to -1 (period of latch + 2) */
 if (d <= (ti->counter_value + 1)) {
-counter = (ti->counter_value - d) & 0x;
+counter = ti->counter_value - d;
 } else {
-counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
-counter = (ti->latch - counter) & 0x;
+int64_t d_post_reload = d - (ti->counter_value + 2);
+/* XXX this calculation assumes that ti->latch has not changed */
+counter = ti->latch - (d_post_reload % (ti->latch + 2));
 }
 } else {
-counter = (ti->counter_value - d) & 0x;
+counter = ti->counter_value - d;
 }
-return counter;
+return counter & 0x;
 }
 
 static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
@@ -102,11 +103,13 @@ static int64_t get_next_irq_time(MOS6522State *s, 
MOS6522Timer *ti,
 
 /* the timer goes down from latch to -1 (period of latch + 2) */
 if (d <= (ti->counter_value + 1)) {
-counter = (ti->counter_value - d) & 0x;
+counter = ti->counter_value - d;
 } else {
-counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
-counter = (ti->latch - counter) & 0x;
+int64_t d_post_reload = d - (ti->counter_value + 2);
+/* XXX this calculation assumes that ti->latch has not changed */
+counter = ti->latch - (d_post_reload % (ti->latch + 2));
 }
+counter &= 0x;
 
 /* Note: we consider the irq is raised on 0 */
 if (counter == 0x) {
-- 
2.26.3




[PATCH v1 3/9] hw/mos6522: Remove redundant mos6522_timer1_update() calls

2021-09-23 Thread Finn Thain
Reads and writes to the TL and TC registers have no immediate effect on
a running timer, with the exception of a write to TCH. Hence these
mos6522_timer_update() calls are not needed.

Signed-off-by: Finn Thain 
---
 hw/misc/mos6522.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index ff246b5437..1d4a56077e 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -234,7 +234,6 @@ uint64_t mos6522_read(void *opaque, hwaddr addr, unsigned 
size)
 val = s->timers[0].latch & 0xff;
 break;
 case VIA_REG_T1LH:
-/* XXX: check this */
 val = (s->timers[0].latch >> 8) & 0xff;
 break;
 case VIA_REG_T2CL:
@@ -303,8 +302,6 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, 
unsigned size)
 break;
 case VIA_REG_T1CL:
 s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
-mos6522_timer1_update(s, >timers[0],
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 break;
 case VIA_REG_T1CH:
 s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
@@ -313,14 +310,10 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t 
val, unsigned size)
 break;
 case VIA_REG_T1LL:
 s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
-mos6522_timer1_update(s, >timers[0],
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 break;
 case VIA_REG_T1LH:
 s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
 s->ifr &= ~T1_INT;
-mos6522_timer1_update(s, >timers[0],
-  qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 break;
 case VIA_REG_T2CL:
 s->timers[1].latch = (s->timers[1].latch & 0xff00) | val;
-- 
2.26.3




[PATCH v1 1/9] hw/mos6522: Remove get_load_time() methods and functions

2021-09-23 Thread Finn Thain
This code appears to be unnecessary.

Signed-off-by: Finn Thain 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/mos6522.c | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 1c57332b40..a478c1ca43 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -63,17 +63,6 @@ static uint64_t get_counter_value(MOS6522State *s, 
MOS6522Timer *ti)
 }
 }
 
-static uint64_t get_load_time(MOS6522State *s, MOS6522Timer *ti)
-{
-MOS6522DeviceClass *mdc = MOS6522_GET_CLASS(s);
-
-if (ti->index == 0) {
-return mdc->get_timer1_load_time(s, ti);
-} else {
-return mdc->get_timer2_load_time(s, ti);
-}
-}
-
 static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti)
 {
 int64_t d;
@@ -98,7 +87,7 @@ static unsigned int get_counter(MOS6522State *s, MOS6522Timer 
*ti)
 static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
 {
 trace_mos6522_set_counter(1 + ti->index, val);
-ti->load_time = get_load_time(s, ti);
+ti->load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 ti->counter_value = val;
 if (ti->index == 0) {
 mos6522_timer1_update(s, ti, ti->load_time);
@@ -208,13 +197,6 @@ static uint64_t mos6522_get_counter_value(MOS6522State *s, 
MOS6522Timer *ti)
 ti->frequency, NANOSECONDS_PER_SECOND);
 }
 
-static uint64_t mos6522_get_load_time(MOS6522State *s, MOS6522Timer *ti)
-{
-uint64_t load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
-
-return load_time;
-}
-
 static void mos6522_portA_write(MOS6522State *s)
 {
 qemu_log_mask(LOG_UNIMP, "portA_write unimplemented\n");
@@ -518,8 +500,6 @@ static void mos6522_class_init(ObjectClass *oc, void *data)
 mdc->update_irq = mos6522_update_irq;
 mdc->get_timer1_counter_value = mos6522_get_counter_value;
 mdc->get_timer2_counter_value = mos6522_get_counter_value;
-mdc->get_timer1_load_time = mos6522_get_load_time;
-mdc->get_timer2_load_time = mos6522_get_load_time;
 }
 
 static const TypeInfo mos6522_type_info = {
-- 
2.26.3




Re: [PATCH] hw/misc: Add an iBT device model

2021-09-23 Thread Titus Rwantare
Hello all,

I'd like some clarification on how the following code transfers irqs
back and forth:

> b/hw/arm/aspeed_soc.c
>+/* iBT */
>+if (!sysbus_realize(SYS_BUS_DEVICE(>ibt), errp)) {
>+return;
>+}
>+memory_region_add_subregion(>lpc.iomem,
>+   sc->memmap[ASPEED_DEV_IBT] - sc->memmap[ASPEED_DEV_LPC],
>+   >ibt.iomem);
>+sysbus_connect_irq(SYS_BUS_DEVICE(>lpc), 1 + aspeed_lpc_ibt,
>+   qdev_get_gpio_in(DEVICE(>lpc), aspeed_lpc_ibt));
> }

and

>hw/misc/aspeed_ibt.c
>+static void aspeed_ibt_realize(DeviceState *dev, Error **errp)
>+{
>+SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
>+AspeedIBTState *ibt = ASPEED_IBT(dev);
...
>+
>+sysbus_init_irq(sbd, >irq);

I ask because the code in aspeed_soc.c seems to connect to the
lpc->subdevice_irqs[aspeed_lpc_ibt], initialised on
hw/misc/aspeed_lpc.c:408.
I noticed that bmc firmware running in qemu was checking the BT_CTRL
register less frequently than I'd like while editing this patch to use
the IPMIInterface.

Thanks,
Titus



Re: [PATCH] ui/gtk: skip any extra draw of same guest scanout blob res

2021-09-23 Thread Dongwon Kim
On Fri, Sep 17, 2021 at 12:02:02PM +0200, Gerd Hoffmann wrote:
>   Hi,
> 
> > +bool  draw_submitted;
> > +QemuMutex mutex;
> 
> Why the mutex?  I think all the code runs while holding the BQL so it
> should be serialized.

Gerd, I did more experiment and verified mutex is actually not required.
I think I had some wrong belief after seeing some of sync problem
resolved after adding mutex but the code sequence was different at that
time.. I will remove mutex.

> 
> > +#ifdef CONFIG_GBM
> > +if (dmabuf) {
> > +qemu_mutex_lock(>mutex);
> > +if (!dmabuf->draw_submitted) {
> > +qemu_mutex_unlock(>mutex);
> > +return;
> > +} else {
> > +dmabuf->draw_submitted = false;
> > +}
> > +}
> > +#endif
> 
> Factoring out that into helper functions is probably a good idea.  Then
> have stub functions for the CONFIG_GBM=no case and *alot* less #ifdefs
> in the code ...
> 

There are oter places controlled by #ifdef CONFIG_GBM.
What about taking care of CONFIG_GBM altogher after v2 (same but no
mutex) of this patch?

> thanks,
>   Gerd
> 



Ping: [PATCH 0/2] cocoa.m: keyboard quality of life reborn

2021-09-23 Thread Programmingkid
Hi Peter, are you reviewing cocoa patches? Should someone else see these 
patches?

Thank you.

Ping:

https://patchwork.kernel.org/project/qemu-devel/patch/90e28997-9afa-4d8c-8323-bd087e629...@gmail.com/

https://patchwork.kernel.org/project/qemu-devel/patch/20210730170945.4468-3-programmingk...@gmail.com/

From 22a7f31c91d0803b0021e9802dde76daaec0738d Mon Sep 17 00:00:00 2001
From: John Arbuckle 
Date: Fri, 30 Jul 2021 13:01:26 -0400
Subject: [PATCH 0/2] cocoa.m: keyboard quality of life reborn

These patches can really help improve keyboard usage with a guest.
Based on patches by Gustavo Noronha Silva . 

John Arbuckle (2):
  Add full keyboard grab support
  Add ability to swap command/meta and options keys

 ui/cocoa.m | 178 ++---
 1 file changed, 170 insertions(+), 8 deletions(-)

-- 
2.24.3 (Apple Git-128)





Re: [PULL 00/12] jobs: mirror: Handle errors after READY cancel

2021-09-23 Thread Vladimir Sementsov-Ogievskiy

22.09.2021 22:19, Vladimir Sementsov-Ogievskiy wrote:

22.09.2021 19:05, Richard Henderson wrote:

On 9/21/21 3:20 AM, Vladimir Sementsov-Ogievskiy wrote:

The following changes since commit 326ff8dd09556fc2e257196c49f35009700794ac:

   Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into 
staging (2021-09-20 16:17:05 +0100)

are available in the Git repository at:

   https://src.openvz.org/scm/~vsementsov/qemu.git  tags/pull-jobs-2021-09-21

for you to fetch changes up to c9489c04319cac75c76af8fc27c254f46e10214c:

   iotests: Add mirror-ready-cancel-error test (2021-09-21 11:56:11 +0300)


mirror: Handle errors after READY cancel


Hanna Reitz (12):
   job: Context changes in job_completed_txn_abort()
   mirror: Keep s->synced on error
   mirror: Drop s->synced
   job: Force-cancel jobs in a failed transaction
   job: @force parameter for job_cancel_sync()
   jobs: Give Job.force_cancel more meaning
   job: Add job_cancel_requested()
   mirror: Use job_is_cancelled()
   mirror: Check job_is_cancelled() earlier
   mirror: Stop active mirroring after force-cancel
   mirror: Do not clear .cancelled
   iotests: Add mirror-ready-cancel-error test


This fails testing with errors like so:

Running test test-replication
test-replication: ../job.c:186: job_state_transition: Assertion 
`JobSTT[s0][s1]' failed.
ERROR test-replication - too few tests run (expected 13, got 8)
make: *** [Makefile.mtest:816: run-test-100] Error 1
Cleaning up project directory and file based variables
ERROR: Job failed: exit code 1

https://gitlab.com/qemu-project/qemu/-/pipelines/375324015/failures




Interesting :(

I've reproduced, starting test-replication in several parallel loops. (it 
doesn't reproduce for me if just start in one loop). So, that's some racy bug..

Hmm, and seems it doesn't reproduce so simple on master. I'll try to bisect the 
series tomorrow.



(gdb) bt
#0  0x7f034a3d09d5 in raise () from /lib64/libc.so.6
#1  0x7f034a3b9954 in abort () from /lib64/libc.so.6
#2  0x7f034a3b9789 in __assert_fail_base.cold () from /lib64/libc.so.6
#3  0x7f034a3c9026 in __assert_fail () from /lib64/libc.so.6
#4  0x55d3b503d670 in job_state_transition (job=0x55d3b5e67020, 
s1=JOB_STATUS_CONCLUDED) at ../job.c:186
#5  0x55d3b503e7c2 in job_conclude (job=0x55d3b5e67020) at ../job.c:652
#6  0x55d3b503eaa1 in job_finalize_single (job=0x55d3b5e67020) at 
../job.c:722
#7  0x55d3b503ecd1 in job_completed_txn_abort (job=0x55d3b5e67020) at 
../job.c:801
#8  0x55d3b503f2ea in job_cancel (job=0x55d3b5e67020, force=false) at 
../job.c:973
#9  0x55d3b503f360 in job_cancel_err (job=0x55d3b5e67020, 
errp=0x7fffcc997a80) at ../job.c:992
#10 0x55d3b503f576 in job_finish_sync (job=0x55d3b5e67020, finish=0x55d3b503f33f 
, errp=0x0) at ../job.c:1054
#11 0x55d3b503f3d0 in job_cancel_sync (job=0x55d3b5e67020, force=false) at 
../job.c:1008
#12 0x55d3b4ff14a3 in replication_close (bs=0x55d3b5e6ef80) at 
../block/replication.c:152
#13 0x55d3b50277fc in bdrv_close (bs=0x55d3b5e6ef80) at ../block.c:4677
#14 0x55d3b50286cf in bdrv_delete (bs=0x55d3b5e6ef80) at ../block.c:5100
#15 0x55d3b502ae3a in bdrv_unref (bs=0x55d3b5e6ef80) at ../block.c:6495
#16 0x55d3b5023a38 in bdrv_root_unref_child (child=0x55d3b5e4c690) at 
../block.c:3010
#17 0x55d3b5047998 in blk_remove_bs (blk=0x55d3b5e73b40) at 
../block/block-backend.c:845
#18 0x55d3b5046e38 in blk_delete (blk=0x55d3b5e73b40) at 
../block/block-backend.c:461
#19 0x55d3b50470dc in blk_unref (blk=0x55d3b5e73b40) at 
../block/block-backend.c:516
#20 0x55d3b4fdb20a in teardown_secondary () at 
../tests/unit/test-replication.c:367
#21 0x55d3b4fdb632 in test_secondary_continuous_replication () at 
../tests/unit/test-replication.c:504
#22 0x7f034b26979e in g_test_run_suite_internal () from 
/lib64/libglib-2.0.so.0
#23 0x7f034b26959b in g_test_run_suite_internal () from 
/lib64/libglib-2.0.so.0
#24 0x7f034b26959b in g_test_run_suite_internal () from 
/lib64/libglib-2.0.so.0
#25 0x7f034b269c8a in g_test_run_suite () from /lib64/libglib-2.0.so.0
#26 0x7f034b269ca5 in g_test_run () from /lib64/libglib-2.0.so.0
#27 0x55d3b4fdb9c0 in main (argc=1, argv=0x7fffcc998138) at 
../tests/unit/test-replication.c:613
(gdb) fr 4
#4  0x55d3b503d670 in job_state_transition (job=0x55d3b5e67020, 
s1=JOB_STATUS_CONCLUDED) at ../job.c:186
186 assert(JobSTT[s0][s1]);
(gdb) list
181 JobStatus s0 = job->status;
182 assert(s1 >= 0 && s1 < JOB_STATUS__MAX);
183 trace_job_state_transition(job, job->ret,
184    JobSTT[s0][s1] ? "allowed" : 
"disallowed",
185    JobStatus_str(s0), JobStatus_str(s1));
186 assert(JobSTT[s0][s1]);
187 

Re: [PATCH v6 07/11] block: use int64_t instead of int in driver write_zeroes handlers

2021-09-23 Thread Vladimir Sementsov-Ogievskiy

23.09.2021 23:33, Eric Blake wrote:

On Fri, Sep 03, 2021 at 01:28:03PM +0300, Vladimir Sementsov-Ogievskiy wrote:

We are generally moving to int64_t for both offset and bytes parameters
on all io paths.

Main motivation is realization of 64-bit write_zeroes operation for
fast zeroing large disk chunks, up to the whole disk.

We chose signed type, to be consistent with off_t (which is signed) and
with possibility for signed return type (where negative value means
error).

So, convert driver write_zeroes handlers bytes parameter to int64_t.

The only caller of all updated function is bdrv_co_do_pwrite_zeroes().

bdrv_co_do_pwrite_zeroes() itself is of course OK with widening of
callee parameter type. Also, bdrv_co_do_pwrite_zeroes()'s
max_write_zeroes is limited to INT_MAX. So, updated functions all are
safe, they will not get "bytes" larger than before.

Still, let's look through all updated functions, and add assertions to
the ones which are actually unprepared to values larger than INT_MAX.
For these drivers also set explicit max_pwrite_zeroes limit.


[snip]


At this point all block drivers are prepared to support 64bit
write-zero requests, or have explicitly set max_pwrite_zeroes.


The long commit message is essential, but the analysis looks sane.



Signed-off-by: Vladimir Sementsov-Ogievskiy 
---



+++ b/block/iscsi.c



@@ -1250,11 +1250,21 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState 
*bs, int64_t offset,
  iscsi_co_init_iscsitask(iscsilun, );
  retry:
  if (use_16_for_ws) {
+/*
+ * iscsi_writesame16_task num_blocks argument is uint32_t. We rely here
+ * on our max_pwrite_zeroes limit.
+ */
+assert(nb_blocks < UINT32_MAX);
  iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, 
lba,
  iscsilun->zeroblock, 
iscsilun->block_size,
  nb_blocks, 0, !!(flags & 
BDRV_REQ_MAY_UNMAP),
  0, 0, iscsi_co_generic_cb, 
);


Should this be <= instead of < ?


  } else {
+/*
+ * iscsi_writesame10_task num_blocks argument is uint16_t. We rely here
+ * on our max_pwrite_zeroes limit.
+ */
+assert(nb_blocks < UINT16_MAX);
  iTask.task = iscsi_writesame10_task(iscsilun->iscsi, iscsilun->lun, 
lba,
  iscsilun->zeroblock, 
iscsilun->block_size,
  nb_blocks, 0, !!(flags & 
BDRV_REQ_MAY_UNMAP),


here too.  The 16-bit limit is where we're most likely to run into
someone actually trying to zeroize that much at once.


+++ b/block/nbd.c
@@ -1407,15 +1407,17 @@ static int nbd_client_co_pwritev(BlockDriverState *bs, 
int64_t offset,
  }
  
  static int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,

-   int bytes, BdrvRequestFlags flags)
+   int64_t bytes, BdrvRequestFlags flags)
  {
  BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
  NBDRequest request = {
  .type = NBD_CMD_WRITE_ZEROES,
  .from = offset,
-.len = bytes,
+.len = bytes,  /* .len is uint32_t actually */
  };
  
+assert(bytes < UINT32_MAX); /* relay on max_pwrite_zeroes */


And again.  Here, you happen to get by with < because we clamped
bl.max_pwrite_zeroes at BDRV_REQUEST_MAX_BYTES, which is INT_MAX
rounded down.  But I had to check; whereas using <= would be less
worrisome, even if we never get a request that large.

If you agree with my analysis, I can make that change while preparing
my pull request.


I agree, <= should be right thing, thanks!



Reviewed-by: Eric Blake 




--
Best regards,
Vladimir



Re: [PATCH v11 00/16] target/riscv: Update QEmu for Zb[abcs] 1.0.0

2021-09-23 Thread Philipp Tomsich
Alistair,

Is there something that is holding this series up?
I believe we should avoid having an outdated draft version of the
bitmanip proposal in 6.2.

Thanks,
Philipp.


On Sat, 11 Sept 2021 at 16:00, Philipp Tomsich  wrote:
>
>
> The Zb[abcs] extensions have complete public review and are nearing
> ratifications. These individual extensions are one part of what was
> previously though of as the "BitManip" (B) extension, leaving the
> final details of future Zb* extensions open as they will undergo
> further public discourse.
>
> This series updates the earlier support for the B extension by
>  - removing those instructions that are not included in Zb[abcs]
>  - splitting this into 4 separate extensions that can be independently
>enabled: Zba (addressing), Zbb (basic bit-manip), Zbc (carryless
>multiplication), Zbs (single-bit operations)
>  - update the to the 1.0.0 version (e.g. w-forms of rev8 and Zbs
>instructions are not included in Zb[abcs])
>
> For the latest version of the public review speicifcaiton
> (incorporating some editorial fixes and corrections from the review
> period), refer to:
>   
> https://github.com/riscv/riscv-bitmanip/releases/download/1.0.0/bitmanip-1.0.0-31-g2af7256.pdf
>
>
> Changes in v11:
> - Swaps out the EXT_ZERO to EXT_NONE, as no extension is to be performed.
> - Fix typos in commit message.
>
> Changes in v10:
> - New patch
> - New patch, fixing regressions discovered with x264_r.
> - New patch, fixing correctnes for clzw called on a register with undefined
>   (as in: not properly sign-extended) upper bits.
> - Retested with CF3 and SPEC2017 (size=test, size=ref); addressing new
>   regressions (due to bugs in gen_clzw) from testing with SPEC2017 using
>   different optimization levels
> - Split off gen_add_uw() fix into a separate patch, as requested.
>
> Changes in v9:
> - Retested with CF3 and SPEC2017 (size=test only).
> - Rebased to 8880cc4362.
> - Update gen_add_uw() to use a temporary instead of messing with
>   arg1 (fixes a regression after rebase on CF3 and SPEC2017).
> - Rebased to 8880cc4362.
> - Picked up Alistair's Reviewed-by, after patman had failed to catch
>   it for v8.
> - Rebased to 8880cc4362.
> - Fixes a whitespace-at-the-end-of-line warning for the rev8 comment
>   in insn32.decode
> - Rebased to 8880cc4362.
>
> Changes in v8:
> - Optimize orc.b further by reordering the shift/and, updating the
>   comment to reflect that we put the truth-value into the LSB, and
>   putting the (now only) constant in a temporary
> - Fold the final bitwise-not into the second and, using and andc.
>
> Changes in v7:
> - Free TCG temporary in gen_orc_b().
>
> Changes in v6:
> - Move gen_clmulh to trans_rvb.c.inc, as per Richard H's request.
> - Fixed orc.b (now passes SPEC w/ optimized string functions) by
>   adding the missing final negation.
>
> Changes in v5:
> - Introduce gen_clmulh (as suggested by Richard H) and use to simplify
>   trans_clmulh().
>
> Changes in v4:
> - Drop rewrite of slli.uw (to match formal specification), as it would
>   remove an optimization.
> - Change orc.b to implementation suggested by Richard Henderson
> - reorder trans_rev8* functions to be sequential
> - rename rev8 to rev8_32 in decoder
> - Renamed RV32 variant to zext_h_32.
> - Reordered trans_zext_h_{32,64} to be next to each other.
>
> Changes in v3:
> - Split off removal of 'x-b' property and 'ext_b' field into a separate
>   patch to ensure bisectability.
> - The changes to the Zba instructions (i.e. the REQUIRE_ZBA macro
>   and its use for qualifying the Zba instructions) are moved into
>   a separate commit.
> - Remove the W-form instructions from Zbs in a separate commit.
> - Remove shift-one instructions in a separate commit.
> - The changes to the Zbs instructions (i.e. the REQUIRE_ZBS macro) and
>   its use for qualifying the Zba instructions) are moved into a
>   separate commit.
> - This adds the Zbc instructions as a spearate commit.
> - Uses a helper for clmul/clmulr instead of inlining the calculation of
>   the result (addressing a comment from Richard Henderson).
> - The changes to the Zbb instructions (i.e. use the REQUIRE_ZBB macro)
>   are now in a separate commit.
> - Moved orc.b and gorc/gorci changes into separate commit.
> - Using the simpler orc.b implementation suggested by Richard Henderson
> - Moved the REQUIRE_32BIT macro into a separate commit.
> - rev8-addition & grevi*-removal moved to a separate commit
> - Moved zext.h-addition & pack*-removal to a separate commit.
> - Removing RVB moved into a separate commit at the tail-end of the series.
>
> Changes in v2:
> - Fix missing ';' from last-minute whitespace cleanups.
>
> Philipp Tomsich (16):
>   target/riscv: Introduce temporary in gen_add_uw()
>   target/riscv: fix clzw implementation to operate on arg1
>   target/riscv: clwz must ignore high bits (use shift-left & changed
> logic)
>   target/riscv: Add x-zba, x-zbb, x-zbc and x-zbs properties
>   target/riscv: Reassign 

Re: [PATCH v4] Prevent vhost-user-blk-test hang

2021-09-23 Thread ebl...@redhat.com
On Thu, Sep 23, 2021 at 03:16:17PM +, Raphael Norwitz wrote:
> In the vhost-user-blk-test, as of now there is nothing stoping
> vhost-user-blk in QEMU writing to the socket right after forking off the
> storage daemon before it has a chance to come up properly, leaving the
> test hanging forever. This intermittently hanging test has caused QEMU
> automation failures reported multiple times on the mailing list [1].
> 
> This change makes the storage-daemon notify the vhost-user-blk-test
> that it is fully initialized and ready to handle client connections by
> creating a pidfile on initialiation. This ensures that the storage-daemon
> backend won't miss vhost-user messages and thereby resolves the hang.
> 
> [1] 
> https://lore.kernel.org/qemu-devel/CAFEAcA8kYpz9LiPNxnWJAPSjc=nv532bedyfynabemeohqb...@mail.gmail.com/
> 
> Signed-off-by: Raphael Norwitz 
> ---
> Accidentally left a raw free() in v3. Converted it to g_free() here.
> 
>  tests/qtest/vhost-user-blk-test.c | 27 ++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/tests/qtest/vhost-user-blk-test.c 
> b/tests/qtest/vhost-user-blk-test.c
> index 6f108a1b62..6898f55f11 100644
> --- a/tests/qtest/vhost-user-blk-test.c
> +++ b/tests/qtest/vhost-user-blk-test.c
> @@ -24,6 +24,7 @@
>  #define TEST_IMAGE_SIZE (64 * 1024 * 1024)
>  #define QVIRTIO_BLK_TIMEOUT_US  (30 * 1000 * 1000)
>  #define PCI_SLOT_HP 0x06
> +#define PIDFILE_RETRIES 5
>  
>  typedef struct {
>  pid_t pid;
> @@ -885,7 +886,8 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
>   int num_queues)
>  {
>  const char *vhost_user_blk_bin = qtest_qemu_storage_daemon_binary();
> -int i;
> +int i, retries;
> +char *daemon_pidfile_path;
>  gchar *img_path;
>  GString *storage_daemon_command = g_string_new(NULL);
>  QemuStorageDaemonState *qsd;
> @@ -898,6 +900,9 @@ static void start_vhost_user_blk(GString *cmd_line, int 
> vus_instances,
>  " -object memory-backend-memfd,id=mem,size=256M,share=on "
>  " -M memory-backend=mem -m 256M ");
>  
> +daemon_pidfile_path = g_strdup_printf("/tmp/daemon-%d", getpid());
> +g_assert_cmpint((uintptr_t) daemon_pidfile_path, !=, (uintptr_t) NULL);

Feels verbose compared to:
g_assert(daemon_pidfile_path)

For that matter, can g_strdup_printf() ever return NULL?  On memory
error, it exit()s rather than returning.  So this assert feels like
overkill.

Otherwise,

Reviewed-by: Eric Blake 

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




Re: [PATCH v6 10/11] block: use int64_t instead of int in driver discard handlers

2021-09-23 Thread Eric Blake
On Fri, Sep 03, 2021 at 01:28:06PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> We are generally moving to int64_t for both offset and bytes parameters
> on all io paths.
> 
> Main motivation is realization of 64-bit write_zeroes operation for
> fast zeroing large disk chunks, up to the whole disk.
> 
> We chose signed type, to be consistent with off_t (which is signed) and
> with possibility for signed return type (where negative value means
> error).
> 
> So, convert driver discard handlers bytes parameter to int64_t.
> 
> The only caller of all updated function is bdrv_co_pdiscard in
> block/io.c. It is already prepared to work with 64bit requests, but
> pass at most max(bs->bl.max_pdiscard, INT_MAX) to the driver.
> 
> Let's look at all updated functions:

> 
> Great! Now all drivers are prepared to handle 64bit discard requests,
> or else have explicit max_pdiscard limits.

Very similar analysis to the write-zeroes.

> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---

> +++ b/block/nbd.c
> @@ -1457,15 +1457,17 @@ static int nbd_client_co_flush(BlockDriverState *bs)
>  }
>  
>  static int nbd_client_co_pdiscard(BlockDriverState *bs, int64_t offset,
> -  int bytes)
> +  int64_t bytes)
>  {
>  BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
>  NBDRequest request = {
>  .type = NBD_CMD_TRIM,
>  .from = offset,
> -.len = bytes,
> +.len = bytes, /* len is uint32_t */
>  };
>  
> +assert(bytes <= UINT32_MAX); /* rely on max_pdiscard */

Aha - you used <= here, compared to < in 7/11 on write zeroes.
Consistency says we want <= in both places.

Reviewed-by: Eric Blake 

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




Re: [PATCH v3 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread Alexander Bulekov
On 210923 1513, John Snow wrote:
> The single backtick markup in ReST is the "default role". Currently,
> Sphinx's default role is called "content". Sphinx suggests you can use
> the "Any" role instead to turn any single-backtick enclosed item into a
> cross-reference.
> 
> This is useful for things like autodoc for Python docstrings, where it's
> often nicer to reference other types with `foo` instead of the more
> laborious :py:meth:`foo`. It's also useful in multi-domain cases to
> easily reference definitions from other Sphinx domains, such as
> referencing C code definitions from outside of kerneldoc comments.
> 
> Before we do that, though, we'll need to turn all existing usages of the
> "content" role to inline verbatim markup wherever it does not correctly
> resolve into a cross-refernece by using double backticks instead.
> 
> Signed-off-by: John Snow 

Reviewed-by: Alexander Bulekov 

Thanks!

> ---
>  docs/devel/fuzzing.rst | 9 +
>  docs/devel/tcg-plugins.rst | 2 +-
>  docs/interop/live-block-operations.rst | 2 +-
>  docs/system/guest-loader.rst   | 2 +-
>  qapi/block-core.json   | 4 ++--
>  include/qemu/module.h  | 6 +++---
>  qemu-options.hx| 4 ++--
>  7 files changed, 15 insertions(+), 14 deletions(-)
> 
> diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
> index 2749bb9bed3..784ecb99e66 100644
> --- a/docs/devel/fuzzing.rst
> +++ b/docs/devel/fuzzing.rst
> @@ -182,10 +182,11 @@ The output should contain a complete list of matched 
> MemoryRegions.
>  
>  OSS-Fuzz
>  
> -QEMU is continuously fuzzed on `OSS-Fuzz` 
> __(https://github.com/google/oss-fuzz).
> -By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
> -generic-fuzz target requires additional information provided in environment
> -variables, we pre-define some generic-fuzz configs in
> +QEMU is continuously fuzzed on `OSS-Fuzz
> +`_.  By default, the OSS-Fuzz build
> +will try to fuzz every fuzz-target. Since the generic-fuzz target
> +requires additional information provided in environment variables, we
> +pre-define some generic-fuzz configs in
>  ``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
>  
>  - ``.name``: To identify the fuzzer config
> diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
> index dac5101a3c9..8b187f8 100644
> --- a/docs/devel/tcg-plugins.rst
> +++ b/docs/devel/tcg-plugins.rst
> @@ -212,7 +212,7 @@ The hotpages plugin can be configured using the following 
> arguments:
>  
>  This is an instruction classifier so can be used to count different
>  types of instructions. It has a number of options to refine which get
> -counted. You can give a value to the `count` argument for a class of
> +counted. You can give a value to the ``count`` argument for a class of
>  instructions to break it down fully, so for example to see all the system
>  registers accesses::
>  
> diff --git a/docs/interop/live-block-operations.rst 
> b/docs/interop/live-block-operations.rst
> index 9e3635b2338..814c29bbe1d 100644
> --- a/docs/interop/live-block-operations.rst
> +++ b/docs/interop/live-block-operations.rst
> @@ -640,7 +640,7 @@ at this point:
>  (QEMU) block-job-complete device=job0
>  
>  In either of the above cases, if you once again run the
> -`query-block-jobs` command, there should not be any active block
> +``query-block-jobs`` command, there should not be any active block
>  operation.
>  
>  Comparing 'commit' and 'mirror': In both then cases, the overlay images
> diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst
> index 4320d1183f7..9ef9776bf07 100644
> --- a/docs/system/guest-loader.rst
> +++ b/docs/system/guest-loader.rst
> @@ -51,4 +51,4 @@ The full syntax of the guest-loader is::
>  
>  ``bootargs=``
>This is an optional field for kernel blobs which will pass command
> -  like via the `/chosen/module@/bootargs` node.
> +  like via the ``/chosen/module@/bootargs`` node.
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index c8ce1d9d5d8..0c64470edb2 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -446,11 +446,11 @@
>  # @granularity: granularity of the dirty bitmap in bytes (since 1.4)
>  #
>  # @recording: true if the bitmap is recording new writes from the guest.
> -# Replaces `active` and `disabled` statuses. (since 4.0)
> +# Replaces ``active`` and ``disabled`` statuses. (since 4.0)
>  #
>  # @busy: true if the bitmap is in-use by some operation (NBD or jobs)
>  #and cannot be modified via QMP or used by another operation.
> -#Replaces `locked` and `frozen` statuses. (since 4.0)
> +#Replaces ``locked`` and ``frozen`` statuses. (since 4.0)
>  #
>  # @persistent: true if the bitmap was stored on disk, is scheduled to be 
> stored
>  #  on disk, or both. (since 4.0)
> 

Re: [PATCH v6 07/11] block: use int64_t instead of int in driver write_zeroes handlers

2021-09-23 Thread Eric Blake
On Thu, Sep 23, 2021 at 03:33:45PM -0500, Eric Blake wrote:
> > +++ b/block/nbd.c
> > @@ -1407,15 +1407,17 @@ static int nbd_client_co_pwritev(BlockDriverState 
> > *bs, int64_t offset,
> >  }
> >  
> >  static int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t 
> > offset,
> > -   int bytes, BdrvRequestFlags flags)
> > +   int64_t bytes, BdrvRequestFlags 
> > flags)
> >  {
> >  BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
> >  NBDRequest request = {
> >  .type = NBD_CMD_WRITE_ZEROES,
> >  .from = offset,
> > -.len = bytes,
> > +.len = bytes,  /* .len is uint32_t actually */
> >  };
> >  
> > +assert(bytes < UINT32_MAX); /* relay on max_pwrite_zeroes */
> 
> And again.  Here, you happen to get by with < because we clamped
> bl.max_pwrite_zeroes at BDRV_REQUEST_MAX_BYTES, which is INT_MAX
> rounded down.  But I had to check; whereas using <= would be less
> worrisome, even if we never get a request that large.

Whoops, I was reading a local patch of mine.  Upstream has merely:

uint32_t max = MIN_NON_ZERO(NBD_MAX_BUFFER_SIZE, s->info.max_block);

bs->bl.max_pdiscard = QEMU_ALIGN_DOWN(INT_MAX, min);
bs->bl.max_pwrite_zeroes = max;

which is an even smaller limit than BDRV_REQUEST_MAX_BYTES (and
obviously one we're trying to raise).  But the point remains that
using <= rather than < will make it easier to review the code where we
raise the limits (either up to the 4G-1 limit of the current protocol,
or with protocol extensions to finally get to 64-bit requests).

> 
> If you agree with my analysis, I can make that change while preparing
> my pull request.
> 

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




Re: [PATCH v3 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread Eduardo Habkost
On Thu, Sep 23, 2021 at 03:13:22PM -0400, John Snow wrote:
> The single backtick markup in ReST is the "default role". Currently,
> Sphinx's default role is called "content". Sphinx suggests you can use
> the "Any" role instead to turn any single-backtick enclosed item into a
> cross-reference.
> 
> This is useful for things like autodoc for Python docstrings, where it's
> often nicer to reference other types with `foo` instead of the more
> laborious :py:meth:`foo`. It's also useful in multi-domain cases to
> easily reference definitions from other Sphinx domains, such as
> referencing C code definitions from outside of kerneldoc comments.
> 
> Before we do that, though, we'll need to turn all existing usages of the
> "content" role to inline verbatim markup wherever it does not correctly
> resolve into a cross-refernece by using double backticks instead.
> 
> Signed-off-by: John Snow 
> ---
>  docs/devel/fuzzing.rst | 9 +
>  docs/devel/tcg-plugins.rst | 2 +-
>  docs/interop/live-block-operations.rst | 2 +-
>  docs/system/guest-loader.rst   | 2 +-
>  qapi/block-core.json   | 4 ++--
>  include/qemu/module.h  | 6 +++---
>  qemu-options.hx| 4 ++--
>  7 files changed, 15 insertions(+), 14 deletions(-)
> 
> diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
> index 2749bb9bed3..784ecb99e66 100644
> --- a/docs/devel/fuzzing.rst
> +++ b/docs/devel/fuzzing.rst
> @@ -182,10 +182,11 @@ The output should contain a complete list of matched 
> MemoryRegions.
>  
>  OSS-Fuzz
>  
> -QEMU is continuously fuzzed on `OSS-Fuzz` 
> __(https://github.com/google/oss-fuzz).
> -By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
> -generic-fuzz target requires additional information provided in environment
> -variables, we pre-define some generic-fuzz configs in
> +QEMU is continuously fuzzed on `OSS-Fuzz
> +`_.  By default, the OSS-Fuzz build

Gosh, I think I'll never understand the syntax for links in
reStructuredText.

> +will try to fuzz every fuzz-target. Since the generic-fuzz target
> +requires additional information provided in environment variables, we
> +pre-define some generic-fuzz configs in
>  ``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
[...]


Reviewed-by: Eduardo Habkost 

-- 
Eduardo




Re: [PATCH v3 2/2] docs/sphinx: change default role to "any"

2021-09-23 Thread Eduardo Habkost
On Thu, Sep 23, 2021 at 03:13:23PM -0400, John Snow wrote:
> This interprets single-backtick syntax in all of our Sphinx docs as a
> cross-reference to *something*, including Python symbols.
> 
> From here on out, new uses of `backticks` will cause a build failure if
> the target cannot be referenced.
> 
> Signed-off-by: John Snow 

Patch 1/2 demonstrates why patch 2/2 is useful.

Reviewed-by: Eduardo Habkost 

> ---
>  docs/conf.py | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/docs/conf.py b/docs/conf.py
> index ff6e92c6e2e..4d9f56601fc 100644
> --- a/docs/conf.py
> +++ b/docs/conf.py
> @@ -85,6 +85,11 @@
>  # The master toctree document.
>  master_doc = 'index'
>  
> +# Interpret `single-backticks` to be a cross-reference to any kind of
> +# referenceable object. Unresolvable or ambiguous references will emit a
> +# warning at build time.
> +default_role = 'any'
> +
>  # General information about the project.
>  project = u'QEMU'
>  copyright = u'2021, The QEMU Project Developers'
> -- 
> 2.31.1
> 

-- 
Eduardo




Re: [PATCH v2 2/6] iotests: add warning for rogue 'qemu' packages

2021-09-23 Thread Vladimir Sementsov-Ogievskiy

23.09.2021 21:44, John Snow wrote:



On Thu, Sep 23, 2021 at 2:32 PM Vladimir Sementsov-Ogievskiy mailto:vsement...@virtuozzo.com>> wrote:

23.09.2021 21:07, John Snow wrote:
 > Add a warning for when 'iotests' runs against a qemu namespace that
 > isn't the one in the source tree. This might occur if you have
 > (accidentally) installed the Python namespace package to your local
 > packages.
 >
 > (I'm not going to say that this is because I bit myself with this,
 > but you can fill in the blanks.)
 >
 > In the future, we will pivot to always preferring a specific installed
 > instance of qemu python packages managed directly by iotests. For now
 > simply warn if there is an ambiguity over which instance that iotests
 > might use.
 >
 > Example: If a user has navigated to ~/src/qemu/python and executed
 > `pip install .`, you will see output like this when running `./check`:
 >
 > WARNING: 'qemu' python packages will be imported from outside the source 
tree ('/home/jsnow/src/qemu/python')
 >           Importing instead from 
'/home/jsnow/.local/lib/python3.9/site-packages/qemu'
 >
 > Signed-off-by: John Snow mailto:js...@redhat.com>>
 > ---
 >   tests/qemu-iotests/testenv.py | 24 
 >   1 file changed, 24 insertions(+)
 >
 > diff --git a/tests/qemu-iotests/testenv.py 
b/tests/qemu-iotests/testenv.py
 > index 99a57a69f3a..1c0f6358538 100644
 > --- a/tests/qemu-iotests/testenv.py
 > +++ b/tests/qemu-iotests/testenv.py
 > @@ -16,6 +16,8 @@
 >   # along with this program.  If not, see >.
 >   #
 >
 > +import importlib.util
 > +import logging
 >   import os
 >   import sys
 >   import tempfile
 > @@ -112,6 +114,27 @@ def init_directories(self) -> None:
 >           # Path where qemu goodies live in this source tree.
 >           qemu_srctree_path = Path(__file__, '../../../python').resolve()
 >
 > +        # Warn if we happen to be able to find qemu namespace packages
 > +        # (using qemu.qmp as a bellwether) from an unexpected location.
 > +        # i.e. the package is already installed in the user's 
environment.
 > +        try:
 > +            qemu_spec = importlib.util.find_spec('qemu.qmp')
 > +        except ModuleNotFoundError:
 > +            qemu_spec = None
 > +
 > +        if qemu_spec and qemu_spec.origin:
 > +            spec_path = Path(qemu_spec.origin)
 > +            try:
 > +                _ = spec_path.relative_to(qemu_srctree_path)

It took some time and looking at specification trying to understand what's 
going on here :)

Could we just use:

if not Path(qemu_spec.origin).is_relative_to(qemu_srctree_path):
     ... logging ...


Nope, that's 3.9+ only. (I made the same mistake.)


Oh :(

OK




 > +            except ValueError:

 > +                self._logger.warning(
 > +                    "WARNING: 'qemu' python packages will be imported 
from"
 > +                    " outside the source tree ('%s')",
 > +                    qemu_srctree_path)


why not use f-strings ? :)


 > +                self._logger.warning(
 > +                    "         Importing instead from '%s'",
 > +                    spec_path.parents[1])
 > +

Also, I'd move this new chunk of code to a separate function (may be even 
out of class, as the only usage of self is self._logger, which you introduce 
with this patch. Still a method would be OK too). And then, just call it from 
__init__(). Just to keep init_directories() simpler. And with this new code we 
don't init any directories to pass to further test execution, it's just a check 
for runtime environment.


I wanted to keep the wiggly python import logic all in one place so that it was 
harder to accidentally forget a piece of it if/when we adjust it.


Hmm right.. I didn't look from that point of view.

So, we actually check the library we are using now is the same which we pass to 
called tests.

So, it's a right place for it. And it's about the fact that we are still 
hacking around importing libraries :) Hope for bright future.


I can create a standalone function for it, but I'd need to stash that 
qemu_srctree_path variable somewhere if we want to call that runtime check from 
somewhere else, because I don't want to compute it twice. Is it still worth 
doing in your opinion if I just create a method/function and pass it the 
qemu_srctree_path variable straight from init_directories()?


My first impression was that init_directories() is not a right place. But now I 
see that we want to check exactly this qemu_srctree_path, which we are going to 
pass to tests.

So, I'm OK as is.

Still, may be adding helper function like

def warn_if_module_loads_not_from(module_name, path):

worth 

Re: [PATCH v6 07/11] block: use int64_t instead of int in driver write_zeroes handlers

2021-09-23 Thread Eric Blake
On Fri, Sep 03, 2021 at 01:28:03PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> We are generally moving to int64_t for both offset and bytes parameters
> on all io paths.
> 
> Main motivation is realization of 64-bit write_zeroes operation for
> fast zeroing large disk chunks, up to the whole disk.
> 
> We chose signed type, to be consistent with off_t (which is signed) and
> with possibility for signed return type (where negative value means
> error).
> 
> So, convert driver write_zeroes handlers bytes parameter to int64_t.
> 
> The only caller of all updated function is bdrv_co_do_pwrite_zeroes().
> 
> bdrv_co_do_pwrite_zeroes() itself is of course OK with widening of
> callee parameter type. Also, bdrv_co_do_pwrite_zeroes()'s
> max_write_zeroes is limited to INT_MAX. So, updated functions all are
> safe, they will not get "bytes" larger than before.
> 
> Still, let's look through all updated functions, and add assertions to
> the ones which are actually unprepared to values larger than INT_MAX.
> For these drivers also set explicit max_pwrite_zeroes limit.
> 
[snip]
> 
> At this point all block drivers are prepared to support 64bit
> write-zero requests, or have explicitly set max_pwrite_zeroes.

The long commit message is essential, but the analysis looks sane.

> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---

> +++ b/block/iscsi.c

> @@ -1250,11 +1250,21 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState 
> *bs, int64_t offset,
>  iscsi_co_init_iscsitask(iscsilun, );
>  retry:
>  if (use_16_for_ws) {
> +/*
> + * iscsi_writesame16_task num_blocks argument is uint32_t. We rely 
> here
> + * on our max_pwrite_zeroes limit.
> + */
> +assert(nb_blocks < UINT32_MAX);
>  iTask.task = iscsi_writesame16_task(iscsilun->iscsi, iscsilun->lun, 
> lba,
>  iscsilun->zeroblock, 
> iscsilun->block_size,
>  nb_blocks, 0, !!(flags & 
> BDRV_REQ_MAY_UNMAP),
>  0, 0, iscsi_co_generic_cb, 
> );

Should this be <= instead of < ?

>  } else {
> +/*
> + * iscsi_writesame10_task num_blocks argument is uint16_t. We rely 
> here
> + * on our max_pwrite_zeroes limit.
> + */
> +assert(nb_blocks < UINT16_MAX);
>  iTask.task = iscsi_writesame10_task(iscsilun->iscsi, iscsilun->lun, 
> lba,
>  iscsilun->zeroblock, 
> iscsilun->block_size,
>  nb_blocks, 0, !!(flags & 
> BDRV_REQ_MAY_UNMAP),

here too.  The 16-bit limit is where we're most likely to run into
someone actually trying to zeroize that much at once.

> +++ b/block/nbd.c
> @@ -1407,15 +1407,17 @@ static int nbd_client_co_pwritev(BlockDriverState 
> *bs, int64_t offset,
>  }
>  
>  static int nbd_client_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
> -   int bytes, BdrvRequestFlags flags)
> +   int64_t bytes, BdrvRequestFlags flags)
>  {
>  BDRVNBDState *s = (BDRVNBDState *)bs->opaque;
>  NBDRequest request = {
>  .type = NBD_CMD_WRITE_ZEROES,
>  .from = offset,
> -.len = bytes,
> +.len = bytes,  /* .len is uint32_t actually */
>  };
>  
> +assert(bytes < UINT32_MAX); /* relay on max_pwrite_zeroes */

And again.  Here, you happen to get by with < because we clamped
bl.max_pwrite_zeroes at BDRV_REQUEST_MAX_BYTES, which is INT_MAX
rounded down.  But I had to check; whereas using <= would be less
worrisome, even if we never get a request that large.

If you agree with my analysis, I can make that change while preparing
my pull request.

Reviewed-by: Eric Blake 

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




Re: [RFC PATCH v2] hw/nvme:Adding Support for namespace management

2021-09-23 Thread Klaus Jensen
On Aug 19 18:39, Naveen Nagar wrote:
> From: Naveen 
> 
> This patch supports namespace management : create and delete operations.
> 
> Since v1:
> - Modified and moved nvme_ns_identify_common in ns.c file 
> - Added check for CSI field in NS management
> - Indentation fix in namespace create
> 
> This patch has been tested with the following command and size of image
> file for unallocated namespaces is taken as 0GB. ns_create will look into
> the list of unallocated namespaces and it will initialize the same and 
> return the nsid of the same. A new mandatory field has been added called
> tnvmcap and we have ensured that the total capacity of namespace created
> does not exceed tnvmcap
> 
> -device nvme-subsys,id=subsys0,tnvmcap=8
> -device nvme,serial=foo,id=nvme0,subsys=subsys0
> -device nvme,serial=bar,id=nvme1,subsys=subsys0
> -drive id=ns1,file=ns1.img,if=none
> -device nvme-ns,drive=ns1,bus=nvme0,nsid=1,zoned=false,shared=true
> -drive id=ns2,file=ns2.img,if=none
> -device nvme-ns,drive=ns2,bus=nvme0,nsid=2,zoned=false,shared=true
> -drive id=ns3,file=ns3.img,if=none
> -device nvme-ns,drive=ns3,bus=nvme0,nsid=3,zoned=false,shared=true
> -drive id=ns4,file=ns4.img,if=none
> -device nvme-ns,drive=ns4,bus=nvme0,nsid=4,zoned=false,shared=true
> 
> Please review and suggest if any changes are required.
> 
> Signed-off-by: Naveen Nagar 
> Reviewed-by: Klaus Jensen 
>   

So, I think this is a fine approach.

However, I think we should let it simmer until we know if my -object
refactoring will be accepted as a way forward. In that case, I'd like to
only add it there and likely as a new namespace "type" (i.e.
x-nvme-ns-unallocated) that will be replaced with a dynamically created
object depending on CSI.


signature.asc
Description: PGP signature


Re: [PATCH v2] hw/nvme: Return error for fused operations

2021-09-23 Thread Klaus Jensen
On Sep 15 17:43, Pankaj Raghav wrote:
> Currently, FUSED operations are not supported by QEMU. As per the 1.4 SPEC,
> controller should abort the command that requested a fused operation with 
> an INVALID FIELD error code if they are not supported.
> 
> Changes from v1:
> Added FUSE flag check also to the admin cmd processing as the FUSED 
> operations are mentioned in the general SQE section in the SPEC. 
> 
> Signed-off-by: Pankaj Raghav 
> ---
>  hw/nvme/ctrl.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
> index dc0e7b0030..2f247a9275 100644
> --- a/hw/nvme/ctrl.c
> +++ b/hw/nvme/ctrl.c
> @@ -3893,6 +3893,10 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeRequest 
> *req)
>  return ns->status;
>  }
>  
> +if (NVME_CMD_FLAGS_FUSE(req->cmd.flags)) {
> +return NVME_INVALID_FIELD;
> +}
> +
>  req->ns = ns;
>  
>  switch (req->cmd.opcode) {
> @@ -5475,6 +5479,10 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, 
> NvmeRequest *req)
>  return NVME_INVALID_FIELD | NVME_DNR;
>  }
>  
> +if (NVME_CMD_FLAGS_FUSE(req->cmd.flags)) {
> +return NVME_INVALID_FIELD;
> +}
> +
>  switch (req->cmd.opcode) {
>  case NVME_ADM_CMD_DELETE_SQ:
>  return nvme_del_sq(n, req);
> -- 
> 2.25.1

Applied to nvme-next. Thanks!


signature.asc
Description: PGP signature


Re: [PATCH] hw/nvme: reattach subsystem namespaces on hotplug

2021-09-23 Thread Klaus Jensen
On Sep  9 13:37, Hannes Reinecke wrote:
> On 9/9/21 12:47 PM, Klaus Jensen wrote:
> > On Sep  9 11:43, Hannes Reinecke wrote:
> >> With commit 5ffbaeed16 ("hw/nvme: fix controller hot unplugging")
> >> namespaces get moved from the controller to the subsystem if one
> >> is specified.
> >> That keeps the namespaces alive after a controller hot-unplug, but
> >> after a controller hotplug we have to reconnect the namespaces
> >> from the subsystem to the controller.
> >>
> >> Fixes: 5ffbaeed16 ("hw/nvme: fix controller hot unplugging")
> >> Cc: Klaus Jensen 
> >> Signed-off-by: Hannes Reinecke 
> >> ---
> >>  hw/nvme/subsys.c | 8 +++-
> >>  1 file changed, 7 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c
> >> index 93c35950d6..a9404f2b5e 100644
> >> --- a/hw/nvme/subsys.c
> >> +++ b/hw/nvme/subsys.c
> >> @@ -14,7 +14,7 @@
> >>  int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp)
> >>  {
> >>  NvmeSubsystem *subsys = n->subsys;
> >> -int cntlid;
> >> +int cntlid, nsid;
> >>  
> >>  for (cntlid = 0; cntlid < ARRAY_SIZE(subsys->ctrls); cntlid++) {
> >>  if (!subsys->ctrls[cntlid]) {
> >> @@ -29,12 +29,18 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error 
> >> **errp)
> >>  
> >>  subsys->ctrls[cntlid] = n;
> >>  
> >> +for (nsid = 0; nsid < ARRAY_SIZE(subsys->namespaces); nsid++) {
> >> +if (subsys->namespaces[nsid]) {
> >> +nvme_attach_ns(n, subsys->namespaces[nsid]);
> >> +}
> > 
> > Thanks Hannes! I like it, keeping things simple.
> > 
> > But we should only attach namespaces that have the shared property or
> > have ns->attached == 0. Non-shared namespaces may already be attached to
> > another controller in the subsystem.
> > 
> 
> Well ... I tried to avoid that subject, but as you brought it up:
> There is a slightly tricky issue in fabrics, in that the 'controller' is
> independent from the 'connection'.
> The 'shared' bit in the CMIC setting indicates that the subsystem may
> have more than one _controller_. It doesn't talk about how many
> _connections_ a controller may support; that then is the realm of
> dynamic or static controllers, which we don't talk about :-).
> Sufficient to say, linux only implements the dynamic controller model,
> so every connection will be to a different controller.
> But you have been warned :-)
> 
> However, the 'CMIC' setting is independent on the 'NMIC' setting (ie the
> 'shared' bit in the namespace).
> Which leads to the interesting question on how exactly should one handle
> non-shared namespaces in subsystems for which there are multiple
> controllers. Especially as the NSID space is per subsystem, so each
> controller will be able to figure out if there are blanked-out namespaces.
> So to make this a sane setup I would propose to set the 'shared' option
> automatically whenever the controller has the 'subsys' option set.
> And actually, I would ditch the 'shared' option completely, and make it
> dependent on the 'subsys' setting for the controller.
> Much like we treat the 'CMIC' setting nowadays.
> That avoids lots of confusions, and also make the implementation _way_
> easier.
> 

I see your point. Unfortunately, there is no easy way to ditch shared=
now. But I think it'd be good enough to attach to shared automatically,
but not to "shared=off".

I've already ditched the shared parameter on my RFC refactor series and
always having the namespaces shared.

> > However...
> > 
> > The spec says that "The attach and detach operations are persistent
> > across all reset events.". This means that we should track those events
> > in the subsystem and only reattach namespaces that were attached at the
> > time of the "reset" event. Currently, we don't have anything mapping
> > that state. But the device already has to take some liberties with
> > regard to stuff that is considered persistent by the spec (SMART log
> > etc.) since we do not have any way to store stuff persistently across
> > qemu invocations, so I think the above is an acceptable compromise.
> > 
> Careful. 'attach' and 'detach' are MI (management interface) operations.
> If and how many namespaces are visible to any given controllers is
> actually independent on that; and, in fact, controllers might not even
> implement 'attach' or 'detach'.
> But I do agree that we don't handle the 'reset' state properly.
> 

The Namespace Attachment command has nothing to do with MI? And the QEMU
controller does support attaching and detaching namespaces.

> > A potential (as good as it gets) fix would be to keep a map/list of
> > "persistently" attached controllers on the namespaces and re-attach
> > according to that when we see that controller joining the subsystem
> > again. CNTLID would be the obvious choice for the key here, but problem
> > is that we cant really use it since we assign it sequentially from the
> > subsystem, which now looks like a pretty bad choice. CNTLID should have
> > been a 

Re: [PATCH v6 06/11] block: make BlockLimits::max_pwrite_zeroes 64bit

2021-09-23 Thread Eric Blake
On Fri, Sep 03, 2021 at 01:28:02PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> We are going to support 64 bit write-zeroes requests. Now update the
> limit variable. It's absolutely safe. The variable is set in some
> drivers, and used in bdrv_co_do_pwrite_zeroes().
> 
> Update also max_write_zeroes variable in bdrv_co_do_pwrite_zeroes(), so
> that bdrv_co_do_pwrite_zeroes() is now prepared to 64bit requests. The
> remaining logic including num, offset and bytes variables is already
> supporting 64bit requests.
> 
> So the only thing that prevents 64 bit requests is limiting
> max_write_zeroes variable to INT_MAX in bdrv_co_do_pwrite_zeroes().
> We'll drop this limitation after updating all block drivers.
> 
> Ah, we also have bdrv_check_request32() in bdrv_co_pwritev_part(). It
> will be modified to do bdrv_check_request() for write-zeroes path.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  include/block/block_int.h | 9 +
>  block/io.c| 2 +-
>  2 files changed, 6 insertions(+), 5 deletions(-)

Reviewed-by: Eric Blake 

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




[PATCH 4/5] util/qemu-option: make qemu_opt_del_all() function public

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
To be used in the following commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 include/qemu/option.h | 1 +
 util/qemu-option.c| 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 306bf07575..4ba88f2632 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -71,6 +71,7 @@ struct QemuOptsList {
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
 char *qemu_opt_get_del(QemuOpts *opts, const char *name);
+void qemu_opt_del_all(QemuOpts *opts, const char *name);
 /**
  * qemu_opt_has_help_opt:
  * @opts: options to search for a help request
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 61cb4a97bd..2c75cc2e46 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -244,7 +244,7 @@ static void qemu_opt_del(QemuOpt *opt)
 /* qemu_opt_set allows many settings for the same option.
  * This function deletes all settings for an option.
  */
-static void qemu_opt_del_all(QemuOpts *opts, const char *name)
+void qemu_opt_del_all(QemuOpts *opts, const char *name)
 {
 QemuOpt *opt, *next_opt;
 
-- 
2.29.2




[PATCH 5/5] trace: add qmp trace event namespace

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
Add a possibility to trace some qmp commands by user selection.

User API is simple: it looks like after this patch we have trace-points
for all qmp commands, in format "qmp:". So user may do

  --trace qmp:drive-backup

or run qmp command trace-event-set-state with arguments

  name="qmp:drive-backup", enable=true

Patterns are supported in the same way as for general trace events, for
example:

  --trace "qmp:query-*"

to cover query-block, query-block-jobs, and a lot of other query-
commands

or

  --trace "qmp:job-*" --trace "qmp:block-job-*"

to cover job manipulation commands.

Trace event qmp covers both qmp command call and its respond.

Implementation details:

In qmp_dispatch() we add two trace points, similar to
trace_handle_qmp_command. We also check for cmd->tracking field being
set, and for handle-qmp-command/monitor-qmp-respond trace points being
disabled, to not print same information twice.

For qmp trace-event-{get,set}-state and for command line
parse additionally new "qmp:" namespace

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 qapi/qmp-dispatch.c | 20 
 softmmu/vl.c| 21 -
 trace/qmp.c | 20 
 qapi/trace-events   |  2 ++
 4 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 59600210ce..40fd008fa8 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -26,6 +26,9 @@
 #include "qemu/coroutine.h"
 #include "qemu/main-loop.h"
 
+#include "trace.h"
+#include "trace/trace-monitor.h"
+
 CompatPolicy compat_policy;
 
 Visitor *qobject_input_visitor_new_qmp(QObject *obj)
@@ -133,6 +136,12 @@ static void do_qmp_dispatch_bh(void *opaque)
 aio_co_wake(data->co);
 }
 
+static void do_trace_qmp(const char *what, QObject *obj)
+{
+g_autoptr(GString) req_json = qobject_to_json(obj);
+trace_qmp(what, req_json->str);
+}
+
 /*
  * Runs outside of coroutine context for OOB commands, but in coroutine
  * context for everything else.
@@ -176,6 +185,11 @@ QDict *qmp_dispatch(const QmpCommandList *cmds, QObject 
*request,
   "The command %s has not been found", command);
 goto out;
 }
+if (!trace_event_get_state_backends(TRACE_HANDLE_QMP_COMMAND) &&
+trace_event_get_state_backends(TRACE_QMP) && cmd->tracing)
+{
+do_trace_qmp(">>", request);
+}
 if (cmd->options & QCO_DEPRECATED) {
 switch (compat_policy.deprecated_input) {
 case COMPAT_POLICY_INPUT_ACCEPT:
@@ -282,5 +296,11 @@ out:
 qdict_put_obj(rsp, "id", qobject_ref(id));
 }
 
+if (!trace_event_get_state_backends(TRACE_MONITOR_QMP_RESPOND) &&
+trace_event_get_state_backends(TRACE_QMP) && cmd->tracing)
+{
+do_trace_qmp("<<", QOBJECT(rsp));
+}
+
 return rsp;
 }
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 55ab70eb97..fd452b7013 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2722,6 +2722,25 @@ void qmp_x_exit_preconfig(Error **errp)
 }
 }
 
+static void trace_opt_parse_with_qmp(const char *optarg)
+{
+const char *pattern;
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
+ optarg, true);
+if (!opts) {
+exit(1);
+}
+
+pattern = qemu_opt_get(opts, "enable");
+if (pattern && !strncmp(pattern, "qmp:", 4)) {
+monitor_qmp_set_tracing(pattern + 4, true);
+qemu_opt_del_all(opts, "enable");
+qemu_opt_set(opts, "enable", "qmp", _abort);
+}
+
+trace_opt_parse_opts(opts);
+}
+
 void qemu_init(int argc, char **argv, char **envp)
 {
 QemuOpts *opts;
@@ -3480,7 +3499,7 @@ void qemu_init(int argc, char **argv, char **envp)
 xen_domid_restrict = true;
 break;
 case QEMU_OPTION_trace:
-trace_opt_parse(optarg);
+trace_opt_parse_with_qmp(optarg);
 break;
 case QEMU_OPTION_plugin:
 qemu_plugin_opt_parse(optarg, _list);
diff --git a/trace/qmp.c b/trace/qmp.c
index 3b4f4702b4..87766422d9 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -11,6 +11,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-trace.h"
 #include "control-vcpu.h"
+#include "monitor/monitor.h"
 
 
 static CPUState *get_cpu(bool has_vcpu, int vcpu, Error **errp)
@@ -77,6 +78,14 @@ TraceEventInfoList *qmp_trace_event_get_state(const char 
*name,
 bool is_pattern = trace_event_is_pattern(name);
 CPUState *cpu;
 
+if (!strncmp(name, "qmp:", 4)) {
+if (!monitor_qmp_is_tracing_enabled(name + 4)) {
+return NULL;
+}
+
+return qmp_trace_event_get_state("qmp", has_vcpu, vcpu, errp);
+}
+
 /* Check provided vcpu */
 cpu = get_cpu(has_vcpu, vcpu, );
 if (err) {
@@ -139,6 +148,17 @@ void qmp_trace_event_set_state(const char *name, bool 
enable,
 bool is_pattern = trace_event_is_pattern(name);
 CPUState *cpu;
 
+if 

[PATCH 2/5] qapi/qmp: QmpCommand: add .tracing field and API

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
We are going to add a possibility to trace some qmp commands by user
selection. For now add a new field to QmpCommand structure and two
functions to manipulate with it.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 include/qapi/qmp/dispatch.h | 14 ++
 qapi/qmp-registry.c | 27 +++
 2 files changed, 41 insertions(+)

diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 075203dc67..5d0df2f984 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -38,6 +38,7 @@ typedef struct QmpCommand
 QTAILQ_ENTRY(QmpCommand) node;
 bool enabled;
 const char *disable_reason;
+bool tracing;
 } QmpCommand;
 
 typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
@@ -64,4 +65,17 @@ typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, 
void *opaque);
 void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn fn,
   void *opaque);
 
+/*
+ * Enable or disable tracing for commands matching the pattern.
+ * Pattern matching is handled by g_pattern_match_simple().
+ */
+void qmp_commands_set_tracing(QmpCommandList *cmds, const char *pattern,
+  bool enable);
+
+/*
+ * Return true if tracing is enabled for any command matching the pattern.
+ * If pattern is NULL, return true if tracing is enabled for any command.
+ */
+bool qmp_commands_is_tracing_enabled(QmpCommandList *cmds, const char 
*pattern);
+
 #endif
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index f78c064aae..56e761857b 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -67,6 +67,33 @@ void qmp_enable_command(QmpCommandList *cmds, const char 
*name)
 qmp_toggle_command(cmds, name, true, NULL);
 }
 
+void qmp_commands_set_tracing(QmpCommandList *cmds, const char *pattern,
+  bool enable)
+{
+QmpCommand *cmd;
+
+QTAILQ_FOREACH(cmd, cmds, node) {
+if (g_pattern_match_simple(pattern, cmd->name)) {
+cmd->tracing = true;
+}
+}
+}
+
+bool qmp_commands_is_tracing_enabled(QmpCommandList *cmds, const char *pattern)
+{
+QmpCommand *cmd;
+
+QTAILQ_FOREACH(cmd, cmds, node) {
+if (cmd->tracing &&
+(!pattern || g_pattern_match_simple(pattern, cmd->name)))
+{
+return true;
+}
+}
+
+return false;
+}
+
 bool qmp_command_is_enabled(const QmpCommand *cmd)
 {
 return cmd->enabled;
-- 
2.29.2




[PATCH 3/5] monitor: add qmp tracing API for qmp_commands

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
Add wrappers to manipulate with .tracing in qmp_commands list.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 include/monitor/monitor.h |  3 +++
 monitor/qmp.c | 10 ++
 2 files changed, 13 insertions(+)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 1a8a369b50..9587998217 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -54,4 +54,7 @@ int64_t monitor_fdset_dup_fd_find(int dup_fd);
 void monitor_register_hmp(const char *name, bool info,
   void (*cmd)(Monitor *mon, const QDict *qdict));
 
+bool monitor_qmp_is_tracing_enabled(const char *pattern);
+void monitor_qmp_set_tracing(const char *pattern, bool enable);
+
 #endif /* MONITOR_H */
diff --git a/monitor/qmp.c b/monitor/qmp.c
index 092c527b6f..def2c7d1da 100644
--- a/monitor/qmp.c
+++ b/monitor/qmp.c
@@ -536,3 +536,13 @@ void monitor_init_qmp(Chardev *chr, bool pretty, Error 
**errp)
 monitor_list_append(>common);
 }
 }
+
+void monitor_qmp_set_tracing(const char *pattern, bool enable)
+{
+qmp_commands_set_tracing(_commands, pattern, enable);
+}
+
+bool monitor_qmp_is_tracing_enabled(const char *pattern)
+{
+return qmp_commands_is_tracing_enabled(_commands, pattern);
+}
-- 
2.29.2




[PATCH 0/5] trace: inroduce qmp: trace namespace

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
Hi all!

We have handle_qmp_command and qmp_command_repond trace points to trace
qmp commands. They are very useful to debug problems involving
management tools like libvirt.

But tracing all qmp commands is too much.

Here I suggest a kind of tracing namespace. Formally this series adds a
trace points called qmp: for every command, which may be
enabled in separate like

  --trace qmp:drive-backup

or by pattern like

  --trace qmp:block-job-*

or similarly with help of qmp command trace-event-set-state.

This also allows to enable tracing of some qmp commands permanently
 (by downstream patch or in libvirt xml). For example, I'm going to
enable tracing of block job comamnds and blockdev-* commands in
Virtuozzo. Qemu logs are often too empty (for example, in comparison
with Libvirt), logging block jobs is not too much but will be very
helpful.

Vladimir Sementsov-Ogievskiy (5):
  trace/control: introduce trace_opt_parse_opts()
  qapi/qmp: QmpCommand: add .tracing field and API
  monitor: add qmp tracing API for qmp_commands
  util/qemu-option: make qemu_opt_del_all() function public
  trace: add qmp trace event namespace

 include/monitor/monitor.h   |  3 +++
 include/qapi/qmp/dispatch.h | 14 ++
 include/qemu/option.h   |  1 +
 trace/control.h |  7 +++
 monitor/qmp.c   | 10 ++
 qapi/qmp-dispatch.c | 20 
 qapi/qmp-registry.c | 27 +++
 softmmu/vl.c| 21 -
 trace/control.c | 18 --
 trace/qmp.c | 20 
 util/qemu-option.c  |  2 +-
 qapi/trace-events   |  2 ++
 12 files changed, 137 insertions(+), 8 deletions(-)

-- 
2.29.2




[PATCH 1/5] trace/control: introduce trace_opt_parse_opts()

2021-09-23 Thread Vladimir Sementsov-Ogievskiy
Add a function same as trace_opt_parse, but parameter is QemuOpts.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 trace/control.h |  7 +++
 trace/control.c | 18 --
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/trace/control.h b/trace/control.h
index 23b8393b29..fb898e2c4a 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -251,6 +251,13 @@ extern QemuOptsList qemu_trace_opts;
  */
 void trace_opt_parse(const char *optarg);
 
+/**
+ * Same as trace_opt_parse, but accept QemuOpts instead of options string.
+ *
+ * Releases @opts at the end.
+ */
+void trace_opt_parse_opts(QemuOpts *opts);
+
 /**
  * trace_get_vcpu_event_count:
  *
diff --git a/trace/control.c b/trace/control.c
index d5b68e846e..4bcbd96511 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -313,13 +313,8 @@ bool trace_init_backends(void)
 return true;
 }
 
-void trace_opt_parse(const char *optarg)
+void trace_opt_parse_opts(QemuOpts *opts)
 {
-QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
- optarg, true);
-if (!opts) {
-exit(1);
-}
 if (qemu_opt_get(opts, "enable")) {
 trace_enable_events(qemu_opt_get(opts, "enable"));
 }
@@ -330,6 +325,17 @@ void trace_opt_parse(const char *optarg)
 qemu_opts_del(opts);
 }
 
+void trace_opt_parse(const char *optarg)
+{
+QemuOpts *opts = qemu_opts_parse_noisily(qemu_find_opts("trace"),
+ optarg, true);
+if (!opts) {
+exit(1);
+}
+
+trace_opt_parse_opts(opts);
+}
+
 uint32_t trace_get_vcpu_event_count(void)
 {
 return next_vcpu_id;
-- 
2.29.2




[PATCH v3 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread John Snow
The single backtick markup in ReST is the "default role". Currently,
Sphinx's default role is called "content". Sphinx suggests you can use
the "Any" role instead to turn any single-backtick enclosed item into a
cross-reference.

This is useful for things like autodoc for Python docstrings, where it's
often nicer to reference other types with `foo` instead of the more
laborious :py:meth:`foo`. It's also useful in multi-domain cases to
easily reference definitions from other Sphinx domains, such as
referencing C code definitions from outside of kerneldoc comments.

Before we do that, though, we'll need to turn all existing usages of the
"content" role to inline verbatim markup wherever it does not correctly
resolve into a cross-refernece by using double backticks instead.

Signed-off-by: John Snow 
---
 docs/devel/fuzzing.rst | 9 +
 docs/devel/tcg-plugins.rst | 2 +-
 docs/interop/live-block-operations.rst | 2 +-
 docs/system/guest-loader.rst   | 2 +-
 qapi/block-core.json   | 4 ++--
 include/qemu/module.h  | 6 +++---
 qemu-options.hx| 4 ++--
 7 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
index 2749bb9bed3..784ecb99e66 100644
--- a/docs/devel/fuzzing.rst
+++ b/docs/devel/fuzzing.rst
@@ -182,10 +182,11 @@ The output should contain a complete list of matched 
MemoryRegions.
 
 OSS-Fuzz
 
-QEMU is continuously fuzzed on `OSS-Fuzz` 
__(https://github.com/google/oss-fuzz).
-By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
-generic-fuzz target requires additional information provided in environment
-variables, we pre-define some generic-fuzz configs in
+QEMU is continuously fuzzed on `OSS-Fuzz
+`_.  By default, the OSS-Fuzz build
+will try to fuzz every fuzz-target. Since the generic-fuzz target
+requires additional information provided in environment variables, we
+pre-define some generic-fuzz configs in
 ``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
 
 - ``.name``: To identify the fuzzer config
diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
index dac5101a3c9..8b187f8 100644
--- a/docs/devel/tcg-plugins.rst
+++ b/docs/devel/tcg-plugins.rst
@@ -212,7 +212,7 @@ The hotpages plugin can be configured using the following 
arguments:
 
 This is an instruction classifier so can be used to count different
 types of instructions. It has a number of options to refine which get
-counted. You can give a value to the `count` argument for a class of
+counted. You can give a value to the ``count`` argument for a class of
 instructions to break it down fully, so for example to see all the system
 registers accesses::
 
diff --git a/docs/interop/live-block-operations.rst 
b/docs/interop/live-block-operations.rst
index 9e3635b2338..814c29bbe1d 100644
--- a/docs/interop/live-block-operations.rst
+++ b/docs/interop/live-block-operations.rst
@@ -640,7 +640,7 @@ at this point:
 (QEMU) block-job-complete device=job0
 
 In either of the above cases, if you once again run the
-`query-block-jobs` command, there should not be any active block
+``query-block-jobs`` command, there should not be any active block
 operation.
 
 Comparing 'commit' and 'mirror': In both then cases, the overlay images
diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst
index 4320d1183f7..9ef9776bf07 100644
--- a/docs/system/guest-loader.rst
+++ b/docs/system/guest-loader.rst
@@ -51,4 +51,4 @@ The full syntax of the guest-loader is::
 
 ``bootargs=``
   This is an optional field for kernel blobs which will pass command
-  like via the `/chosen/module@/bootargs` node.
+  like via the ``/chosen/module@/bootargs`` node.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index c8ce1d9d5d8..0c64470edb2 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -446,11 +446,11 @@
 # @granularity: granularity of the dirty bitmap in bytes (since 1.4)
 #
 # @recording: true if the bitmap is recording new writes from the guest.
-# Replaces `active` and `disabled` statuses. (since 4.0)
+# Replaces ``active`` and ``disabled`` statuses. (since 4.0)
 #
 # @busy: true if the bitmap is in-use by some operation (NBD or jobs)
 #and cannot be modified via QMP or used by another operation.
-#Replaces `locked` and `frozen` statuses. (since 4.0)
+#Replaces ``locked`` and ``frozen`` statuses. (since 4.0)
 #
 # @persistent: true if the bitmap was stored on disk, is scheduled to be stored
 #  on disk, or both. (since 4.0)
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 3deac0078b9..5fcc323b2a7 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -77,14 +77,14 @@ void module_allow_arch(const char *arch);
 /**
  * DOC: module info annotation macros
  *
- * 

[PATCH v3 2/2] docs/sphinx: change default role to "any"

2021-09-23 Thread John Snow
This interprets single-backtick syntax in all of our Sphinx docs as a
cross-reference to *something*, including Python symbols.

>From here on out, new uses of `backticks` will cause a build failure if
the target cannot be referenced.

Signed-off-by: John Snow 
---
 docs/conf.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/docs/conf.py b/docs/conf.py
index ff6e92c6e2e..4d9f56601fc 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -85,6 +85,11 @@
 # The master toctree document.
 master_doc = 'index'
 
+# Interpret `single-backticks` to be a cross-reference to any kind of
+# referenceable object. Unresolvable or ambiguous references will emit a
+# warning at build time.
+default_role = 'any'
+
 # General information about the project.
 project = u'QEMU'
 copyright = u'2021, The QEMU Project Developers'
-- 
2.31.1




[PATCH v3 0/2] docs/sphinx: change default `role` to "any"

2021-09-23 Thread John Snow
Rebased to not let the work done in removing erroneous references prior
to 6.1 regress.

V3: Removed bad rebase confetti
fixed the OSS-Fuzz link to ... actually be a link.

John Snow (2):
  docs: remove non-reference uses of single backticks
  docs/sphinx: change default role to "any"

 docs/conf.py   | 5 +
 docs/devel/fuzzing.rst | 9 +
 docs/devel/tcg-plugins.rst | 2 +-
 docs/interop/live-block-operations.rst | 2 +-
 docs/system/guest-loader.rst   | 2 +-
 qapi/block-core.json   | 4 ++--
 include/qemu/module.h  | 6 +++---
 qemu-options.hx| 4 ++--
 8 files changed, 20 insertions(+), 14 deletions(-)

-- 
2.31.1





Re: [PATCH v2 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread John Snow
On Thu, Sep 23, 2021 at 2:33 PM Eduardo Habkost  wrote:

> On Thu, Sep 23, 2021 at 02:22:03PM -0400, John Snow wrote:
> > The single backtick markup in ReST is the "default role". Currently,
> > Sphinx's default role is called "content". Sphinx suggests you can use
> > the "Any" role instead to turn any single-backtick enclosed item into a
> > cross-reference.
> >
> > This is useful for things like autodoc for Python docstrings, where it's
> > often nicer to reference other types with `foo` instead of the more
> > laborious :py:meth:`foo`. It's also useful in multi-domain cases to
> > easily reference definitions from other Sphinx domains, such as
> > referencing C code definitions from outside of kerneldoc comments.
> >
> > Before we do that, though, we'll need to turn all existing usages of the
> > "content" role to inline verbatim markup wherever it does not correctly
> > resolve into a cross-refernece by using double backticks instead.
> >
> > Signed-off-by: John Snow 
>
> Clear demonstration of the usefulness of patch 2/2 (these
> occurrences of `foo` wouldn't have been added if the default role
> was "any" because "any" errors out on invalid references).
>
> However, it looks like there are unrelated changes:
>
> [...]
> > diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
> > index 24012534827..6b1230f2d7f 100644
> > --- a/docs/devel/migration.rst
> > +++ b/docs/devel/migration.rst
> > @@ -403,8 +403,8 @@ version_id.  And the function ``load_state_old()``
> (if present) is able to
> >  load state from minimum_version_id_old to minimum_version_id.  This
> >  function is deprecated and will be removed when no more users are left.
> >
> > -There are *_V* forms of many ``VMSTATE_`` macros to load fields for
> version dependent fields,
> > -e.g.
> > +There are *_V* forms of many ``VMSTATE_`` macros to load fields for
> > +version dependent fields, e.g.
>
> Unrelated?  Line wrapping change only.
>
> >
> >  .. code:: c
> >
> > @@ -819,9 +819,9 @@ Postcopy now works with hugetlbfs backed memory:
> >  Postcopy with shared memory
> >  ---
> >
> > -Postcopy migration with shared memory needs explicit support from the
> other
> > -processes that share memory and from QEMU. There are restrictions on
> the type of
> > -memory that userfault can support shared.
> > +Postcopy migration with shared memory needs explicit support from the
> > +other processes that share memory and from QEMU. There are restrictions
> > +on the type of memory that userfault can support shared.
>
> Unrelated?  Line wrapping change only.
>
> Reviewed-by: Eduardo Habkost   # if unrelated line
> wrapping changes are dropped
>
> --
> Eduardo
>
>
Apologies for that -- it's bad rebase confetti. Something got merged
automatically and it resulted in weird junk. Sorry for the noise.

--js


Re: [PATCH v2 2/6] iotests: add warning for rogue 'qemu' packages

2021-09-23 Thread John Snow
On Thu, Sep 23, 2021 at 2:32 PM Vladimir Sementsov-Ogievskiy <
vsement...@virtuozzo.com> wrote:

> 23.09.2021 21:07, John Snow wrote:
> > Add a warning for when 'iotests' runs against a qemu namespace that
> > isn't the one in the source tree. This might occur if you have
> > (accidentally) installed the Python namespace package to your local
> > packages.
> >
> > (I'm not going to say that this is because I bit myself with this,
> > but you can fill in the blanks.)
> >
> > In the future, we will pivot to always preferring a specific installed
> > instance of qemu python packages managed directly by iotests. For now
> > simply warn if there is an ambiguity over which instance that iotests
> > might use.
> >
> > Example: If a user has navigated to ~/src/qemu/python and executed
> > `pip install .`, you will see output like this when running `./check`:
> >
> > WARNING: 'qemu' python packages will be imported from outside the source
> tree ('/home/jsnow/src/qemu/python')
> >   Importing instead from
> '/home/jsnow/.local/lib/python3.9/site-packages/qemu'
> >
> > Signed-off-by: John Snow 
> > ---
> >   tests/qemu-iotests/testenv.py | 24 
> >   1 file changed, 24 insertions(+)
> >
> > diff --git a/tests/qemu-iotests/testenv.py
> b/tests/qemu-iotests/testenv.py
> > index 99a57a69f3a..1c0f6358538 100644
> > --- a/tests/qemu-iotests/testenv.py
> > +++ b/tests/qemu-iotests/testenv.py
> > @@ -16,6 +16,8 @@
> >   # along with this program.  If not, see  >.
> >   #
> >
> > +import importlib.util
> > +import logging
> >   import os
> >   import sys
> >   import tempfile
> > @@ -112,6 +114,27 @@ def init_directories(self) -> None:
> >   # Path where qemu goodies live in this source tree.
> >   qemu_srctree_path = Path(__file__, '../../../python').resolve()
> >
> > +# Warn if we happen to be able to find qemu namespace packages
> > +# (using qemu.qmp as a bellwether) from an unexpected location.
> > +# i.e. the package is already installed in the user's
> environment.
> > +try:
> > +qemu_spec = importlib.util.find_spec('qemu.qmp')
> > +except ModuleNotFoundError:
> > +qemu_spec = None
> > +
> > +if qemu_spec and qemu_spec.origin:
> > +spec_path = Path(qemu_spec.origin)
> > +try:
> > +_ = spec_path.relative_to(qemu_srctree_path)
>
> It took some time and looking at specification trying to understand what's
> going on here :)
>
> Could we just use:
>
> if not Path(qemu_spec.origin).is_relative_to(qemu_srctree_path):
> ... logging ...
>
>
Nope, that's 3.9+ only. (I made the same mistake.)


> > +except ValueError:
>
> +self._logger.warning(
> > +"WARNING: 'qemu' python packages will be imported
> from"
> > +" outside the source tree ('%s')",
> > +qemu_srctree_path)
> > +self._logger.warning(
> > +" Importing instead from '%s'",
> > +spec_path.parents[1])
> > +
>
> Also, I'd move this new chunk of code to a separate function (may be even
> out of class, as the only usage of self is self._logger, which you
> introduce with this patch. Still a method would be OK too). And then, just
> call it from __init__(). Just to keep init_directories() simpler. And with
> this new code we don't init any directories to pass to further test
> execution, it's just a check for runtime environment.
>
>
I wanted to keep the wiggly python import logic all in one place so that it
was harder to accidentally forget a piece of it if/when we adjust it. I can
create a standalone function for it, but I'd need to stash that
qemu_srctree_path variable somewhere if we want to call that runtime check
from somewhere else, because I don't want to compute it twice. Is it still
worth doing in your opinion if I just create a method/function and pass it
the qemu_srctree_path variable straight from init_directories()?

Not adding _logger is valid, though. I almost removed it myself. I'll
squash that in.


> >   self.pythonpath = os.pathsep.join(filter(None, (
> >   self.source_iotests,
> >   str(qemu_srctree_path),
> > @@ -230,6 +253,7 @@ def __init__(self, imgfmt: str, imgproto: str,
> aiomode: str,
> >
> >   self.build_root = os.path.join(self.build_iotests, '..', '..')
> >
> > +self._logger = logging.getLogger('qemu.iotests')
> >   self.init_directories()
> >   self.init_binaries()
> >
> >
>
>
> --
> Best regards,
> Vladimir
>
>


Re: [PATCH v2 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread Eduardo Habkost
On Thu, Sep 23, 2021 at 02:22:03PM -0400, John Snow wrote:
> The single backtick markup in ReST is the "default role". Currently,
> Sphinx's default role is called "content". Sphinx suggests you can use
> the "Any" role instead to turn any single-backtick enclosed item into a
> cross-reference.
> 
> This is useful for things like autodoc for Python docstrings, where it's
> often nicer to reference other types with `foo` instead of the more
> laborious :py:meth:`foo`. It's also useful in multi-domain cases to
> easily reference definitions from other Sphinx domains, such as
> referencing C code definitions from outside of kerneldoc comments.
> 
> Before we do that, though, we'll need to turn all existing usages of the
> "content" role to inline verbatim markup wherever it does not correctly
> resolve into a cross-refernece by using double backticks instead.
> 
> Signed-off-by: John Snow 

Clear demonstration of the usefulness of patch 2/2 (these
occurrences of `foo` wouldn't have been added if the default role
was "any" because "any" errors out on invalid references).

However, it looks like there are unrelated changes:

[...]
> diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
> index 24012534827..6b1230f2d7f 100644
> --- a/docs/devel/migration.rst
> +++ b/docs/devel/migration.rst
> @@ -403,8 +403,8 @@ version_id.  And the function ``load_state_old()`` (if 
> present) is able to
>  load state from minimum_version_id_old to minimum_version_id.  This
>  function is deprecated and will be removed when no more users are left.
>  
> -There are *_V* forms of many ``VMSTATE_`` macros to load fields for version 
> dependent fields,
> -e.g.
> +There are *_V* forms of many ``VMSTATE_`` macros to load fields for
> +version dependent fields, e.g.

Unrelated?  Line wrapping change only.

>  
>  .. code:: c
>  
> @@ -819,9 +819,9 @@ Postcopy now works with hugetlbfs backed memory:
>  Postcopy with shared memory
>  ---
>  
> -Postcopy migration with shared memory needs explicit support from the other
> -processes that share memory and from QEMU. There are restrictions on the 
> type of
> -memory that userfault can support shared.
> +Postcopy migration with shared memory needs explicit support from the
> +other processes that share memory and from QEMU. There are restrictions
> +on the type of memory that userfault can support shared.

Unrelated?  Line wrapping change only.

Reviewed-by: Eduardo Habkost   # if unrelated line 
wrapping changes are dropped

-- 
Eduardo




Re: [PATCH v2 2/6] iotests: add warning for rogue 'qemu' packages

2021-09-23 Thread Vladimir Sementsov-Ogievskiy

23.09.2021 21:07, John Snow wrote:

Add a warning for when 'iotests' runs against a qemu namespace that
isn't the one in the source tree. This might occur if you have
(accidentally) installed the Python namespace package to your local
packages.

(I'm not going to say that this is because I bit myself with this,
but you can fill in the blanks.)

In the future, we will pivot to always preferring a specific installed
instance of qemu python packages managed directly by iotests. For now
simply warn if there is an ambiguity over which instance that iotests
might use.

Example: If a user has navigated to ~/src/qemu/python and executed
`pip install .`, you will see output like this when running `./check`:

WARNING: 'qemu' python packages will be imported from outside the source tree 
('/home/jsnow/src/qemu/python')
  Importing instead from 
'/home/jsnow/.local/lib/python3.9/site-packages/qemu'

Signed-off-by: John Snow 
---
  tests/qemu-iotests/testenv.py | 24 
  1 file changed, 24 insertions(+)

diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 99a57a69f3a..1c0f6358538 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -16,6 +16,8 @@
  # along with this program.  If not, see .
  #
  
+import importlib.util

+import logging
  import os
  import sys
  import tempfile
@@ -112,6 +114,27 @@ def init_directories(self) -> None:
  # Path where qemu goodies live in this source tree.
  qemu_srctree_path = Path(__file__, '../../../python').resolve()
  
+# Warn if we happen to be able to find qemu namespace packages

+# (using qemu.qmp as a bellwether) from an unexpected location.
+# i.e. the package is already installed in the user's environment.
+try:
+qemu_spec = importlib.util.find_spec('qemu.qmp')
+except ModuleNotFoundError:
+qemu_spec = None
+
+if qemu_spec and qemu_spec.origin:
+spec_path = Path(qemu_spec.origin)
+try:
+_ = spec_path.relative_to(qemu_srctree_path)


It took some time and looking at specification trying to understand what's 
going on here :)

Could we just use:

if not Path(qemu_spec.origin).is_relative_to(qemu_srctree_path):
   ... logging ...



+except ValueError:
+self._logger.warning(
+"WARNING: 'qemu' python packages will be imported from"
+" outside the source tree ('%s')",
+qemu_srctree_path)
+self._logger.warning(
+" Importing instead from '%s'",
+spec_path.parents[1])
+


Also, I'd move this new chunk of code to a separate function (may be even out 
of class, as the only usage of self is self._logger, which you introduce with 
this patch. Still a method would be OK too). And then, just call it from 
__init__(). Just to keep init_directories() simpler. And with this new code we 
don't init any directories to pass to further test execution, it's just a check 
for runtime environment.


  self.pythonpath = os.pathsep.join(filter(None, (
  self.source_iotests,
  str(qemu_srctree_path),
@@ -230,6 +253,7 @@ def __init__(self, imgfmt: str, imgproto: str, aiomode: str,
  
  self.build_root = os.path.join(self.build_iotests, '..', '..')
  
+self._logger = logging.getLogger('qemu.iotests')

  self.init_directories()
  self.init_binaries()
  




--
Best regards,
Vladimir



Re: [PATCH v2 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread Peter Maydell
On Thu, 23 Sept 2021 at 19:22, John Snow  wrote:
>
> The single backtick markup in ReST is the "default role". Currently,
> Sphinx's default role is called "content". Sphinx suggests you can use
> the "Any" role instead to turn any single-backtick enclosed item into a
> cross-reference.
>
> This is useful for things like autodoc for Python docstrings, where it's
> often nicer to reference other types with `foo` instead of the more
> laborious :py:meth:`foo`. It's also useful in multi-domain cases to
> easily reference definitions from other Sphinx domains, such as
> referencing C code definitions from outside of kerneldoc comments.
>
> Before we do that, though, we'll need to turn all existing usages of the
> "content" role to inline verbatim markup wherever it does not correctly
> resolve into a cross-refernece by using double backticks instead.
>
> Signed-off-by: John Snow 

> diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
> index 2749bb9bed3..d5fe9314c65 100644
> --- a/docs/devel/fuzzing.rst
> +++ b/docs/devel/fuzzing.rst
> @@ -182,10 +182,11 @@ The output should contain a complete list of matched 
> MemoryRegions.
>
>  OSS-Fuzz
>  
> -QEMU is continuously fuzzed on `OSS-Fuzz` 
> __(https://github.com/google/oss-fuzz).
> -By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
> -generic-fuzz target requires additional information provided in environment
> -variables, we pre-define some generic-fuzz configs in
> +QEMU is continuously fuzzed on ``OSS-Fuzz``
> +__(https://github.com/google/oss-fuzz).  By default, the OSS-Fuzz build

This is supposed to be a link and I don't think it's intended to be
fixed-width font formatting, so I don't think this is the correct syntax fix.

> +will try to fuzz every fuzz-target. Since the generic-fuzz target
> +requires additional information provided in environment variables, we
> +pre-define some generic-fuzz configs in
>  ``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
>
>  - ``.name``: To identify the fuzzer config
> diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
> index 24012534827..6b1230f2d7f 100644
> --- a/docs/devel/migration.rst
> +++ b/docs/devel/migration.rst
> @@ -403,8 +403,8 @@ version_id.  And the function ``load_state_old()`` (if 
> present) is able to
>  load state from minimum_version_id_old to minimum_version_id.  This
>  function is deprecated and will be removed when no more users are left.
>
> -There are *_V* forms of many ``VMSTATE_`` macros to load fields for version 
> dependent fields,
> -e.g.
> +There are *_V* forms of many ``VMSTATE_`` macros to load fields for
> +version dependent fields, e.g.

This doesn't seem to be changing a `...` ?

>  .. code:: c
>
> @@ -819,9 +819,9 @@ Postcopy now works with hugetlbfs backed memory:
>  Postcopy with shared memory
>  ---
>
> -Postcopy migration with shared memory needs explicit support from the other
> -processes that share memory and from QEMU. There are restrictions on the 
> type of
> -memory that userfault can support shared.
> +Postcopy migration with shared memory needs explicit support from the
> +other processes that share memory and from QEMU. There are restrictions
> +on the type of memory that userfault can support shared.
>

This part doesn't seem to be changing any `...` use ?

The rest looks OK.

thanks
-- PMM



Re: [PATCH 6/6] ide: Rename ide_bus_new() to ide_bus_init()

2021-09-23 Thread John Snow
On Thu, Sep 23, 2021 at 8:12 AM Peter Maydell 
wrote:

> The function ide_bus_new() does an in-place initialization.  Rename
> it to ide_bus_init() to follow our _init vs _new convention.
>
> Signed-off-by: Peter Maydell 
> ---
>  include/hw/ide/internal.h | 4 ++--
>  hw/ide/ahci.c | 2 +-
>  hw/ide/cmd646.c   | 2 +-
>  hw/ide/isa.c  | 2 +-
>  hw/ide/macio.c| 2 +-
>  hw/ide/microdrive.c   | 2 +-
>  hw/ide/mmio.c | 2 +-
>  hw/ide/piix.c | 2 +-
>  hw/ide/qdev.c | 2 +-
>  hw/ide/sii3112.c  | 2 +-
>  hw/ide/via.c  | 2 +-
>  11 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
> index 79172217ccb..97e7e59dc58 100644
> --- a/include/hw/ide/internal.h
> +++ b/include/hw/ide/internal.h
> @@ -648,8 +648,8 @@ void ide_atapi_cmd(IDEState *s);
>  void ide_atapi_cmd_reply_end(IDEState *s);
>
>  /* hw/ide/qdev.c */
> -void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
> - int bus_id, int max_units);
> +void ide_bus_init(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
> +  int bus_id, int max_units);
>  IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
>
>  int ide_handle_rw_error(IDEState *s, int error, int op);
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index f2c51574839..a94c6e26fb0 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -1548,7 +1548,7 @@ void ahci_realize(AHCIState *s, DeviceState *qdev,
> AddressSpace *as, int ports)
>  for (i = 0; i < s->ports; i++) {
>  AHCIDevice *ad = >dev[i];
>
> -ide_bus_new(>port, sizeof(ad->port), qdev, i, 1);
> +ide_bus_init(>port, sizeof(ad->port), qdev, i, 1);
>  ide_init2(>port, irqs[i]);
>
>  ad->hba = s;
> diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
> index c2546314855..94c576262c1 100644
> --- a/hw/ide/cmd646.c
> +++ b/hw/ide/cmd646.c
> @@ -293,7 +293,7 @@ static void pci_cmd646_ide_realize(PCIDevice *dev,
> Error **errp)
>
>  qdev_init_gpio_in(ds, cmd646_set_irq, 2);
>  for (i = 0; i < 2; i++) {
> -ide_bus_new(>bus[i], sizeof(d->bus[i]), ds, i, 2);
> +ide_bus_init(>bus[i], sizeof(d->bus[i]), ds, i, 2);
>  ide_init2(>bus[i], qdev_get_gpio_in(ds, i));
>
>  bmdma_init(>bus[i], >bmdma[i], d);
> diff --git a/hw/ide/isa.c b/hw/ide/isa.c
> index 6bc19de2265..24bbde24c2b 100644
> --- a/hw/ide/isa.c
> +++ b/hw/ide/isa.c
> @@ -73,7 +73,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error
> **errp)
>  ISADevice *isadev = ISA_DEVICE(dev);
>  ISAIDEState *s = ISA_IDE(dev);
>
> -ide_bus_new(>bus, sizeof(s->bus), dev, 0, 2);
> +ide_bus_init(>bus, sizeof(s->bus), dev, 0, 2);
>  ide_init_ioport(>bus, isadev, s->iobase, s->iobase2);
>  isa_init_irq(isadev, >irq, s->isairq);
>  ide_init2(>bus, s->irq);
> diff --git a/hw/ide/macio.c b/hw/ide/macio.c
> index b270a101632..b03d401ceb5 100644
> --- a/hw/ide/macio.c
> +++ b/hw/ide/macio.c
> @@ -449,7 +449,7 @@ static void macio_ide_initfn(Object *obj)
>  SysBusDevice *d = SYS_BUS_DEVICE(obj);
>  MACIOIDEState *s = MACIO_IDE(obj);
>
> -ide_bus_new(>bus, sizeof(s->bus), DEVICE(obj), 0, 2);
> +ide_bus_init(>bus, sizeof(s->bus), DEVICE(obj), 0, 2);
>  memory_region_init_io(>mem, obj, _ide_ops, s, "pmac-ide",
> 0x1000);
>  sysbus_init_mmio(d, >mem);
>  sysbus_init_irq(d, >real_ide_irq);
> diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
> index 58a14fea363..6df9b4cbbe1 100644
> --- a/hw/ide/microdrive.c
> +++ b/hw/ide/microdrive.c
> @@ -605,7 +605,7 @@ static void microdrive_init(Object *obj)
>  {
>  MicroDriveState *md = MICRODRIVE(obj);
>
> -ide_bus_new(>bus, sizeof(md->bus), DEVICE(obj), 0, 1);
> +ide_bus_init(>bus, sizeof(md->bus), DEVICE(obj), 0, 1);
>  }
>
>  static void microdrive_class_init(ObjectClass *oc, void *data)
> diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
> index 36e2f4790ab..fb2ebd4847f 100644
> --- a/hw/ide/mmio.c
> +++ b/hw/ide/mmio.c
> @@ -142,7 +142,7 @@ static void mmio_ide_initfn(Object *obj)
>  SysBusDevice *d = SYS_BUS_DEVICE(obj);
>  MMIOState *s = MMIO_IDE(obj);
>
> -ide_bus_new(>bus, sizeof(s->bus), DEVICE(obj), 0, 2);
> +ide_bus_init(>bus, sizeof(s->bus), DEVICE(obj), 0, 2);
>  sysbus_init_irq(d, >irq);
>  }
>
> diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> index d3e738320be..ce89fd0aa36 100644
> --- a/hw/ide/piix.c
> +++ b/hw/ide/piix.c
> @@ -137,7 +137,7 @@ static int pci_piix_init_ports(PCIIDEState *d)
>  int i, ret;
>
>  for (i = 0; i < 2; i++) {
> -ide_bus_new(>bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
> +ide_bus_init(>bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
>  ret = ide_init_ioport(>bus[i], NULL, port_info[i].iobase,
>port_info[i].iobase2);
>  if (ret) {
> diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c

[PATCH v2 2/2] docs/sphinx: change default role to "any"

2021-09-23 Thread John Snow
This interprets single-backtick syntax in all of our Sphinx docs as a
cross-reference to *something*, including Python symbols.

>From here on out, new uses of `backticks` will cause a build failure if
the target cannot be referenced.

Signed-off-by: John Snow 
---
 docs/conf.py | 5 +
 1 file changed, 5 insertions(+)

diff --git a/docs/conf.py b/docs/conf.py
index ff6e92c6e2e..4d9f56601fc 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -85,6 +85,11 @@
 # The master toctree document.
 master_doc = 'index'
 
+# Interpret `single-backticks` to be a cross-reference to any kind of
+# referenceable object. Unresolvable or ambiguous references will emit a
+# warning at build time.
+default_role = 'any'
+
 # General information about the project.
 project = u'QEMU'
 copyright = u'2021, The QEMU Project Developers'
-- 
2.31.1




[PATCH v2 1/2] docs: remove non-reference uses of single backticks

2021-09-23 Thread John Snow
The single backtick markup in ReST is the "default role". Currently,
Sphinx's default role is called "content". Sphinx suggests you can use
the "Any" role instead to turn any single-backtick enclosed item into a
cross-reference.

This is useful for things like autodoc for Python docstrings, where it's
often nicer to reference other types with `foo` instead of the more
laborious :py:meth:`foo`. It's also useful in multi-domain cases to
easily reference definitions from other Sphinx domains, such as
referencing C code definitions from outside of kerneldoc comments.

Before we do that, though, we'll need to turn all existing usages of the
"content" role to inline verbatim markup wherever it does not correctly
resolve into a cross-refernece by using double backticks instead.

Signed-off-by: John Snow 
---
 docs/devel/fuzzing.rst |  9 +
 docs/devel/migration.rst   | 10 +-
 docs/devel/tcg-plugins.rst |  2 +-
 docs/interop/live-block-operations.rst |  2 +-
 docs/system/guest-loader.rst   |  2 +-
 qapi/block-core.json   |  4 ++--
 include/qemu/module.h  |  6 +++---
 qemu-options.hx|  4 ++--
 8 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/docs/devel/fuzzing.rst b/docs/devel/fuzzing.rst
index 2749bb9bed3..d5fe9314c65 100644
--- a/docs/devel/fuzzing.rst
+++ b/docs/devel/fuzzing.rst
@@ -182,10 +182,11 @@ The output should contain a complete list of matched 
MemoryRegions.
 
 OSS-Fuzz
 
-QEMU is continuously fuzzed on `OSS-Fuzz` 
__(https://github.com/google/oss-fuzz).
-By default, the OSS-Fuzz build will try to fuzz every fuzz-target. Since the
-generic-fuzz target requires additional information provided in environment
-variables, we pre-define some generic-fuzz configs in
+QEMU is continuously fuzzed on ``OSS-Fuzz``
+__(https://github.com/google/oss-fuzz).  By default, the OSS-Fuzz build
+will try to fuzz every fuzz-target. Since the generic-fuzz target
+requires additional information provided in environment variables, we
+pre-define some generic-fuzz configs in
 ``tests/qtest/fuzz/generic_fuzz_configs.h``. Each config must specify:
 
 - ``.name``: To identify the fuzzer config
diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
index 24012534827..6b1230f2d7f 100644
--- a/docs/devel/migration.rst
+++ b/docs/devel/migration.rst
@@ -403,8 +403,8 @@ version_id.  And the function ``load_state_old()`` (if 
present) is able to
 load state from minimum_version_id_old to minimum_version_id.  This
 function is deprecated and will be removed when no more users are left.
 
-There are *_V* forms of many ``VMSTATE_`` macros to load fields for version 
dependent fields,
-e.g.
+There are *_V* forms of many ``VMSTATE_`` macros to load fields for
+version dependent fields, e.g.
 
 .. code:: c
 
@@ -819,9 +819,9 @@ Postcopy now works with hugetlbfs backed memory:
 Postcopy with shared memory
 ---
 
-Postcopy migration with shared memory needs explicit support from the other
-processes that share memory and from QEMU. There are restrictions on the type 
of
-memory that userfault can support shared.
+Postcopy migration with shared memory needs explicit support from the
+other processes that share memory and from QEMU. There are restrictions
+on the type of memory that userfault can support shared.
 
 The Linux kernel userfault support works on ``/dev/shm`` memory and on 
``hugetlbfs``
 (although the kernel doesn't provide an equivalent to 
``madvise(MADV_DONTNEED)``
diff --git a/docs/devel/tcg-plugins.rst b/docs/devel/tcg-plugins.rst
index dac5101a3c9..8b187f8 100644
--- a/docs/devel/tcg-plugins.rst
+++ b/docs/devel/tcg-plugins.rst
@@ -212,7 +212,7 @@ The hotpages plugin can be configured using the following 
arguments:
 
 This is an instruction classifier so can be used to count different
 types of instructions. It has a number of options to refine which get
-counted. You can give a value to the `count` argument for a class of
+counted. You can give a value to the ``count`` argument for a class of
 instructions to break it down fully, so for example to see all the system
 registers accesses::
 
diff --git a/docs/interop/live-block-operations.rst 
b/docs/interop/live-block-operations.rst
index 9e3635b2338..814c29bbe1d 100644
--- a/docs/interop/live-block-operations.rst
+++ b/docs/interop/live-block-operations.rst
@@ -640,7 +640,7 @@ at this point:
 (QEMU) block-job-complete device=job0
 
 In either of the above cases, if you once again run the
-`query-block-jobs` command, there should not be any active block
+``query-block-jobs`` command, there should not be any active block
 operation.
 
 Comparing 'commit' and 'mirror': In both then cases, the overlay images
diff --git a/docs/system/guest-loader.rst b/docs/system/guest-loader.rst
index 4320d1183f7..9ef9776bf07 100644
--- a/docs/system/guest-loader.rst
+++ b/docs/system/guest-loader.rst
@@ 

[PATCH v2 0/2] docs/sphinx: change default `role` to "any"

2021-09-23 Thread John Snow
Rebased to not let the work done in removing erroneous references prior
to 6.1 regress.

John Snow (2):
  docs: remove non-reference uses of single backticks
  docs/sphinx: change default role to "any"

 docs/conf.py   |  5 +
 docs/devel/fuzzing.rst |  9 +
 docs/devel/migration.rst   | 10 +-
 docs/devel/tcg-plugins.rst |  2 +-
 docs/interop/live-block-operations.rst |  2 +-
 docs/system/guest-loader.rst   |  2 +-
 qapi/block-core.json   |  4 ++--
 include/qemu/module.h  |  6 +++---
 qemu-options.hx|  4 ++--
 9 files changed, 25 insertions(+), 19 deletions(-)

-- 
2.31.1





[PATCH v2 6/6] iotests: Update for pylint 2.11.1

2021-09-23 Thread John Snow
1. Ignore the new f-strings warning, we're not interested in doing a
   full conversion at this time.

2. Just mute the unbalanced-tuple-unpacking warning, it's not a real
   error in this case and muting the dozens of callsites is just not
   worth it.

3. Add encodings to read_text().

Signed-off-by: John Snow 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Kevin Wolf 
---
 tests/qemu-iotests/pylintrc  | 6 +-
 tests/qemu-iotests/testrunner.py | 7 ---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/tests/qemu-iotests/pylintrc b/tests/qemu-iotests/pylintrc
index f2c0b522ac0..8cb4e1d6a6d 100644
--- a/tests/qemu-iotests/pylintrc
+++ b/tests/qemu-iotests/pylintrc
@@ -19,13 +19,17 @@ disable=invalid-name,
 too-many-public-methods,
 # pylint warns about Optional[] etc. as unsubscriptable in 3.9
 unsubscriptable-object,
+# pylint's static analysis causes false positivies for file_path();
+# If we really care to make it statically knowable, we'll use mypy.
+unbalanced-tuple-unpacking,
 # Sometimes we need to disable a newly introduced pylint warning.
 # Doing so should not produce a warning in older versions of pylint.
 bad-option-value,
 # These are temporary, and should be removed:
 missing-docstring,
 too-many-return-statements,
-too-many-statements
+too-many-statements,
+consider-using-f-string,
 
 [FORMAT]
 
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index 4a6ec421ed6..a56b6da3968 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -266,12 +266,13 @@ def do_run_test(self, test: str) -> TestResult:
   diff=file_diff(str(f_reference), str(f_bad)))
 
 if f_notrun.exists():
-return TestResult(status='not run',
-  description=f_notrun.read_text().strip())
+return TestResult(
+status='not run',
+description=f_notrun.read_text(encoding='utf-8').strip())
 
 casenotrun = ''
 if f_casenotrun.exists():
-casenotrun = f_casenotrun.read_text()
+casenotrun = f_casenotrun.read_text(encoding='utf-8')
 
 diff = file_diff(str(f_reference), str(f_bad))
 if diff:
-- 
2.31.1




[PATCH v2 2/6] iotests: add warning for rogue 'qemu' packages

2021-09-23 Thread John Snow
Add a warning for when 'iotests' runs against a qemu namespace that
isn't the one in the source tree. This might occur if you have
(accidentally) installed the Python namespace package to your local
packages.

(I'm not going to say that this is because I bit myself with this,
but you can fill in the blanks.)

In the future, we will pivot to always preferring a specific installed
instance of qemu python packages managed directly by iotests. For now
simply warn if there is an ambiguity over which instance that iotests
might use.

Example: If a user has navigated to ~/src/qemu/python and executed
`pip install .`, you will see output like this when running `./check`:

WARNING: 'qemu' python packages will be imported from outside the source tree 
('/home/jsnow/src/qemu/python')
 Importing instead from 
'/home/jsnow/.local/lib/python3.9/site-packages/qemu'

Signed-off-by: John Snow 
---
 tests/qemu-iotests/testenv.py | 24 
 1 file changed, 24 insertions(+)

diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 99a57a69f3a..1c0f6358538 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -16,6 +16,8 @@
 # along with this program.  If not, see .
 #
 
+import importlib.util
+import logging
 import os
 import sys
 import tempfile
@@ -112,6 +114,27 @@ def init_directories(self) -> None:
 # Path where qemu goodies live in this source tree.
 qemu_srctree_path = Path(__file__, '../../../python').resolve()
 
+# Warn if we happen to be able to find qemu namespace packages
+# (using qemu.qmp as a bellwether) from an unexpected location.
+# i.e. the package is already installed in the user's environment.
+try:
+qemu_spec = importlib.util.find_spec('qemu.qmp')
+except ModuleNotFoundError:
+qemu_spec = None
+
+if qemu_spec and qemu_spec.origin:
+spec_path = Path(qemu_spec.origin)
+try:
+_ = spec_path.relative_to(qemu_srctree_path)
+except ValueError:
+self._logger.warning(
+"WARNING: 'qemu' python packages will be imported from"
+" outside the source tree ('%s')",
+qemu_srctree_path)
+self._logger.warning(
+" Importing instead from '%s'",
+spec_path.parents[1])
+
 self.pythonpath = os.pathsep.join(filter(None, (
 self.source_iotests,
 str(qemu_srctree_path),
@@ -230,6 +253,7 @@ def __init__(self, imgfmt: str, imgproto: str, aiomode: str,
 
 self.build_root = os.path.join(self.build_iotests, '..', '..')
 
+self._logger = logging.getLogger('qemu.iotests')
 self.init_directories()
 self.init_binaries()
 
-- 
2.31.1




[PATCH v2 1/6] iotests: add 'qemu' package location to PYTHONPATH in testenv

2021-09-23 Thread John Snow
We can drop the sys.path hacking in various places by doing
this. Additionally, by doing it in one place right up top, we can print
interesting warnings in case the environment does not look correct. (See
next commit.)

If we ever decide to change how the environment is crafted, all of the
"help me find my python packages" goop is all in one place, right in one
function.

Signed-off-by: John Snow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Kevin Wolf 
---
 tests/qemu-iotests/235|  2 --
 tests/qemu-iotests/297|  6 --
 tests/qemu-iotests/300|  7 +++
 tests/qemu-iotests/iotests.py |  2 --
 tests/qemu-iotests/testenv.py | 15 +--
 tests/qemu-iotests/tests/mirror-top-perms |  7 +++
 6 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/tests/qemu-iotests/235 b/tests/qemu-iotests/235
index 8aed45f9a76..4de920c3801 100755
--- a/tests/qemu-iotests/235
+++ b/tests/qemu-iotests/235
@@ -24,8 +24,6 @@ import os
 import iotests
 from iotests import qemu_img_create, qemu_io, file_path, log
 
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
-
 from qemu.machine import QEMUMachine
 
 iotests.script_initialize(supported_fmts=['qcow2'])
diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index b04cba53667..467b712280e 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -68,12 +68,6 @@ def run_linters():
 # Todo notes are fine, but fixme's or xxx's should probably just be
 # fixed (in tests, at least)
 env = os.environ.copy()
-qemu_module_path = os.path.join(os.path.dirname(__file__),
-'..', '..', 'python')
-try:
-env['PYTHONPATH'] += os.pathsep + qemu_module_path
-except KeyError:
-env['PYTHONPATH'] = qemu_module_path
 subprocess.run(('pylint-3', '--score=n', '--notes=FIXME,XXX', *files),
env=env, check=False)
 
diff --git a/tests/qemu-iotests/300 b/tests/qemu-iotests/300
index fe94de84edd..10f9f2a8da6 100755
--- a/tests/qemu-iotests/300
+++ b/tests/qemu-iotests/300
@@ -24,12 +24,11 @@ import random
 import re
 from typing import Dict, List, Optional
 
-import iotests
-
-# Import qemu after iotests.py has amended sys.path
-# pylint: disable=wrong-import-order
 from qemu.machine import machine
 
+import iotests
+
+
 BlockBitmapMapping = List[Dict[str, object]]
 
 mig_sock = os.path.join(iotests.sock_dir, 'mig_sock')
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index ce06cf56304..b06ad76e0c5 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -36,8 +36,6 @@
 
 from contextlib import contextmanager
 
-# pylint: disable=import-error, wrong-import-position
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
 from qemu.machine import qtest
 from qemu.qmp import QMPMessage
 
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 70da0d60c80..99a57a69f3a 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -108,12 +108,15 @@ def init_directories(self) -> None:
  SAMPLE_IMG_DIR
  OUTPUT_DIR
 """
-self.pythonpath = os.getenv('PYTHONPATH')
-if self.pythonpath:
-self.pythonpath = self.source_iotests + os.pathsep + \
-self.pythonpath
-else:
-self.pythonpath = self.source_iotests
+
+# Path where qemu goodies live in this source tree.
+qemu_srctree_path = Path(__file__, '../../../python').resolve()
+
+self.pythonpath = os.pathsep.join(filter(None, (
+self.source_iotests,
+str(qemu_srctree_path),
+os.getenv('PYTHONPATH'),
+)))
 
 self.test_dir = os.getenv('TEST_DIR',
   os.path.join(os.getcwd(), 'scratch'))
diff --git a/tests/qemu-iotests/tests/mirror-top-perms 
b/tests/qemu-iotests/tests/mirror-top-perms
index 2fc8dd66e0a..73138a0ef91 100755
--- a/tests/qemu-iotests/tests/mirror-top-perms
+++ b/tests/qemu-iotests/tests/mirror-top-perms
@@ -20,13 +20,12 @@
 #
 
 import os
+
+import qemu
+
 import iotests
 from iotests import qemu_img
 
-# Import qemu after iotests.py has amended sys.path
-# pylint: disable=wrong-import-order
-import qemu
-
 
 image_size = 1 * 1024 * 1024
 source = os.path.join(iotests.test_dir, 'source.img')
-- 
2.31.1




[PATCH v2 5/6] iotests/migrate-bitmaps-test: delint

2021-09-23 Thread John Snow
Mostly uninteresting stuff. Move the test injections under a function
named main() so that the variables used during that process aren't in
the global scope.

Signed-off-by: John Snow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Hanna Reitz 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Kevin Wolf 
---
 tests/qemu-iotests/tests/migrate-bitmaps-test | 50 +++
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-test 
b/tests/qemu-iotests/tests/migrate-bitmaps-test
index dc431c35b35..c23df3d75c7 100755
--- a/tests/qemu-iotests/tests/migrate-bitmaps-test
+++ b/tests/qemu-iotests/tests/migrate-bitmaps-test
@@ -19,10 +19,11 @@
 # along with this program.  If not, see .
 #
 
-import os
 import itertools
 import operator
+import os
 import re
+
 import iotests
 from iotests import qemu_img, qemu_img_create, Timeout
 
@@ -224,25 +225,6 @@ def inject_test_case(klass, suffix, method, *args, 
**kwargs):
 setattr(klass, 'test_' + method + suffix, lambda self: mc(self))
 
 
-for cmb in list(itertools.product((True, False), repeat=5)):
-name = ('_' if cmb[0] else '_not_') + 'persistent_'
-name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
-name += '_online' if cmb[2] else '_offline'
-name += '_shared' if cmb[3] else '_nonshared'
-if cmb[4]:
-name += '__pre_shutdown'
-
-inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
- *list(cmb))
-
-for cmb in list(itertools.product((True, False), repeat=2)):
-name = ('_' if cmb[0] else '_not_') + 'persistent_'
-name += ('_' if cmb[1] else '_not_') + 'migbitmap'
-
-inject_test_case(TestDirtyBitmapMigration, name,
- 'do_test_migration_resume_source', *list(cmb))
-
-
 class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
 def setUp(self):
 qemu_img_create('-f', iotests.imgfmt, base_a, size)
@@ -304,6 +286,30 @@ class TestDirtyBitmapBackingMigration(iotests.QMPTestCase):
 self.assert_qmp(result, 'return', {})
 
 
+def main() -> None:
+for cmb in list(itertools.product((True, False), repeat=5)):
+name = ('_' if cmb[0] else '_not_') + 'persistent_'
+name += ('_' if cmb[1] else '_not_') + 'migbitmap_'
+name += '_online' if cmb[2] else '_offline'
+name += '_shared' if cmb[3] else '_nonshared'
+if cmb[4]:
+name += '__pre_shutdown'
+
+inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration',
+ *list(cmb))
+
+for cmb in list(itertools.product((True, False), repeat=2)):
+name = ('_' if cmb[0] else '_not_') + 'persistent_'
+name += ('_' if cmb[1] else '_not_') + 'migbitmap'
+
+inject_test_case(TestDirtyBitmapMigration, name,
+ 'do_test_migration_resume_source', *list(cmb))
+
+iotests.main(
+supported_fmts=['qcow2'],
+supported_protocols=['file']
+)
+
+
 if __name__ == '__main__':
-iotests.main(supported_fmts=['qcow2'],
- supported_protocols=['file'])
+main()
-- 
2.31.1




[PATCH v2 0/6] iotests: update environment and linting configuration

2021-09-23 Thread John Snow
GitLab: https://gitlab.com/jsnow/qemu/-/commits/python-package-iotest-pt1
CI: https://gitlab.com/jsnow/qemu/-/pipelines/376236687

This series partially supersedes:
  [PATCH v3 00/16] python/iotests: Run iotest linters during Python CI'

Howdy, this is good stuff we want even if we aren't yet in agreement
about the best way to run iotest 297 from CI.

- Update linting config to tolerate pylint 2.11.1
- Eliminate sys.path hacking in individual test files
- make mypy execution in test 297 faster

The rest of the actual "run at CI time" stuff can get handled separately
and later pending some discussion on the other series.

V2:

001/6:[0011] [FC] 'iotests: add 'qemu' package location to PYTHONPATH in 
testenv'
002/6:[0025] [FC] 'iotests: add warning for rogue 'qemu' packages'

- Squashed in a small optimization from Vladimir to 001, kept R-Bs.
- Fixed the package detection logic to not panic if it can't find
  'qemu' at all (kwolf)
- Updated commit messages for the first two patches.

--js

John Snow (6):
  iotests: add 'qemu' package location to PYTHONPATH in testenv
  iotests: add warning for rogue 'qemu' packages
  iotests/linters: check mypy files all at once
  iotests/mirror-top-perms: Adjust imports
  iotests/migrate-bitmaps-test: delint
  iotests: Update for pylint 2.11.1

 tests/qemu-iotests/235|  2 -
 tests/qemu-iotests/297| 50 ---
 tests/qemu-iotests/300|  7 ++-
 tests/qemu-iotests/iotests.py |  2 -
 tests/qemu-iotests/pylintrc   |  6 ++-
 tests/qemu-iotests/testenv.py | 39 ---
 tests/qemu-iotests/testrunner.py  |  7 +--
 tests/qemu-iotests/tests/migrate-bitmaps-test | 50 +++
 tests/qemu-iotests/tests/mirror-top-perms | 12 ++---
 9 files changed, 99 insertions(+), 76 deletions(-)

-- 
2.31.1





[PATCH v2 3/6] iotests/linters: check mypy files all at once

2021-09-23 Thread John Snow
We can circumvent the '__main__' redefinition problem by passing
--scripts-are-modules. Take mypy out of the loop per-filename and check
everything in one go: it's quite a bit faster.

Signed-off-by: John Snow 
Reviewed-by: Hanna Reitz 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Kevin Wolf 
---
 tests/qemu-iotests/297 | 44 +++---
 1 file changed, 20 insertions(+), 24 deletions(-)

diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index 467b712280e..91ec34d9521 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -74,32 +74,28 @@ def run_linters():
 print('=== mypy ===')
 sys.stdout.flush()
 
-# We have to call mypy separately for each file.  Otherwise, it
-# will interpret all given files as belonging together (i.e., they
-# may not both define the same classes, etc.; most notably, they
-# must not both define the __main__ module).
 env['MYPYPATH'] = env['PYTHONPATH']
-for filename in files:
-p = subprocess.run(('mypy',
-'--warn-unused-configs',
-'--disallow-subclassing-any',
-'--disallow-any-generics',
-'--disallow-incomplete-defs',
-'--disallow-untyped-decorators',
-'--no-implicit-optional',
-'--warn-redundant-casts',
-'--warn-unused-ignores',
-'--no-implicit-reexport',
-'--namespace-packages',
-filename),
-   env=env,
-   check=False,
-   stdout=subprocess.PIPE,
-   stderr=subprocess.STDOUT,
-   universal_newlines=True)
+p = subprocess.run(('mypy',
+'--warn-unused-configs',
+'--disallow-subclassing-any',
+'--disallow-any-generics',
+'--disallow-incomplete-defs',
+'--disallow-untyped-decorators',
+'--no-implicit-optional',
+'--warn-redundant-casts',
+'--warn-unused-ignores',
+'--no-implicit-reexport',
+'--namespace-packages',
+'--scripts-are-modules',
+*files),
+   env=env,
+   check=False,
+   stdout=subprocess.PIPE,
+   stderr=subprocess.STDOUT,
+   universal_newlines=True)
 
-if p.returncode != 0:
-print(p.stdout)
+if p.returncode != 0:
+print(p.stdout)
 
 
 for linter in ('pylint-3', 'mypy'):
-- 
2.31.1




Re: [PATCH v5 01/31] target/arm: Implement arm_v7m_cpu_has_work()

2021-09-23 Thread Philippe Mathieu-Daudé

On 9/23/21 20:01, Peter Maydell wrote:

On Thu, 23 Sept 2021 at 18:17, Philippe Mathieu-Daudé  wrote:

Since we provide info->class_init as arm_v7m_class_init(), only
tcg_ops and gdb_core_xml_file from CPUClass are set:

static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
  ARMCPUClass *acc = ARM_CPU_CLASS(oc);
  CPUClass *cc = CPU_CLASS(oc);

  acc->info = data;
#ifdef CONFIG_TCG
  cc->tcg_ops = _v7m_tcg_ops;
#endif /* CONFIG_TCG */

  cc->gdb_core_xml_file = "arm-m-profile.xml";
}


This class's parent type is TYPE_ARM_CPU; so TYPE_ARM_CPU's class_init
runs first and sets up most of the class fields. This function only
needs to set the ones which must be different on a M-profile core.


Of course... Thanks!



[PATCH v2 4/6] iotests/mirror-top-perms: Adjust imports

2021-09-23 Thread John Snow
We need to import subpackages from the qemu namespace package; importing
the namespace package alone doesn't bring the subpackages with it --
unless someone else (like iotests.py) imports them too.

Adjust the imports.

Signed-off-by: John Snow 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Hanna Reitz 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Kevin Wolf 
---
 tests/qemu-iotests/tests/mirror-top-perms | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/tests/mirror-top-perms 
b/tests/qemu-iotests/tests/mirror-top-perms
index 73138a0ef91..3d475aa3a54 100755
--- a/tests/qemu-iotests/tests/mirror-top-perms
+++ b/tests/qemu-iotests/tests/mirror-top-perms
@@ -21,7 +21,8 @@
 
 import os
 
-import qemu
+from qemu import qmp
+from qemu.machine import machine
 
 import iotests
 from iotests import qemu_img
@@ -46,7 +47,7 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
 def tearDown(self):
 try:
 self.vm.shutdown()
-except qemu.machine.machine.AbnormalShutdown:
+except machine.AbnormalShutdown:
 pass
 
 if self.vm_b is not None:
@@ -101,7 +102,7 @@ class TestMirrorTopPerms(iotests.QMPTestCase):
 self.vm_b.launch()
 print('ERROR: VM B launched successfully, this should not have '
   'happened')
-except qemu.qmp.QMPConnectError:
+except qmp.QMPConnectError:
 assert 'Is another process using the image' in self.vm_b.get_log()
 
 result = self.vm.qmp('block-job-cancel',
-- 
2.31.1




Re: [PATCH v5 01/31] target/arm: Implement arm_v7m_cpu_has_work()

2021-09-23 Thread Peter Maydell
On Thu, 23 Sept 2021 at 18:17, Philippe Mathieu-Daudé  wrote:
> Since we provide info->class_init as arm_v7m_class_init(), only
> tcg_ops and gdb_core_xml_file from CPUClass are set:
>
> static void arm_v7m_class_init(ObjectClass *oc, void *data)
> {
>  ARMCPUClass *acc = ARM_CPU_CLASS(oc);
>  CPUClass *cc = CPU_CLASS(oc);
>
>  acc->info = data;
> #ifdef CONFIG_TCG
>  cc->tcg_ops = _v7m_tcg_ops;
> #endif /* CONFIG_TCG */
>
>  cc->gdb_core_xml_file = "arm-m-profile.xml";
> }

This class's parent type is TYPE_ARM_CPU; so TYPE_ARM_CPU's class_init
runs first and sets up most of the class fields. This function only
needs to set the ones which must be different on a M-profile core.

-- PMM



Re: [PATCH v4 02/30] MAINTAINERS: Add tcg/loongarch64 entry with myself as maintainer

2021-09-23 Thread Philippe Mathieu-Daudé

On 9/23/21 18:59, WANG Xuerui wrote:

I ported the initial code, so I should maintain it of course.

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
  MAINTAINERS | 5 +
  1 file changed, 5 insertions(+)


Welcome ;)

Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v5 05/31] sysemu: Introduce AccelOpsClass::has_work()

2021-09-23 Thread Philippe Mathieu-Daudé

On 9/20/21 23:58, Richard Henderson wrote:

On 9/20/21 2:44 PM, Philippe Mathieu-Daudé wrote:

-    g_assert(cc->has_work);
-    return cc->has_work(cpu);
+    if (cc->has_work) {
+    return cc->has_work(cpu);
+    }
+    if (cpus_accel->has_work) {
+    return cpus_accel->has_work(cpu);
+    }
+    g_assert_not_reached();


This might be close to the end result, but it isn't what we begin with 
in cpu_thread_is_idle.


You'd want

     if (cc->has_work && cc->has_work(cpu)) {
     return true;
     }
     if (cpus_accel->has_work && cpus_accel->has_work(cpu)) {
     return true;
     }
     return false;

to start.  After the cpus_accel hook is filled in you can assert and 
return from cpus_accel->has_work.  And of course after cc->has_work is 
removed, that clause is gone.


Much cleaner, thank you for the hints :)



[PATCH v4 27/30] tcg/loongarch64: Register the JIT

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 44 
 1 file changed, 44 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 83b8bcdfdf..bce03a96d7 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1594,3 +1594,47 @@ static void tcg_target_init(TCGContext *s)
 tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
 tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
 }
+
+typedef struct {
+DebugFrameHeader h;
+uint8_t fde_def_cfa[4];
+uint8_t fde_reg_ofs[ARRAY_SIZE(tcg_target_callee_save_regs) * 2];
+} DebugFrame;
+
+#define ELF_HOST_MACHINE EM_LOONGARCH
+
+static const DebugFrame debug_frame = {
+.h.cie.len = sizeof(DebugFrameCIE) - 4, /* length after .len member */
+.h.cie.id = -1,
+.h.cie.version = 1,
+.h.cie.code_align = 1,
+.h.cie.data_align = -(TCG_TARGET_REG_BITS / 8) & 0x7f, /* sleb128 */
+.h.cie.return_column = TCG_REG_RA,
+
+/* Total FDE size does not include the "len" member.  */
+.h.fde.len = sizeof(DebugFrame) - offsetof(DebugFrame, h.fde.cie_offset),
+
+.fde_def_cfa = {
+12, TCG_REG_SP, /* DW_CFA_def_cfa sp, ...  */
+(FRAME_SIZE & 0x7f) | 0x80, /* ... uleb128 FRAME_SIZE */
+(FRAME_SIZE >> 7)
+},
+.fde_reg_ofs = {
+0x80 + 23, 11,  /* DW_CFA_offset, s0, -88 */
+0x80 + 24, 10,  /* DW_CFA_offset, s1, -80 */
+0x80 + 25, 9,   /* DW_CFA_offset, s2, -72 */
+0x80 + 26, 8,   /* DW_CFA_offset, s3, -64 */
+0x80 + 27, 7,   /* DW_CFA_offset, s4, -56 */
+0x80 + 28, 6,   /* DW_CFA_offset, s5, -48 */
+0x80 + 29, 5,   /* DW_CFA_offset, s6, -40 */
+0x80 + 30, 4,   /* DW_CFA_offset, s7, -32 */
+0x80 + 31, 3,   /* DW_CFA_offset, s8, -24 */
+0x80 + 22, 2,   /* DW_CFA_offset, s9, -16 */
+0x80 + 1 , 1,   /* DW_CFA_offset, ra, -8 */
+}
+};
+
+void tcg_register_jit(const void *buf, size_t buf_size)
+{
+tcg_register_jit_int(buf, buf_size, _frame, sizeof(debug_frame));
+}
-- 
2.33.0




[PATCH v4 26/30] tcg/loongarch64: Implement tcg_target_init

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index e09bf832bd..83b8bcdfdf 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1567,3 +1567,30 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
 tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0);
 }
+
+static void tcg_target_init(TCGContext *s)
+{
+tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
+tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
+
+tcg_target_call_clobber_regs = ALL_GENERAL_REGS;
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S3);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S4);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S5);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S6);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S7);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S8);
+tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S9);
+
+s->reserved_regs = 0;
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_ZERO);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP0);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP1);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TMP2);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
+tcg_regset_set_reg(s->reserved_regs, TCG_REG_RESERVED);
+}
-- 
2.33.0




Re: [PATCH v5 08/31] accel/tcg: Implement AccelOpsClass::has_work() as stub

2021-09-23 Thread Philippe Mathieu-Daudé

On 9/21/21 00:01, Richard Henderson wrote:

On 9/20/21 2:44 PM, Philippe Mathieu-Daudé wrote:

+static bool tcg_cpu_has_work(CPUState *cpu)
+{
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    g_assert(cc->tcg_ops->has_work);
+    return cc->tcg_ops->has_work(cpu);
+}


Now, you're expecting cc->has_work to disappear as cc->tcg_ops->has_work 
appears.  If we're expecting cc->has_work to not affect other 
accelerators, then I think you should first move cc->has_work to this 
function, *before* you add the tcg_ops hook.


Indeed, thanks.



[PATCH v4 24/30] tcg/loongarch64: Implement tcg_target_qemu_prologue

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 68 
 1 file changed, 68 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 09ec560a72..3cf9a4924b 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -931,6 +931,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg 
*args)
  * Entry-points
  */
 
+static const tcg_insn_unit *tb_ret_addr;
+
 static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const TCGArg args[TCG_MAX_OP_ARGS],
const int const_args[TCG_MAX_OP_ARGS])
@@ -1480,3 +1482,69 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 g_assert_not_reached();
 }
 }
+
+static const int tcg_target_callee_save_regs[] = {
+TCG_REG_S0, /* used for the global env (TCG_AREG0) */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+TCG_REG_RA, /* should be last for ABI compliance */
+};
+
+/* Stack frame parameters.  */
+#define REG_SIZE   (TCG_TARGET_REG_BITS / 8)
+#define SAVE_SIZE  ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZE)
+#define TEMP_SIZE  (CPU_TEMP_BUF_NLONGS * (int)sizeof(long))
+#define FRAME_SIZE ((TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE + SAVE_SIZE \
+ + TCG_TARGET_STACK_ALIGN - 1) \
+& -TCG_TARGET_STACK_ALIGN)
+#define SAVE_OFS   (TCG_STATIC_CALL_ARGS_SIZE + TEMP_SIZE)
+
+/* We're expecting to be able to use an immediate for frame allocation.  */
+QEMU_BUILD_BUG_ON(FRAME_SIZE > 0x7ff);
+
+/* Generate global QEMU prologue and epilogue code */
+static void tcg_target_qemu_prologue(TCGContext *s)
+{
+int i;
+
+tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE, TEMP_SIZE);
+
+/* TB prologue */
+tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, -FRAME_SIZE);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_st(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+#if !defined(CONFIG_SOFTMMU)
+if (USE_GUEST_BASE) {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, guest_base);
+tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+}
+#endif
+
+/* Call generated code */
+tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+tcg_out_opc_jirl(s, TCG_REG_ZERO, tcg_target_call_iarg_regs[1], 0);
+
+/* Return path for goto_ptr. Set return value to 0 */
+tcg_code_gen_epilogue = tcg_splitwx_to_rx(s->code_ptr);
+tcg_out_mov(s, TCG_TYPE_REG, TCG_REG_A0, TCG_REG_ZERO);
+
+/* TB epilogue */
+tb_ret_addr = tcg_splitwx_to_rx(s->code_ptr);
+for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+tcg_out_ld(s, TCG_TYPE_REG, tcg_target_callee_save_regs[i],
+   TCG_REG_SP, SAVE_OFS + i * REG_SIZE);
+}
+
+tcg_out_opc_addi_d(s, TCG_REG_SP, TCG_REG_SP, FRAME_SIZE);
+tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_RA, 0);
+}
-- 
2.33.0




Re: [PATCH v5 01/31] target/arm: Implement arm_v7m_cpu_has_work()

2021-09-23 Thread Philippe Mathieu-Daudé

Hi Peter,

On 9/21/21 11:45, Philippe Mathieu-Daudé wrote:

On 9/21/21 11:34, Peter Maydell wrote:
On Mon, 20 Sept 2021 at 22:44, Philippe Mathieu-Daudé 
 wrote:


Implement SysemuCPUOps::has_work() handler for the ARM v7M CPU.

See the comments added in commit 7ecdaa4a963 ("armv7m: Fix
condition check for taking exceptions") which eventually
forgot to implement this has_work() handler:


Huh? M-profile and A-profile share the same arm_cpu_has_work()
function. Some of the checks the code there does are perhaps
unnecessary for M-profile, but they're harmless.


A v7M core is registered as (example for Cortex-M0):

static const ARMCPUInfo arm_tcg_cpus[] = {
...
{ .name = "cortex-m0",   .initfn = cortex_m0_initfn,
 .class_init = arm_v7m_class_init },


static void arm_tcg_cpu_register_types(void)
{
...
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
arm_cpu_register(_tcg_cpus[i]);


void arm_cpu_register(const ARMCPUInfo *info)
{
TypeInfo type_info = {
.parent = TYPE_ARM_CPU,
.instance_size = sizeof(ARMCPU),
.instance_align = __alignof__(ARMCPU),
.instance_init = arm_cpu_instance_init,
.class_size = sizeof(ARMCPUClass),
.class_init = info->class_init ?: cpu_register_class_init,
.class_data = (void *)info,
};

Since we provide info->class_init as arm_v7m_class_init(), only
tcg_ops and gdb_core_xml_file from CPUClass are set:

static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
ARMCPUClass *acc = ARM_CPU_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);

acc->info = data;
#ifdef CONFIG_TCG
cc->tcg_ops = _v7m_tcg_ops;
#endif /* CONFIG_TCG */

cc->gdb_core_xml_file = "arm-m-profile.xml";
}

Thus v7M cores end calling cpu_common_has_work() registered by
cpu_class_init(), which is:

static bool cpu_common_has_work(CPUState *cs)
{
return false;
}

What am I missing?




   * ARMv7-M interrupt masking works differently than -A or -R.
   * There is no FIQ/IRQ distinction.

The NVIC signal any pending interrupt by raising ARM_CPU_IRQ
(see commit 56b7c66f498: "armv7m: QOMify the armv7m container")
which ends setting the CPU_INTERRUPT_HARD bit in interrupt_request.

Thus arm_v7m_cpu_has_work() implementation is thus quite trivial,
we simply need to check for this bit.

Cc: Peter Maydell 
Cc: Michael Davidsaver 
Signed-off-by: Philippe Mathieu-Daudé 
---
  target/arm/cpu_tcg.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0d5adccf1a7..da348938407 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -23,6 +23,11 @@
  #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)

  #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
+static bool arm_v7m_cpu_has_work(CPUState *cs)
+{
+    return cs->interrupt_request & CPU_INTERRUPT_HARD;
+}


This seems to be missing at least the check on
cpu->power_state and the CPU_INTERRUPT_EXITTB test.

Is there any reason why we shouldn't just continue to
share the same function between A and M profile, and avoid
the extra function and the ifdefs ?


The only reason I can think of is I should have been resting
instead of posting this patch :/ I'll re-use arm_cpu_has_work()
which is, as you said, harmless and safer.





[PATCH v4 23/30] tcg/loongarch64: Add softmmu load/store helpers, implement qemu_ld/qemu_st ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
---
 tcg/loongarch64/tcg-target-con-set.h |   2 +
 tcg/loongarch64/tcg-target.c.inc | 342 +++
 2 files changed, 344 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index e54ca9b2de..349c672687 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -17,7 +17,9 @@
 C_O0_I1(r)
 C_O0_I2(rZ, r)
 C_O0_I2(rZ, rZ)
+C_O0_I2(LZ, L)
 C_O1_I1(r, r)
+C_O1_I1(r, L)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rI)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 1f6bad95ce..09ec560a72 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -117,6 +117,11 @@ static const int tcg_target_call_oarg_regs[] = {
 TCG_REG_A1,
 };
 
+#ifndef CONFIG_SOFTMMU
+#define USE_GUEST_BASE (guest_base != 0)
+#define TCG_GUEST_BASE_REG TCG_REG_S1
+#endif
+
 #define TCG_CT_CONST_ZERO  0x100
 #define TCG_CT_CONST_S12   0x200
 #define TCG_CT_CONST_N12   0x400
@@ -606,6 +611,322 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
TCGArg val,
 return false;
 }
 
+/*
+ * Load/store helpers for SoftMMU, and qemu_ld/st implementations
+ */
+
+#if defined(CONFIG_SOFTMMU)
+#include "../tcg-ldst.c.inc"
+
+/*
+ * helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ * TCGMemOpIdx oi, uintptr_t ra)
+ */
+static void * const qemu_ld_helpers[4] = {
+[MO_8]  = helper_ret_ldub_mmu,
+[MO_16] = helper_le_lduw_mmu,
+[MO_32] = helper_le_ldul_mmu,
+[MO_64] = helper_le_ldq_mmu,
+};
+
+/*
+ * helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ * uintxx_t val, TCGMemOpIdx oi,
+ * uintptr_t ra)
+ */
+static void * const qemu_st_helpers[4] = {
+[MO_8]  = helper_ret_stb_mmu,
+[MO_16] = helper_le_stw_mmu,
+[MO_32] = helper_le_stl_mmu,
+[MO_64] = helper_le_stq_mmu,
+};
+
+/* We expect to use a 12-bit negative offset from ENV.  */
+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0);
+QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11));
+
+static bool tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
+{
+tcg_out_opc_b(s, 0);
+return reloc_br_sd10k16(s->code_ptr - 1, target);
+}
+
+static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, TCGMemOpIdx oi,
+ tcg_insn_unit **label_ptr, bool is_load)
+{
+MemOp opc = get_memop(oi);
+unsigned s_bits = opc & MO_SIZE;
+unsigned a_bits = get_alignment_bits(opc);
+tcg_target_long compare_mask;
+int mem_index = get_mmuidx(oi);
+int fast_ofs = TLB_MASK_TABLE_OFS(mem_index);
+int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask);
+int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table);
+
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
+
+tcg_out_opc_srli_d(s, TCG_REG_TMP2, addrl,
+TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+tcg_out_opc_and(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP0);
+tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, TCG_REG_TMP1);
+
+/* Load the tlb comparator and the addend.  */
+tcg_out_ld(s, TCG_TYPE_TL, TCG_REG_TMP0, TCG_REG_TMP2,
+   is_load ? offsetof(CPUTLBEntry, addr_read)
+   : offsetof(CPUTLBEntry, addr_write));
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP2, TCG_REG_TMP2,
+   offsetof(CPUTLBEntry, addend));
+
+/* We don't support unaligned accesses.  */
+if (a_bits < s_bits) {
+a_bits = s_bits;
+}
+/* Clear the non-page, non-alignment bits from the address.  */
+compare_mask = (tcg_target_long)TARGET_PAGE_MASK | ((1 << a_bits) - 1);
+tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_TMP1, compare_mask);
+tcg_out_opc_and(s, TCG_REG_TMP1, TCG_REG_TMP1, addrl);
+
+/* Compare masked address with the TLB entry.  */
+label_ptr[0] = s->code_ptr;
+tcg_out_opc_bne(s, TCG_REG_TMP0, TCG_REG_TMP1, 0);
+
+/* TLB Hit - translate address using addend.  */
+if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+tcg_out_ext32u(s, TCG_REG_TMP0, addrl);
+addrl = TCG_REG_TMP0;
+}
+tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
+}
+
+static void add_qemu_ldst_label(TCGContext *s, int is_ld, TCGMemOpIdx oi,
+TCGType type,
+TCGReg datalo, TCGReg addrlo,
+void *raddr, tcg_insn_unit **label_ptr)
+{
+TCGLabelQemuLdst *label = new_ldst_label(s);
+
+label->is_ld = is_ld;
+label->oi = oi;
+label->type = type;
+label->datalo_reg = datalo;
+label->datahi_reg = 0; /* unused */
+label->addrlo_reg = addrlo;
+label->addrhi_reg = 0; /* unused */
+label->raddr = tcg_splitwx_to_rx(raddr);
+  

[PATCH v4 30/30] configure, meson.build: Mark support for loongarch64 hosts

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 configure   | 7 ++-
 meson.build | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 1043ccce4f..3a9035385d 100755
--- a/configure
+++ b/configure
@@ -659,6 +659,8 @@ elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
   cpu="aarch64"
+elif check_define __loongarch64 ; then
+  cpu="loongarch64"
 else
   cpu=$(uname -m)
 fi
@@ -667,7 +669,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64)
+  ppc|ppc64|s390x|sparc64|x32|riscv32|riscv64|loongarch64)
   ;;
   ppc64le)
 ARCH="ppc64"
@@ -4969,6 +4971,9 @@ if test "$linux" = "yes" ; then
   aarch64)
 linux_arch=arm64
 ;;
+  loongarch*)
+linux_arch=loongarch
+;;
   mips64)
 linux_arch=mips
 ;;
diff --git a/meson.build b/meson.build
index 15ef4d3c41..fc55712ac3 100644
--- a/meson.build
+++ b/meson.build
@@ -57,7 +57,7 @@ python = import('python').find_installation()
 
 supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 
'sunos', 'linux']
 supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 
'x86_64',
-  'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
+  'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc', 'sparc64']
 
 cpu = host_machine.cpu_family()
 targetos = host_machine.system()
-- 
2.33.0




[PATCH v4 28/30] linux-user: Add safe syscall handling for loongarch64 hosts

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 linux-user/host/loongarch64/hostdep.h | 34 
 .../host/loongarch64/safe-syscall.inc.S   | 80 +++
 2 files changed, 114 insertions(+)
 create mode 100644 linux-user/host/loongarch64/hostdep.h
 create mode 100644 linux-user/host/loongarch64/safe-syscall.inc.S

diff --git a/linux-user/host/loongarch64/hostdep.h 
b/linux-user/host/loongarch64/hostdep.h
new file mode 100644
index 00..e3d5fa703f
--- /dev/null
+++ b/linux-user/host/loongarch64/hostdep.h
@@ -0,0 +1,34 @@
+/*
+ * hostdep.h : things which are dependent on the host architecture
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LOONGARCH64_HOSTDEP_H
+#define LOONGARCH64_HOSTDEP_H
+
+/* We have a safe-syscall.inc.S */
+#define HAVE_SAFE_SYSCALL
+
+#ifndef __ASSEMBLER__
+
+/* These are defined by the safe-syscall.inc.S file */
+extern char safe_syscall_start[];
+extern char safe_syscall_end[];
+
+/* Adjust the signal context to rewind out of safe-syscall if we're in it */
+static inline void rewind_if_in_safe_syscall(void *puc)
+{
+ucontext_t *uc = puc;
+unsigned long long *pcreg = >uc_mcontext.__pc;
+
+if (*pcreg > (uintptr_t)safe_syscall_start
+&& *pcreg < (uintptr_t)safe_syscall_end) {
+*pcreg = (uintptr_t)safe_syscall_start;
+}
+}
+
+#endif /* __ASSEMBLER__ */
+
+#endif
diff --git a/linux-user/host/loongarch64/safe-syscall.inc.S 
b/linux-user/host/loongarch64/safe-syscall.inc.S
new file mode 100644
index 00..bb530248b3
--- /dev/null
+++ b/linux-user/host/loongarch64/safe-syscall.inc.S
@@ -0,0 +1,80 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by linux-user/safe-syscall.S
+ *
+ * Ported to LoongArch by WANG Xuerui 
+ *
+ * Based on safe-syscall.inc.S code for every other architecture,
+ * originally written by Richard Henderson 
+ * Copyright (C) 2018 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+   .global safe_syscall_base
+   .global safe_syscall_start
+   .global safe_syscall_end
+   .type   safe_syscall_base, @function
+   .type   safe_syscall_start, @function
+   .type   safe_syscall_end, @function
+
+   /*
+* This is the entry point for making a system call. The calling
+* convention here is that of a C varargs function with the
+* first argument an 'int *' to the signal_pending flag, the
+* second one the system call number (as a 'long'), and all further
+* arguments being syscall arguments (also 'long').
+* We return a long which is the syscall's return value, which
+* may be negative-errno on failure. Conversion to the
+* -1-and-errno-set convention is done by the calling wrapper.
+*/
+safe_syscall_base:
+   .cfi_startproc
+   /*
+* The syscall calling convention is nearly the same as C:
+* we enter with a0 == *signal_pending
+*   a1 == syscall number
+*   a2 ... a7 == syscall arguments
+*   and return the result in a0
+* and the syscall instruction needs
+*   a7 == syscall number
+*   a0 ... a5 == syscall arguments
+*   and returns the result in a0
+* Shuffle everything around appropriately.
+*/
+   move$t0, $a0/* signal_pending pointer */
+   move$t1, $a1/* syscall number */
+   move$a0, $a2/* syscall arguments */
+   move$a1, $a3
+   move$a2, $a4
+   move$a3, $a5
+   move$a4, $a6
+   move$a5, $a7
+   move$a7, $t1
+
+   /*
+* This next sequence of code works in conjunction with the
+* rewind_if_safe_syscall_function(). If a signal is taken
+* and the interrupted PC is anywhere between 'safe_syscall_start'
+* and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+* The code sequence must therefore be able to cope with this, and
+* the syscall instruction must be the final one in the sequence.
+*/
+safe_syscall_start:
+   /* If signal_pending is non-zero, don't do the call */
+   ld.w$t1, $t0, 0
+   bnez$t1, 0f
+   syscall 0
+safe_syscall_end:
+   /* code path for having successfully executed the syscall */
+   jr  $ra
+
+0:
+   /* code path when we didn't execute the syscall */
+   li.w$a0, -TARGET_ERESTARTSYS
+   jr  $ra
+   .cfi_endproc
+
+   .size   safe_syscall_base, .-safe_syscall_base
-- 
2.33.0




[PATCH v4 21/30] tcg/loongarch64: Implement tcg_out_call

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 34 
 1 file changed, 34 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3f12fbeb78..6a374c1941 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -506,6 +506,39 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, 
TCGReg arg1,
 tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
 }
 
+static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool 
tail)
+{
+TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
+ptrdiff_t offset = tcg_pcrel_diff(s, arg);
+
+tcg_debug_assert((offset & 3) == 0);
+if (offset == sextreg(offset, 0, 28)) {
+/* short jump: +/- 256MiB */
+if (tail) {
+tcg_out_opc_b(s, offset >> 2);
+} else {
+tcg_out_opc_bl(s, offset >> 2);
+}
+} else if (offset == sextreg(offset, 0, 38)) {
+/* long jump: +/- 256GiB */
+tcg_target_long lo = sextreg(offset, 0, 18);
+tcg_target_long hi = offset - lo;
+tcg_out_opc_pcaddu18i(s, TCG_REG_TMP0, hi >> 18);
+tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
+} else {
+/* far jump: 64-bit */
+tcg_target_long lo = sextreg((tcg_target_long)arg, 0, 18);
+tcg_target_long hi = (tcg_target_long)arg - lo;
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, hi);
+tcg_out_opc_jirl(s, link, TCG_REG_TMP0, lo >> 2);
+}
+}
+
+static void tcg_out_call(TCGContext *s, const tcg_insn_unit *arg)
+{
+tcg_out_call_int(s, arg, false);
+}
+
 /*
  * Entry-points
  */
@@ -856,6 +889,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
+case INDEX_op_call: /* Always emitted via tcg_out_call.  */
 default:
 g_assert_not_reached();
 }
-- 
2.33.0




[PATCH v4 20/30] tcg/loongarch64: Implement setcond ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 69 
 2 files changed, 70 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 367689c2e2..a2ec61237e 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -22,6 +22,7 @@ C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
+C_O1_I2(r, r, rZ)
 C_O1_I2(r, 0, rZ)
 C_O1_I2(r, rZ, rN)
 C_O1_I2(r, rZ, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index f081388d2d..3f12fbeb78 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -408,6 +408,66 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn 
opc,
 tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+TCGReg arg1, TCGReg arg2, bool c2)
+{
+TCGReg tmp;
+
+if (c2) {
+tcg_debug_assert(arg2 == 0);
+}
+
+switch (cond) {
+case TCG_COND_EQ:
+if (c2) {
+tmp = arg1;
+} else {
+tcg_out_opc_sub_d(s, ret, arg1, arg2);
+tmp = ret;
+}
+tcg_out_opc_sltui(s, ret, tmp, 1);
+break;
+case TCG_COND_NE:
+if (c2) {
+tmp = arg1;
+} else {
+tcg_out_opc_sub_d(s, ret, arg1, arg2);
+tmp = ret;
+}
+tcg_out_opc_sltu(s, ret, TCG_REG_ZERO, tmp);
+break;
+case TCG_COND_LT:
+tcg_out_opc_slt(s, ret, arg1, arg2);
+break;
+case TCG_COND_GE:
+tcg_out_opc_slt(s, ret, arg1, arg2);
+tcg_out_opc_xori(s, ret, ret, 1);
+break;
+case TCG_COND_LE:
+tcg_out_setcond(s, TCG_COND_GE, ret, arg2, arg1, false);
+break;
+case TCG_COND_GT:
+tcg_out_setcond(s, TCG_COND_LT, ret, arg2, arg1, false);
+break;
+case TCG_COND_LTU:
+tcg_out_opc_sltu(s, ret, arg1, arg2);
+break;
+case TCG_COND_GEU:
+tcg_out_opc_sltu(s, ret, arg1, arg2);
+tcg_out_opc_xori(s, ret, ret, 1);
+break;
+case TCG_COND_LEU:
+tcg_out_setcond(s, TCG_COND_GEU, ret, arg2, arg1, false);
+break;
+case TCG_COND_GTU:
+tcg_out_setcond(s, TCG_COND_LTU, ret, arg2, arg1, false);
+break;
+default:
+g_assert_not_reached();
+break;
+}
+}
+
 /*
  * Branch helpers
  */
@@ -789,6 +849,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_mod_du(s, a0, a1, a2);
 break;
 
+case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
+tcg_out_setcond(s, args[3], a0, a1, a2, c2);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -875,6 +940,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_ctz_i64:
 return C_O1_I2(r, r, rW);
 
+case INDEX_op_setcond_i32:
+case INDEX_op_setcond_i64:
+return C_O1_I2(r, r, rZ);
+
 case INDEX_op_deposit_i32:
 case INDEX_op_deposit_i64:
 /* Must deposit into the same register as input */
-- 
2.33.0




[PATCH v4 18/30] tcg/loongarch64: Implement mul/mulsh/muluh/div/divu/rem/remu ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 65 
 tcg/loongarch64/tcg-target.h | 16 +++
 3 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 4b8ce85897..fb56f3a295 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -23,3 +23,4 @@ C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
 C_O1_I2(r, rZ, rN)
+C_O1_I2(r, rZ, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index b389052180..a92f50b165 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -691,6 +691,55 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 break;
 
+case INDEX_op_mul_i32:
+tcg_out_opc_mul_w(s, a0, a1, a2);
+break;
+case INDEX_op_mul_i64:
+tcg_out_opc_mul_d(s, a0, a1, a2);
+break;
+
+case INDEX_op_mulsh_i32:
+tcg_out_opc_mulh_w(s, a0, a1, a2);
+break;
+case INDEX_op_mulsh_i64:
+tcg_out_opc_mulh_d(s, a0, a1, a2);
+break;
+
+case INDEX_op_muluh_i32:
+tcg_out_opc_mulh_wu(s, a0, a1, a2);
+break;
+case INDEX_op_muluh_i64:
+tcg_out_opc_mulh_du(s, a0, a1, a2);
+break;
+
+case INDEX_op_div_i32:
+tcg_out_opc_div_w(s, a0, a1, a2);
+break;
+case INDEX_op_div_i64:
+tcg_out_opc_div_d(s, a0, a1, a2);
+break;
+
+case INDEX_op_divu_i32:
+tcg_out_opc_div_wu(s, a0, a1, a2);
+break;
+case INDEX_op_divu_i64:
+tcg_out_opc_div_du(s, a0, a1, a2);
+break;
+
+case INDEX_op_rem_i32:
+tcg_out_opc_mod_w(s, a0, a1, a2);
+break;
+case INDEX_op_rem_i64:
+tcg_out_opc_mod_d(s, a0, a1, a2);
+break;
+
+case INDEX_op_remu_i32:
+tcg_out_opc_mod_wu(s, a0, a1, a2);
+break;
+case INDEX_op_remu_i64:
+tcg_out_opc_mod_du(s, a0, a1, a2);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -782,6 +831,22 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_sub_i64:
 return C_O1_I2(r, rZ, rN);
 
+case INDEX_op_mul_i32:
+case INDEX_op_mul_i64:
+case INDEX_op_mulsh_i32:
+case INDEX_op_mulsh_i64:
+case INDEX_op_muluh_i32:
+case INDEX_op_muluh_i64:
+case INDEX_op_div_i32:
+case INDEX_op_div_i64:
+case INDEX_op_divu_i32:
+case INDEX_op_divu_i64:
+case INDEX_op_rem_i32:
+case INDEX_op_rem_i64:
+case INDEX_op_remu_i32:
+case INDEX_op_remu_i64:
+return C_O1_I2(r, rZ, rZ);
+
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index e59c2a7bec..2ac2c342c7 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -93,8 +93,8 @@ typedef enum {
 
 /* optional instructions */
 #define TCG_TARGET_HAS_movcond_i32  0
-#define TCG_TARGET_HAS_div_i32  0
-#define TCG_TARGET_HAS_rem_i32  0
+#define TCG_TARGET_HAS_div_i32  1
+#define TCG_TARGET_HAS_rem_i32  1
 #define TCG_TARGET_HAS_div2_i32 0
 #define TCG_TARGET_HAS_rot_i32  1
 #define TCG_TARGET_HAS_deposit_i32  1
@@ -105,8 +105,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i32 0
 #define TCG_TARGET_HAS_mulu2_i320
 #define TCG_TARGET_HAS_muls2_i320
-#define TCG_TARGET_HAS_muluh_i320
-#define TCG_TARGET_HAS_mulsh_i320
+#define TCG_TARGET_HAS_muluh_i321
+#define TCG_TARGET_HAS_mulsh_i321
 #define TCG_TARGET_HAS_ext8s_i321
 #define TCG_TARGET_HAS_ext16s_i32   1
 #define TCG_TARGET_HAS_ext8u_i321
@@ -130,8 +130,8 @@ typedef enum {
 
 /* 64-bit operations */
 #define TCG_TARGET_HAS_movcond_i64  0
-#define TCG_TARGET_HAS_div_i64  0
-#define TCG_TARGET_HAS_rem_i64  0
+#define TCG_TARGET_HAS_div_i64  1
+#define TCG_TARGET_HAS_rem_i64  1
 #define TCG_TARGET_HAS_div2_i64 0
 #define TCG_TARGET_HAS_rot_i64  1
 #define TCG_TARGET_HAS_deposit_i64  1
@@ -163,8 +163,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64 0
 #define TCG_TARGET_HAS_mulu2_i640
 #define TCG_TARGET_HAS_muls2_i640
-#define TCG_TARGET_HAS_muluh_i640
-#define TCG_TARGET_HAS_mulsh_i640
+#define TCG_TARGET_HAS_muluh_i641
+#define TCG_TARGET_HAS_mulsh_i641
 
 /* not defined -- call should be eliminated at compile time */
 void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t, uintptr_t);
-- 
2.33.0




[PATCH v4 12/30] tcg/loongarch64: Implement not/and/or/xor/nor/andc/orc ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  2 +
 tcg/loongarch64/tcg-target.c.inc | 88 
 tcg/loongarch64/tcg-target.h | 16 ++---
 3 files changed, 98 insertions(+), 8 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 7e459490ea..9ac24b8ad0 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -16,3 +16,5 @@
  */
 C_O0_I1(r)
 C_O1_I1(r, r)
+C_O1_I2(r, r, rC)
+C_O1_I2(r, r, rU)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 346e232129..0ec9044111 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -396,6 +396,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 {
 TCGArg a0 = args[0];
 TCGArg a1 = args[1];
+TCGArg a2 = args[2];
+int c2 = const_args[2];
 
 switch (opc) {
 case INDEX_op_mb:
@@ -441,6 +443,68 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_srai_d(s, a0, a1, 32);
 break;
 
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
+tcg_out_opc_nor(s, a0, a1, TCG_REG_ZERO);
+break;
+
+case INDEX_op_nor_i32:
+case INDEX_op_nor_i64:
+if (c2) {
+tcg_out_opc_ori(s, a0, a1, a2);
+tcg_out_opc_nor(s, a0, a0, TCG_REG_ZERO);
+} else {
+tcg_out_opc_nor(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_andc_i32:
+case INDEX_op_andc_i64:
+if (c2) {
+/* guaranteed to fit due to constraint */
+tcg_out_opc_andi(s, a0, a1, ~a2);
+} else {
+tcg_out_opc_andn(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_orc_i32:
+case INDEX_op_orc_i64:
+if (c2) {
+/* guaranteed to fit due to constraint */
+tcg_out_opc_ori(s, a0, a1, ~a2);
+} else {
+tcg_out_opc_orn(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_and_i32:
+case INDEX_op_and_i64:
+if (c2) {
+tcg_out_opc_andi(s, a0, a1, a2);
+} else {
+tcg_out_opc_and(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_or_i32:
+case INDEX_op_or_i64:
+if (c2) {
+tcg_out_opc_ori(s, a0, a1, a2);
+} else {
+tcg_out_opc_or(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
+if (c2) {
+tcg_out_opc_xori(s, a0, a1, a2);
+} else {
+tcg_out_opc_xor(s, a0, a1, a2);
+}
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -468,8 +532,32 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_extrl_i64_i32:
 case INDEX_op_extrh_i64_i32:
 case INDEX_op_ext_i32_i64:
+case INDEX_op_not_i32:
+case INDEX_op_not_i64:
 return C_O1_I1(r, r);
 
+case INDEX_op_andc_i32:
+case INDEX_op_andc_i64:
+case INDEX_op_orc_i32:
+case INDEX_op_orc_i64:
+/*
+ * LoongArch insns for these ops don't have reg-imm forms, but we
+ * can express using andi/ori if ~constant satisfies
+ * TCG_CT_CONST_U12.
+ */
+return C_O1_I2(r, r, rC);
+
+case INDEX_op_and_i32:
+case INDEX_op_and_i64:
+case INDEX_op_nor_i32:
+case INDEX_op_nor_i64:
+case INDEX_op_or_i32:
+case INDEX_op_or_i64:
+case INDEX_op_xor_i32:
+case INDEX_op_xor_i64:
+/* LoongArch reg-imm bitops have their imms ZERO-extended */
+return C_O1_I2(r, r, rU);
+
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 2b7d5a19b9..cb1739a54a 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -113,13 +113,13 @@ typedef enum {
 #define TCG_TARGET_HAS_ext16u_i32   1
 #define TCG_TARGET_HAS_bswap16_i32  0
 #define TCG_TARGET_HAS_bswap32_i32  0
-#define TCG_TARGET_HAS_not_i32  0
+#define TCG_TARGET_HAS_not_i32  1
 #define TCG_TARGET_HAS_neg_i32  0
-#define TCG_TARGET_HAS_andc_i32 0
-#define TCG_TARGET_HAS_orc_i32  0
+#define TCG_TARGET_HAS_andc_i32 1
+#define TCG_TARGET_HAS_orc_i32  1
 #define TCG_TARGET_HAS_eqv_i32  0
 #define TCG_TARGET_HAS_nand_i32 0
-#define TCG_TARGET_HAS_nor_i32  0
+#define TCG_TARGET_HAS_nor_i32  1
 #define TCG_TARGET_HAS_clz_i32  0
 #define TCG_TARGET_HAS_ctz_i32  0
 #define TCG_TARGET_HAS_ctpop_i320
@@ -149,13 +149,13 @@ typedef enum {
 #define TCG_TARGET_HAS_bswap16_i64  0
 #define TCG_TARGET_HAS_bswap32_i64  0
 #define TCG_TARGET_HAS_bswap64_i64  0
-#define TCG_TARGET_HAS_not_i64  0
+#define 

[PATCH v4 29/30] accel/tcg/user-exec: Implement CPU-specific signal handler for loongarch64 hosts

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 accel/tcg/user-exec.c | 73 +++
 1 file changed, 73 insertions(+)

diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 8fed542622..38d4ad8a7d 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -878,6 +878,79 @@ int cpu_signal_handler(int host_signum, void *pinfo,
 return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
 }
 
+#elif defined(__loongarch64)
+
+int cpu_signal_handler(int host_signum, void *pinfo,
+   void *puc)
+{
+siginfo_t *info = pinfo;
+ucontext_t *uc = puc;
+greg_t pc = uc->uc_mcontext.__pc;
+uint32_t insn = *(uint32_t *)pc;
+int is_write = 0;
+
+/* Detect store by reading the instruction at the program counter.  */
+switch ((insn >> 26) & 0b11) {
+case 0b001000: /* {ll,sc}.[wd] */
+switch ((insn >> 24) & 0b11) {
+case 0b01: /* sc.w */
+case 0b11: /* sc.d */
+is_write = 1;
+break;
+}
+break;
+case 0b001001: /* {ld,st}ox4.[wd] ({ld,st}ptr.[wd]) */
+switch ((insn >> 24) & 0b11) {
+case 0b01: /* stox4.w (stptr.w) */
+case 0b11: /* stox4.d (stptr.d) */
+is_write = 1;
+break;
+}
+break;
+case 0b001010: /* {ld,st}.* family */
+switch ((insn >> 22) & 0b) {
+case 0b0100: /* st.b */
+case 0b0101: /* st.h */
+case 0b0110: /* st.w */
+case 0b0111: /* st.d */
+case 0b1101: /* fst.s */
+case 0b: /* fst.d */
+is_write = 1;
+break;
+}
+break;
+case 0b001110: /* indexed, atomic, bounds-checking memory operations */
+uint32_t sel = (insn >> 15) & 0b111;
+
+switch (sel) {
+case 0b010: /* stx.b */
+case 0b0101000: /* stx.h */
+case 0b011: /* stx.w */
+case 0b0111000: /* stx.d */
+case 0b111: /* fstx.s */
+case 0b000: /* fstx.d */
+case 0b00011101100: /* fstgt.s */
+case 0b00011101101: /* fstgt.d */
+case 0b00011101110: /* fstle.s */
+case 0b0001110: /* fstle.d */
+case 0b0001000: /* stgt.b */
+case 0b0001001: /* stgt.h */
+case 0b0001010: /* stgt.w */
+case 0b0001011: /* stgt.d */
+case 0b0001100: /* stle.b */
+case 0b0001101: /* stle.h */
+case 0b0001110: /* stle.w */
+case 0b000: /* stle.d */
+case 0b0001100 ... 0b00011100011: /* am* insns */
+is_write = 1;
+break;
+}
+break;
+}
+
+return handle_cpu_signal(pc, info, is_write, >uc_sigmask);
+}
+
 #else
 
 #error host CPU specific signal handler needed
-- 
2.33.0




[PATCH v4 15/30] tcg/loongarch64: Implement clz/ctz ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 42 
 tcg/loongarch64/tcg-target.h |  8 +++---
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index d958183020..2975e03127 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -18,4 +18,5 @@ C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, rU)
+C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index ce6843b408..5b529b52ad 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -386,6 +386,28 @@ static void tcg_out_ext32s(TCGContext *s, TCGReg ret, 
TCGReg arg)
 tcg_out_opc_addi_w(s, ret, arg, 0);
 }
 
+static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
+   TCGReg a0, TCGReg a1, TCGReg a2,
+   bool c2, bool is_32bit)
+{
+if (c2) {
+/*
+ * Fast path: semantics already satisfied due to constraint and
+ * insn behavior, single instruction is enough.
+ */
+tcg_debug_assert(a2 == (is_32bit ? 32 : 64));
+/* all clz/ctz insns belong to DJ-format */
+tcg_out32(s, encode_dj_insn(opc, a0, a1));
+return;
+}
+
+tcg_out32(s, encode_dj_insn(opc, TCG_REG_TMP0, a1));
+/* a0 = a1 ? REG_TMP0 : a2 */
+tcg_out_opc_maskeqz(s, TCG_REG_TMP0, TCG_REG_TMP0, a1);
+tcg_out_opc_masknez(s, a0, a2, a1);
+tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
+}
+
 /*
  * Entry-points
  */
@@ -546,6 +568,20 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_revb_d(s, a0, a1);
 break;
 
+case INDEX_op_clz_i32:
+tcg_out_clzctz(s, OPC_CLZ_W, a0, a1, a2, c2, true);
+break;
+case INDEX_op_clz_i64:
+tcg_out_clzctz(s, OPC_CLZ_D, a0, a1, a2, c2, false);
+break;
+
+case INDEX_op_ctz_i32:
+tcg_out_clzctz(s, OPC_CTZ_W, a0, a1, a2, c2, true);
+break;
+case INDEX_op_ctz_i64:
+tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -606,6 +642,12 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 /* LoongArch reg-imm bitops have their imms ZERO-extended */
 return C_O1_I2(r, r, rU);
 
+case INDEX_op_clz_i32:
+case INDEX_op_clz_i64:
+case INDEX_op_ctz_i32:
+case INDEX_op_ctz_i64:
+return C_O1_I2(r, r, rW);
+
 case INDEX_op_deposit_i32:
 case INDEX_op_deposit_i64:
 /* Must deposit into the same register as input */
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 02d17d2f6d..ef489cbc86 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -120,8 +120,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i32  0
 #define TCG_TARGET_HAS_nand_i32 0
 #define TCG_TARGET_HAS_nor_i32  1
-#define TCG_TARGET_HAS_clz_i32  0
-#define TCG_TARGET_HAS_ctz_i32  0
+#define TCG_TARGET_HAS_clz_i32  1
+#define TCG_TARGET_HAS_ctz_i32  1
 #define TCG_TARGET_HAS_ctpop_i320
 #define TCG_TARGET_HAS_direct_jump  0
 #define TCG_TARGET_HAS_brcond2  0
@@ -156,8 +156,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i64  0
 #define TCG_TARGET_HAS_nand_i64 0
 #define TCG_TARGET_HAS_nor_i64  1
-#define TCG_TARGET_HAS_clz_i64  0
-#define TCG_TARGET_HAS_ctz_i64  0
+#define TCG_TARGET_HAS_clz_i64  1
+#define TCG_TARGET_HAS_ctz_i64  1
 #define TCG_TARGET_HAS_ctpop_i640
 #define TCG_TARGET_HAS_add2_i64 0
 #define TCG_TARGET_HAS_sub2_i64 0
-- 
2.33.0




[PATCH v4 17/30] tcg/loongarch64: Implement add/sub ops

2021-09-23 Thread WANG Xuerui
The neg_i{32,64} ops is fully expressible with sub, so omitted for
simplicity.

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  2 ++
 tcg/loongarch64/tcg-target.c.inc | 38 
 2 files changed, 40 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 42f8e28741..4b8ce85897 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -18,6 +18,8 @@ C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
+C_O1_I2(r, r, rI)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
+C_O1_I2(r, rZ, rN)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index e3b0958318..b389052180 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -661,6 +661,36 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 break;
 
+case INDEX_op_add_i32:
+if (c2) {
+tcg_out_opc_addi_w(s, a0, a1, a2);
+} else {
+tcg_out_opc_add_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_add_i64:
+if (c2) {
+tcg_out_opc_addi_d(s, a0, a1, a2);
+} else {
+tcg_out_opc_add_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_sub_i32:
+if (c2) {
+tcg_out_opc_addi_w(s, a0, a1, -a2);
+} else {
+tcg_out_opc_sub_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_sub_i64:
+if (c2) {
+tcg_out_opc_addi_d(s, a0, a1, -a2);
+} else {
+tcg_out_opc_sub_d(s, a0, a1, a2);
+}
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -722,6 +752,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_rotr_i64:
 return C_O1_I2(r, r, ri);
 
+case INDEX_op_add_i32:
+case INDEX_op_add_i64:
+return C_O1_I2(r, r, rI);
+
 case INDEX_op_and_i32:
 case INDEX_op_and_i64:
 case INDEX_op_nor_i32:
@@ -744,6 +778,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 /* Must deposit into the same register as input */
 return C_O1_I2(r, 0, rZ);
 
+case INDEX_op_sub_i32:
+case INDEX_op_sub_i64:
+return C_O1_I2(r, rZ, rN);
+
 default:
 g_assert_not_reached();
 }
-- 
2.33.0




[PATCH v4 25/30] tcg/loongarch64: Implement exit_tb/goto_tb

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 3cf9a4924b..e09bf832bd 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -943,6 +943,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 int c2 = const_args[2];
 
 switch (opc) {
+case INDEX_op_exit_tb:
+/* Reuse the zeroing that exists for goto_ptr.  */
+if (a0 == 0) {
+tcg_out_call_int(s, tcg_code_gen_epilogue, true);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_A0, a0);
+tcg_out_call_int(s, tb_ret_addr, true);
+}
+break;
+
+case INDEX_op_goto_tb:
+assert(s->tb_jmp_insn_offset == 0);
+/* indirect jump method */
+tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_REG_ZERO,
+   (uintptr_t)(s->tb_jmp_target_addr + a0));
+tcg_out_opc_jirl(s, TCG_REG_ZERO, TCG_REG_TMP0, 0);
+set_jmp_reset_offset(s, a0);
+break;
+
 case INDEX_op_mb:
 tcg_out_mb(s, a0);
 break;
-- 
2.33.0




[PATCH v4 11/30] tcg/loongarch64: Implement sign-/zero-extension ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 82 
 tcg/loongarch64/tcg-target.h | 24 
 3 files changed, 95 insertions(+), 12 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 5cc4407367..7e459490ea 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,3 +15,4 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O1_I1(r, r)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 21f812a6a9..346e232129 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -356,6 +356,36 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
 }
 }
 
+static void tcg_out_ext8u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_andi(s, ret, arg, 0xff);
+}
+
+static void tcg_out_ext16u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_bstrpick_w(s, ret, arg, 0, 15);
+}
+
+static void tcg_out_ext32u(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_bstrpick_d(s, ret, arg, 0, 31);
+}
+
+static void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_sext_b(s, ret, arg);
+}
+
+static void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_sext_h(s, ret, arg);
+}
+
+static void tcg_out_ext32s(TCGContext *s, TCGReg ret, TCGReg arg)
+{
+tcg_out_opc_addi_w(s, ret, arg, 0);
+}
+
 /*
  * Entry-points
  */
@@ -365,6 +395,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
const int const_args[TCG_MAX_OP_ARGS])
 {
 TCGArg a0 = args[0];
+TCGArg a1 = args[1];
 
 switch (opc) {
 case INDEX_op_mb:
@@ -375,6 +406,41 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
 break;
 
+case INDEX_op_ext8s_i32:
+case INDEX_op_ext8s_i64:
+tcg_out_ext8s(s, a0, a1);
+break;
+
+case INDEX_op_ext8u_i32:
+case INDEX_op_ext8u_i64:
+tcg_out_ext8u(s, a0, a1);
+break;
+
+case INDEX_op_ext16s_i32:
+case INDEX_op_ext16s_i64:
+tcg_out_ext16s(s, a0, a1);
+break;
+
+case INDEX_op_ext16u_i32:
+case INDEX_op_ext16u_i64:
+tcg_out_ext16u(s, a0, a1);
+break;
+
+case INDEX_op_ext32u_i64:
+case INDEX_op_extu_i32_i64:
+tcg_out_ext32u(s, a0, a1);
+break;
+
+case INDEX_op_ext32s_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_ext_i32_i64:
+tcg_out_ext32s(s, a0, a1);
+break;
+
+case INDEX_op_extrh_i64_i32:
+tcg_out_opc_srai_d(s, a0, a1, 32);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -388,6 +454,22 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_goto_ptr:
 return C_O0_I1(r);
 
+case INDEX_op_ext8s_i32:
+case INDEX_op_ext8s_i64:
+case INDEX_op_ext8u_i32:
+case INDEX_op_ext8u_i64:
+case INDEX_op_ext16s_i32:
+case INDEX_op_ext16s_i64:
+case INDEX_op_ext16u_i32:
+case INDEX_op_ext16u_i64:
+case INDEX_op_ext32s_i64:
+case INDEX_op_ext32u_i64:
+case INDEX_op_extu_i32_i64:
+case INDEX_op_extrl_i64_i32:
+case INDEX_op_extrh_i64_i32:
+case INDEX_op_ext_i32_i64:
+return C_O1_I1(r, r);
+
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 5fc097b3c1..2b7d5a19b9 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -107,10 +107,10 @@ typedef enum {
 #define TCG_TARGET_HAS_muls2_i320
 #define TCG_TARGET_HAS_muluh_i320
 #define TCG_TARGET_HAS_mulsh_i320
-#define TCG_TARGET_HAS_ext8s_i320
-#define TCG_TARGET_HAS_ext16s_i32   0
-#define TCG_TARGET_HAS_ext8u_i320
-#define TCG_TARGET_HAS_ext16u_i32   0
+#define TCG_TARGET_HAS_ext8s_i321
+#define TCG_TARGET_HAS_ext16s_i32   1
+#define TCG_TARGET_HAS_ext8u_i321
+#define TCG_TARGET_HAS_ext16u_i32   1
 #define TCG_TARGET_HAS_bswap16_i32  0
 #define TCG_TARGET_HAS_bswap32_i32  0
 #define TCG_TARGET_HAS_not_i32  0
@@ -138,14 +138,14 @@ typedef enum {
 #define TCG_TARGET_HAS_extract_i64  0
 #define TCG_TARGET_HAS_sextract_i64 0
 #define TCG_TARGET_HAS_extract2_i64 0
-#define TCG_TARGET_HAS_extrl_i64_i320
-#define TCG_TARGET_HAS_extrh_i64_i320
-#define TCG_TARGET_HAS_ext8s_i640
-#define TCG_TARGET_HAS_ext16s_i64   0
-#define TCG_TARGET_HAS_ext32s_i64   0
-#define TCG_TARGET_HAS_ext8u_i640
-#define TCG_TARGET_HAS_ext16u_i64   0
-#define TCG_TARGET_HAS_ext32u_i64   0
+#define TCG_TARGET_HAS_extrl_i64_i321

[PATCH v4 10/30] tcg/loongarch64: Implement goto_ptr

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h | 17 +
 tcg/loongarch64/tcg-target.c.inc | 15 +++
 2 files changed, 32 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-target-con-set.h

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
new file mode 100644
index 00..5cc4407367
--- /dev/null
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define LoongArch target-specific constraint sets.
+ *
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * Based on tcg/riscv/tcg-target-con-set.h
+ *
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * C_On_Im(...) defines a constraint set with  outputs and  inputs.
+ * Each operand should be a sequence of constraint letters as defined by
+ * tcg-target-con-str.h; the constraint combination is inclusive or.
+ */
+C_O0_I1(r)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index afaed5017a..21f812a6a9 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -371,9 +371,24 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_mb(s, a0);
 break;
 
+case INDEX_op_goto_ptr:
+tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
 g_assert_not_reached();
 }
 }
+
+static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
+{
+switch (op) {
+case INDEX_op_goto_ptr:
+return C_O0_I1(r);
+
+default:
+g_assert_not_reached();
+}
+}
-- 
2.33.0




[PATCH v4 22/30] tcg/loongarch64: Implement simple load/store ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |   1 +
 tcg/loongarch64/tcg-target.c.inc | 131 +++
 2 files changed, 132 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index a2ec61237e..e54ca9b2de 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,6 +15,7 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O0_I2(rZ, r)
 C_O0_I2(rZ, rZ)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 6a374c1941..1f6bad95ce 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -539,6 +539,73 @@ static void tcg_out_call(TCGContext *s, const 
tcg_insn_unit *arg)
 tcg_out_call_int(s, arg, false);
 }
 
+/*
+ * Load/store helpers
+ */
+
+static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
+ TCGReg addr, intptr_t offset)
+{
+intptr_t imm12 = sextreg(offset, 0, 12);
+
+if (offset != imm12) {
+intptr_t diff = offset - (uintptr_t)s->code_ptr;
+
+if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
+imm12 = sextreg(diff, 0, 12);
+tcg_out_opc_pcaddu12i(s, TCG_REG_TMP2, (diff - imm12) >> 12);
+} else {
+tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP2, offset - imm12);
+if (addr != TCG_REG_ZERO) {
+tcg_out_opc_add_d(s, TCG_REG_TMP2, TCG_REG_TMP2, addr);
+}
+}
+addr = TCG_REG_TMP2;
+}
+
+switch (opc) {
+case OPC_LD_B:
+case OPC_LD_BU:
+case OPC_LD_H:
+case OPC_LD_HU:
+case OPC_LD_W:
+case OPC_LD_WU:
+case OPC_LD_D:
+case OPC_ST_B:
+case OPC_ST_H:
+case OPC_ST_W:
+case OPC_ST_D:
+tcg_out32(s, encode_djsk12_insn(opc, data, addr, imm12));
+break;
+default:
+g_assert_not_reached();
+}
+}
+
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is_32bit = type == TCG_TYPE_I32;
+tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2);
+}
+
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+   TCGReg arg1, intptr_t arg2)
+{
+bool is_32bit = type == TCG_TYPE_I32;
+tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2);
+}
+
+static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
+TCGReg base, intptr_t ofs)
+{
+if (val == 0) {
+tcg_out_st(s, type, TCG_REG_ZERO, base, ofs);
+return true;
+}
+return false;
+}
+
 /*
  * Entry-points
  */
@@ -887,6 +954,49 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_setcond(s, args[3], a0, a1, a2, c2);
 break;
 
+case INDEX_op_ld8s_i32:
+case INDEX_op_ld8s_i64:
+tcg_out_ldst(s, OPC_LD_B, a0, a1, a2);
+break;
+case INDEX_op_ld8u_i32:
+case INDEX_op_ld8u_i64:
+tcg_out_ldst(s, OPC_LD_BU, a0, a1, a2);
+break;
+case INDEX_op_ld16s_i32:
+case INDEX_op_ld16s_i64:
+tcg_out_ldst(s, OPC_LD_H, a0, a1, a2);
+break;
+case INDEX_op_ld16u_i32:
+case INDEX_op_ld16u_i64:
+tcg_out_ldst(s, OPC_LD_HU, a0, a1, a2);
+break;
+case INDEX_op_ld_i32:
+case INDEX_op_ld32s_i64:
+tcg_out_ldst(s, OPC_LD_W, a0, a1, a2);
+break;
+case INDEX_op_ld32u_i64:
+tcg_out_ldst(s, OPC_LD_WU, a0, a1, a2);
+break;
+case INDEX_op_ld_i64:
+tcg_out_ldst(s, OPC_LD_D, a0, a1, a2);
+break;
+
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+tcg_out_ldst(s, OPC_ST_B, a0, a1, a2);
+break;
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+tcg_out_ldst(s, OPC_ST_H, a0, a1, a2);
+break;
+case INDEX_op_st_i32:
+case INDEX_op_st32_i64:
+tcg_out_ldst(s, OPC_ST_W, a0, a1, a2);
+break;
+case INDEX_op_st_i64:
+tcg_out_ldst(s, OPC_ST_D, a0, a1, a2);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 case INDEX_op_call: /* Always emitted via tcg_out_call.  */
@@ -901,6 +1011,15 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_goto_ptr:
 return C_O0_I1(r);
 
+case INDEX_op_st8_i32:
+case INDEX_op_st8_i64:
+case INDEX_op_st16_i32:
+case INDEX_op_st16_i64:
+case INDEX_op_st32_i64:
+case INDEX_op_st_i32:
+case INDEX_op_st_i64:
+return C_O0_I2(rZ, r);
+
 case INDEX_op_brcond_i32:
 case INDEX_op_brcond_i64:
 return C_O0_I2(rZ, rZ);
@@ -928,6 +1047,18 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_bswap32_i32:
 case 

[PATCH v4 13/30] tcg/loongarch64: Implement deposit/extract ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 21 +
 tcg/loongarch64/tcg-target.h |  8 
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 9ac24b8ad0..d958183020 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -18,3 +18,4 @@ C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, rU)
+C_O1_I2(r, 0, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 0ec9044111..46b4f54562 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -505,6 +505,20 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 }
 break;
 
+case INDEX_op_extract_i32:
+tcg_out_opc_bstrpick_w(s, a0, a1, a2, a2 + args[3] - 1);
+break;
+case INDEX_op_extract_i64:
+tcg_out_opc_bstrpick_d(s, a0, a1, a2, a2 + args[3] - 1);
+break;
+
+case INDEX_op_deposit_i32:
+tcg_out_opc_bstrins_w(s, a0, a2, args[3], args[3] + args[4] - 1);
+break;
+case INDEX_op_deposit_i64:
+tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -534,6 +548,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 case INDEX_op_ext_i32_i64:
 case INDEX_op_not_i32:
 case INDEX_op_not_i64:
+case INDEX_op_extract_i32:
+case INDEX_op_extract_i64:
 return C_O1_I1(r, r);
 
 case INDEX_op_andc_i32:
@@ -558,6 +574,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 /* LoongArch reg-imm bitops have their imms ZERO-extended */
 return C_O1_I2(r, r, rU);
 
+case INDEX_op_deposit_i32:
+case INDEX_op_deposit_i64:
+/* Must deposit into the same register as input */
+return C_O1_I2(r, 0, rZ);
+
 default:
 g_assert_not_reached();
 }
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index cb1739a54a..084d635a8e 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -97,8 +97,8 @@ typedef enum {
 #define TCG_TARGET_HAS_rem_i32  0
 #define TCG_TARGET_HAS_div2_i32 0
 #define TCG_TARGET_HAS_rot_i32  0
-#define TCG_TARGET_HAS_deposit_i32  0
-#define TCG_TARGET_HAS_extract_i32  0
+#define TCG_TARGET_HAS_deposit_i32  1
+#define TCG_TARGET_HAS_extract_i32  1
 #define TCG_TARGET_HAS_sextract_i32 0
 #define TCG_TARGET_HAS_extract2_i32 0
 #define TCG_TARGET_HAS_add2_i32 0
@@ -134,8 +134,8 @@ typedef enum {
 #define TCG_TARGET_HAS_rem_i64  0
 #define TCG_TARGET_HAS_div2_i64 0
 #define TCG_TARGET_HAS_rot_i64  0
-#define TCG_TARGET_HAS_deposit_i64  0
-#define TCG_TARGET_HAS_extract_i64  0
+#define TCG_TARGET_HAS_deposit_i64  1
+#define TCG_TARGET_HAS_extract_i64  1
 #define TCG_TARGET_HAS_sextract_i64 0
 #define TCG_TARGET_HAS_extract2_i64 0
 #define TCG_TARGET_HAS_extrl_i64_i321
-- 
2.33.0




[PATCH v4 07/30] tcg/loongarch64: Implement necessary relocation operations

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 66 
 1 file changed, 66 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index f0930f77ef..6967f143e9 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -168,3 +168,69 @@ static bool tcg_target_const_match(int64_t val, TCGType 
type, int ct)
 }
 return 0;
 }
+
+/*
+ * Relocations
+ */
+
+/*
+ * Relocation records defined in LoongArch ELF psABI v1.00 is way too
+ * complicated; a whopping stack machine is needed to stuff the fields, at
+ * the very least one SOP_PUSH and one SOP_POP (of the correct format) are
+ * needed.
+ *
+ * Hence, define our own simpler relocation types. Numbers are chosen as to
+ * not collide with potential future additions to the true ELF relocation
+ * type enum.
+ */
+
+/* Field Sk16, shifted right by 2; suitable for conditional jumps */
+#define R_LOONGARCH_BR_SK16 256
+/* Field Sd10k16, shifted right by 2; suitable for B and BL */
+#define R_LOONGARCH_BR_SD10K16  257
+
+static bool reloc_br_sk16(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
+{
+const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
+intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
+
+tcg_debug_assert((offset & 3) == 0);
+offset >>= 2;
+if (offset == sextreg(offset, 0, 16)) {
+*src_rw = deposit64(*src_rw, 10, 16, offset);
+return true;
+}
+
+return false;
+}
+
+static bool reloc_br_sd10k16(tcg_insn_unit *src_rw,
+ const tcg_insn_unit *target)
+{
+const tcg_insn_unit *src_rx = tcg_splitwx_to_rx(src_rw);
+intptr_t offset = (intptr_t)target - (intptr_t)src_rx;
+
+tcg_debug_assert((offset & 3) == 0);
+offset >>= 2;
+if (offset == sextreg(offset, 0, 26)) {
+*src_rw = deposit64(*src_rw, 0, 10, offset >> 16); /* slot d10 */
+*src_rw = deposit64(*src_rw, 10, 16, offset); /* slot k16 */
+return true;
+}
+
+return false;
+}
+
+static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
+intptr_t value, intptr_t addend)
+{
+tcg_debug_assert(addend == 0);
+switch (type) {
+case R_LOONGARCH_BR_SK16:
+return reloc_br_sk16(code_ptr, (tcg_insn_unit *)value);
+case R_LOONGARCH_BR_SD10K16:
+return reloc_br_sd10k16(code_ptr, (tcg_insn_unit *)value);
+default:
+g_assert_not_reached();
+}
+}
-- 
2.33.0




[PATCH v4 19/30] tcg/loongarch64: Implement br/brcond ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 53 
 2 files changed, 54 insertions(+)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index fb56f3a295..367689c2e2 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,6 +15,7 @@
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O0_I2(rZ, rZ)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index a92f50b165..f081388d2d 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -408,6 +408,44 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn 
opc,
 tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+/*
+ * Branch helpers
+ */
+
+static const struct {
+LoongArchInsn op;
+bool swap;
+} tcg_brcond_to_loongarch[] = {
+[TCG_COND_EQ] =  { OPC_BEQ,  false },
+[TCG_COND_NE] =  { OPC_BNE,  false },
+[TCG_COND_LT] =  { OPC_BGT,  true  },
+[TCG_COND_GE] =  { OPC_BLE,  true  },
+[TCG_COND_LE] =  { OPC_BLE,  false },
+[TCG_COND_GT] =  { OPC_BGT,  false },
+[TCG_COND_LTU] = { OPC_BGTU, true  },
+[TCG_COND_GEU] = { OPC_BLEU, true  },
+[TCG_COND_LEU] = { OPC_BLEU, false },
+[TCG_COND_GTU] = { OPC_BGTU, false }
+};
+
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+   TCGReg arg2, TCGLabel *l)
+{
+LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
+
+tcg_debug_assert(op != 0);
+
+if (tcg_brcond_to_loongarch[cond].swap) {
+TCGReg t = arg1;
+arg1 = arg2;
+arg2 = t;
+}
+
+/* all conditional branch insns belong to DJSk16-format */
+tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0);
+tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
+}
+
 /*
  * Entry-points
  */
@@ -430,6 +468,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
 break;
 
+case INDEX_op_br:
+tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0),
+  0);
+tcg_out_opc_b(s, 0);
+break;
+
+case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
+tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
+break;
+
 case INDEX_op_ext8s_i32:
 case INDEX_op_ext8s_i64:
 tcg_out_ext8s(s, a0, a1);
@@ -753,6 +802,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_goto_ptr:
 return C_O0_I1(r);
 
+case INDEX_op_brcond_i32:
+case INDEX_op_brcond_i64:
+return C_O0_I2(rZ, rZ);
+
 case INDEX_op_ext8s_i32:
 case INDEX_op_ext8s_i64:
 case INDEX_op_ext8u_i32:
-- 
2.33.0




[PATCH v4 14/30] tcg/loongarch64: Implement bswap{16,32,64} ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 32 
 tcg/loongarch64/tcg-target.h | 10 +-
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 46b4f54562..ce6843b408 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -519,6 +519,33 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_opc_bstrins_d(s, a0, a2, args[3], args[3] + args[4] - 1);
 break;
 
+case INDEX_op_bswap16_i32:
+case INDEX_op_bswap16_i64:
+tcg_out_opc_revb_2h(s, a0, a1);
+if (a2 & TCG_BSWAP_OS) {
+tcg_out_ext16s(s, a0, a0);
+} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
+tcg_out_ext16u(s, a0, a0);
+}
+break;
+
+case INDEX_op_bswap32_i32:
+/* All 32-bit values are computed sign-extended in the register.  */
+a2 = TCG_BSWAP_OS;
+/* fallthrough */
+case INDEX_op_bswap32_i64:
+tcg_out_opc_revb_2w(s, a0, a1);
+if (a2 & TCG_BSWAP_OS) {
+tcg_out_ext32s(s, a0, a0);
+} else if ((a2 & (TCG_BSWAP_IZ | TCG_BSWAP_OZ)) == TCG_BSWAP_OZ) {
+tcg_out_ext32u(s, a0, a0);
+}
+break;
+
+case INDEX_op_bswap64_i64:
+tcg_out_opc_revb_d(s, a0, a1);
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -550,6 +577,11 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
 case INDEX_op_not_i64:
 case INDEX_op_extract_i32:
 case INDEX_op_extract_i64:
+case INDEX_op_bswap16_i32:
+case INDEX_op_bswap16_i64:
+case INDEX_op_bswap32_i32:
+case INDEX_op_bswap32_i64:
+case INDEX_op_bswap64_i64:
 return C_O1_I1(r, r);
 
 case INDEX_op_andc_i32:
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index 084d635a8e..02d17d2f6d 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -111,8 +111,8 @@ typedef enum {
 #define TCG_TARGET_HAS_ext16s_i32   1
 #define TCG_TARGET_HAS_ext8u_i321
 #define TCG_TARGET_HAS_ext16u_i32   1
-#define TCG_TARGET_HAS_bswap16_i32  0
-#define TCG_TARGET_HAS_bswap32_i32  0
+#define TCG_TARGET_HAS_bswap16_i32  1
+#define TCG_TARGET_HAS_bswap32_i32  1
 #define TCG_TARGET_HAS_not_i32  1
 #define TCG_TARGET_HAS_neg_i32  0
 #define TCG_TARGET_HAS_andc_i32 1
@@ -146,9 +146,9 @@ typedef enum {
 #define TCG_TARGET_HAS_ext8u_i641
 #define TCG_TARGET_HAS_ext16u_i64   1
 #define TCG_TARGET_HAS_ext32u_i64   1
-#define TCG_TARGET_HAS_bswap16_i64  0
-#define TCG_TARGET_HAS_bswap32_i64  0
-#define TCG_TARGET_HAS_bswap64_i64  0
+#define TCG_TARGET_HAS_bswap16_i64  1
+#define TCG_TARGET_HAS_bswap32_i64  1
+#define TCG_TARGET_HAS_bswap64_i64  1
 #define TCG_TARGET_HAS_not_i64  1
 #define TCG_TARGET_HAS_neg_i64  0
 #define TCG_TARGET_HAS_andc_i64 1
-- 
2.33.0




[PATCH v4 09/30] tcg/loongarch64: Implement tcg_out_mov and tcg_out_movi

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
---
 tcg/loongarch64/tcg-target.c.inc | 111 +++
 1 file changed, 111 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 8f7c556c37..afaed5017a 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -247,6 +247,115 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)
 tcg_out_opc_dbar(s, 0);
 }
 
+static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
+{
+if (ret == arg) {
+return true;
+}
+switch (type) {
+case TCG_TYPE_I32:
+case TCG_TYPE_I64:
+/*
+ * Conventional register-register move used in LoongArch is
+ * `or dst, src, zero`.
+ */
+tcg_out_opc_or(s, ret, arg, TCG_REG_ZERO);
+break;
+default:
+g_assert_not_reached();
+}
+return true;
+}
+
+static bool imm_part_needs_loading(bool high_bits_are_ones,
+   tcg_target_long part)
+{
+if (high_bits_are_ones) {
+return part != -1;
+} else {
+return part != 0;
+}
+}
+
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
+ tcg_target_long val)
+{
+if (type == TCG_TYPE_I32) {
+val = (int32_t)val;
+}
+
+/* Single-instruction cases.  */
+tcg_target_long low = sextreg(val, 0, 12);
+if (low == val) {
+/* val fits in simm12: addi.w rd, zero, val */
+tcg_out_opc_addi_w(s, rd, TCG_REG_ZERO, val);
+return;
+}
+if (0x800 <= val && val <= 0xfff) {
+/* val fits in uimm12: ori rd, zero, val */
+tcg_out_opc_ori(s, rd, TCG_REG_ZERO, val);
+return;
+}
+
+/* Test for PC-relative values that can be loaded faster.  */
+intptr_t pc_offset = tcg_pcrel_diff(s, (void *)val);
+if (pc_offset == sextreg(pc_offset, 0, 22) && (pc_offset & 3) == 0) {
+tcg_out_opc_pcaddu2i(s, rd, pc_offset >> 2);
+return;
+}
+
+if (pc_offset == (int32_t)pc_offset) {
+/* Load using pcalau12i + ori.  */
+tcg_target_long pc_hi = (val - pc_offset) >> 12;
+tcg_target_long val_hi = val >> 12;
+tcg_target_long offset_hi = val_hi - pc_hi;
+tcg_debug_assert(offset_hi == sextreg(offset_hi, 0, 20));
+tcg_out_opc_pcalau12i(s, rd, offset_hi);
+if (low != 0) {
+tcg_out_opc_ori(s, rd, rd, low & 0xfff);
+}
+return;
+}
+
+/*
+ * Slow path: at most lu12i.w + ori + cu32i.d + cu52i.d.
+ *
+ * Chop upper bits into 3 immediate-field-sized segments respectively.
+ */
+tcg_target_long upper = sextreg(val, 12, 20);
+tcg_target_long higher = sextreg(val, 32, 20);
+tcg_target_long top = sextreg(val, 52, 12);
+bool rd_written = false;
+bool rd_high_bits_are_ones = false;
+
+if (upper != 0) {
+tcg_out_opc_lu12i_w(s, rd, upper);
+rd_written = true;
+rd_high_bits_are_ones = upper < 0;
+}
+if (low != 0) {
+tcg_out_opc_ori(s, rd, rd_written ? rd : TCG_REG_ZERO, low & 0xfff);
+rd_written = true;
+}
+
+if (imm_part_needs_loading(rd_high_bits_are_ones, higher)) {
+if (!rd_written) {
+/*
+ * cu32i.d only has 1 input register, yet rd is still untouched
+ * by now. We must zero it here.
+ */
+tcg_out_opc_or(s, rd, TCG_REG_ZERO, TCG_REG_ZERO);
+}
+tcg_out_opc_cu32i_d(s, rd, higher);
+rd_written = true;
+rd_high_bits_are_ones = higher < 0;
+}
+
+if (imm_part_needs_loading(rd_high_bits_are_ones, top)) {
+tcg_out_opc_cu52i_d(s, rd, rd_written ? rd : TCG_REG_ZERO, top);
+}
+}
+
 /*
  * Entry-points
  */
@@ -262,6 +371,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_mb(s, a0);
 break;
 
+case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
+case INDEX_op_mov_i64:
 default:
 g_assert_not_reached();
 }
-- 
2.33.0




[PATCH v4 04/30] tcg/loongarch64: Add generated instruction opcodes and encoding helpers

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Acked-by: Richard Henderson 
---
 tcg/loongarch64/tcg-insn-defs.c.inc | 891 
 1 file changed, 891 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-insn-defs.c.inc

diff --git a/tcg/loongarch64/tcg-insn-defs.c.inc 
b/tcg/loongarch64/tcg-insn-defs.c.inc
new file mode 100644
index 00..a12b0301b7
--- /dev/null
+++ b/tcg/loongarch64/tcg-insn-defs.c.inc
@@ -0,0 +1,891 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * LoongArch instruction formats, opcodes, and encoders for TCG use.
+ *
+ * This file is auto-generated by genqemutcgdefs from
+ * https://github.com/loongson-community/loongarch-opcodes,
+ * from commit ec4eec92c1ffcc33e604a9d77a9279aeaf57558b.
+ * DO NOT EDIT.
+ */
+
+typedef enum {
+OPC_CLZ_W = 0x1400,
+OPC_CTZ_W = 0x1c00,
+OPC_CLZ_D = 0x2400,
+OPC_CTZ_D = 0x2c00,
+OPC_REVB_2H = 0x3000,
+OPC_REVB_2W = 0x3800,
+OPC_REVB_D = 0x3c00,
+OPC_SEXT_H = 0x5800,
+OPC_SEXT_B = 0x5c00,
+OPC_ADD_W = 0x0010,
+OPC_ADD_D = 0x00108000,
+OPC_SUB_W = 0x0011,
+OPC_SUB_D = 0x00118000,
+OPC_SLT = 0x0012,
+OPC_SLTU = 0x00128000,
+OPC_MASKEQZ = 0x0013,
+OPC_MASKNEZ = 0x00138000,
+OPC_NOR = 0x0014,
+OPC_AND = 0x00148000,
+OPC_OR = 0x0015,
+OPC_XOR = 0x00158000,
+OPC_ORN = 0x0016,
+OPC_ANDN = 0x00168000,
+OPC_SLL_W = 0x0017,
+OPC_SRL_W = 0x00178000,
+OPC_SRA_W = 0x0018,
+OPC_SLL_D = 0x00188000,
+OPC_SRL_D = 0x0019,
+OPC_SRA_D = 0x00198000,
+OPC_ROTR_W = 0x001b,
+OPC_ROTR_D = 0x001b8000,
+OPC_MUL_W = 0x001c,
+OPC_MULH_W = 0x001c8000,
+OPC_MULH_WU = 0x001d,
+OPC_MUL_D = 0x001d8000,
+OPC_MULH_D = 0x001e,
+OPC_MULH_DU = 0x001e8000,
+OPC_DIV_W = 0x0020,
+OPC_MOD_W = 0x00208000,
+OPC_DIV_WU = 0x0021,
+OPC_MOD_WU = 0x00218000,
+OPC_DIV_D = 0x0022,
+OPC_MOD_D = 0x00228000,
+OPC_DIV_DU = 0x0023,
+OPC_MOD_DU = 0x00238000,
+OPC_SLLI_W = 0x00408000,
+OPC_SLLI_D = 0x0041,
+OPC_SRLI_W = 0x00448000,
+OPC_SRLI_D = 0x0045,
+OPC_SRAI_W = 0x00488000,
+OPC_SRAI_D = 0x0049,
+OPC_ROTRI_W = 0x004c8000,
+OPC_ROTRI_D = 0x004d,
+OPC_BSTRINS_W = 0x0060,
+OPC_BSTRPICK_W = 0x00608000,
+OPC_BSTRINS_D = 0x0080,
+OPC_BSTRPICK_D = 0x00c0,
+OPC_SLTI = 0x0200,
+OPC_SLTUI = 0x0240,
+OPC_ADDI_W = 0x0280,
+OPC_ADDI_D = 0x02c0,
+OPC_CU52I_D = 0x0300,
+OPC_ANDI = 0x0340,
+OPC_ORI = 0x0380,
+OPC_XORI = 0x03c0,
+OPC_LU12I_W = 0x1400,
+OPC_CU32I_D = 0x1600,
+OPC_PCADDU2I = 0x1800,
+OPC_PCALAU12I = 0x1a00,
+OPC_PCADDU12I = 0x1c00,
+OPC_PCADDU18I = 0x1e00,
+OPC_LD_B = 0x2800,
+OPC_LD_H = 0x2840,
+OPC_LD_W = 0x2880,
+OPC_LD_D = 0x28c0,
+OPC_ST_B = 0x2900,
+OPC_ST_H = 0x2940,
+OPC_ST_W = 0x2980,
+OPC_ST_D = 0x29c0,
+OPC_LD_BU = 0x2a00,
+OPC_LD_HU = 0x2a40,
+OPC_LD_WU = 0x2a80,
+OPC_DBAR = 0x3872,
+OPC_JIRL = 0x4c00,
+OPC_B = 0x5000,
+OPC_BL = 0x5400,
+OPC_BEQ = 0x5800,
+OPC_BNE = 0x5c00,
+OPC_BGT = 0x6000,
+OPC_BLE = 0x6400,
+OPC_BGTU = 0x6800,
+OPC_BLEU = 0x6c00,
+} LoongArchInsn;
+
+static int32_t __attribute__((unused))
+encode_d_slot(LoongArchInsn opc, uint32_t d)
+{
+return opc | d;
+}
+
+static int32_t __attribute__((unused))
+encode_dj_slots(LoongArchInsn opc, uint32_t d, uint32_t j)
+{
+return opc | d | j << 5;
+}
+
+static int32_t __attribute__((unused))
+encode_djk_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k)
+{
+return opc | d | j << 5 | k << 10;
+}
+
+static int32_t __attribute__((unused))
+encode_djkm_slots(LoongArchInsn opc, uint32_t d, uint32_t j, uint32_t k,
+  uint32_t m)
+{
+return opc | d | j << 5 | k << 10 | m << 16;
+}
+
+static int32_t __attribute__((unused))
+encode_dk_slots(LoongArchInsn opc, uint32_t d, uint32_t k)
+{
+return opc | d | k << 10;
+}
+
+static int32_t __attribute__((unused))
+encode_dj_insn(LoongArchInsn opc, TCGReg d, TCGReg j)
+{
+tcg_debug_assert(d >= 0 && d <= 0x1f);
+tcg_debug_assert(j >= 0 && j <= 0x1f);
+return encode_dj_slots(opc, d, j);
+}
+
+static int32_t __attribute__((unused))
+encode_djk_insn(LoongArchInsn opc, TCGReg d, TCGReg j, TCGReg k)
+{
+tcg_debug_assert(d >= 0 && d <= 0x1f);
+tcg_debug_assert(j >= 0 && j <= 0x1f);
+tcg_debug_assert(k >= 0 && k <= 0x1f);
+return encode_djk_slots(opc, d, j, k);
+}
+
+static int32_t __attribute__((unused))
+encode_djsk12_insn(LoongArchInsn opc, TCGReg d, TCGReg j, int32_t sk12)
+{
+tcg_debug_assert(d >= 0 && d <= 0x1f);
+tcg_debug_assert(j >= 0 && j <= 0x1f);
+tcg_debug_assert(sk12 >= -0x800 

[PATCH v4 08/30] tcg/loongarch64: Implement the memory barrier op

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 32 
 1 file changed, 32 insertions(+)

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 6967f143e9..8f7c556c37 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -234,3 +234,35 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
 g_assert_not_reached();
 }
 }
+
+#include "tcg-insn-defs.c.inc"
+
+/*
+ * TCG intrinsics
+ */
+
+static void tcg_out_mb(TCGContext *s, TCGArg a0)
+{
+/* Baseline LoongArch only has the full barrier, unfortunately.  */
+tcg_out_opc_dbar(s, 0);
+}
+
+/*
+ * Entry-points
+ */
+
+static void tcg_out_op(TCGContext *s, TCGOpcode opc,
+   const TCGArg args[TCG_MAX_OP_ARGS],
+   const int const_args[TCG_MAX_OP_ARGS])
+{
+TCGArg a0 = args[0];
+
+switch (opc) {
+case INDEX_op_mb:
+tcg_out_mb(s, a0);
+break;
+
+default:
+g_assert_not_reached();
+}
+}
-- 
2.33.0




[PATCH v4 03/30] tcg/loongarch64: Add the tcg-target.h file

2021-09-23 Thread WANG Xuerui
Support for all optional TCG ops are initially marked disabled; the bits
are to be set in individual commits later.

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 tcg/loongarch64/tcg-target.h | 180 +++
 1 file changed, 180 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-target.h

diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
new file mode 100644
index 00..5fc097b3c1
--- /dev/null
+++ b/tcg/loongarch64/tcg-target.h
@@ -0,0 +1,180 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * Based on tcg/riscv/tcg-target.h
+ *
+ * Copyright (c) 2018 SiFive, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef LOONGARCH_TCG_TARGET_H
+#define LOONGARCH_TCG_TARGET_H
+
+/*
+ * Loongson removed the (incomplete) 32-bit support from kernel and toolchain
+ * for the initial upstreaming of this architecture, so don't bother and just
+ * support the LP64 ABI for now.
+ */
+#if defined(__loongarch64)
+# define TCG_TARGET_REG_BITS 64
+#else
+# error unsupported LoongArch register size
+#endif
+
+#define TCG_TARGET_INSN_UNIT_SIZE 4
+#define TCG_TARGET_NB_REGS 32
+#define MAX_CODE_GEN_BUFFER_SIZE  SIZE_MAX
+
+typedef enum {
+TCG_REG_ZERO,
+TCG_REG_RA,
+TCG_REG_TP,
+TCG_REG_SP,
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+TCG_REG_T7,
+TCG_REG_T8,
+TCG_REG_RESERVED,
+TCG_REG_S9,
+TCG_REG_S0,
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+
+/* aliases */
+TCG_AREG0= TCG_REG_S0,
+TCG_REG_TMP0 = TCG_REG_T8,
+TCG_REG_TMP1 = TCG_REG_T7,
+TCG_REG_TMP2 = TCG_REG_T6,
+} TCGReg;
+
+/* used for function call generation */
+#define TCG_REG_CALL_STACK  TCG_REG_SP
+#define TCG_TARGET_STACK_ALIGN  16
+#define TCG_TARGET_CALL_ALIGN_ARGS  1
+#define TCG_TARGET_CALL_STACK_OFFSET0
+
+/* optional instructions */
+#define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_div_i32  0
+#define TCG_TARGET_HAS_rem_i32  0
+#define TCG_TARGET_HAS_div2_i32 0
+#define TCG_TARGET_HAS_rot_i32  0
+#define TCG_TARGET_HAS_deposit_i32  0
+#define TCG_TARGET_HAS_extract_i32  0
+#define TCG_TARGET_HAS_sextract_i32 0
+#define TCG_TARGET_HAS_extract2_i32 0
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
+#define TCG_TARGET_HAS_muls2_i320
+#define TCG_TARGET_HAS_muluh_i320
+#define TCG_TARGET_HAS_mulsh_i320
+#define TCG_TARGET_HAS_ext8s_i320
+#define TCG_TARGET_HAS_ext16s_i32   0
+#define TCG_TARGET_HAS_ext8u_i320
+#define TCG_TARGET_HAS_ext16u_i32   0
+#define TCG_TARGET_HAS_bswap16_i32  0
+#define TCG_TARGET_HAS_bswap32_i32  0
+#define TCG_TARGET_HAS_not_i32  0
+#define TCG_TARGET_HAS_neg_i32  0
+#define TCG_TARGET_HAS_andc_i32 0
+#define TCG_TARGET_HAS_orc_i32  0
+#define TCG_TARGET_HAS_eqv_i32  0
+#define TCG_TARGET_HAS_nand_i32 0
+#define TCG_TARGET_HAS_nor_i32  0
+#define TCG_TARGET_HAS_clz_i32  0
+#define TCG_TARGET_HAS_ctz_i32  0
+#define TCG_TARGET_HAS_ctpop_i320
+#define TCG_TARGET_HAS_direct_jump  0
+#define TCG_TARGET_HAS_brcond2  0
+#define TCG_TARGET_HAS_setcond2 0
+#define TCG_TARGET_HAS_qemu_st8_i32 0
+
+/* 64-bit operations */
+#define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_div_i64  0
+#define TCG_TARGET_HAS_rem_i64  0
+#define 

[PATCH v4 05/30] tcg/loongarch64: Add register names, allocation order and input/output sets

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target.c.inc | 118 +++
 1 file changed, 118 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-target.c.inc

diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
new file mode 100644
index 00..42eebef78e
--- /dev/null
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -0,0 +1,118 @@
+/*
+ * Tiny Code Generator for QEMU
+ *
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * Based on tcg/riscv/tcg-target.c.inc
+ *
+ * Copyright (c) 2018 SiFive, Inc
+ * Copyright (c) 2008-2009 Arnaud Patard 
+ * Copyright (c) 2009 Aurelien Jarno 
+ * Copyright (c) 2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef CONFIG_DEBUG_TCG
+static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+"zero",
+"ra",
+"tp",
+"sp",
+"a0",
+"a1",
+"a2",
+"a3",
+"a4",
+"a5",
+"a6",
+"a7",
+"t0",
+"t1",
+"t2",
+"t3",
+"t4",
+"t5",
+"t6",
+"t7",
+"t8",
+"r21", /* reserved in the LP64 ABI, hence no ABI name */
+"s9",
+"s0",
+"s1",
+"s2",
+"s3",
+"s4",
+"s5",
+"s6",
+"s7",
+"s8"
+};
+#endif
+
+static const int tcg_target_reg_alloc_order[] = {
+/* Registers preserved across calls */
+/* TCG_REG_S0 reserved for TCG_AREG0 */
+TCG_REG_S1,
+TCG_REG_S2,
+TCG_REG_S3,
+TCG_REG_S4,
+TCG_REG_S5,
+TCG_REG_S6,
+TCG_REG_S7,
+TCG_REG_S8,
+TCG_REG_S9,
+
+/* Registers (potentially) clobbered across calls */
+TCG_REG_T0,
+TCG_REG_T1,
+TCG_REG_T2,
+TCG_REG_T3,
+TCG_REG_T4,
+TCG_REG_T5,
+TCG_REG_T6,
+TCG_REG_T7,
+TCG_REG_T8,
+
+/* Argument registers, opposite order of allocation.  */
+TCG_REG_A7,
+TCG_REG_A6,
+TCG_REG_A5,
+TCG_REG_A4,
+TCG_REG_A3,
+TCG_REG_A2,
+TCG_REG_A1,
+TCG_REG_A0,
+};
+
+static const int tcg_target_call_iarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+TCG_REG_A2,
+TCG_REG_A3,
+TCG_REG_A4,
+TCG_REG_A5,
+TCG_REG_A6,
+TCG_REG_A7,
+};
+
+static const int tcg_target_call_oarg_regs[] = {
+TCG_REG_A0,
+TCG_REG_A1,
+};
-- 
2.33.0




[PATCH v4 16/30] tcg/loongarch64: Implement shl/shr/sar/rotl/rotr ops

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc | 91 
 tcg/loongarch64/tcg-target.h |  4 +-
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h 
b/tcg/loongarch64/tcg-target-con-set.h
index 2975e03127..42f8e28741 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -17,6 +17,7 @@
 C_O0_I1(r)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
+C_O1_I2(r, r, ri)
 C_O1_I2(r, r, rU)
 C_O1_I2(r, r, rW)
 C_O1_I2(r, 0, rZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 5b529b52ad..e3b0958318 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -582,6 +582,85 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 tcg_out_clzctz(s, OPC_CTZ_D, a0, a1, a2, c2, false);
 break;
 
+case INDEX_op_shl_i32:
+if (c2) {
+tcg_out_opc_slli_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_sll_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_shl_i64:
+if (c2) {
+tcg_out_opc_slli_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_sll_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_shr_i32:
+if (c2) {
+tcg_out_opc_srli_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_srl_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_shr_i64:
+if (c2) {
+tcg_out_opc_srli_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_srl_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_sar_i32:
+if (c2) {
+tcg_out_opc_srai_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_sra_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_sar_i64:
+if (c2) {
+tcg_out_opc_srai_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_sra_d(s, a0, a1, a2);
+}
+break;
+
+case INDEX_op_rotl_i32:
+/* transform into equivalent rotr/rotri */
+if (c2) {
+tcg_out_opc_rotri_w(s, a0, a1, (32 - a2) & 0x1f);
+} else {
+tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
+tcg_out_opc_rotr_w(s, a0, a1, TCG_REG_TMP0);
+}
+break;
+case INDEX_op_rotl_i64:
+/* transform into equivalent rotr/rotri */
+if (c2) {
+tcg_out_opc_rotri_d(s, a0, a1, (64 - a2) & 0x3f);
+} else {
+tcg_out_opc_sub_w(s, TCG_REG_TMP0, TCG_REG_ZERO, a2);
+tcg_out_opc_rotr_d(s, a0, a1, TCG_REG_TMP0);
+}
+break;
+
+case INDEX_op_rotr_i32:
+if (c2) {
+tcg_out_opc_rotri_w(s, a0, a1, a2 & 0x1f);
+} else {
+tcg_out_opc_rotr_w(s, a0, a1, a2);
+}
+break;
+case INDEX_op_rotr_i64:
+if (c2) {
+tcg_out_opc_rotri_d(s, a0, a1, a2 & 0x3f);
+} else {
+tcg_out_opc_rotr_d(s, a0, a1, a2);
+}
+break;
+
 case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */
 case INDEX_op_mov_i64:
 default:
@@ -631,6 +710,18 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode 
op)
  */
 return C_O1_I2(r, r, rC);
 
+case INDEX_op_shl_i32:
+case INDEX_op_shl_i64:
+case INDEX_op_shr_i32:
+case INDEX_op_shr_i64:
+case INDEX_op_sar_i32:
+case INDEX_op_sar_i64:
+case INDEX_op_rotl_i32:
+case INDEX_op_rotl_i64:
+case INDEX_op_rotr_i32:
+case INDEX_op_rotr_i64:
+return C_O1_I2(r, r, ri);
+
 case INDEX_op_and_i32:
 case INDEX_op_and_i64:
 case INDEX_op_nor_i32:
diff --git a/tcg/loongarch64/tcg-target.h b/tcg/loongarch64/tcg-target.h
index ef489cbc86..e59c2a7bec 100644
--- a/tcg/loongarch64/tcg-target.h
+++ b/tcg/loongarch64/tcg-target.h
@@ -96,7 +96,7 @@ typedef enum {
 #define TCG_TARGET_HAS_div_i32  0
 #define TCG_TARGET_HAS_rem_i32  0
 #define TCG_TARGET_HAS_div2_i32 0
-#define TCG_TARGET_HAS_rot_i32  0
+#define TCG_TARGET_HAS_rot_i32  1
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_extract_i32  1
 #define TCG_TARGET_HAS_sextract_i32 0
@@ -133,7 +133,7 @@ typedef enum {
 #define TCG_TARGET_HAS_div_i64  0
 #define TCG_TARGET_HAS_rem_i64  0
 #define TCG_TARGET_HAS_div2_i64 0
-#define TCG_TARGET_HAS_rot_i64  0
+#define TCG_TARGET_HAS_rot_i64  1
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_extract_i64  1
 #define TCG_TARGET_HAS_sextract_i64 0
-- 
2.33.0




[PATCH v4 06/30] tcg/loongarch64: Define the operand constraints

2021-09-23 Thread WANG Xuerui
Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 tcg/loongarch64/tcg-target-con-str.h | 28 +++
 tcg/loongarch64/tcg-target.c.inc | 52 
 2 files changed, 80 insertions(+)
 create mode 100644 tcg/loongarch64/tcg-target-con-str.h

diff --git a/tcg/loongarch64/tcg-target-con-str.h 
b/tcg/loongarch64/tcg-target-con-str.h
new file mode 100644
index 00..c3986a4fd4
--- /dev/null
+++ b/tcg/loongarch64/tcg-target-con-str.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Define LoongArch target-specific operand constraints.
+ *
+ * Copyright (c) 2021 WANG Xuerui 
+ *
+ * Based on tcg/riscv/tcg-target-con-str.h
+ *
+ * Copyright (c) 2021 Linaro
+ */
+
+/*
+ * Define constraint letters for register sets:
+ * REGS(letter, register_mask)
+ */
+REGS('r', ALL_GENERAL_REGS)
+REGS('L', ALL_GENERAL_REGS & ~SOFTMMU_RESERVE_REGS)
+
+/*
+ * Define constraint letters for constants:
+ * CONST(letter, TCG_CT_CONST_* bit set)
+ */
+CONST('I', TCG_CT_CONST_S12)
+CONST('N', TCG_CT_CONST_N12)
+CONST('U', TCG_CT_CONST_U12)
+CONST('Z', TCG_CT_CONST_ZERO)
+CONST('C', TCG_CT_CONST_C12)
+CONST('W', TCG_CT_CONST_WSZ)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index 42eebef78e..f0930f77ef 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -116,3 +116,55 @@ static const int tcg_target_call_oarg_regs[] = {
 TCG_REG_A0,
 TCG_REG_A1,
 };
+
+#define TCG_CT_CONST_ZERO  0x100
+#define TCG_CT_CONST_S12   0x200
+#define TCG_CT_CONST_N12   0x400
+#define TCG_CT_CONST_U12   0x800
+#define TCG_CT_CONST_C12   0x1000
+#define TCG_CT_CONST_WSZ   0x2000
+
+#define ALL_GENERAL_REGS  MAKE_64BIT_MASK(0, 32)
+/*
+ * For softmmu, we need to avoid conflicts with the first 5
+ * argument registers to call the helper.  Some of these are
+ * also used for the tlb lookup.
+ */
+#ifdef CONFIG_SOFTMMU
+#define SOFTMMU_RESERVE_REGS  MAKE_64BIT_MASK(TCG_REG_A0, 5)
+#else
+#define SOFTMMU_RESERVE_REGS  0
+#endif
+
+
+static inline tcg_target_long sextreg(tcg_target_long val, int pos, int len)
+{
+return sextract64(val, pos, len);
+}
+
+/* test if a constant matches the constraint */
+static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
+{
+if (ct & TCG_CT_CONST) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_U12) && val >= 0 && val <= 0xfff) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_C12) && ~val >= 0 && ~val <= 0xfff) {
+return 1;
+}
+if ((ct & TCG_CT_CONST_WSZ) && val == (type == TCG_TYPE_I32 ? 32 : 64)) {
+return 1;
+}
+return 0;
+}
-- 
2.33.0




[PATCH v4 01/30] elf: Add machine type value for LoongArch

2021-09-23 Thread WANG Xuerui
This is already officially allocated as recorded in GNU binutils
repo [1], and the description is updated in [2]. Add to enable further
work.

[1]: 
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=4cf2ad720078a9f490dd5b5bc8893a926479196e
[2]: 
https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=01a8c731aacbdbed0eb5682d13cc074dc7e25fb3

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/elf.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index 811bf4a1cb..3a4bcb646a 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 {
 
 #define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */
 
+#define EM_LOONGARCH258 /* LoongArch */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
-- 
2.33.0




[PATCH v4 02/30] MAINTAINERS: Add tcg/loongarch64 entry with myself as maintainer

2021-09-23 Thread WANG Xuerui
I ported the initial code, so I should maintain it of course.

Signed-off-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
---
 MAINTAINERS | 5 +
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d7915ec128..859e5b5ba2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3114,6 +3114,11 @@ S: Maintained
 F: tcg/i386/
 F: disas/i386.c
 
+LoongArch64 TCG target
+M: WANG Xuerui 
+S: Maintained
+F: tcg/loongarch64/
+
 MIPS TCG target
 M: Philippe Mathieu-Daudé 
 R: Aurelien Jarno 
-- 
2.33.0




[PATCH v4 00/30] LoongArch64 port of QEMU TCG

2021-09-23 Thread WANG Xuerui
Hi all,

This is a port of QEMU TCG to the brand-new CPU architecture LoongArch,
introduced by Loongson with their 3A5000 chips.

Tests (run with `ninja test`) all passed, as usual; I also boot-tested
x86_64 (Debian and Gentoo installation CDs) and install-tested aarch64
(Debian netboot installer), and ran riscv64 linux-user emulation with a
chroot; everything seems fine.

## About the series

Only the LP64 ABI is supported, as this is the only one fully
implemented and supported by Loongson. 32-bit support is incomplete from
outset, and removed from the very latest upstream submissions, so you
can't even configure for that.

The architecture's documentation is already translated into English;
it can be browsed at https://loongson.github.io/LoongArch-Documentation/.
The LoongArch ELF psABI doc (version 1.00) could be found at [1];
if anything is missing there, it's most likely the same as RISC-V, but
you can always raise an issue over their issue tracker at [2].

[1]: 
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
[2]: https://github.com/loongson/LoongArch-Documentation/issues

In this series I made use of generated instruction encodings and
emitters from https://github.com/loongson-community/loongarch-opcodes
(a community project started by myself, something I must admit), as the
LoongArch encoding is highly irregular even for a fixed 32-bit ISA, and
I want to minimize the maintenance burden for future collaboration. This
is something not seen in any of the other TCG ports out there, so I'd
like to see if this is acceptable practice (and also maybe bikeshed the
file name).

This series touches some of the same files as Song Gao's previous
submission of LoongArch *target* support, which is a bit unfortunate;
one of us will have to rebase after either series gets in. Actual
conflict should only happen on build system bits and include/elf.h,
though, as we're working on entirely different areas.

## How to build and test this

Upstream support for LoongArch is largely WIP for now, which means you
must apply a lot of patches if you want to even cross-build for this arch.
The main sources I used are as follows:

* binutils: https://github.com/xen0n/binutils-gdb/tree/for-gentoo-2.37-v2
  based on 
https://github.com/loongson/binutils-gdb/tree/loongarch/upstream_v6_a1d65b3
* gcc: https://github.com/xen0n/gcc/tree/for-gentoo-gcc-12-v2
  based on https://github.com/loongson/gcc/tree/loongarch_upstream
* glibc: https://github.com/xen0n/glibc/tree/for-gentoo-glibc-2.34
  based on https://github.com/loongson/glibc/tree/loongarch_2_34_for_upstream
* Linux: https://github.com/xen0n/linux/tree/loongarch-playground
  based on https://github.com/loongson/linux/tree/loongarch-next
* Gentoo overlay: https://github.com/xen0n/loongson-overlay

I have made ready-to-use Gentoo stage3 tarballs, but they're served with
CDN off my personal cloud account, and I don't want the link to be
exposed so that my bills skyrocket; you can reach me off-list to get the
links if you're interested.

As for the hardware availability, the boards can already be bought in
China on Taobao, and I think some people at Loongson might be able to
arrange for testing environments, if testing on real hardware other than
mine is required before merging; they have their in-house Debian spin-off
from the early days of this architecture. Their kernel is
ABI-incompatible with the version being upstreamed and used by me, but
QEMU should work there regardless.

Lastly, I'm new to QEMU development and this is my first patch series
here; apologizes if I get anything wrong, and any help or suggestion is
certainly appreciated!

## Changelog

v4 -> v3:

- Addressed all review comments from v3
  - Made MAX_CODE_GEN_BUFFER_SIZE to be just SIZE_MAX (but kept
TCG_TARGET_NB_REGS as macro definition)
  - Updated generated instruction definition, made it clear that the
whole file is generated
  - Used deposit64 for hand-written relocation code
  - Reworked tcg_out_movi
- Use pcalau12i + ori for PC-relative values whose offset fits in
  32-bit
- Every individual insn in the slow path (lu12i.w + ori + cu32i.d +
  cu52i.d) can be suppressed if not needed
  - Fixed constraint of setcond ops, don't allow constant zero for 1st
operand

v3 -> v2:

- Addressed all review comments from v2
  - Re-organized changes to tcg-target.h so that it's incrementally
updated in each commit implementing ops
  - Removed support for the eqv op
  - Added support for bswap16_i{32,64} ops
  - Fixed and refactored various places as pointed out during review
- Updated generated instruction definitions to latest

v2 -> v1:

- Addressed all review comments from v1
  - Use "loongarch64" everywhere, tcg directory renamed to "tcg/loongarch64"
  - Removed all redundant TCG_TARGET_REG_BITS conditional
  - Removed support for the neg op
  - Added support for eqv and bswap32_i64 ops
  - Added safe syscall handling for linux-user
  - Fixed everything 

Re: [PATCH 1/2] tests/qapi-schema: Use Python OSError instead of outmoded IOError

2021-09-23 Thread John Snow
On Thu, Sep 23, 2021 at 5:33 AM Markus Armbruster  wrote:

> John Snow  writes:
>
> > On Wed, Sep 22, 2021 at 8:56 AM Markus Armbruster 
> wrote:
> >
> >> Signed-off-by: Markus Armbruster 
> >> ---
> >>  tests/qapi-schema/test-qapi.py | 4 ++--
> >>  1 file changed, 2 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/tests/qapi-schema/test-qapi.py
> >> b/tests/qapi-schema/test-qapi.py
> >> index 73cffae2b6..2e384f5efd 100755
> >> --- a/tests/qapi-schema/test-qapi.py
> >> +++ b/tests/qapi-schema/test-qapi.py
> >> @@ -154,7 +154,7 @@ def test_and_diff(test_name, dir_name, update):
> >>  errfp = open(os.path.join(dir_name, test_name + '.err'), mode)
> >>  expected_out = outfp.readlines()
> >>  expected_err = errfp.readlines()
> >> -except IOError as err:
> >> +except OSError as err:
> >>  print("%s: can't open '%s': %s"
> >>% (sys.argv[0], err.filename, err.strerror),
> >>file=sys.stderr)
> >> @@ -180,7 +180,7 @@ def test_and_diff(test_name, dir_name, update):
> >>  errfp.truncate(0)
> >>  errfp.seek(0)
> >>  errfp.writelines(actual_err)
> >> -except IOError as err:
> >> +except OSError as err:
> >>  print("%s: can't write '%s': %s"
> >>% (sys.argv[0], err.filename, err.strerror),
> >>file=sys.stderr)
> >> --
> >> 2.31.1
> >>
> >>
> > If you're happy with the expanded scope of the exception-catcher, I am
> too.
>
> https://docs.python.org/3.6/library/exceptions.html has
>
> Changed in version 3.3: EnvironmentError, IOError, WindowsError,
> socket.error, select.error and mmap.error have been merged into
> OSError, and the constructor may return a subclass.
>
> and
>
> The following exceptions are kept for compatibility with previous
> versions; starting from Python 3.3, they are aliases of OSError.
>
> exception EnvironmentError
>
> exception IOError
>
> exception WindowsError
>
> Only available on Windows.
>
> So unless I'm misunderstanding something (which is quite possible),
> we're catching exactly the same exceptions as before, we just switch to
> their preferred name.
>
> > Reviewed-by: John Snow 
>
> Thanks!
>
>
Yeah, I suppose the 3.3 upgrade already "expanded" the coverage here, so
you aren't expanding anything. It's just an expansion of intent in the
source code, if that distinction makes sense. The code is obviously fine so
far as I can tell. My RB stands!

--js


Re: [PATCH] block: introduce max_hw_iov for use in scsi-generic

2021-09-23 Thread Halil Pasic
On Thu, 23 Sep 2021 16:28:11 +0200
Halil Pasic  wrote:

> Can't we use some of the established constants instead of hard coding a
> qemu specific IOV_MAX?
> 
> POSIX.1 seems to guarantee the availability of IOV_MAX in 
> according to: https://man7.org/linux/man-pages/man2/readv.2.html
> and  may have UIO_MAXIOV defined.

Never mind, the 
#define IOV_MAX 1024
in osdep.h is conditional and I guess we already use IOV_MAX from limit
when CONFIG_IOVEC is defined, i.e. when we don't emulate the interface.

Sorry for the noise.

Regards,
Halil



[PATCH v3 1/3] tests/Makefile: allow control over tags during check-acceptance

2021-09-23 Thread Willian Rampazzo
Although it is possible to run a specific test using the avocado
command-line, a user may want to use a specific tag while running the
``make check-acceptance`` during the development or debugging.

This allows using the AVOCADO_TAGS environment variable where the user
takes total control of which tests should run based on the tags defined.

This also makes the check-acceptance command flexible to restrict tests
based on tags while running on CI.

e.g.:

AVOCADO_TAGS="foo bar baz" make check-acceptance

Signed-off-by: Willian Rampazzo 
Tested-by: Wainer dos Santos Moschetta 
Reviewed-by: Wainer dos Santos Moschetta 
Reviewed-by: Thomas Huth 
---
 docs/devel/testing.rst | 14 ++
 tests/Makefile.include | 12 +---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 4a0abbf23d..d1841e35d5 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -732,6 +732,20 @@ available.  On Debian and Ubuntu based systems, depending 
on the
 specific version, they may be on packages named ``python3-venv`` and
 ``python3-pip``.
 
+It is also possible to run tests based on tags using the
+``make check-acceptance`` command and the ``AVOCADO_TAGS`` environment
+variable:
+
+.. code::
+
+   make check-acceptance AVOCADO_TAGS=quick
+
+Note that tags separated with commas have an AND behavior, while tags
+separated by spaces have an OR behavior. For more information on Avocado
+tags, see:
+
+ 
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/tags.html
+
 The scripts installed inside the virtual environment may be used
 without an "activation".  For instance, the Avocado test runner
 may be invoked by running:
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 6e16c05f10..f6484e5b31 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -92,7 +92,12 @@ TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
 # Any number of command separated loggers are accepted.  For more
 # information please refer to "avocado --help".
 AVOCADO_SHOW=app
-AVOCADO_TAGS=$(patsubst %-softmmu,-t arch:%, $(filter %-softmmu,$(TARGETS)))
+ifndef AVOCADO_TAGS
+   AVOCADO_CMDLINE_TAGS=$(patsubst %-softmmu,-t arch:%, \
+$(filter %-softmmu,$(TARGETS)))
+else
+   AVOCADO_CMDLINE_TAGS=$(addprefix -t , $(AVOCADO_TAGS))
+endif
 
 $(TESTS_VENV_DIR): $(TESTS_VENV_REQ)
$(call quiet-command, \
@@ -128,8 +133,9 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR) 
get-vm-images
$(call quiet-command, \
 $(TESTS_VENV_DIR)/bin/python -m avocado \
 --show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
---filter-by-tags-include-empty --filter-by-tags-include-empty-key \
-$(AVOCADO_TAGS) \
+$(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
+   --filter-by-tags-include-empty-key) \
+$(AVOCADO_CMDLINE_TAGS) \
 $(if $(GITLAB_CI),,--failfast) tests/acceptance, \
 "AVOCADO", "tests/acceptance")
 
-- 
2.31.1




[PATCH v3 3/3] tests/Makefile: add AVOCADO_TESTS option to make check-acceptance

2021-09-23 Thread Willian Rampazzo
Add the possibility of running all the tests from a single file, or
multiple files, running a single test within a file or multiple tests
within multiple files using `make check-acceptance` and the
AVOCADO_TESTS environment variable.

Suggested-by: Daniel P. Berrangé 
Signed-off-by: Willian Rampazzo 
---
 docs/devel/testing.rst | 27 +++
 tests/Makefile.include |  5 -
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index c9f6b97f87..64c9744795 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -746,6 +746,33 @@ tags, see:
 
  
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/tags.html
 
+To run a single test file, a couple of them, or a test within a file
+using the ``make check-acceptance`` command, set the ``AVOCADO_TESTS``
+environment variable with the test files or test names. To run all
+tests from a single file, use:
+
+ .. code::
+
+  make check-acceptance AVOCADO_TESTS=$FILEPATH
+
+The same is valid to run tests from multiple test files:
+
+ .. code::
+
+  make check-acceptance AVOCADO_TESTS='$FILEPATH1 $FILEPATH2'
+
+To run a single test within a file, use:
+
+ .. code::
+
+  make check-acceptance AVOCADO_TESTS=$FILEPATH:$TESTCLASS.$TESTNAME
+
+The same is valid to run single tests from multiple test files:
+
+ .. code::
+
+  make check-acceptance AVOCADO_TESTS='$FILEPATH1:$TESTCLASS1.$TESTNAME1 
$FILEPATH2:$TESTCLASS2.$TESTNAME2'
+
 The scripts installed inside the virtual environment may be used
 without an "activation".  For instance, the Avocado test runner
 may be invoked by running:
diff --git a/tests/Makefile.include b/tests/Makefile.include
index f6484e5b31..e69c4fae53 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -88,6 +88,9 @@ clean-tcg: $(CLEAN_TCG_TARGET_RULES)
 TESTS_VENV_DIR=$(BUILD_DIR)/tests/venv
 TESTS_VENV_REQ=$(SRC_PATH)/tests/requirements.txt
 TESTS_RESULTS_DIR=$(BUILD_DIR)/tests/results
+ifndef AVOCADO_TESTS
+   AVOCADO_TESTS=tests/acceptance
+endif
 # Controls the output generated by Avocado when running tests.
 # Any number of command separated loggers are accepted.  For more
 # information please refer to "avocado --help".
@@ -136,7 +139,7 @@ check-acceptance: check-venv $(TESTS_RESULTS_DIR) 
get-vm-images
 $(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
--filter-by-tags-include-empty-key) \
 $(AVOCADO_CMDLINE_TAGS) \
-$(if $(GITLAB_CI),,--failfast) tests/acceptance, \
+$(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \
 "AVOCADO", "tests/acceptance")
 
 # Consolidated targets
-- 
2.31.1




  1   2   3   >